From be753549c23d25633568b08c118dd166225f6724 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 22 May 2010 15:16:14 +0000 Subject: [PATCH 001/292] [SHELL32] - Duplicate the string instead of freeing the memory twice at two different positions - Fixes a heap warning when stating cmd from the desktop See issue #4924 for more details. svn path=/trunk/; revision=47305 --- reactos/dll/win32/shell32/shelllink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/shell32/shelllink.c b/reactos/dll/win32/shell32/shelllink.c index b2dd1cb6ff8..ae159cdcdc2 100644 --- a/reactos/dll/win32/shell32/shelllink.c +++ b/reactos/dll/win32/shell32/shelllink.c @@ -2828,7 +2828,7 @@ ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici ) } else if (This->sArgs != NULL) { - args = This->sArgs; + args = strdupW( This->sArgs ); } memset( &sei, 0, sizeof sei ); From fdbfc02407c86b5fca480fb65ccc03bdd1ba4ebf Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 22 May 2010 15:28:23 +0000 Subject: [PATCH 002/292] [REACTOS.DFF] - Add kmtest.sys and kmtestassist.sys to bootcd (optional) svn path=/trunk/; revision=47306 --- reactos/boot/bootdata/packages/reactos.dff | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index c76e469d7f2..12db9f8d330 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -756,6 +756,8 @@ modules\rosapps\drivers\green\green.sys 2 o ; Rostests modules\rostests\rosautotest\rosautotest.exe 1 optional +modules\rostests\drivers\kmtest\kmtest.sys 2 optional +modules\rostests\drivers\kmtest\kmtestassist.sys 2 optional modules\rostests\tests\pseh2\pseh2_test.exe 7 optional modules\rostests\winetests\advapi32\advapi32_winetest.exe 7 optional modules\rostests\winetests\advpack\advpack_winetest.exe 7 optional From df9115f1d23ff7cccae0a9fe356a0ce9e0bbc09c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 22 May 2010 16:03:25 +0000 Subject: [PATCH 003/292] [NTOSKRNL] - Free the string buffer after the DPRINT1 that prints the contents of the string - Fixes debug print corruption found by kmtest svn path=/trunk/; revision=47307 --- reactos/ntoskrnl/io/iomgr/driver.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 1ab54458526..d32957ec7d7 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -1171,17 +1171,18 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) 0, (PVOID*)&DriverObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); + ExFreePool(ObjectName.Buffer); + return Status; + } + /* * Free the buffer for driver object name */ ExFreePool(ObjectName.Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); - return Status; - } - /* Check that driver is not already unloading */ if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) { From d7bbeaed19404486112b642de54d754b8370d393 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 22 May 2010 16:12:59 +0000 Subject: [PATCH 004/292] [NTOSKRNL] - Print a warning instead of crashing when a driver provides a NULL pointer in the MajorFunction array svn path=/trunk/; revision=47308 --- reactos/ntoskrnl/io/iomgr/driver.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index d32957ec7d7..7dcb0354ea1 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -1556,11 +1556,14 @@ try_again: * Doing so is illegal; drivers shouldn't touch entry points they * do not implement. */ - ASSERT(DriverObject->MajorFunction[i] != NULL); /* Check if it did so anyway */ - if (!DriverObject->MajorFunction[i]) + if (!DriverObject->MajorFunction[i]) { + /* Print a warning in the debug log */ + DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%d] to NULL!\n", + &DriverObject->DriverName, i); + /* Fix it up */ DriverObject->MajorFunction[i] = IopInvalidDeviceRequest; } From afcd401a323cce883f45d0d97b0c0e7f13583857 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 22 May 2010 18:34:01 +0000 Subject: [PATCH 005/292] [KMTEST] - Add support for recovering from crashed tests - Add check to prevent us from running the test every boot - Delete some useless code - Record test result information in the registry - Under the Kmtest\Parameters key, you will find CurrentStage which is the stage that testing is on (almost always 8 if it boots). You will also find SuccessCount which is the number of successful tests, FailureCount which is the number of failed tests, TotalCount which is the total number of tests, and SkippedCount which is the number of tests that have been skipped - Enjoy your reg testing! :) svn path=/trunk/; revision=47309 --- rostests/drivers/kmtest/deviface.c | 545 ------------------------ rostests/drivers/kmtest/deviface_test.c | 35 +- rostests/drivers/kmtest/kmtest.c | 343 ++++++++++++--- rostests/drivers/kmtest/kmtest.h | 8 +- rostests/drivers/kmtest/kmtest.rbuild | 1 - rostests/drivers/kmtest/ntos_ex.c | 15 +- rostests/drivers/kmtest/ntos_io.c | 17 +- rostests/drivers/kmtest/ntos_ke.c | 15 +- rostests/drivers/kmtest/ntos_ob.c | 6 +- rostests/drivers/kmtest/ntos_pools.c | 21 +- 10 files changed, 330 insertions(+), 676 deletions(-) delete mode 100644 rostests/drivers/kmtest/deviface.c diff --git a/rostests/drivers/kmtest/deviface.c b/rostests/drivers/kmtest/deviface.c deleted file mode 100644 index a3011f3d141..00000000000 --- a/rostests/drivers/kmtest/deviface.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * PnP Test - * ReactOS Device Interface functions implementation - * - * Copyright 2003, 2004 Filip Navara - * Copyright 2003, 2004 Matthew Brace - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; see the file COPYING.LIB. - * If not, write to the Free Software Foundation, - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* INCLUDES *******************************************************************/ - -#include -#include "kmtest.h" - -//#define NDEBUG -#include "debug.h" - -/* PUBLIC FUNCTIONS ***********************************************************/ - -/* - * IoGetDeviceInterfaces - * - * Returns a list of device interfaces of a particular device interface class. - * - * Parameters - * InterfaceClassGuid - * Points to a class GUID specifying the device interface class. - * - * PhysicalDeviceObject - * Points to an optional PDO that narrows the search to only the - * device interfaces of the device represented by the PDO. - * - * Flags - * Specifies flags that modify the search for device interfaces. The - * DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of - * returned symbolic links should contain also disabled device - * interfaces in addition to the enabled ones. - * - * SymbolicLinkList - * Points to a character pointer that is filled in on successful return - * with a list of unicode strings identifying the device interfaces - * that match the search criteria. The newly allocated buffer contains - * a list of symbolic link names. Each unicode string in the list is - * null-terminated; the end of the whole list is marked by an additional - * NULL. The caller is responsible for freeing the buffer (ExFreePool) - * when it is no longer needed. - * If no device interfaces match the search criteria, this routine - * returns STATUS_SUCCESS and the string contains a single NULL - * character. - * - * Status - * @unimplemented - * - * The parameters PhysicalDeviceObject and Flags aren't correctly - * processed. Rest of the cases was tested under Win XP and the - * function worked correctly. - */ - -NTSTATUS NTAPI -ReactOS_IoGetDeviceInterfaces( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList) -{ - PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"; - PWCHAR BaseInterfaceString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; - UNICODE_STRING GuidString; - UNICODE_STRING BaseKeyName; - UNICODE_STRING AliasKeyName; - UNICODE_STRING SymbolicLink; - UNICODE_STRING Control; - UNICODE_STRING SubKeyName; - UNICODE_STRING SymbolicLinkKeyName; - UNICODE_STRING ControlKeyName; - UNICODE_STRING TempString; - HANDLE InterfaceKey; - HANDLE SubKey; - HANDLE SymbolicLinkKey; - PKEY_FULL_INFORMATION fip; - PKEY_FULL_INFORMATION bfip=NULL; - PKEY_BASIC_INFORMATION bip; - PKEY_VALUE_PARTIAL_INFORMATION vpip=NULL; - PWCHAR SymLinkList = NULL; - ULONG SymLinkListSize = 0; - NTSTATUS Status; - ULONG Size = 0; - ULONG i = 0; - ULONG j = 0; - OBJECT_ATTRIBUTES ObjectAttributes; - - Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlStringFromGUID() Failed.\n"); - return STATUS_INVALID_HANDLE; - } - - RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString); - RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink"); - RtlInitUnicodeString(&Control, L"\\Control"); - BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR); - BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR)); - BaseKeyName.Buffer = ExAllocatePool( - NonPagedPool, - BaseKeyName.MaximumLength); - ASSERT(BaseKeyName.Buffer != NULL); - wcscpy(BaseKeyName.Buffer, BaseKeyString); - RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString); - - if (PhysicalDeviceObject) - { - WCHAR GuidBuffer[40]; - UNICODE_STRING PdoGuidString; - - RtlFreeUnicodeString(&BaseKeyName); - - IoGetDeviceProperty( - PhysicalDeviceObject, - DevicePropertyClassGuid, - sizeof(GuidBuffer), - GuidBuffer, - &Size); - - RtlInitUnicodeString(&PdoGuidString, GuidBuffer); - if (RtlCompareUnicodeString(&GuidString, &PdoGuidString, TRUE)) - { - DPRINT("Inconsistent Guid's asked for in IoGetDeviceInterfaces()\n"); - return STATUS_INVALID_HANDLE; - } - - DPRINT("IoGetDeviceInterfaces() called with PDO, not implemented.\n"); - return STATUS_NOT_IMPLEMENTED; - } - else - { - InitializeObjectAttributes( - &ObjectAttributes, - &BaseKeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwOpenKey( - &InterfaceKey, - KEY_READ, - &ObjectAttributes); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status); - RtlFreeUnicodeString(&BaseKeyName); - return Status; - } - - Status = ZwQueryKey( - InterfaceKey, - KeyFullInformation, - NULL, - 0, - &Size); - - if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - return Status; - } - - fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size); - ASSERT(fip != NULL); - - Status = ZwQueryKey( - InterfaceKey, - KeyFullInformation, - fip, - Size, - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status); - ExFreePool(fip); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - return Status; - } - - for (; i < fip->SubKeys; i++) - { - Status = ZwEnumerateKey( - InterfaceKey, - i, - KeyBasicInformation, - NULL, - 0, - &Size); - - if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status); - ExFreePool(fip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - return Status; - } - - bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size); - ASSERT(bip != NULL); - - Status = ZwEnumerateKey( - InterfaceKey, - i, - KeyBasicInformation, - bip, - Size, - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status); - ExFreePool(fip); - ExFreePool(bip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - return Status; - } - - SubKeyName.Length = 0; - SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR); - SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength); - ASSERT(SubKeyName.Buffer != NULL); - TempString.Length = TempString.MaximumLength = bip->NameLength; - TempString.Buffer = bip->Name; - RtlCopyUnicodeString(&SubKeyName, &BaseKeyName); - RtlAppendUnicodeToString(&SubKeyName, L"\\"); - RtlAppendUnicodeStringToString(&SubKeyName, &TempString); - - ExFreePool(bip); - - InitializeObjectAttributes( - &ObjectAttributes, - &SubKeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwOpenKey( - &SubKey, - KEY_READ, - &ObjectAttributes); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status); - ExFreePool(fip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - return Status; - } - - Status = ZwQueryKey( - SubKey, - KeyFullInformation, - NULL, - 0, - &Size); - - if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status); - ExFreePool(fip); - RtlFreeUnicodeString(&BaseKeyName); - RtlFreeUnicodeString(&SubKeyName); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - bfip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size); - ASSERT(bfip != NULL); - - Status = ZwQueryKey( - SubKey, - KeyFullInformation, - bfip, - Size, - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status); - ExFreePool(fip); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - for(j = 0; j < bfip->SubKeys; j++) - { - Status = ZwEnumerateKey( - SubKey, - j, - KeyBasicInformation, - NULL, - 0, - &Size); - - if (Status == STATUS_NO_MORE_ENTRIES) - continue; - - if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status); - ExFreePool(bfip); - ExFreePool(fip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size); - ASSERT(bip != NULL); - - Status = ZwEnumerateKey( - SubKey, - j, - KeyBasicInformation, - bip, - Size, - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status); - ExFreePool(fip); - ExFreePool(bfip); - ExFreePool(bip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - if (!wcsncmp(bip->Name, L"Control", bip->NameLength)) - { - continue; - } - - SymbolicLinkKeyName.Length = 0; - SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR); - SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength); - ASSERT(SymbolicLinkKeyName.Buffer != NULL); - TempString.Length = TempString.MaximumLength = bip->NameLength; - TempString.Buffer = bip->Name; - RtlCopyUnicodeString(&SymbolicLinkKeyName, &SubKeyName); - RtlAppendUnicodeToString(&SymbolicLinkKeyName, L"\\"); - RtlAppendUnicodeStringToString(&SymbolicLinkKeyName, &TempString); - - ControlKeyName.Length = 0; - ControlKeyName.MaximumLength = SymbolicLinkKeyName.Length + Control.Length + sizeof(WCHAR); - ControlKeyName.Buffer = ExAllocatePool(NonPagedPool, ControlKeyName.MaximumLength); - ASSERT(ControlKeyName.Buffer != NULL); - RtlCopyUnicodeString(&ControlKeyName, &SymbolicLinkKeyName); - RtlAppendUnicodeStringToString(&ControlKeyName, &Control); - - ExFreePool(bip); - - InitializeObjectAttributes( - &ObjectAttributes, - &SymbolicLinkKeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwOpenKey( - &SymbolicLinkKey, - KEY_READ, - &ObjectAttributes); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status); - ExFreePool(fip); - ExFreePool(bfip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SymbolicLinkKeyName); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - Status = ZwQueryValueKey( - SymbolicLinkKey, - &SymbolicLink, - KeyValuePartialInformation, - NULL, - 0, - &Size); - - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - continue; - - if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status); - ExFreePool(fip); - ExFreePool(bfip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SymbolicLinkKeyName); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SymbolicLinkKey); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size); - ASSERT(vpip != NULL); - - Status = ZwQueryValueKey( - SymbolicLinkKey, - &SymbolicLink, - KeyValuePartialInformation, - vpip, - Size, - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status); - ExFreePool(fip); - ExFreePool(bfip); - ExFreePool(vpip); - if (SymLinkList != NULL) - ExFreePool(SymLinkList); - RtlFreeUnicodeString(&SymbolicLinkKeyName); - RtlFreeUnicodeString(&SubKeyName); - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(SymbolicLinkKey); - ZwClose(SubKey); - ZwClose(InterfaceKey); - return Status; - } - - Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ControlKeyName.Buffer); - - if (NT_SUCCESS(Status)) - { - /* Put the name in the string here */ - if (SymLinkList == NULL) - { - SymLinkListSize = vpip->DataLength; - SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR)); - ASSERT(SymLinkList != NULL); - RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength); - SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0; - SymLinkList[1] = '?'; - } - else - { - PWCHAR OldSymLinkList; - ULONG OldSymLinkListSize; - PWCHAR SymLinkListPtr; - - OldSymLinkList = SymLinkList; - OldSymLinkListSize = SymLinkListSize; - SymLinkListSize += vpip->DataLength; - SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR)); - ASSERT(SymLinkList != NULL); - RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize); - ExFreePool(OldSymLinkList); - SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR)); - RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength); - SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0; - SymLinkListPtr[1] = '?'; - } - } - - RtlFreeUnicodeString(&SymbolicLinkKeyName); - RtlFreeUnicodeString(&ControlKeyName); - ZwClose(SymbolicLinkKey); - } - - ExFreePool(vpip); - RtlFreeUnicodeString(&SubKeyName); - ZwClose(SubKey); - } - - if (SymLinkList != NULL) - { - SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0; - } - else - { - SymLinkList = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR)); - SymLinkList[0] = 0; - } - - *SymbolicLinkList = SymLinkList; - - RtlFreeUnicodeString(&BaseKeyName); - ZwClose(InterfaceKey); - ExFreePool(bfip); - ExFreePool(fip); - } - - return STATUS_SUCCESS; -} diff --git a/rostests/drivers/kmtest/deviface_test.c b/rostests/drivers/kmtest/deviface_test.c index 0fbd91ea23e..2e27349697c 100644 --- a/rostests/drivers/kmtest/deviface_test.c +++ b/rostests/drivers/kmtest/deviface_test.c @@ -26,7 +26,7 @@ #include #include "kmtest.h" -//#define NDEBUG +#define NDEBUG #include "debug.h" /* PRIVATE FUNCTIONS **********************************************************/ @@ -52,26 +52,26 @@ VOID DeviceInterfaceTest_Func() PWSTR SymbolicLinkListPtr; GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; - Status = IoGetDeviceInterfaces_Func( + Status = IoGetDeviceInterfaces( &Guid, NULL, 0, &SymbolicLinkList); + ok(NT_SUCCESS(Status), + "IoGetDeviceInterfaces failed with status 0x%X\n", + (unsigned int)Status); if (!NT_SUCCESS(Status)) { - DPRINT( - "[PnP Test] IoGetDeviceInterfaces failed with status 0x%X\n", - Status); return; } - DPRINT("[PnP Test] IoGetDeviceInterfaces results:\n"); + DPRINT("IoGetDeviceInterfaces results:\n"); for (SymbolicLinkListPtr = SymbolicLinkList; SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) { - DPRINT("[PnP Test] %S\n", SymbolicLinkListPtr); + DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr); } #if 0 @@ -102,7 +102,7 @@ VOID DeviceInterfaceTest_Func() ExFreePool(SymbolicLinkList); } -VOID RegisterDI_Test() +VOID RegisterDI_Test(HANDLE KeyHandle) { GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; DEVICE_OBJECT DeviceObject; @@ -111,6 +111,8 @@ VOID RegisterDI_Test() UNICODE_STRING SymbolicLinkName; NTSTATUS Status; + StartTest(); + RtlInitUnicodeString(&SymbolicLinkName, L""); // Prepare our surrogate of a Device Object @@ -132,23 +134,8 @@ VOID RegisterDI_Test() ok(Status == STATUS_INVALID_DEVICE_REQUEST, "IoRegisterDeviceInterface returned 0x%08lX\n", Status); -} -VOID NtoskrnlIoDeviceInterface() -{ - StartTest(); - - // Test IoRegisterDeviceInterface() failures now - RegisterDI_Test(); - -/* - DPRINT("Calling DeviceInterfaceTest_Func with native functions\n"); - IoGetDeviceInterfaces_Func = IoGetDeviceInterfaces; DeviceInterfaceTest_Func(); - DPRINT("Calling DeviceInterfaceTest_Func with ReactOS functions\n"); - IoGetDeviceInterfaces_Func = ReactOS_IoGetDeviceInterfaces; - DeviceInterfaceTest_Func(); -*/ - FinishTest("NTOSKRNL Io Device Interface Test"); + FinishTest(KeyHandle, L"IoDeviceInterfaceTest"); } diff --git a/rostests/drivers/kmtest/kmtest.c b/rostests/drivers/kmtest/kmtest.c index 964486a93f6..3164688336c 100644 --- a/rostests/drivers/kmtest/kmtest.c +++ b/rostests/drivers/kmtest/kmtest.c @@ -25,8 +25,12 @@ #include #include "kmtest.h" +#define NDEBUG +#include + LONG successes; LONG failures; +LONG skipped; tls_data glob_data; /* PRIVATE FUNCTIONS ***********************************************************/ @@ -35,12 +39,61 @@ StartTest() { successes = 0; failures = 0; + skipped = 0; } VOID -FinishTest(LPSTR TestName) +FinishTest(HANDLE KeyHandle, LPWSTR TestName) { - DbgPrint("%s: %d test executed (0 marked as todo, %d failures), 0 skipped.\n", TestName, successes + failures, failures); + WCHAR KeyName[100]; + LONG total = successes + failures; + UNICODE_STRING KeyNameU; + + wcscpy(KeyName, TestName); + wcscat(KeyName, L"SuccessCount"); + RtlInitUnicodeString(&KeyNameU, KeyName); + + ZwSetValueKey(KeyHandle, + &KeyNameU, + 0, + REG_DWORD, + &successes, + sizeof(ULONG)); + + wcscpy(KeyName, TestName); + wcscat(KeyName, L"FailureCount"); + RtlInitUnicodeString(&KeyNameU, KeyName); + + ZwSetValueKey(KeyHandle, + &KeyNameU, + 0, + REG_DWORD, + &failures, + sizeof(ULONG)); + + wcscpy(KeyName, TestName); + wcscat(KeyName, L"TotalCount"); + RtlInitUnicodeString(&KeyNameU, KeyName); + + ZwSetValueKey(KeyHandle, + &KeyNameU, + 0, + REG_DWORD, + &total, + sizeof(ULONG)); + + wcscpy(KeyName, TestName); + wcscat(KeyName, L"SkipCount"); + RtlInitUnicodeString(&KeyNameU, KeyName); + + ZwSetValueKey(KeyHandle, + &KeyNameU, + 0, + REG_DWORD, + &skipped, + sizeof(ULONG)); + + DbgPrint("%S: %d test executed (0 marked as todo, %d failures), %d skipped.\n", TestName, total, failures, skipped); } void kmtest_set_location(const char* file, int line) @@ -105,11 +158,14 @@ PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriv /* * Test Declarations */ -VOID NtoskrnlIoTests(); -VOID NtoskrnlKeTests(); -VOID NtoskrnlObTest(); -VOID NtoskrnlExecutiveTests(); -VOID NtoskrnlPoolsTest(); +VOID RegisterDI_Test(HANDLE KeyHandle); +VOID NtoskrnlIoMdlTest(HANDLE KeyHandle); +VOID NtoskrnlIoIrpTest(HANDLE KeyHandle); +VOID NtoskrnlObTest(HANDLE KeyHandle); +VOID ExTimerTest(HANDLE KeyHandle); +VOID PoolsTest(HANDLE KeyHandle); +VOID PoolsCorruption(HANDLE KeyHandle); +VOID KeStallTest(HANDLE KeyHandle); VOID DriverObjectTest(PDRIVER_OBJECT, int); VOID DeviceCreateDeleteTest(PDRIVER_OBJECT); VOID DeviceObjectTest(PDEVICE_OBJECT); @@ -119,6 +175,19 @@ BOOLEAN DetachDeviceTest(PDEVICE_OBJECT); BOOLEAN AttachDeviceTest(PDEVICE_OBJECT, PWCHAR); VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN); +typedef enum { + TestStageExTimer = 0, + TestStageIoMdl, + TestStageIoDi, + TestStageIoIrp, + TestStageMmPoolTest, + TestStageMmPoolCorruption, + TestStageOb, + TestStageKeStall, + TestStageDrv, + TestStageMax +} TEST_STAGE; + /* * KmtestDispatch */ @@ -192,7 +261,148 @@ KmtestUnload(IN PDRIVER_OBJECT DriverObject) IoDeleteDevice(MainDeviceObject); } - FinishTest("Driver Tests"); +} + +static +PKEY_VALUE_PARTIAL_INFORMATION +NTAPI +ReadRegistryValue(HANDLE KeyHandle, PWCHAR ValueName) +{ + NTSTATUS Status; + PKEY_VALUE_PARTIAL_INFORMATION InformationBuffer = NULL; + ULONG AllocatedLength = 0, RequiredLength = 0; + UNICODE_STRING ValueNameU; + + RtlInitUnicodeString(&ValueNameU, ValueName); + + Status = ZwQueryValueKey(KeyHandle, + &ValueNameU, + KeyValuePartialInformation, + NULL, + 0, + &RequiredLength); + if (Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW) + { + InformationBuffer = ExAllocatePool(PagedPool, RequiredLength); + AllocatedLength = RequiredLength; + if (!InformationBuffer) return NULL; + + Status = ZwQueryValueKey(KeyHandle, + &ValueNameU, + KeyValuePartialInformation, + InformationBuffer, + AllocatedLength, + &RequiredLength); + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to read %S (0x%x)\n", ValueName, Status); + if (InformationBuffer != NULL) + ExFreePool(InformationBuffer); + return NULL; + } + + return InformationBuffer; +} + +static +VOID +RunKernelModeTest(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath, + HANDLE KeyHandle, + TEST_STAGE Stage) +{ + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"CurrentStage"); + PWCHAR LowerDriverRegPath; + + DPRINT1("Running stage %d test...\n", Stage); + + ZwSetValueKey(KeyHandle, + &KeyName, + 0, + REG_DWORD, + &Stage, + sizeof(ULONG)); + + switch (Stage) + { + case TestStageExTimer: + ExTimerTest(KeyHandle); + break; + + case TestStageIoMdl: + NtoskrnlIoMdlTest(KeyHandle); + break; + + case TestStageIoDi: + RegisterDI_Test(KeyHandle); + break; + + case TestStageIoIrp: + NtoskrnlIoIrpTest(KeyHandle); + break; + + case TestStageMmPoolTest: + PoolsTest(KeyHandle); + break; + + case TestStageMmPoolCorruption: + PoolsCorruption(KeyHandle); + break; + + case TestStageOb: + NtoskrnlObTest(KeyHandle); + break; + + case TestStageKeStall: + KeStallTest(KeyHandle); + break; + + case TestStageDrv: + /* Start the tests for the driver routines */ + StartTest(); + + /* Do DriverObject Test for Driver Entry */ + DriverObjectTest(DriverObject, 0); + + /* Create and delete device, on return MainDeviceObject has been created */ + DeviceCreateDeleteTest(DriverObject); + + /* Make sure a device object was created */ + if (MainDeviceObject) + { + LowerDriverRegPath = CreateLowerDeviceRegistryKey(RegistryPath, L"kmtestassist"); + + if (LowerDriverRegPath) + { + /* Load driver test and load the lower driver */ + if (ZwLoadTest(DriverObject, RegistryPath, LowerDriverRegPath)) + { + AttachDeviceTest(MainDeviceObject, L"kmtestassists"); + if (AttachDeviceObject) + { + LowerDeviceKernelAPITest(MainDeviceObject, FALSE); + } + + /* Unload lower driver without detaching from its device */ + ZwUnloadTest(DriverObject, RegistryPath, LowerDriverRegPath); + LowerDeviceKernelAPITest(MainDeviceObject, TRUE); + } + else + { + DbgPrint("Failed to load kmtestassist driver\n"); + } + } + } + + FinishTest(KeyHandle, L"DriverTest"); + break; + + default: + ASSERT(FALSE); + break; + } } /* @@ -204,61 +414,98 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { int i; - PWCHAR LowerDriverRegPath; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING ParameterKeyName = RTL_CONSTANT_STRING(L"Parameters"); + PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; + PULONG KeyValue; + TEST_STAGE CurrentStage; + HANDLE DriverKeyHandle, ParameterKeyHandle; DbgPrint("\n===============================================\n"); DbgPrint("Kernel Mode Regression Driver Test starting...\n"); DbgPrint("===============================================\n"); - MainDeviceObject = NULL; - AttachDeviceObject = NULL; - ThisDriverObject = DriverObject; + InitializeObjectAttributes(&ObjectAttributes, + RegistryPath, + OBJ_CASE_INSENSITIVE, + 0, + NULL); - NtoskrnlExecutiveTests(); - NtoskrnlKeTests(); - NtoskrnlIoTests(); - NtoskrnlObTest(); - NtoskrnlPoolsTest(); - - /* Start the tests for the driver routines */ - StartTest(); - - /* Do DriverObject Test for Driver Entry */ - DriverObjectTest(DriverObject, 0); - /* Create and delete device, on return MainDeviceObject has been created */ - DeviceCreateDeleteTest(DriverObject); - - /* Make sure a device object was created */ - if (MainDeviceObject) + Status = ZwOpenKey(&DriverKeyHandle, + KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) { - LowerDriverRegPath = CreateLowerDeviceRegistryKey(RegistryPath, L"kmtestassist"); + DPRINT1("Failed to open %wZ\n", RegistryPath); + return Status; + } - if (LowerDriverRegPath) + InitializeObjectAttributes(&ObjectAttributes, + &ParameterKeyName, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + DriverKeyHandle, + NULL); + Status = ZwCreateKey(&ParameterKeyHandle, + KEY_SET_VALUE | KEY_QUERY_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + ZwClose(DriverKeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create %wZ\\%wZ\n", RegistryPath, &ParameterKeyName); + return Status; + } + + KeyInfo = ReadRegistryValue(ParameterKeyHandle, L"CurrentStage"); + if (KeyInfo) + { + if (KeyInfo->DataLength != sizeof(ULONG)) { - /* Load driver test and load the lower driver */ - if (ZwLoadTest(DriverObject, RegistryPath, LowerDriverRegPath)) - { - AttachDeviceTest(MainDeviceObject, L"kmtestassists"); - if (AttachDeviceObject) - { - LowerDeviceKernelAPITest(MainDeviceObject, FALSE); - } - - /* Unload lower driver without detaching from its device */ - ZwUnloadTest(DriverObject, RegistryPath, LowerDriverRegPath); - LowerDeviceKernelAPITest(MainDeviceObject, TRUE); - } - else - { - DbgPrint("Failed to load kmtestassist driver\n"); - } + DPRINT1("Invalid data length for CurrentStage: %d\n", KeyInfo->DataLength); + ExFreePool(KeyInfo); + return STATUS_UNSUCCESSFUL; } + + KeyValue = (PULONG)KeyInfo->Data; + + if ((*KeyValue) + 1 < TestStageMax) + { + DPRINT1("Resuming testing after a crash at stage %d\n", (*KeyValue)); + + CurrentStage = (TEST_STAGE)((*KeyValue) + 1); + } + else + { + DPRINT1("Testing was completed on a previous boot\n"); + ExFreePool(KeyInfo); + return STATUS_UNSUCCESSFUL; + } + + ExFreePool(KeyInfo); } else { - return STATUS_UNSUCCESSFUL; + DPRINT1("Starting a fresh test\n"); + CurrentStage = (TEST_STAGE)0; } + /* Run the tests */ + while (CurrentStage < TestStageMax) + { + RunKernelModeTest(DriverObject, + RegistryPath, + ParameterKeyHandle, + CurrentStage); + CurrentStage++; + } + + DPRINT1("Testing is complete!\n"); + ZwClose(ParameterKeyHandle); + /* Set all MajorFunctions to NULL to verify that kernel fixes them */ for (i = 1; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i] = NULL; diff --git a/rostests/drivers/kmtest/kmtest.h b/rostests/drivers/kmtest/kmtest.h index a0f20d3405d..c244d303841 100644 --- a/rostests/drivers/kmtest/kmtest.h +++ b/rostests/drivers/kmtest/kmtest.h @@ -1,5 +1,5 @@ -#ifndef PNPTEST_H -#define PNPTEST_H +#ifndef KMTEST_H +#define KMTEST_H #include #include @@ -30,7 +30,7 @@ typedef struct extern tls_data glob_data; VOID StartTest(); -VOID FinishTest(LPSTR TestName); +VOID FinishTest(HANDLE KeyHandle, LPWSTR TestName); void kmtest_set_location(const char* file, int line); #ifdef __GNUC__ @@ -51,4 +51,4 @@ PDEVICE_OBJECT AttachDeviceObject; PDEVICE_OBJECT MainDeviceObject; PDRIVER_OBJECT ThisDriverObject; -#endif /* PNPTEST_H */ +#endif /* KMTEST_H */ diff --git a/rostests/drivers/kmtest/kmtest.rbuild b/rostests/drivers/kmtest/kmtest.rbuild index 9219db9f9c1..b9920797178 100644 --- a/rostests/drivers/kmtest/kmtest.rbuild +++ b/rostests/drivers/kmtest/kmtest.rbuild @@ -5,7 +5,6 @@ hal pseh kmtest.c - deviface.c deviface_test.c drvobj_test.c devobj_test.c diff --git a/rostests/drivers/kmtest/ntos_ex.c b/rostests/drivers/kmtest/ntos_ex.c index 84d6859ab51..8edf7fec1a8 100644 --- a/rostests/drivers/kmtest/ntos_ex.c +++ b/rostests/drivers/kmtest/ntos_ex.c @@ -27,7 +27,7 @@ #include #include "kmtest.h" -//#define NDEBUG +#define NDEBUG #include "debug.h" /* PRIVATE FUNCTIONS ***********************************************************/ @@ -44,9 +44,10 @@ TestTimerApcRoutine(IN PVOID TimerContext, (*ApcCount)++; } +/* PUBLIC FUNCTIONS *************************************************************/ VOID -ExTimerTest() +ExTimerTest(HANDLE KeyHandle) { UNICODE_STRING TimerName; OBJECT_ATTRIBUTES ObjectAttributes; @@ -167,13 +168,5 @@ ExTimerTest() Status = ZwClose(TimerHandle); ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status); - FinishTest("NTOSKRNL Executive Timer"); -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -VOID -NtoskrnlExecutiveTests() -{ - ExTimerTest(); + FinishTest(KeyHandle, L"ExTimerTest"); } diff --git a/rostests/drivers/kmtest/ntos_io.c b/rostests/drivers/kmtest/ntos_io.c index 986098edc7d..d49955b95e6 100644 --- a/rostests/drivers/kmtest/ntos_io.c +++ b/rostests/drivers/kmtest/ntos_io.c @@ -29,12 +29,10 @@ #define NDEBUG #include "debug.h" -VOID NtoskrnlIoDeviceInterface(); - /* PUBLIC FUNCTIONS ***********************************************************/ -VOID NtoskrnlIoMdlTest() +VOID NtoskrnlIoMdlTest(HANDLE KeyHandle) { PMDL Mdl; PIRP Irp; @@ -81,10 +79,10 @@ VOID NtoskrnlIoMdlTest() IoFreeIrp(Irp); ExFreePool(VirtualAddress); - FinishTest("NTOSKRNL Io Mdl"); + FinishTest(KeyHandle, L"IoMdlTest"); } -VOID NtoskrnlIoIrpTest() +VOID NtoskrnlIoIrpTest(HANDLE KeyHandle) { USHORT size; IRP *iorp; @@ -166,12 +164,5 @@ VOID NtoskrnlIoIrpTest() IoFreeIrp(iorp); } - FinishTest("NTOSKRNL Io Irp"); -} - -VOID NtoskrnlIoTests() -{ - NtoskrnlIoMdlTest(); - NtoskrnlIoDeviceInterface(); - NtoskrnlIoIrpTest(); + FinishTest(KeyHandle, L"IoIrpTest"); } diff --git a/rostests/drivers/kmtest/ntos_ke.c b/rostests/drivers/kmtest/ntos_ke.c index 1c6032238be..d59eeb3a00f 100644 --- a/rostests/drivers/kmtest/ntos_ke.c +++ b/rostests/drivers/kmtest/ntos_ke.c @@ -30,11 +30,10 @@ #define NDEBUG #include "debug.h" -/* PRIVATE FUNCTIONS ***********************************************************/ +/* PUBLIC FUNCTIONS ***********************************************************/ VOID -NTAPI -KeStallTest() +KeStallTest(HANDLE KeyHandle) { ULONG i; LARGE_INTEGER TimeStart, TimeFinish; @@ -74,13 +73,5 @@ KeStallTest() KeQuerySystemTime(&TimeFinish); DPRINT1("Time elapsed: %d secs\n", (TimeFinish.QuadPart - TimeStart.QuadPart) / 10000000); // 30 - FinishTest("NTOSKRNL KeStallmanExecution test"); -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -VOID -NtoskrnlKeTests() -{ - KeStallTest(); + FinishTest(KeyHandle, L"KeStallmanExecutionTest"); } diff --git a/rostests/drivers/kmtest/ntos_ob.c b/rostests/drivers/kmtest/ntos_ob.c index a7c62fa5641..c8b4d35156a 100644 --- a/rostests/drivers/kmtest/ntos_ob.c +++ b/rostests/drivers/kmtest/ntos_ob.c @@ -26,7 +26,7 @@ #include #include "kmtest.h" -//#define NDEBUG +#define NDEBUG #include "debug.h" #include "ntndk.h" @@ -487,7 +487,7 @@ ObtReferenceTests() /* PUBLIC FUNCTIONS ***********************************************************/ VOID -NtoskrnlObTest() +NtoskrnlObTest(HANDLE KeyHandle) { StartTest(); @@ -515,5 +515,5 @@ NtoskrnlObTest() ObtClose(); DPRINT("Cleanup done\n"); - FinishTest("NTOSKRNL Ob Manager"); + FinishTest(KeyHandle, L"ObMgrTest"); } diff --git a/rostests/drivers/kmtest/ntos_pools.c b/rostests/drivers/kmtest/ntos_pools.c index 816d7c325f3..37c998774b1 100644 --- a/rostests/drivers/kmtest/ntos_pools.c +++ b/rostests/drivers/kmtest/ntos_pools.c @@ -29,15 +29,15 @@ #include #include "kmtest.h" -//#define NDEBUG +#define NDEBUG #include "debug.h" #define TAG_POOLTEST 'tstP' -/* PRIVATE FUNCTIONS ***********************************************************/ +/* PUBLIC FUNCTIONS ***********************************************************/ VOID -PoolsTest() +PoolsTest(HANDLE KeyHandle) { PVOID Ptr; ULONG AllocSize, i, AllocNumber; @@ -124,11 +124,11 @@ PoolsTest() ExFreePoolWithTag(Allocs, TAG_POOLTEST); - FinishTest("NTOSKRNL Pools Tests"); + FinishTest(KeyHandle, L"MmPoolAllocTest"); } VOID -PoolsCorruption() +PoolsCorruption(HANDLE KeyHandle) { PULONG Ptr, TestPtr; ULONG AllocSize; @@ -174,14 +174,5 @@ PoolsCorruption() // free the pool ExFreePoolWithTag(Ptr, TAG_POOLTEST); - FinishTest("NTOSKRNL Pool Corruption"); -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -VOID -NtoskrnlPoolsTest() -{ - PoolsTest(); - //PoolsCorruption(); + FinishTest(KeyHandle, L"MmPoolCorruptionTest"); } From 9b0af1861b460e4019b366a6f235098e5368f535 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 22 May 2010 18:34:54 +0000 Subject: [PATCH 006/292] [HIVESYS.INF] - Enable kmtest svn path=/trunk/; revision=47310 --- reactos/boot/bootdata/hivesys_i386.inf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/boot/bootdata/hivesys_i386.inf b/reactos/boot/bootdata/hivesys_i386.inf index 3ca06176457..05e00057d33 100644 --- a/reactos/boot/bootdata/hivesys_i386.inf +++ b/reactos/boot/bootdata/hivesys_i386.inf @@ -1078,11 +1078,11 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 ; Kernel-Mode Tests -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ImagePath",0x00020000,"system32\drivers\kmtest.sys" -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" +HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ImagePath",0x00020000,"system32\drivers\kmtest.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 ; Keyboard class driver HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ErrorControl",0x00010001,0x00000000 From dc17a010c90aa34aa37a436349f4099d6931a79f Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 22 May 2010 20:10:52 +0000 Subject: [PATCH 007/292] [DEVMGR] devman.dll improvements by Viliam Lejcik: - display version info for selected driver file in 'Driver File Details' dialog - resource modification - changed some labels to read-only editboxes Fixes bug #4875. svn path=/trunk/; revision=47311 --- reactos/dll/win32/devmgr/advprop.c | 195 ++++++++++++++++++++++--- reactos/dll/win32/devmgr/devmgr.rbuild | 1 + reactos/dll/win32/devmgr/lang/bg-BG.rc | 20 +-- reactos/dll/win32/devmgr/lang/cs-CZ.rc | 24 +-- reactos/dll/win32/devmgr/lang/de-DE.rc | 12 +- reactos/dll/win32/devmgr/lang/el-GR.rc | 12 +- reactos/dll/win32/devmgr/lang/en-US.rc | 12 +- reactos/dll/win32/devmgr/lang/es-ES.rc | 12 +- reactos/dll/win32/devmgr/lang/fr-FR.rc | 12 +- reactos/dll/win32/devmgr/lang/hu-HU.rc | 22 +++ reactos/dll/win32/devmgr/lang/id-ID.rc | 12 +- reactos/dll/win32/devmgr/lang/it-IT.rc | 12 +- reactos/dll/win32/devmgr/lang/no-NO.rc | 12 +- reactos/dll/win32/devmgr/lang/pl-PL.rc | 22 +++ reactos/dll/win32/devmgr/lang/pt-BR.rc | 12 +- reactos/dll/win32/devmgr/lang/ro-RO.rc | 14 +- reactos/dll/win32/devmgr/lang/ru-RU.rc | 12 +- reactos/dll/win32/devmgr/lang/sk-SK.rc | 32 ++-- reactos/dll/win32/devmgr/lang/uk-UA.rc | 12 +- 19 files changed, 331 insertions(+), 131 deletions(-) diff --git a/reactos/dll/win32/devmgr/advprop.c b/reactos/dll/win32/devmgr/advprop.c index b7c38678769..b7af67e9dc1 100644 --- a/reactos/dll/win32/devmgr/advprop.c +++ b/reactos/dll/win32/devmgr/advprop.c @@ -165,26 +165,6 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, &DriverInfoData)) { HSPFILEQ queueHandle; - DWORD HiVal, LoVal; - WCHAR szTime[25]; - - HiVal = (DriverInfoData.DriverVersion >> 32); - if (HiVal) - { - swprintf (szTime, L"%d.%d", HIWORD(HiVal), LOWORD(HiVal)); - LoVal = (DriverInfoData.DriverVersion & 0xFFFFFFFF); - if (HIWORD(LoVal)) - { - swprintf(&szTime[wcslen(szTime)], L".%d", HIWORD(LoVal)); - if (LOWORD(LoVal)) - { - swprintf(&szTime[wcslen(szTime)], L".%d", LOWORD(LoVal)); - } - } - SetDlgItemTextW(hwndDlg, IDC_FILEVERSION, szTime); - } - SetDlgItemText(hwndDlg, IDC_FILEPROVIDER, DriverInfoData.ProviderName); - queueHandle = SetupOpenFileQueue(); if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE) @@ -225,6 +205,15 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, (void)ListView_SetColumn(hDriversListView, 0, &lvc); + + /* highlight the first item from list */ + if (ListView_GetSelectedCount(hDriversListView) != 0) + { + ListView_SetItemState(hDriversListView, + 0, + LVIS_FOCUSED | LVIS_SELECTED, + LVIS_FOCUSED | LVIS_SELECTED); + } } } @@ -234,6 +223,124 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, } +static VOID +UpdateDriverVersionInfoDetails(IN HWND hwndDlg, + IN LPCWSTR lpszDriverPath) +{ + DWORD dwHandle; + DWORD dwVerInfoSize; + LPVOID lpData = NULL; + LPVOID lpInfo; + UINT uInfoLen; + DWORD dwLangId; + WCHAR szLangInfo[255]; + WCHAR szLangPath[MAX_PATH]; + LPWSTR lpCompanyName = NULL; + LPWSTR lpFileVersion = NULL; + LPWSTR lpLegalCopyright = NULL; + LPWSTR lpDigitalSigner = NULL; + UINT uBufLen; + WCHAR szNotAvailable[255]; + + /* extract version info from selected file */ + dwVerInfoSize = GetFileVersionInfoSize(lpszDriverPath, + &dwHandle); + if (!dwVerInfoSize) + goto done; + + lpData = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwVerInfoSize); + if (!lpData) + goto done; + + if (!GetFileVersionInfo(lpszDriverPath, + dwHandle, + dwVerInfoSize, + lpData)) + goto done; + + if (!VerQueryValue(lpData, + L"\\VarFileInfo\\Translation", + &lpInfo, + &uInfoLen)) + goto done; + + dwLangId = *(LPDWORD)lpInfo; + swprintf(szLangInfo, L"\\StringFileInfo\\%04x%04x\\", + LOWORD(dwLangId), HIWORD(dwLangId)); + + /* read CompanyName */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"CompanyName"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpCompanyName, + (PUINT)&uBufLen); + + /* read FileVersion */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"FileVersion"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpFileVersion, + (PUINT)&uBufLen); + + /* read LegalTrademarks */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"LegalCopyright"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpLegalCopyright, + (PUINT)&uBufLen); + + /* TODO: read digital signer info */ + +done: + if (!LoadString(hDllInstance, + IDS_NOTAVAILABLE, + szNotAvailable, + sizeof(szNotAvailable) / sizeof(WCHAR))) + { + wcscpy(szNotAvailable, L"n/a"); + } + + /* update labels */ + if (!lpCompanyName) + lpCompanyName = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILEPROVIDER, + lpCompanyName); + + if (!lpFileVersion) + lpFileVersion = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILEVERSION, + lpFileVersion); + + if (!lpLegalCopyright) + lpLegalCopyright = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILECOPYRIGHT, + lpLegalCopyright); + + if (!lpDigitalSigner) + lpDigitalSigner = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_DIGITALSIGNER, + lpDigitalSigner); + + /* release version info */ + if (lpData) + HeapFree(GetProcessHeap(), + 0, + lpData); +} + + static INT_PTR CALLBACK DriverDetailsDlgProc(IN HWND hwndDlg, @@ -256,6 +363,7 @@ DriverDetailsDlgProc(IN HWND hwndDlg, switch (LOWORD(wParam)) { case IDOK: + case IDCANCEL: { EndDialog(hwndDlg, IDOK); @@ -303,6 +411,53 @@ DriverDetailsDlgProc(IN HWND hwndDlg, Ret = TRUE; break; } + + case WM_NOTIFY: + { + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; + HWND hDriversListView = GetDlgItem(hwndDlg, + IDC_DRIVERFILES); + + if (ListView_GetSelectedCount(hDriversListView) == 0) + { + /* nothing is selected - empty the labels */ + SetDlgItemText(hwndDlg, + IDC_FILEPROVIDER, + NULL); + SetDlgItemText(hwndDlg, + IDC_FILEVERSION, + NULL); + SetDlgItemText(hwndDlg, + IDC_FILECOPYRIGHT, + NULL); + SetDlgItemText(hwndDlg, + IDC_DIGITALSIGNER, + NULL); + } + else if (pnmv->uNewState != 0) + { + /* extract version info and update the labels */ + WCHAR szDriverPath[MAX_PATH]; + + ListView_GetItemText(hDriversListView, + pnmv->iItem, + pnmv->iSubItem, + szDriverPath, + MAX_PATH); + + UpdateDriverVersionInfoDetails(hwndDlg, + szDriverPath); + } + } + } + break; + } } } diff --git a/reactos/dll/win32/devmgr/devmgr.rbuild b/reactos/dll/win32/devmgr/devmgr.rbuild index b746bd39b9c..fafa15fb898 100644 --- a/reactos/dll/win32/devmgr/devmgr.rbuild +++ b/reactos/dll/win32/devmgr/devmgr.rbuild @@ -5,6 +5,7 @@ setupapi advapi32 user32 + version devmgr.rc advprop.c devprblm.c diff --git a/reactos/dll/win32/devmgr/lang/bg-BG.rc b/reactos/dll/win32/devmgr/lang/bg-BG.rc index 7ade5f18be8..ec278d57810 100644 --- a/reactos/dll/win32/devmgr/lang/bg-BG.rc +++ b/reactos/dll/win32/devmgr/lang/bg-BG.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Ïîêàçâàíå íà ïîäðîáíîñòè çà ôàéëîâåòå íà âîäà÷à.", -1, 105, 110, 141, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Ïîäðîáíîñòèòå çà ôàéëîâåòå íà âîäà÷à" FONT 8, "MS Shell Dlg" @@ -186,15 +186,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Äîñòàâ÷èê:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 82, 134, 140, 8 - LTEXT "Ôàéëîâà âåðñèÿ:", -1, 14, 150, 70, 16 - LTEXT "", IDC_FILEVERSION, 82, 150, 140, 8 - LTEXT "Âúçïðîèçâîäñòâåíè ïðàâà:", -1, 14, 166, 70, 16 - LTEXT "", IDC_FILECOPYRIGHT, 82, 166, 140, 8 - LTEXT "Ïîäïèñàë öèôðîâî:", -1, 14, 182, 70, 16 - LTEXT "", IDC_DIGITALSIGNER, 82, 182, 140, 8 - PUSHBUTTON "Äîáðå", IDOK, 167, 228, 50, 14 + LTEXT "Äîñòàâ÷èê:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 82, 134, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Ôàéëîâà âåðñèÿ:", -1, 14, 150, 66, 16 + EDITTEXT IDC_FILEVERSION, 82, 150, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Âúçïðîèçâîäñòâåíè ïðàâà:", -1, 14, 166, 66, 16 + EDITTEXT IDC_FILECOPYRIGHT, 82, 166, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Ïîäïèñàë öèôðîâî:", -1, 14, 182, 66, 16 + EDITTEXT IDC_DIGITALSIGNER, 82, 182, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "Äîáðå", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/cs-CZ.rc b/reactos/dll/win32/devmgr/lang/cs-CZ.rc index aa7a56e21c5..3716d97803d 100644 --- a/reactos/dll/win32/devmgr/lang/cs-CZ.rc +++ b/reactos/dll/win32/devmgr/lang/cs-CZ.rc @@ -16,7 +16,7 @@ BEGIN IDS_LOCATIONSTR "Umístìní %1!u! (%2)" IDS_DEVCODE " (Kód %1!u!)" IDS_DEVCODE2 " (Kód %2!u!)" - IDS_ENABLEDEVICE "Použít toto zaøízení (zapnout)" + IDS_ENABLEDEVICE "Používat toto zaøízení (zapnout)" IDS_DISABLEDEVICE "Nepoužívat toto zaøízení (vypnout)" IDS_UNKNOWNDEVICE "Neznámé zaøízení" IDS_NODRIVERLOADED "Pro toto zaøízení nejsou nainstalovány žádné ovladaèe." @@ -166,7 +166,7 @@ FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX - LTEXT "Poskytovatel ovladaèe:", -1, 37, 39, 60, 8, SS_NOPREFIX + LTEXT "Zprostøedkovatel:", -1, 37, 39, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVPROVIDER, 100, 39, 146, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Datum ovladaèe:", -1, 37, 53, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVDATE, 100, 53, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY @@ -178,7 +178,7 @@ BEGIN LTEXT "Zobrazí detaily souborù ovladaèe.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detaily souborù ovladaèe" FONT 8, "MS Shell Dlg" @@ -189,15 +189,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Poskytovatel:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 - LTEXT "Verze souboru:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 - LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 - LTEXT "Digitální podpis:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + LTEXT "Zprostøedkovatel:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 80, 134, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Verze souboru:", -1, 14, 150, 66, 8 + EDITTEXT IDC_FILEVERSION, 80, 150, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Autorská práva:", -1, 14, 166, 66, 8 + EDITTEXT IDC_FILECOPYRIGHT, 80, 166, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digitální podpis:", -1, 14, 182, 66, 8 + EDITTEXT IDC_DIGITALSIGNER, 80, 182, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/de-DE.rc b/reactos/dll/win32/devmgr/lang/de-DE.rc index 91769ff11f5..a027c814c63 100644 --- a/reactos/dll/win32/devmgr/lang/de-DE.rc +++ b/reactos/dll/win32/devmgr/lang/de-DE.rc @@ -176,7 +176,7 @@ BEGIN LTEXT "Einzelheiten über die Treiberdateien anzeigen.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Treiberdateidetails" FONT 8, "MS Shell Dlg" @@ -188,14 +188,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Anbieter:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Dateiversion:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signaturgeber:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/el-GR.rc b/reactos/dll/win32/devmgr/lang/el-GR.rc index 9ccb338000f..e51db8729ed 100644 --- a/reactos/dll/win32/devmgr/lang/el-GR.rc +++ b/reactos/dll/win32/devmgr/lang/el-GR.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "ËåðôïìÝñåéåò Áñ÷åßùí Ïäçãïý" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "ÐñïìçèåõôÞò:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "¸êäïóç áñ÷åßïõ:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Äéêáéþìáôá:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital Signer:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/en-US.rc b/reactos/dll/win32/devmgr/lang/en-US.rc index 64b44f2e0af..27009dddb78 100644 --- a/reactos/dll/win32/devmgr/lang/en-US.rc +++ b/reactos/dll/win32/devmgr/lang/en-US.rc @@ -176,7 +176,7 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Driver File Details" FONT 8, "MS Shell Dlg" @@ -188,14 +188,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Provider:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "File version:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital Signer:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/es-ES.rc b/reactos/dll/win32/devmgr/lang/es-ES.rc index 2b728c199e8..32b3820f5c0 100644 --- a/reactos/dll/win32/devmgr/lang/es-ES.rc +++ b/reactos/dll/win32/devmgr/lang/es-ES.rc @@ -176,7 +176,7 @@ BEGIN LTEXT "Ver detalles de los archivos del controlador.", -1, 100, 110, 150, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalles de archivo de controlador" FONT 8, "MS Shell Dlg" @@ -188,14 +188,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Proveedor:", -1, 10, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versión:", -1, 10, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 10, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Firmante Digital:", -1, 10, 182, 60, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "Aceptar", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "Aceptar", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/fr-FR.rc b/reactos/dll/win32/devmgr/lang/fr-FR.rc index 1d1e580b314..697998f32bc 100644 --- a/reactos/dll/win32/devmgr/lang/fr-FR.rc +++ b/reactos/dll/win32/devmgr/lang/fr-FR.rc @@ -174,7 +174,7 @@ BEGIN LTEXT "Voir les détails à propos des fichiers du Pilote.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Fichiers du Pilote" FONT 8, "MS Shell Dlg" @@ -186,14 +186,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fournisseur :", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Version :", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright :", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signature numérique :", -1, 14, 182, 80, 8 - LTEXT "", IDC_DIGITALSIGNER, 96, 182, 125, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 96, 182, 125, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/hu-HU.rc b/reactos/dll/win32/devmgr/lang/hu-HU.rc index 23180c63b5c..daf66ad14ee 100644 --- a/reactos/dll/win32/devmgr/lang/hu-HU.rc +++ b/reactos/dll/win32/devmgr/lang/hu-HU.rc @@ -174,6 +174,28 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME +CAPTION "Driver File Details" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "", IDC_DEVICON, 7, 7, 20, 20 + LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX + LTEXT "&Driver files:", -1, 7, 36, 204, 8 + CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 + LTEXT "Provider:", -1, 14, 134, 50, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "File version:", -1, 14, 150, 50, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Copyright:", -1, 14, 166, 50, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digital Signer:", -1, 14, 182, 50, 8 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 +END + IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Details" diff --git a/reactos/dll/win32/devmgr/lang/id-ID.rc b/reactos/dll/win32/devmgr/lang/id-ID.rc index 3f4dc520f77..5c69016780f 100644 --- a/reactos/dll/win32/devmgr/lang/id-ID.rc +++ b/reactos/dll/win32/devmgr/lang/id-ID.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Untuk melihat rincian tetang file driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Rincian File Driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Penyedia:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versi File:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Hak Cipta:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Penanda tangan Digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/it-IT.rc b/reactos/dll/win32/devmgr/lang/it-IT.rc index f024abf10d9..239ac83a5ec 100644 --- a/reactos/dll/win32/devmgr/lang/it-IT.rc +++ b/reactos/dll/win32/devmgr/lang/it-IT.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Per vedere i dettagli sui file del driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Dettagli sui file del driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fornitore del Driver:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versione:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Firmatario digitale:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/no-NO.rc b/reactos/dll/win32/devmgr/lang/no-NO.rc index a7a5a7b8a66..c46fe017818 100644 --- a/reactos/dll/win32/devmgr/lang/no-NO.rc +++ b/reactos/dll/win32/devmgr/lang/no-NO.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "For å vise detaljer om driver filene.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Driver fil detaljer" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Produsent:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Filversjon:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Opphavsrett:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital signert:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/pl-PL.rc b/reactos/dll/win32/devmgr/lang/pl-PL.rc index 59bd6ae2c09..3f71bb18ec4 100644 --- a/reactos/dll/win32/devmgr/lang/pl-PL.rc +++ b/reactos/dll/win32/devmgr/lang/pl-PL.rc @@ -182,6 +182,28 @@ BEGIN LTEXT "Wyœwietla informacje szczegó³owe.", -1, 91, 110, 154, 17, SS_NOPREFIX END +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME +CAPTION "Driver File Details" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "", IDC_DEVICON, 7, 7, 20, 20 + LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX + LTEXT "&Driver files:", -1, 7, 36, 204, 8 + CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 + LTEXT "Provider:", -1, 14, 134, 50, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "File version:", -1, 14, 150, 50, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Copyright:", -1, 14, 166, 50, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digital Signer:", -1, 14, 182, 50, 8 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 +END + IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Szczegó³y" diff --git a/reactos/dll/win32/devmgr/lang/pt-BR.rc b/reactos/dll/win32/devmgr/lang/pt-BR.rc index 5b0c477b2c0..ea9e4cc2938 100644 --- a/reactos/dll/win32/devmgr/lang/pt-BR.rc +++ b/reactos/dll/win32/devmgr/lang/pt-BR.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Exibir detalhes sobre os arquivos de driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalhes sobre os arquivos de driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fornecedor:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versão do arquivo:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Direitos autorais:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signatário digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/ro-RO.rc b/reactos/dll/win32/devmgr/lang/ro-RO.rc index 4e18c3a212a..b7b578c4e31 100644 --- a/reactos/dll/win32/devmgr/lang/ro-RO.rc +++ b/reactos/dll/win32/devmgr/lang/ro-RO.rc @@ -1,4 +1,4 @@ -// Romanian language resource file (Petru Dimitriu, 2009-07-15) +// Romanian language resource file (Petru Dimitriu, 2009-07-15) LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -177,7 +177,7 @@ BEGIN LTEXT "Pentru a vedea detalii despre fi?ierele driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalii fi?iere driver" FONT 8, "MS Shell Dlg" @@ -189,14 +189,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Furnizor:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versiune fi?ier:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Drept de autor:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Semnatar digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/ru-RU.rc b/reactos/dll/win32/devmgr/lang/ru-RU.rc index 9a417930515..8c3839826c1 100644 --- a/reactos/dll/win32/devmgr/lang/ru-RU.rc +++ b/reactos/dll/win32/devmgr/lang/ru-RU.rc @@ -173,7 +173,7 @@ BEGIN LTEXT "Ïðîñìîòð ñâåäåíèé î ôàéëàõ äðàéâåðîâ.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Ñâåäåíèÿ î ôàéëàõ äðàéâåðîâ" FONT 8, "MS Shell Dlg" @@ -185,14 +185,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Ïîñòàâùèê:", -1, 7, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 137, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 137, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Âåðñèÿ ôàéëà:", -1, 7, 150, 80, 8 - LTEXT "", IDC_FILEVERSION, 137, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 137, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Àâòîðñêèå ïðàâà:", -1, 7, 166, 112, 8 - LTEXT "", IDC_FILECOPYRIGHT, 137, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 137, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Öèôðîâàÿ ïîäïèñü:", -1, 7, 182, 125, 8 - LTEXT "", IDC_DIGITALSIGNER, 137, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 137, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/sk-SK.rc b/reactos/dll/win32/devmgr/lang/sk-SK.rc index 7be94acfeb1..ae4f1bebfd7 100644 --- a/reactos/dll/win32/devmgr/lang/sk-SK.rc +++ b/reactos/dll/win32/devmgr/lang/sk-SK.rc @@ -16,8 +16,8 @@ BEGIN IDS_LOCATIONSTR "Umiestnenie %1!u! (%2)" IDS_DEVCODE " (Kód %1!u!)" IDS_DEVCODE2 " (Kód %2!u!)" - IDS_ENABLEDEVICE "Použi toto zariadenie (povolené)" - IDS_DISABLEDEVICE "Nepouži toto zariadenie (zakázané)" + IDS_ENABLEDEVICE "Používa toto zariadenie (povolené)" + IDS_DISABLEDEVICE "Nepoužíva toto zariadenie (zakázané)" IDS_UNKNOWNDEVICE "Neznáme zariadenie" IDS_NODRIVERLOADED "Pre toto zariadenie nie sú nainštalované žiadne ovládaèe." IDS_DEVONPARENT "na %1" @@ -166,19 +166,19 @@ FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX - LTEXT "Poskytovate¾ ovládaèa:", -1, 37, 39, 60, 8, SS_NOPREFIX + LTEXT "Sprostredkovate¾:", -1, 34, 39, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVPROVIDER, 100, 39, 146, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Dátum ovládaèa:", -1, 37, 53, 60, 8, SS_NOPREFIX + LTEXT "Dátum ovládaèa:", -1, 34, 53, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVDATE, 100, 53, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Verzia ovládaèa:", -1, 37, 67, 60, 8, SS_NOPREFIX + LTEXT "Verzia ovládaèa:", -1, 34, 67, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVVERSION, 100, 67, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Digitálne podpísal:", -1, 37, 81, 60, 8, SS_NOPREFIX + LTEXT "Digitálne podpísal:", -1, 34, 81, 60, 8, SS_NOPREFIX EDITTEXT IDC_DIGITALSIGNER, 100, 81, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY PUSHBUTTON "&Driver Details...", IDC_DRIVERDETAILS, 7, 106, 70, 15 LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detaily o súboroch ovládaèa" FONT 8, "MS Shell Dlg" @@ -189,15 +189,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Poskytovate¾:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 - LTEXT "Verzia súboru:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 - LTEXT "Autorské práva:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 - LTEXT "Digitálne podpísal:", -1, 14, 182, 50, 8 //Digital Signer - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + LTEXT "Sprostredkovate¾:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 80, 134, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Verzia súboru:", -1, 14, 150, 66, 8 + EDITTEXT IDC_FILEVERSION, 80, 150, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Autorské práva:", -1, 14, 166, 66, 8 + EDITTEXT IDC_FILECOPYRIGHT, 80, 166, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digitálne podpísal:", -1, 14, 182, 66, 8 + EDITTEXT IDC_DIGITALSIGNER, 80, 182, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/reactos/dll/win32/devmgr/lang/uk-UA.rc b/reactos/dll/win32/devmgr/lang/uk-UA.rc index 050e5207fad..2d553038c1b 100644 --- a/reactos/dll/win32/devmgr/lang/uk-UA.rc +++ b/reactos/dll/win32/devmgr/lang/uk-UA.rc @@ -181,7 +181,7 @@ BEGIN LTEXT "Ïåðåãëÿä â³äîìîñòåé ïðî ôàéëè äðàéâåðà.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "³äîìîñò³ ïðî ôàéëè äðàéâåðà" FONT 8, "MS Shell Dlg" @@ -193,14 +193,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Ïîñòà÷àëüíèê:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Âåðñ³ÿ ôàéëó:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Àâòîðñüê³ ïðàâà:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Öèôðîâèé ï³äïèñ:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 From 6a0342f830e2652986eb23ac43d14df1fb418f8c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 22 May 2010 20:27:14 +0000 Subject: [PATCH 008/292] [INTL] Translation for entries added by r47298. Patch by Radek Liska. Fixes bug #5416. svn path=/trunk/; revision=47312 --- reactos/dll/cpl/intl/lang/cs-CZ.rc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/intl/lang/cs-CZ.rc b/reactos/dll/cpl/intl/lang/cs-CZ.rc index c72579df513..6685326e741 100644 --- a/reactos/dll/cpl/intl/lang/cs-CZ.rc +++ b/reactos/dll/cpl/intl/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/cpl/intl/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2009-07-16 + * UPDATED: 2010-05-22 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -193,8 +193,8 @@ STRINGTABLE BEGIN IDS_CUSTOMIZE_TITLE "Pøizpùsobit místní nastavení" IDS_SPAIN "Španìlština (Španìlsko)" - IDS_METRIC "Metric" - IDS_IMPERIAL "Imperial" + IDS_METRIC "Metrický" + IDS_IMPERIAL "Imperiální" END STRINGTABLE From a2c5273653cc7146faf8c3322b51a45c0ca5a60c Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 22 May 2010 21:40:20 +0000 Subject: [PATCH 009/292] [WIN32CSR] Make CsrFreeConsole close the process's console handles. svn path=/trunk/; revision=47313 --- .../win32/csrss/csrsrv/api/handle.c | 39 +++++++++++++++++++ .../win32/csrss/csrsrv/api/process.c | 19 +-------- reactos/subsystems/win32/csrss/csrsrv/init.c | 1 + reactos/subsystems/win32/csrss/include/api.h | 1 + .../win32/csrss/include/csrplugin.h | 2 + .../subsystems/win32/csrss/include/win32csr.h | 1 + .../subsystems/win32/csrss/win32csr/conio.c | 17 +------- .../subsystems/win32/csrss/win32csr/dllmain.c | 6 +++ 8 files changed, 52 insertions(+), 34 deletions(-) diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/handle.c b/reactos/subsystems/win32/csrss/csrsrv/api/handle.c index eb6c12c0531..6567f896c12 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/handle.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/handle.c @@ -146,6 +146,45 @@ CsrReleaseObject( return CsrReleaseObjectByPointer(Object); } +NTSTATUS +WINAPI +CsrReleaseConsole( + PCSRSS_PROCESS_DATA ProcessData) +{ + ULONG HandleTableSize; + PCSRSS_HANDLE HandleTable; + PCSRSS_CONSOLE Console; + ULONG i; + + /* Close all console handles and detach process from console */ + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + HandleTableSize = ProcessData->HandleTableSize; + HandleTable = ProcessData->HandleTable; + Console = ProcessData->Console; + ProcessData->HandleTableSize = 0; + ProcessData->HandleTable = NULL; + ProcessData->Console = NULL; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + + for (i = 0; i < HandleTableSize; i++) + { + if (HandleTable[i].Object != NULL) + CsrReleaseObjectByPointer(HandleTable[i].Object); + } + RtlFreeHeap(CsrssApiHeap, 0, HandleTable); + + if (Console != NULL) + { + RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)&Console->Header.Lock); + RemoveEntryList(&ProcessData->ProcessEntry); + RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)&Console->Header.Lock); + CsrReleaseObjectByPointer(&Console->Header); + return STATUS_SUCCESS; + } + + return STATUS_INVALID_PARAMETER; +} + NTSTATUS WINAPI CsrInsertObject( diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 5fcac045c70..580cb21943b 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -140,7 +140,6 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId) NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) { ULONG hash; - UINT c; PCSRSS_PROCESS_DATA pProcessData, *pPrevLink; HANDLE Process; @@ -158,23 +157,7 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) { DPRINT("CsrFreeProcessData pid: %d\n", Pid); Process = pProcessData->Process; - if (pProcessData->HandleTable) - { - for (c = 0; c < pProcessData->HandleTableSize; c++) - { - if (pProcessData->HandleTable[c].Object) - { - CsrReleaseObjectByPointer(pProcessData->HandleTable[c].Object); - } - } - RtlFreeHeap(CsrssApiHeap, 0, pProcessData->HandleTable); - } - RtlDeleteCriticalSection(&pProcessData->HandleTableLock); - if (pProcessData->Console) - { - RemoveEntryList(&pProcessData->ProcessEntry); - CsrReleaseObjectByPointer((Object_t *) pProcessData->Console); - } + CsrReleaseConsole(pProcessData); if (pProcessData->CsrSectionViewBase) { NtUnmapViewOfSection(NtCurrentProcess(), pProcessData->CsrSectionViewBase); diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index 51adb2cacca..a5076284740 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -335,6 +335,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) Exports.CsrGetObjectProc = CsrGetObject; Exports.CsrReleaseObjectByPointerProc = CsrReleaseObjectByPointer; Exports.CsrReleaseObjectProc = CsrReleaseObject; + Exports.CsrReleaseConsoleProc = CsrReleaseConsole; Exports.CsrEnumProcessesProc = CsrEnumProcesses; if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc, &HardErrorProc, &Exports, CsrssApiHeap)) diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 7fbf6db9e58..444cee7777d 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -193,6 +193,7 @@ NTSTATUS WINAPI CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Ob NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); +NTSTATUS WINAPI CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); //hack diff --git a/reactos/subsystems/win32/csrss/include/csrplugin.h b/reactos/subsystems/win32/csrss/include/csrplugin.h index 357b65bcd25..24c0c7debc3 100644 --- a/reactos/subsystems/win32/csrss/include/csrplugin.h +++ b/reactos/subsystems/win32/csrss/include/csrplugin.h @@ -33,6 +33,7 @@ typedef NTSTATUS (WINAPI *CSRSS_GET_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_BY_POINTER_PROC)(Object_t *Object); typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); +typedef NTSTATUS (WINAPI *CSRSS_RELEASE_CONSOLE_PROC)(PCSRSS_PROCESS_DATA ProcessData); typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); @@ -42,6 +43,7 @@ typedef struct tagCSRSS_EXPORTED_FUNCS CSRSS_GET_OBJECT_PROC CsrGetObjectProc; CSRSS_RELEASE_OBJECT_BY_POINTER_PROC CsrReleaseObjectByPointerProc; CSRSS_RELEASE_OBJECT_PROC CsrReleaseObjectProc; + CSRSS_RELEASE_CONSOLE_PROC CsrReleaseConsoleProc; CSRSS_ENUM_PROCESSES_PROC CsrEnumProcessesProc; } CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS; diff --git a/reactos/subsystems/win32/csrss/include/win32csr.h b/reactos/subsystems/win32/csrss/include/win32csr.h index 6b7791f72f6..4b5ab4756cf 100644 --- a/reactos/subsystems/win32/csrss/include/win32csr.h +++ b/reactos/subsystems/win32/csrss/include/win32csr.h @@ -33,6 +33,7 @@ NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Object); +NTSTATUS FASTCALL Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 493ac172db0..5aa5cf811c4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -369,25 +369,10 @@ CSR_API(CsrAllocConsole) CSR_API(CsrFreeConsole) { - PCSRSS_CONSOLE Console; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (ProcessData->Console == NULL) - { - return STATUS_INVALID_PARAMETER; - } - - Console = ProcessData->Console; - ProcessData->Console = NULL; - RemoveEntryList(&ProcessData->ProcessEntry); - if (0 == InterlockedDecrement(&Console->Header.ReferenceCount)) - { - ConioDeleteConsole((Object_t *) Console); - } - return STATUS_SUCCESS; + return Win32CsrReleaseConsole(ProcessData); } static VOID FASTCALL diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index f8332a7ea76..52486633031 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -166,6 +166,12 @@ Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, return (CsrExports.CsrReleaseObjectProc)(ProcessData, Object); } +NTSTATUS FASTCALL +Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData) +{ + return (CsrExports.CsrReleaseConsoleProc)(ProcessData); +} + NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) From 7d27afbe966cf56df1bca1efecf91ddaa990e277 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 22 May 2010 23:47:54 +0000 Subject: [PATCH 010/292] [CSRSRV], [WIN32CSR] - Move code for managing console handles from csrsrv to win32csr, where the rest of the console code is. No changes in functionality intended. - Unify the csrsrv->win32csr callbacks (now numbering 4) into one table to avoid excessive code duplication. svn path=/trunk/; revision=47314 --- .../win32/csrss/csrsrv/api/process.c | 137 +---------------- .../win32/csrss/csrsrv/csrsrv.rbuild | 1 - reactos/subsystems/win32/csrss/csrsrv/init.c | 131 ++++++---------- reactos/subsystems/win32/csrss/include/api.h | 4 +- .../win32/csrss/include/csrplugin.h | 35 ++--- .../win32/csrss/{include => win32csr}/conio.h | 0 .../subsystems/win32/csrss/win32csr/dllmain.c | 34 +++-- .../csrss/{csrsrv/api => win32csr}/handle.c | 142 +++++++++++++++++- .../csrss/{include => win32csr}/win32csr.h | 0 .../win32/csrss/win32csr/win32csr.rbuild | 1 + .../win32/csrss/win32csr/win32csr.spec | 2 +- 11 files changed, 228 insertions(+), 259 deletions(-) rename reactos/subsystems/win32/csrss/{include => win32csr}/conio.h (100%) rename reactos/subsystems/win32/csrss/{csrsrv/api => win32csr}/handle.c (61%) rename reactos/subsystems/win32/csrss/{include => win32csr}/win32csr.h (100%) diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 580cb21943b..8b7a4832f8d 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -18,6 +18,9 @@ #define CsrAcquireProcessLock() LOCK #define CsrReleaseProcessLock() UNLOCK +extern NTSTATUS CallProcessInherit(PCSRSS_PROCESS_DATA, PCSRSS_PROCESS_DATA); +extern NTSTATUS CallProcessDeleted(PCSRSS_PROCESS_DATA); + /* GLOBALS *******************************************************************/ static ULONG NrProcess; @@ -157,7 +160,7 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) { DPRINT("CsrFreeProcessData pid: %d\n", Pid); Process = pProcessData->Process; - CsrReleaseConsole(pProcessData); + CallProcessDeleted(pProcessData); if (pProcessData->CsrSectionViewBase) { NtUnmapViewOfSection(NtCurrentProcess(), pProcessData->CsrSectionViewBase); @@ -205,7 +208,7 @@ CSR_API(CsrCreateProcess) NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles; if (Request->Data.CreateProcessRequest.bInheritHandles) { - Status = CsrDuplicateHandleTable(ProcessData, NewProcessData); + Status = CallProcessInherit(ProcessData, NewProcessData); } } @@ -343,134 +346,4 @@ CSR_API(CsrSetShutdownParameters) return(STATUS_SUCCESS); } -CSR_API(CsrGetInputHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console) - { - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetInputHandleRequest.InputHandle, - (Object_t *)ProcessData->Console, - Request->Data.GetInputHandleRequest.Access, - Request->Data.GetInputHandleRequest.Inheritable); - } - else - { - Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - - return Request->Status; -} - -CSR_API(CsrGetOutputHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console) - { - RtlEnterCriticalSection(&ProcessDataLock); - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetOutputHandleRequest.OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, - Request->Data.GetOutputHandleRequest.Access, - Request->Data.GetOutputHandleRequest.Inheritable); - RtlLeaveCriticalSection(&ProcessDataLock); - } - else - { - Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - - return Request->Status; -} - -CSR_API(CsrCloseHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - return CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); -} - -CSR_API(CsrVerifyHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Request->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle); - if (!NT_SUCCESS(Request->Status)) - { - DPRINT("CsrVerifyObject failed, status=%x\n", Request->Status); - } - - return Request->Status; -} - -CSR_API(CsrDuplicateHandle) -{ - ULONG_PTR Index; - PCSRSS_HANDLE Entry; - DWORD DesiredAccess; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2; - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (Index >= ProcessData->HandleTableSize - || (Entry = &ProcessData->HandleTable[Index])->Object == NULL) - { - DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - - if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS) - { - DesiredAccess = Entry->Access; - } - else - { - DesiredAccess = Request->Data.DuplicateHandleRequest.Access; - /* Make sure the source handle has all the desired flags */ - if (~Entry->Access & DesiredAccess) - { - DPRINT1("Handle %p only has access %X; requested %X\n", - Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_PARAMETER; - } - } - - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.DuplicateHandleRequest.Handle, - Entry->Object, - DesiredAccess, - Request->Data.DuplicateHandleRequest.Inheritable); - if (NT_SUCCESS(Request->Status) - && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) - { - /* Close the original handle. This cannot drop the count to 0, since a new handle now exists */ - _InterlockedDecrement(&Entry->Object->ReferenceCount); - Entry->Object = NULL; - } - - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Request->Status; -} - -CSR_API(CsrGetInputWaitHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent; - return STATUS_SUCCESS; -} - /* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild index 3f002106bfe..c7b9b53acff 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -10,7 +10,6 @@ pseh smdll - handle.c process.c user.c wapi.c diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index a5076284740..c66411cf18a 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -18,10 +18,8 @@ HANDLE CsrHeap = (HANDLE) 0; HANDLE CsrObjectDirectory = (HANDLE) 0; UNICODE_STRING CsrDirectoryName; extern HANDLE CsrssApiHeap; -static unsigned InitCompleteProcCount; -static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL; -static unsigned HardErrorProcCount; -static CSRPLUGIN_HARDERROR_PROC *HardErrorProcs = NULL; +static unsigned ServerProcCount; +static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL; HANDLE hSbApiPort = (HANDLE) 0; HANDLE hBootstrapOk = (HANDLE) 0; HANDLE hSmApiPort = (HANDLE) 0; @@ -124,60 +122,32 @@ InitializeVideoAddressSpace(VOID) static NTSTATUS FASTCALL -CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) +CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs) { - CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs; + CSRPLUGIN_SERVER_PROCS *NewProcs; DPRINT("CSR: %s called\n", __FUNCTION__); NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, - (InitCompleteProcCount + 1) - * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); + (ServerProcCount + 1) + * sizeof(CSRPLUGIN_SERVER_PROCS)); if (NULL == NewProcs) { return STATUS_NO_MEMORY; } - if (0 != InitCompleteProcCount) + if (0 != ServerProcCount) { - RtlCopyMemory(NewProcs, InitCompleteProcs, - InitCompleteProcCount * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); - RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs); + RtlCopyMemory(NewProcs, ServerProcs, + ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS)); + RtlFreeHeap(CsrssApiHeap, 0, ServerProcs); } - NewProcs[InitCompleteProcCount] = Proc; - InitCompleteProcs = NewProcs; - InitCompleteProcCount++; + NewProcs[ServerProcCount] = *Procs; + ServerProcs = NewProcs; + ServerProcCount++; return STATUS_SUCCESS; } -static NTSTATUS FASTCALL -CsrpAddHardErrorProc(CSRPLUGIN_HARDERROR_PROC Proc) -{ - CSRPLUGIN_HARDERROR_PROC *NewProcs; - - DPRINT("CSR: %s called\n", __FUNCTION__); - - NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, - (HardErrorProcCount + 1) - * sizeof(CSRPLUGIN_HARDERROR_PROC)); - if (NULL == NewProcs) - { - return STATUS_NO_MEMORY; - } - if (0 != HardErrorProcCount) - { - RtlCopyMemory(NewProcs, HardErrorProcs, - HardErrorProcCount * sizeof(CSRPLUGIN_HARDERROR_PROC)); - RtlFreeHeap(CsrssApiHeap, 0, HardErrorProcs); - } - - NewProcs[HardErrorProcCount] = Proc; - HardErrorProcs = NewProcs; - HardErrorProcCount++; - - return STATUS_SUCCESS; -} - /********************************************************************** * CallInitComplete/0 */ @@ -190,13 +160,9 @@ CallInitComplete(void) DPRINT("CSR: %s called\n", __FUNCTION__); Ok = TRUE; - if (0 != InitCompleteProcCount) + for (i = 0; i < ServerProcCount && Ok; i++) { - for (i = 0; i < InitCompleteProcCount && Ok; i++) - { - Ok = (*(InitCompleteProcs[i]))(); - } - RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs); + Ok = (*ServerProcs[i].InitCompleteProc)(); } return Ok; @@ -212,17 +178,44 @@ CallHardError(IN PCSRSS_PROCESS_DATA ProcessData, DPRINT("CSR: %s called\n", __FUNCTION__); Ok = TRUE; - if (0 != HardErrorProcCount) + for (i = 0; i < ServerProcCount && Ok; i++) { - for (i = 0; i < HardErrorProcCount && Ok; i++) - { - Ok = (*(HardErrorProcs[i]))(ProcessData, HardErrorMessage); - } + Ok = (*ServerProcs[i].HardErrorProc)(ProcessData, HardErrorMessage); } return Ok; } +NTSTATUS +CallProcessInherit(IN PCSRSS_PROCESS_DATA SourceProcessData, + IN PCSRSS_PROCESS_DATA TargetProcessData) +{ + NTSTATUS Status = STATUS_SUCCESS; + unsigned i; + + DPRINT("CSR: %s called\n", __FUNCTION__); + + for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++) + Status = (*ServerProcs[i].ProcessInheritProc)(SourceProcessData, TargetProcessData); + + return Status; +} + +NTSTATUS +CallProcessDeleted(IN PCSRSS_PROCESS_DATA ProcessData) +{ + NTSTATUS Status = STATUS_SUCCESS; + unsigned i; + + DPRINT("CSR: %s called\n", __FUNCTION__); + + for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++) + Status = (*ServerProcs[i].ProcessDeletedProc)(ProcessData); + + return Status; +} + + ULONG InitializeVideoAddressSpace(VOID); @@ -313,9 +306,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) CSRPLUGIN_INITIALIZE_PROC InitProc; CSRSS_EXPORTED_FUNCS Exports; PCSRSS_API_DEFINITION ApiDefinitions; - PCSRSS_OBJECT_DEFINITION ObjectDefinitions; - CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; - CSRPLUGIN_HARDERROR_PROC HardErrorProc; + CSRPLUGIN_SERVER_PROCS ServerProcs; DPRINT("CSR: %s called\n", __FUNCTION__); @@ -331,14 +322,8 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) { return Status; } - Exports.CsrInsertObjectProc = CsrInsertObject; - Exports.CsrGetObjectProc = CsrGetObject; - Exports.CsrReleaseObjectByPointerProc = CsrReleaseObjectByPointer; - Exports.CsrReleaseObjectProc = CsrReleaseObject; - Exports.CsrReleaseConsoleProc = CsrReleaseConsole; Exports.CsrEnumProcessesProc = CsrEnumProcesses; - if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc, - &HardErrorProc, &Exports, CsrssApiHeap)) + if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrssApiHeap)) { return STATUS_UNSUCCESSFUL; } @@ -348,17 +333,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) { return Status; } - Status = CsrRegisterObjectDefinitions(ObjectDefinitions); - if (! NT_SUCCESS(Status)) - { - return Status; - } - if (NULL != InitCompleteProc) - { - Status = CsrpAddInitCompleteProc(InitCompleteProc); - } - if (HardErrorProc) Status = CsrpAddHardErrorProc(HardErrorProc); - + Status = CsrpAddServerProcs(&ServerProcs); return Status; } @@ -371,12 +346,6 @@ CSRSS_API_DEFINITION NativeDefinitions[] = CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess), CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters), CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters), - CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), - CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), - CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), - CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), - CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), - CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle), { 0, 0, NULL } }; diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 444cee7777d..c927ea80360 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -71,8 +71,8 @@ typedef struct _CSRSS_HANDLE typedef struct _CSRSS_PROCESS_DATA { - PCSRSS_CONSOLE Console; - PCSRSS_CONSOLE ParentConsole; + struct tagCSRSS_CONSOLE *Console; + struct tagCSRSS_CONSOLE *ParentConsole; BOOL bInheritHandles; RTL_CRITICAL_SECTION HandleTableLock; ULONG HandleTableSize; diff --git a/reactos/subsystems/win32/csrss/include/csrplugin.h b/reactos/subsystems/win32/csrss/include/csrplugin.h index 24c0c7debc3..20830bc76eb 100644 --- a/reactos/subsystems/win32/csrss/include/csrplugin.h +++ b/reactos/subsystems/win32/csrss/include/csrplugin.h @@ -21,29 +21,11 @@ #include #include "api.h" -typedef NTSTATUS (WINAPI *CSRSS_INSERT_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable); -typedef NTSTATUS (WINAPI *CSRSS_GET_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access); -typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_BY_POINTER_PROC)(Object_t *Object); -typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Object ); -typedef NTSTATUS (WINAPI *CSRSS_RELEASE_CONSOLE_PROC)(PCSRSS_PROCESS_DATA ProcessData); typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); typedef struct tagCSRSS_EXPORTED_FUNCS { - CSRSS_INSERT_OBJECT_PROC CsrInsertObjectProc; - CSRSS_GET_OBJECT_PROC CsrGetObjectProc; - CSRSS_RELEASE_OBJECT_BY_POINTER_PROC CsrReleaseObjectByPointerProc; - CSRSS_RELEASE_OBJECT_PROC CsrReleaseObjectProc; - CSRSS_RELEASE_CONSOLE_PROC CsrReleaseConsoleProc; CSRSS_ENUM_PROCESSES_PROC CsrEnumProcessesProc; } CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS; @@ -52,10 +34,21 @@ typedef BOOL (WINAPI *CSRPLUGIN_INIT_COMPLETE_PROC)(void); typedef BOOL (WINAPI *CSRPLUGIN_HARDERROR_PROC)(IN PCSRSS_PROCESS_DATA ProcessData, IN PHARDERROR_MSG HardErrorMessage); +typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_INHERIT_PROC)(IN PCSRSS_PROCESS_DATA SourceProcessData, + IN PCSRSS_PROCESS_DATA TargetProcessData); + +typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_DELETED_PROC)(IN PCSRSS_PROCESS_DATA ProcessData); + +typedef struct tagCSRSS_SERVER_PROCS +{ + CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; + CSRPLUGIN_HARDERROR_PROC HardErrorProc; + CSRPLUGIN_PROCESS_INHERIT_PROC ProcessInheritProc; + CSRPLUGIN_PROCESS_DELETED_PROC ProcessDeletedProc; +} CSRPLUGIN_SERVER_PROCS, *PCSRPLUGIN_SERVER_PROCS; + typedef BOOL (WINAPI *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions, - PCSRSS_OBJECT_DEFINITION *ObjectDefinitions, - CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProc, - CSRPLUGIN_HARDERROR_PROC *HardErrorProc, + PCSRPLUGIN_SERVER_PROCS ServerProcs, PCSRSS_EXPORTED_FUNCS Exports, HANDLE CsrssApiHeap); diff --git a/reactos/subsystems/win32/csrss/include/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h similarity index 100% rename from reactos/subsystems/win32/csrss/include/conio.h rename to reactos/subsystems/win32/csrss/win32csr/conio.h diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 52486633031..353d886babe 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -24,6 +24,12 @@ static CSRSS_EXPORTED_FUNCS CsrExports; static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = { + CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), + CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), + CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), + CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), + CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), + CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle), CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole), CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole), CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole), @@ -108,7 +114,7 @@ Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, DWORD Access, BOOL Inheritable) { - return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object, Access, Inheritable); + return CsrInsertObject(ProcessData, Handle, Object, Access, Inheritable); } NTSTATUS FASTCALL @@ -117,7 +123,7 @@ Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, Object_t **Object, DWORD Access) { - return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access); + return CsrGetObject(ProcessData, Handle, Object, Access); } NTSTATUS FASTCALL @@ -129,7 +135,7 @@ Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, { NTSTATUS Status; - Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access); + Status = CsrGetObject(ProcessData, Handle, Object, Access); if (! NT_SUCCESS(Status)) { return Status; @@ -137,7 +143,7 @@ Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, if ((*Object)->Type != Type) { - (CsrExports.CsrReleaseObjectByPointerProc)(*Object); + CsrReleaseObjectByPointer(*Object); return STATUS_INVALID_HANDLE; } @@ -150,26 +156,26 @@ VOID FASTCALL Win32CsrUnlockObject(Object_t *Object) { LeaveCriticalSection(&(Object->Lock)); - (CsrExports.CsrReleaseObjectByPointerProc)(Object); + CsrReleaseObjectByPointer(Object); } NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object) { - return (CsrExports.CsrReleaseObjectByPointerProc)(Object); + return CsrReleaseObjectByPointer(Object); } NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Object) { - return (CsrExports.CsrReleaseObjectProc)(ProcessData, Object); + return CsrReleaseObject(ProcessData, Object); } NTSTATUS FASTCALL Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData) { - return (CsrExports.CsrReleaseConsoleProc)(ProcessData); + return CsrReleaseConsole(ProcessData); } NTSTATUS FASTCALL @@ -189,9 +195,7 @@ Win32CsrInitComplete(void) BOOL WINAPI Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, - PCSRSS_OBJECT_DEFINITION *ObjectDefinitions, - CSRPLUGIN_INIT_COMPLETE_PROC *InitComplete, - CSRPLUGIN_HARDERROR_PROC *HardError, + PCSRPLUGIN_SERVER_PROCS ServerProcs, PCSRSS_EXPORTED_FUNCS Exports, HANDLE CsrssApiHeap) { @@ -203,11 +207,13 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, PrivateCsrssManualGuiCheck(0); CsrInitConsoleSupport(); + CsrRegisterObjectDefinitions(Win32CsrObjectDefinitions); *ApiDefinitions = Win32CsrApiDefinitions; - *ObjectDefinitions = Win32CsrObjectDefinitions; - *InitComplete = Win32CsrInitComplete; - *HardError = Win32CsrHardError; + ServerProcs->InitCompleteProc = Win32CsrInitComplete; + ServerProcs->HardErrorProc = Win32CsrHardError; + ServerProcs->ProcessInheritProc = CsrDuplicateHandleTable; + ServerProcs->ProcessDeletedProc = CsrReleaseConsole; return TRUE; } diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c similarity index 61% rename from reactos/subsystems/win32/csrss/csrsrv/api/handle.c rename to reactos/subsystems/win32/csrss/win32csr/handle.c index 6567f896c12..4d971b324d5 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -9,7 +9,7 @@ /* INCLUDES ******************************************************************/ -#include +#include #define NDEBUG #include @@ -42,7 +42,7 @@ CsrRegisterObjectDefinitions( NewCount++; } - New = RtlAllocateHeap(CsrssApiHeap, + New = RtlAllocateHeap(Win32CsrApiHeap, 0, (ObjectDefinitionsCount + NewCount) * sizeof(CSRSS_OBJECT_DEFINITION)); @@ -57,7 +57,7 @@ CsrRegisterObjectDefinitions( RtlCopyMemory(New, ObjectDefinitions, ObjectDefinitionsCount * sizeof(CSRSS_OBJECT_DEFINITION)); - RtlFreeHeap(CsrssApiHeap, 0, ObjectDefinitions); + RtlFreeHeap(Win32CsrApiHeap, 0, ObjectDefinitions); } RtlCopyMemory(New + ObjectDefinitionsCount, @@ -171,7 +171,7 @@ CsrReleaseConsole( if (HandleTable[i].Object != NULL) CsrReleaseObjectByPointer(HandleTable[i].Object); } - RtlFreeHeap(CsrssApiHeap, 0, HandleTable); + RtlFreeHeap(Win32CsrApiHeap, 0, HandleTable); if (Console != NULL) { @@ -208,7 +208,7 @@ CsrInsertObject( } if (i >= ProcessData->HandleTableSize) { - Block = RtlAllocateHeap(CsrssApiHeap, + Block = RtlAllocateHeap(Win32CsrApiHeap, HEAP_ZERO_MEMORY, (ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE)); if (Block == NULL) @@ -220,7 +220,7 @@ CsrInsertObject( ProcessData->HandleTable, ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE)); Block = _InterlockedExchangePointer((void* volatile)&ProcessData->HandleTable, Block); - RtlFreeHeap( CsrssApiHeap, 0, Block ); + RtlFreeHeap( Win32CsrApiHeap, 0, Block ); ProcessData->HandleTableSize += 64; } ProcessData->HandleTable[i].Object = Object; @@ -249,7 +249,7 @@ CsrDuplicateHandleTable( /* we are called from CreateProcessData, it isn't necessary to lock the target process data */ - TargetProcessData->HandleTable = RtlAllocateHeap(CsrssApiHeap, + TargetProcessData->HandleTable = RtlAllocateHeap(Win32CsrApiHeap, HEAP_ZERO_MEMORY, SourceProcessData->HandleTableSize * sizeof(CSRSS_HANDLE)); @@ -289,4 +289,132 @@ CsrVerifyObject( return STATUS_SUCCESS; } +CSR_API(CsrGetInputHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (ProcessData->Console) + { + Request->Status = CsrInsertObject(ProcessData, + &Request->Data.GetInputHandleRequest.InputHandle, + (Object_t *)ProcessData->Console, + Request->Data.GetInputHandleRequest.Access, + Request->Data.GetInputHandleRequest.Inheritable); + } + else + { + Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; + Request->Status = STATUS_SUCCESS; + } + + return Request->Status; +} + +CSR_API(CsrGetOutputHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (ProcessData->Console) + { + Request->Status = CsrInsertObject(ProcessData, + &Request->Data.GetOutputHandleRequest.OutputHandle, + &ProcessData->Console->ActiveBuffer->Header, + Request->Data.GetOutputHandleRequest.Access, + Request->Data.GetOutputHandleRequest.Inheritable); + } + else + { + Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE; + Request->Status = STATUS_SUCCESS; + } + + return Request->Status; +} + +CSR_API(CsrCloseHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + return CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); +} + +CSR_API(CsrVerifyHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Request->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle); + if (!NT_SUCCESS(Request->Status)) + { + DPRINT("CsrVerifyObject failed, status=%x\n", Request->Status); + } + + return Request->Status; +} + +CSR_API(CsrDuplicateHandle) +{ + ULONG_PTR Index; + PCSRSS_HANDLE Entry; + DWORD DesiredAccess; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (Index >= ProcessData->HandleTableSize + || (Entry = &ProcessData->HandleTable[Index])->Object == NULL) + { + DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + + if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS) + { + DesiredAccess = Entry->Access; + } + else + { + DesiredAccess = Request->Data.DuplicateHandleRequest.Access; + /* Make sure the source handle has all the desired flags */ + if (~Entry->Access & DesiredAccess) + { + DPRINT1("Handle %p only has access %X; requested %X\n", + Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_PARAMETER; + } + } + + Request->Status = CsrInsertObject(ProcessData, + &Request->Data.DuplicateHandleRequest.Handle, + Entry->Object, + DesiredAccess, + Request->Data.DuplicateHandleRequest.Inheritable); + if (NT_SUCCESS(Request->Status) + && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) + { + /* Close the original handle. This cannot drop the count to 0, since a new handle now exists */ + _InterlockedDecrement(&Entry->Object->ReferenceCount); + Entry->Object = NULL; + } + + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Request->Status; +} + +CSR_API(CsrGetInputWaitHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent; + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/reactos/subsystems/win32/csrss/include/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h similarity index 100% rename from reactos/subsystems/win32/csrss/include/win32csr.h rename to reactos/subsystems/win32/csrss/win32csr/win32csr.h diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index eec81fcba60..8d04c718e73 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -22,6 +22,7 @@ dllmain.c exitros.c guiconsole.c + handle.c harderror.c tuiconsole.c appswitch.c diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.spec b/reactos/subsystems/win32/csrss/win32csr/win32csr.spec index 85e81a759b4..2e513757b03 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.spec +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.spec @@ -1 +1 @@ -@ stdcall Win32CsrInitialization(ptr ptr ptr ptr ptr ptr) +@ stdcall Win32CsrInitialization(ptr ptr ptr ptr) From 8686d42f934a81e8758deb57dbbd63959f6071fc Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 00:51:29 +0000 Subject: [PATCH 011/292] [WIN32CSR] Clean up the debris from r47314: Removed some redundant code, reorganized headers, fixed win32csr.rbuild indentation svn path=/trunk/; revision=47315 --- reactos/subsystems/win32/csrss/csrsrv/srv.h | 1 - reactos/subsystems/win32/csrss/include/api.h | 75 +------ .../subsystems/win32/csrss/win32csr/conio.h | 12 ++ .../csrss/{include => win32csr}/desktopbg.h | 0 .../subsystems/win32/csrss/win32csr/dllmain.c | 83 +------- .../subsystems/win32/csrss/win32csr/handle.c | 185 ++++++++---------- .../win32/csrss/win32csr/win32csr.h | 41 +++- .../win32/csrss/win32csr/win32csr.rbuild | 2 +- 8 files changed, 144 insertions(+), 255 deletions(-) rename reactos/subsystems/win32/csrss/{include => win32csr}/desktopbg.h (100%) diff --git a/reactos/subsystems/win32/csrss/csrsrv/srv.h b/reactos/subsystems/win32/csrss/csrsrv/srv.h index cc11b70603c..b784e6ed575 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/srv.h +++ b/reactos/subsystems/win32/csrss/csrsrv/srv.h @@ -17,5 +17,4 @@ /* Internal CSRSS Headers */ #include -#include #include diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index c927ea80360..7e956b66698 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -44,31 +44,6 @@ typedef enum _CSR_PROCESS_FLAGS CsrProcessIsConsoleApp = 0x800 } CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS; -typedef struct Object_tt -{ - LONG Type; - LONG ReferenceCount; - CRITICAL_SECTION Lock; -} Object_t; - -typedef struct ConsoleInput_t -{ - LIST_ENTRY ListEntry; - INPUT_RECORD InputEvent; - BOOLEAN Echoed; // already been echoed or not - BOOLEAN Fake; // synthesized, not a real event - BOOLEAN NotChar; // message should not be used to return a character -} ConsoleInput; - -typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; - -typedef struct _CSRSS_HANDLE -{ - Object_t *Object; - DWORD Access; - BOOL Inheritable; -} CSRSS_HANDLE, *PCSRSS_HANDLE; - typedef struct _CSRSS_PROCESS_DATA { struct tagCSRSS_CONSOLE *Console; @@ -76,7 +51,7 @@ typedef struct _CSRSS_PROCESS_DATA BOOL bInheritHandles; RTL_CRITICAL_SECTION HandleTableLock; ULONG HandleTableSize; - PCSRSS_HANDLE HandleTable; + struct _CSRSS_HANDLE *HandleTable; HANDLE ProcessId; DWORD ProcessGroup; HANDLE Process; @@ -109,14 +84,6 @@ typedef struct _CSR_THREAD ULONG ImpersonationCount; } CSR_THREAD, *PCSR_THREAD; -typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); - -typedef struct tagCSRSS_OBJECT_DEFINITION -{ - LONG Type; - CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc; -} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION; - typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSRSS_PROCESS_DATA ProcessData, PCSR_API_MESSAGE Request); @@ -143,33 +110,25 @@ PCSR_API_MESSAGE Request) /* init.c */ extern HANDLE hBootstrapOk; +NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); /* api/process.c */ CSR_API(CsrConnectProcess); CSR_API(CsrCreateProcess); CSR_API(CsrTerminateProcess); CSR_API(CsrSrvCreateThread); - -/* print.c */ -VOID WINAPI DisplayString(LPCWSTR lpwString); -VOID WINAPI PrintString (char* fmt, ...); +CSR_API(CsrGetShutdownParameters); +CSR_API(CsrSetShutdownParameters); /* api/wapi.c */ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions); VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData, PCSR_API_MESSAGE Request); -DWORD WINAPI ServerApiPortThread (PVOID PortHandle); DWORD WINAPI ServerSbApiPortThread (PVOID PortHandle); -DWORD WINAPI Console_Api( PVOID unused ); -VOID -NTAPI -ClientConnectionThread(HANDLE ServerPort); +VOID NTAPI ClientConnectionThread(HANDLE ServerPort); extern HANDLE CsrssApiHeap; -/* api/conio.c */ -VOID WINAPI CsrInitConsoleSupport(VOID); - /* api/process.c */ typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSRSS_PROCESS_DATA ProcessData, PVOID Context); @@ -185,34 +144,10 @@ NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSRSS_PROCESS_DATA * NTSTATUS NTAPI CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId); NTSTATUS NTAPI CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess); -/* api/handle.c */ -NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions); -NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable ); -NTSTATUS WINAPI CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); -NTSTATUS WINAPI CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, DWORD Access ); -NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); -NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object); -NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); -NTSTATUS WINAPI CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); -NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); - //hack VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); -CSR_API(CsrGetInputHandle); -CSR_API(CsrGetOutputHandle); -CSR_API(CsrCloseHandle); -CSR_API(CsrVerifyHandle); -CSR_API(CsrDuplicateHandle); -CSR_API(CsrGetInputWaitHandle); - /* api/user.c */ CSR_API(CsrRegisterServicesProcess); -CSR_API(CsrExitReactos); -CSR_API(CsrGetShutdownParameters); -CSR_API(CsrSetShutdownParameters); - -CSR_API(CsrSetLogonNotifyWindow); -CSR_API(CsrRegisterLogonProcess); /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index cf62ac71c52..1d1ab7f908d 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -48,6 +48,8 @@ typedef struct tagCSRSS_SCREEN_BUFFER USHORT Mode; } CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER; +typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; + typedef struct tagCSRSS_CONSOLE_VTBL { VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); @@ -88,9 +90,19 @@ typedef struct tagCSRSS_CONSOLE struct tagALIAS_HEADER *Aliases; } CSRSS_CONSOLE; +typedef struct ConsoleInput_t +{ + LIST_ENTRY ListEntry; + INPUT_RECORD InputEvent; + BOOLEAN Echoed; // already been echoed or not + BOOLEAN Fake; // synthesized, not a real event + BOOLEAN NotChar; // message should not be used to return a character +} ConsoleInput; + NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); VOID WINAPI ConioDeleteConsole(Object_t *Object); VOID WINAPI ConioDeleteScreenBuffer(Object_t *Buffer); +VOID WINAPI CsrInitConsoleSupport(VOID); void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); diff --git a/reactos/subsystems/win32/csrss/include/desktopbg.h b/reactos/subsystems/win32/csrss/win32csr/desktopbg.h similarity index 100% rename from reactos/subsystems/win32/csrss/include/desktopbg.h rename to reactos/subsystems/win32/csrss/win32csr/desktopbg.h diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 353d886babe..a8fdd418161 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -84,13 +84,6 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = { 0, 0, NULL } }; -static CSRSS_OBJECT_DEFINITION Win32CsrObjectDefinitions[] = - { - { CONIO_CONSOLE_MAGIC, ConioDeleteConsole }, - { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer }, - { 0, NULL } - }; - /* FUNCTIONS *****************************************************************/ BOOL WINAPI @@ -107,77 +100,6 @@ DllMain(HANDLE hDll, return TRUE; } -NTSTATUS FASTCALL -Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable) -{ - return CsrInsertObject(ProcessData, Handle, Object, Access, Inheritable); -} - -NTSTATUS FASTCALL -Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access) -{ - return CsrGetObject(ProcessData, Handle, Object, Access); -} - -NTSTATUS FASTCALL -Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access, - LONG Type) -{ - NTSTATUS Status; - - Status = CsrGetObject(ProcessData, Handle, Object, Access); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - if ((*Object)->Type != Type) - { - CsrReleaseObjectByPointer(*Object); - return STATUS_INVALID_HANDLE; - } - - EnterCriticalSection(&((*Object)->Lock)); - - return STATUS_SUCCESS; -} - -VOID FASTCALL -Win32CsrUnlockObject(Object_t *Object) -{ - LeaveCriticalSection(&(Object->Lock)); - CsrReleaseObjectByPointer(Object); -} - -NTSTATUS FASTCALL -Win32CsrReleaseObjectByPointer(Object_t *Object) -{ - return CsrReleaseObjectByPointer(Object); -} - -NTSTATUS FASTCALL -Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Object) -{ - return CsrReleaseObject(ProcessData, Object); -} - -NTSTATUS FASTCALL -Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData) -{ - return CsrReleaseConsole(ProcessData); -} - NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) @@ -207,13 +129,12 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, PrivateCsrssManualGuiCheck(0); CsrInitConsoleSupport(); - CsrRegisterObjectDefinitions(Win32CsrObjectDefinitions); *ApiDefinitions = Win32CsrApiDefinitions; ServerProcs->InitCompleteProc = Win32CsrInitComplete; ServerProcs->HardErrorProc = Win32CsrHardError; - ServerProcs->ProcessInheritProc = CsrDuplicateHandleTable; - ServerProcs->ProcessDeletedProc = CsrReleaseConsole; + ServerProcs->ProcessInheritProc = Win32CsrDuplicateHandleTable; + ServerProcs->ProcessDeletedProc = Win32CsrReleaseConsole; return TRUE; } diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index 4d971b324d5..b137c3c66e5 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -16,8 +16,12 @@ /* FUNCTIONS *****************************************************************/ -static unsigned ObjectDefinitionsCount = 0; -static PCSRSS_OBJECT_DEFINITION ObjectDefinitions = NULL; +static unsigned ObjectDefinitionsCount = 2; +static CSRSS_OBJECT_DEFINITION ObjectDefinitions[] = +{ + { CONIO_CONSOLE_MAGIC, ConioDeleteConsole }, + { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer }, +}; static BOOL @@ -26,52 +30,9 @@ CsrIsConsoleHandle(HANDLE Handle) return ((ULONG_PTR)Handle & 0x10000003) == 0x3; } - NTSTATUS FASTCALL -CsrRegisterObjectDefinitions( - PCSRSS_OBJECT_DEFINITION NewDefinitions) -{ - unsigned NewCount; - PCSRSS_OBJECT_DEFINITION Scan; - PCSRSS_OBJECT_DEFINITION New; - - NewCount = 0; - for (Scan = NewDefinitions; 0 != Scan->Type; Scan++) - { - NewCount++; - } - - New = RtlAllocateHeap(Win32CsrApiHeap, - 0, - (ObjectDefinitionsCount + NewCount) - * sizeof(CSRSS_OBJECT_DEFINITION)); - if (NULL == New) - { - DPRINT1("Unable to allocate memory\n"); - return STATUS_NO_MEMORY; - } - - if (0 != ObjectDefinitionsCount) - { - RtlCopyMemory(New, - ObjectDefinitions, - ObjectDefinitionsCount * sizeof(CSRSS_OBJECT_DEFINITION)); - RtlFreeHeap(Win32CsrApiHeap, 0, ObjectDefinitions); - } - - RtlCopyMemory(New + ObjectDefinitionsCount, - NewDefinitions, - NewCount * sizeof(CSRSS_OBJECT_DEFINITION)); - ObjectDefinitions = New; - ObjectDefinitionsCount += NewCount; - - return STATUS_SUCCESS; -} - -NTSTATUS -WINAPI -CsrGetObject( +Win32CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, @@ -99,8 +60,8 @@ CsrGetObject( NTSTATUS -WINAPI -CsrReleaseObjectByPointer( +FASTCALL +Win32CsrReleaseObjectByPointer( Object_t *Object) { unsigned DefIndex; @@ -123,10 +84,9 @@ CsrReleaseObjectByPointer( return STATUS_SUCCESS; } - NTSTATUS -WINAPI -CsrReleaseObject( +FASTCALL +Win32CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle) { @@ -143,12 +103,47 @@ CsrReleaseObject( ProcessData->HandleTable[h].Object = NULL; RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return CsrReleaseObjectByPointer(Object); + return Win32CsrReleaseObjectByPointer(Object); +} + +NTSTATUS +FASTCALL +Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, + HANDLE Handle, + Object_t **Object, + DWORD Access, + LONG Type) +{ + NTSTATUS Status; + + Status = Win32CsrGetObject(ProcessData, Handle, Object, Access); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + if ((*Object)->Type != Type) + { + Win32CsrReleaseObjectByPointer(*Object); + return STATUS_INVALID_HANDLE; + } + + EnterCriticalSection(&((*Object)->Lock)); + + return STATUS_SUCCESS; +} + +VOID +FASTCALL +Win32CsrUnlockObject(Object_t *Object) +{ + LeaveCriticalSection(&(Object->Lock)); + Win32CsrReleaseObjectByPointer(Object); } NTSTATUS WINAPI -CsrReleaseConsole( +Win32CsrReleaseConsole( PCSRSS_PROCESS_DATA ProcessData) { ULONG HandleTableSize; @@ -169,16 +164,16 @@ CsrReleaseConsole( for (i = 0; i < HandleTableSize; i++) { if (HandleTable[i].Object != NULL) - CsrReleaseObjectByPointer(HandleTable[i].Object); + Win32CsrReleaseObjectByPointer(HandleTable[i].Object); } RtlFreeHeap(Win32CsrApiHeap, 0, HandleTable); if (Console != NULL) { - RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)&Console->Header.Lock); + EnterCriticalSection(&Console->Header.Lock); RemoveEntryList(&ProcessData->ProcessEntry); - RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)&Console->Header.Lock); - CsrReleaseObjectByPointer(&Console->Header); + LeaveCriticalSection(&Console->Header.Lock); + Win32CsrReleaseObjectByPointer(&Console->Header); return STATUS_SUCCESS; } @@ -186,8 +181,8 @@ CsrReleaseConsole( } NTSTATUS -WINAPI -CsrInsertObject( +FASTCALL +Win32CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, @@ -195,7 +190,7 @@ CsrInsertObject( BOOL Inheritable) { ULONG i; - PVOID* Block; + PCSRSS_HANDLE Block; RtlEnterCriticalSection(&ProcessData->HandleTableLock); @@ -219,8 +214,8 @@ CsrInsertObject( RtlCopyMemory(Block, ProcessData->HandleTable, ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE)); - Block = _InterlockedExchangePointer((void* volatile)&ProcessData->HandleTable, Block); - RtlFreeHeap( Win32CsrApiHeap, 0, Block ); + RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable); + ProcessData->HandleTable = Block; ProcessData->HandleTableSize += 64; } ProcessData->HandleTable[i].Object = Object; @@ -234,7 +229,7 @@ CsrInsertObject( NTSTATUS WINAPI -CsrDuplicateHandleTable( +Win32CsrDuplicateHandleTable( PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData) { @@ -272,23 +267,6 @@ CsrDuplicateHandleTable( return(STATUS_SUCCESS); } -NTSTATUS -WINAPI -CsrVerifyObject( - PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle) -{ - ULONG_PTR h = (ULONG_PTR)Handle >> 2; - - if (h >= ProcessData->HandleTableSize || - ProcessData->HandleTable[h].Object == NULL) - { - return STATUS_INVALID_HANDLE; - } - - return STATUS_SUCCESS; -} - CSR_API(CsrGetInputHandle) { Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); @@ -296,11 +274,11 @@ CSR_API(CsrGetInputHandle) if (ProcessData->Console) { - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetInputHandleRequest.InputHandle, - (Object_t *)ProcessData->Console, - Request->Data.GetInputHandleRequest.Access, - Request->Data.GetInputHandleRequest.Inheritable); + Request->Status = Win32CsrInsertObject(ProcessData, + &Request->Data.GetInputHandleRequest.InputHandle, + &ProcessData->Console->Header, + Request->Data.GetInputHandleRequest.Access, + Request->Data.GetInputHandleRequest.Inheritable); } else { @@ -318,11 +296,11 @@ CSR_API(CsrGetOutputHandle) if (ProcessData->Console) { - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetOutputHandleRequest.OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, - Request->Data.GetOutputHandleRequest.Access, - Request->Data.GetOutputHandleRequest.Inheritable); + Request->Status = Win32CsrInsertObject(ProcessData, + &Request->Data.GetOutputHandleRequest.OutputHandle, + &ProcessData->Console->ActiveBuffer->Header, + Request->Data.GetOutputHandleRequest.Access, + Request->Data.GetOutputHandleRequest.Inheritable); } else { @@ -338,21 +316,28 @@ CSR_API(CsrCloseHandle) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); + return Win32CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); } CSR_API(CsrVerifyHandle) { + ULONG_PTR Index; + NTSTATUS Status = STATUS_SUCCESS; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle); - if (!NT_SUCCESS(Request->Status)) + Index = (ULONG_PTR)Request->Data.VerifyHandleRequest.Handle >> 2; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (Index >= ProcessData->HandleTableSize || + ProcessData->HandleTable[Index].Object == NULL) { - DPRINT("CsrVerifyObject failed, status=%x\n", Request->Status); + DPRINT("CsrVerifyObject failed\n"); + Status = STATUS_INVALID_HANDLE; } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Request->Status; + return Status; } CSR_API(CsrDuplicateHandle) @@ -391,11 +376,11 @@ CSR_API(CsrDuplicateHandle) } } - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.DuplicateHandleRequest.Handle, - Entry->Object, - DesiredAccess, - Request->Data.DuplicateHandleRequest.Inheritable); + Request->Status = Win32CsrInsertObject(ProcessData, + &Request->Data.DuplicateHandleRequest.Handle, + Entry->Object, + DesiredAccess, + Request->Data.DuplicateHandleRequest.Inheritable); if (NT_SUCCESS(Request->Status) && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) { diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h index 4b5ab4756cf..5bcd0c268a9 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.h @@ -14,6 +14,29 @@ extern HANDLE Win32CsrApiHeap; extern HINSTANCE Win32CsrDllHandle; +typedef struct Object_tt +{ + LONG Type; + LONG ReferenceCount; + CRITICAL_SECTION Lock; +} Object_t; + +typedef struct _CSRSS_HANDLE +{ + Object_t *Object; + DWORD Access; + BOOL Inheritable; +} CSRSS_HANDLE, *PCSRSS_HANDLE; + +typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); + +typedef struct tagCSRSS_OBJECT_DEFINITION +{ + LONG Type; + CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc; +} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION; + +/* handle.c */ NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, @@ -25,7 +48,6 @@ NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, DWORD Access, long Type); VOID FASTCALL Win32CsrUnlockObject(Object_t *Object); - NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, @@ -33,8 +55,23 @@ NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Object); -NTSTATUS FASTCALL Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); +NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); +NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, + PCSRSS_PROCESS_DATA TargetProcessData); +CSR_API(CsrGetInputHandle); +CSR_API(CsrGetOutputHandle); +CSR_API(CsrCloseHandle); +CSR_API(CsrVerifyHandle); +CSR_API(CsrDuplicateHandle); +CSR_API(CsrGetInputWaitHandle); + NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); +/* exitros.c */ +CSR_API(CsrExitReactos); +CSR_API(CsrSetLogonNotifyWindow); +CSR_API(CsrRegisterLogonProcess); + + /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 8d04c718e73..392dccbf50d 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -22,7 +22,7 @@ dllmain.c exitros.c guiconsole.c - handle.c + handle.c harderror.c tuiconsole.c appswitch.c From ff2f27f29b9381a364fbb1f5d5e89015a20d59a9 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 02:58:23 +0000 Subject: [PATCH 012/292] [WIN32CSR] Protect ProcessData->Console with the HandleTableLock. svn path=/trunk/; revision=47316 --- .../subsystems/win32/csrss/win32csr/conio.c | 18 ++++++++++++- .../subsystems/win32/csrss/win32csr/handle.c | 25 ++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 5aa5cf811c4..cb75428c6d7 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -41,15 +41,20 @@ NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) { - PCSRSS_CONSOLE ProcessConsole = ProcessData->Console; + PCSRSS_CONSOLE ProcessConsole; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + ProcessConsole = ProcessData->Console; if (!ProcessConsole) { *Console = NULL; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; } InterlockedIncrement(&ProcessConsole->Header.ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); EnterCriticalSection(&(ProcessConsole->Header.Lock)); *Console = ProcessConsole; @@ -247,9 +252,11 @@ CSR_API(CsrAllocConsole) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + RtlEnterCriticalSection(&ProcessData->HandleTableLock); if (ProcessData->Console) { DPRINT1("Process already has a console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_PARAMETER; } @@ -257,6 +264,7 @@ CSR_API(CsrAllocConsole) if (!Request->Data.AllocConsoleRequest.ConsoleNeeded) { DPRINT("No console needed\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_SUCCESS; } @@ -270,6 +278,7 @@ CSR_API(CsrAllocConsole) if (NULL == Console) { DPRINT1("Not enough memory for console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_NO_MEMORY; } /* initialize list head */ @@ -282,6 +291,7 @@ CSR_API(CsrAllocConsole) { DPRINT1("Console init failed\n"); HeapFree(Win32CsrApiHeap, 0, Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Status; } } @@ -313,6 +323,7 @@ CSR_API(CsrAllocConsole) DPRINT1("Failed to insert object\n"); ConioDeleteConsole((Object_t *) Console); ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Status; } @@ -328,6 +339,7 @@ CSR_API(CsrAllocConsole) Win32CsrReleaseObject(ProcessData, Request->Data.AllocConsoleRequest.InputHandle); ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Status; } } @@ -351,6 +363,7 @@ CSR_API(CsrAllocConsole) Request->Data.AllocConsoleRequest.InputHandle); } ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Status; } @@ -364,6 +377,7 @@ CSR_API(CsrAllocConsole) InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_SUCCESS; } @@ -1960,6 +1974,7 @@ CSR_API(CsrCreateScreenBuffer) DPRINT("CsrCreateScreenBuffer\n"); + RtlEnterCriticalSection(&ProcessData->HandleTableLock); Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status)) { @@ -2012,6 +2027,7 @@ CSR_API(CsrCreateScreenBuffer) } ConioUnlockConsole(Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Status; } diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index b137c3c66e5..e1afd16b873 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -146,28 +146,25 @@ WINAPI Win32CsrReleaseConsole( PCSRSS_PROCESS_DATA ProcessData) { - ULONG HandleTableSize; - PCSRSS_HANDLE HandleTable; PCSRSS_CONSOLE Console; ULONG i; /* Close all console handles and detach process from console */ RtlEnterCriticalSection(&ProcessData->HandleTableLock); - HandleTableSize = ProcessData->HandleTableSize; - HandleTable = ProcessData->HandleTable; - Console = ProcessData->Console; + + for (i = 0; i < ProcessData->HandleTableSize; i++) + { + if (ProcessData->HandleTable[i].Object != NULL) + Win32CsrReleaseObjectByPointer(ProcessData->HandleTable[i].Object); + } ProcessData->HandleTableSize = 0; + RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable); ProcessData->HandleTable = NULL; + + Console = ProcessData->Console; ProcessData->Console = NULL; RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - for (i = 0; i < HandleTableSize; i++) - { - if (HandleTable[i].Object != NULL) - Win32CsrReleaseObjectByPointer(HandleTable[i].Object); - } - RtlFreeHeap(Win32CsrApiHeap, 0, HandleTable); - if (Console != NULL) { EnterCriticalSection(&Console->Header.Lock); @@ -272,6 +269,7 @@ CSR_API(CsrGetInputHandle) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + RtlEnterCriticalSection(&ProcessData->HandleTableLock); if (ProcessData->Console) { Request->Status = Win32CsrInsertObject(ProcessData, @@ -285,6 +283,7 @@ CSR_API(CsrGetInputHandle) Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; Request->Status = STATUS_SUCCESS; } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Request->Status; } @@ -294,6 +293,7 @@ CSR_API(CsrGetOutputHandle) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + RtlEnterCriticalSection(&ProcessData->HandleTableLock); if (ProcessData->Console) { Request->Status = Win32CsrInsertObject(ProcessData, @@ -307,6 +307,7 @@ CSR_API(CsrGetOutputHandle) Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE; Request->Status = STATUS_SUCCESS; } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return Request->Status; } From 3c777cde9cf46cc5689048ca34c0e9ac19f30012 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 05:33:21 +0000 Subject: [PATCH 013/292] [WIN32CSR] - Simplify locking: having a lock for each screen buffer is overkill since most programs only use one screen buffer at a time. (besides, almost all APIs were taking the console lock anyway) Reduce to just having one lock for a console. - Instead of keeping track of how many references a screen buffer has, keep track of handles only. When all handles to a screen buffer are closed, it should be deleted even if it's the active buffer (not yet implemented). svn path=/trunk/; revision=47317 --- .../subsystems/win32/csrss/win32csr/conio.c | 188 ++++-------------- .../subsystems/win32/csrss/win32csr/conio.h | 2 + .../win32/csrss/win32csr/guiconsole.c | 12 +- .../subsystems/win32/csrss/win32csr/handle.c | 146 ++++++-------- .../win32/csrss/win32csr/win32csr.h | 9 +- 5 files changed, 113 insertions(+), 244 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index cb75428c6d7..4b8e65c8cd4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -53,9 +53,9 @@ ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Con return STATUS_INVALID_HANDLE; } - InterlockedIncrement(&ProcessConsole->Header.ReferenceCount); + InterlockedIncrement(&ProcessConsole->ReferenceCount); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - EnterCriticalSection(&(ProcessConsole->Header.Lock)); + EnterCriticalSection(&(ProcessConsole->Lock)); *Console = ProcessConsole; return STATUS_SUCCESS; @@ -117,7 +117,8 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; - Buffer->Header.ReferenceCount = 0; + Buffer->Header.Console = Console; + Buffer->Header.HandleCount = 0; Buffer->ShowX = 0; Buffer->ShowY = 0; Buffer->VirtualY = 0; @@ -126,7 +127,6 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, { return STATUS_INSUFFICIENT_RESOURCES; } - InitializeCriticalSection(&Buffer->Header.Lock); ConioInitScreenBuffer(Console, Buffer); /* initialize buffer to be empty with default attributes */ for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) @@ -154,11 +154,12 @@ CsrInitConsole(PCSRSS_CONSOLE Console) //FIXME RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); - Console->Header.ReferenceCount = 0; + Console->ReferenceCount = 0; Console->WaitingChars = 0; Console->WaitingLines = 0; Console->EchoCount = 0; Console->Header.Type = CONIO_CONSOLE_MAGIC; + Console->Header.Console = Console; Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; Console->EarlyReturn = FALSE; Console->ActiveBuffer = NULL; @@ -177,7 +178,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) return STATUS_UNSUCCESSFUL; } Console->PrivateData = NULL; - InitializeCriticalSection(&Console->Header.Lock); + InitializeCriticalSection(&Console->Lock); GuiMode = DtbgIsDesktopVisible(); @@ -186,7 +187,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) if (NULL == NewBuffer) { RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); + DeleteCriticalSection(&Console->Lock); CloseHandle(Console->ActiveEvent); return STATUS_INSUFFICIENT_RESOURCES; } @@ -212,7 +213,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) { HeapFree(Win32CsrApiHeap,0, NewBuffer); RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); + DeleteCriticalSection(&Console->Lock); CloseHandle(Console->ActiveEvent); DPRINT1("GuiInitConsole: failed\n"); return Status; @@ -224,16 +225,13 @@ CsrInitConsole(PCSRSS_CONSOLE Console) { ConioCleanupConsole(Console); RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); + DeleteCriticalSection(&Console->Lock); CloseHandle(Console->ActiveEvent); HeapFree(Win32CsrApiHeap, 0, NewBuffer); DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); return Status; } - /* add a reference count because the buffer is tied to the console */ - InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount); - /* copy buffer contents to screen */ ConioDrawConsole(Console); @@ -308,7 +306,7 @@ CSR_API(CsrAllocConsole) Request->Data.AllocConsoleRequest.Console = Console; /* Add a reference count because the process is tied to the console */ - Console->Header.ReferenceCount++; + _InterlockedIncrement(&Console->ReferenceCount); if (NewConsole || !ProcessData->bInheritHandles) { @@ -836,15 +834,16 @@ CSR_API(CsrWriteConsole) Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); return STATUS_INVALID_PARAMETER; } - Status = ConioConsoleFromProcessData(ProcessData, &Console); Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { return Status; } + Console = Buff->Header.Console; if(Request->Data.WriteConsoleRequest.Unicode) { @@ -872,7 +871,6 @@ CSR_API(CsrWriteConsole) if (Buffer) { - Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (NT_SUCCESS(Status)) { Status = ConioWriteConsole(Console, Buff, Buffer, @@ -881,14 +879,13 @@ CSR_API(CsrWriteConsole) { Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; } - ConioUnlockScreenBuffer(Buff); } if (Request->Data.WriteConsoleRequest.Unicode) { RtlFreeHeap(GetProcessHeap(), 0, Buffer); } } - ConioUnlockConsole(Console); + ConioUnlockScreenBuffer(Buff); Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; @@ -899,7 +896,6 @@ VOID WINAPI ConioDeleteScreenBuffer(Object_t *Object) { PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object; - DeleteCriticalSection(&Buffer->Header.Lock); HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); HeapFree(Win32CsrApiHeap, 0, Buffer); } @@ -933,15 +929,12 @@ ConioDeleteConsole(Object_t *Object) } ConioCleanupConsole(Console); - if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount)) - { - ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); - } + ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); Console->ActiveBuffer = NULL; CloseHandle(Console->ActiveEvent); - DeleteCriticalSection(&Console->Header.Lock); + DeleteCriticalSection(&Console->Lock); RtlFreeUnicodeString(&Console->Title); IntDeleteAllAliases(Console->Aliases); HeapFree(Win32CsrApiHeap, 0, Console); @@ -1280,17 +1273,12 @@ CSR_API(CsrGetScreenBufferInfo) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; pInfo = &Request->Data.ScreenBufferInfoRequest.Info; pInfo->dwSize.X = Buff->MaxX; pInfo->dwSize.Y = Buff->MaxY; @@ -1304,7 +1292,6 @@ CSR_API(CsrGetScreenBufferInfo) pInfo->dwMaximumWindowSize.X = Buff->MaxX; pInfo->dwMaximumWindowSize.Y = Buff->MaxY; ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -1319,21 +1306,15 @@ CSR_API(CsrSetCursor) DPRINT("CsrSetCursor\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; NewCursorX = Request->Data.SetCursorRequest.Position.X; NewCursorY = Request->Data.SetCursorRequest.Position.Y; @@ -1341,7 +1322,6 @@ CSR_API(CsrSetCursor) NewCursorY < 0 || NewCursorY >= Buff->MaxY) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_INVALID_PARAMETER; } OldCursorX = Buff->CurrentX; @@ -1353,13 +1333,11 @@ CSR_API(CsrSetCursor) if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_UNSUCCESSFUL; } } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -1415,11 +1393,15 @@ CSR_API(CsrWriteConsoleOutputChar) return STATUS_INVALID_PARAMETER; } - Status = ConioConsoleFromProcessData(ProcessData, &Console); + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); if (NT_SUCCESS(Status)) { + Console = Buff->Header.Console; if(Request->Data.WriteConsoleOutputCharRequest.Unicode) { Length = WideCharToMultiByte(Console->OutputCodePage, 0, @@ -1446,10 +1428,6 @@ CSR_API(CsrWriteConsoleOutputChar) if (String) { - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); if (NT_SUCCESS(Status)) { X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; @@ -1481,14 +1459,13 @@ CSR_API(CsrWriteConsoleOutputChar) Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - ConioUnlockScreenBuffer(Buff); } if (Request->Data.WriteConsoleRequest.Unicode) { RtlFreeHeap(GetProcessHeap(), 0, tmpString); } } - ConioUnlockConsole(Console); + ConioUnlockScreenBuffer(Buff); } Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; return Status; @@ -1509,18 +1486,12 @@ CSR_API(CsrFillOutputChar) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; X = Request->Data.FillOutputRequest.Position.X; Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; @@ -1554,7 +1525,6 @@ CSR_API(CsrFillOutputChar) } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); Length = Request->Data.FillOutputRequest.Length; Request->Data.FillOutputRequest.NrCharactersWritten = Length; return STATUS_SUCCESS; @@ -1661,13 +1631,8 @@ CSR_API(CsrWriteConsoleOutputAttrib) return STATUS_INVALID_PARAMETER; } - Status = ConioConsoleFromProcessData(ProcessData, &Console); Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (! NT_SUCCESS(Status)) - { - return Status; - } Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, @@ -1675,9 +1640,9 @@ CSR_API(CsrWriteConsoleOutputAttrib) GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; @@ -1706,8 +1671,6 @@ CSR_API(CsrWriteConsoleOutputAttrib) ConioDrawRegion(Console, &UpdateRect); } - ConioUnlockConsole(Console); - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; @@ -1728,20 +1691,14 @@ CSR_API(CsrFillOutputAttrib) DPRINT("CsrFillOutputAttrib\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; X = Request->Data.FillOutputAttribRequest.Coord.X; Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; @@ -1771,7 +1728,6 @@ CSR_API(CsrFillOutputAttrib) } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -1812,18 +1768,12 @@ CSR_API(CsrSetCursorInfo) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; Size = Request->Data.SetCursorInfoRequest.Info.dwSize; Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; @@ -1845,13 +1795,11 @@ CSR_API(CsrSetCursorInfo) if (! ConioSetCursorInfo(Console, Buff)) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_UNSUCCESSFUL; } } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -1864,18 +1812,12 @@ CSR_API(CsrSetTextAttrib) DPRINT("CsrSetTextAttrib\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; if (Buff == Console->ActiveBuffer) @@ -1883,13 +1825,11 @@ CSR_API(CsrSetTextAttrib) if (! ConioUpdateScreenInfo(Console, Buff)) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_UNSUCCESSFUL; } } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -1904,9 +1844,9 @@ CSR_API(CsrSetConsoleMode) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrGetObject(ProcessData, - Request->Data.SetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_WRITE); + Status = Win32CsrLockObject(ProcessData, + Request->Data.SetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_WRITE, 0); if (! NT_SUCCESS(Status)) { return Status; @@ -1926,7 +1866,7 @@ CSR_API(CsrSetConsoleMode) Status = STATUS_INVALID_HANDLE; } - Win32CsrReleaseObjectByPointer((Object_t *)Console); + Win32CsrUnlockObject((Object_t *)Console); return Status; } @@ -1941,8 +1881,8 @@ CSR_API(CsrGetConsoleMode) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_READ); + Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_READ, 0); if (! NT_SUCCESS(Status)) { return Status; @@ -1962,7 +1902,7 @@ CSR_API(CsrGetConsoleMode) Status = STATUS_INVALID_HANDLE; } - Win32CsrReleaseObjectByPointer((Object_t *)Console); + Win32CsrUnlockObject((Object_t *)Console); return Status; } @@ -2039,43 +1979,33 @@ CSR_API(CsrSetScreenBuffer) DPRINT("CsrSetScreenBuffer\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; if (Buff == Console->ActiveBuffer) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } - /* drop reference to old buffer, maybe delete */ - if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount)) + /* If old buffer has no handles, it's now unreferenced */ + if (Console->ActiveBuffer->Header.HandleCount == 0) { ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); } /* tie console to new buffer */ Console->ActiveBuffer = Buff; - /* inc ref count on new buffer */ - InterlockedIncrement(&Buff->Header.ReferenceCount); /* Redraw the console */ ConioDrawConsole(Console); ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -2181,12 +2111,6 @@ CSR_API(CsrWriteConsoleOutput) DPRINT("CsrWriteConsoleOutput\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Status = ConioLockScreenBuffer(ProcessData, @@ -2195,9 +2119,9 @@ CSR_API(CsrWriteConsoleOutput) GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); @@ -2208,7 +2132,6 @@ CSR_API(CsrWriteConsoleOutput) ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; } WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left; @@ -2226,7 +2149,6 @@ CSR_API(CsrWriteConsoleOutput) if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); /* It is okay to have a WriteRegion completely outside the screen buffer. No data is written then. */ @@ -2257,7 +2179,6 @@ CSR_API(CsrWriteConsoleOutput) ConioDrawRegion(Console, &WriteRegion); ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1; Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1; @@ -2327,20 +2248,14 @@ CSR_API(CsrScrollConsoleScreenBuffer) DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left; ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top; @@ -2352,7 +2267,6 @@ CSR_API(CsrScrollConsoleScreenBuffer) if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) { ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -2374,7 +2288,6 @@ CSR_API(CsrScrollConsoleScreenBuffer) ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom; if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) { - ConioUnlockConsole(Console); ConioUnlockScreenBuffer(Buff); return STATUS_SUCCESS; } @@ -2408,7 +2321,6 @@ CSR_API(CsrScrollConsoleScreenBuffer) } ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return STATUS_SUCCESS; } @@ -2432,18 +2344,12 @@ CSR_API(CsrReadConsoleOutputChar) CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); if (! NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; @@ -2479,7 +2385,6 @@ CSR_API(CsrReadConsoleOutputChar) Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) @@ -3131,22 +3036,15 @@ CSR_API(CsrSetScreenBufferSize) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (!NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); if (!NT_SUCCESS(Status)) { - ConioUnlockConsole(Console); return Status; } + Console = Buff->Header.Console; Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); return Status; } diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 1d1ab7f908d..14abebf8478 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -69,6 +69,8 @@ typedef struct tagCSRSS_CONSOLE_VTBL typedef struct tagCSRSS_CONSOLE { Object_t Header; /* Object header */ + LONG ReferenceCount; + CRITICAL_SECTION Lock; PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */ HANDLE ActiveEvent; LIST_ENTRY InputEvents; /* List head for input event queue */ diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 243246d5d47..625b1b52a67 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -872,7 +872,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, Buff = Console->ActiveBuffer; - EnterCriticalSection(&Buff->Header.Lock); + EnterCriticalSection(&Buff->Header.Console->Lock); TopLine = rc->top / GuiData->CharHeight + Buff->ShowY; BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY; @@ -971,7 +971,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, } } - LeaveCriticalSection(&Buff->Header.Lock); + LeaveCriticalSection(&Buff->Header.Console->Lock); SelectObject(hDC, OldFont); @@ -1327,7 +1327,7 @@ GuiConsoleHandleClose(HWND hWnd) GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - EnterCriticalSection(&Console->Header.Lock); + EnterCriticalSection(&Console->Lock); current_entry = Console->ProcessList.Flink; while (current_entry != &Console->ProcessList) @@ -1341,7 +1341,7 @@ GuiConsoleHandleClose(HWND hWnd) ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); } - LeaveCriticalSection(&Console->Header.Lock); + LeaveCriticalSection(&Console->Lock); } static VOID FASTCALL @@ -1809,7 +1809,7 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole COORD BufSize; BOOL SizeChanged = FALSE; - EnterCriticalSection(&ActiveBuffer->Header.Lock); + EnterCriticalSection(&Console->Lock); /* apply text / background color */ GuiData->ScreenText = pConInfo->ScreenText; @@ -1844,7 +1844,7 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole GuiData->WindowSizeLock = FALSE; } - LeaveCriticalSection(&ActiveBuffer->Header.Lock); + LeaveCriticalSection(&Console->Lock); InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); } diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index e1afd16b873..a712fd356b2 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -16,13 +16,6 @@ /* FUNCTIONS *****************************************************************/ -static unsigned ObjectDefinitionsCount = 2; -static CSRSS_OBJECT_DEFINITION ObjectDefinitions[] = -{ - { CONIO_CONSOLE_MAGIC, ConioDeleteConsole }, - { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer }, -}; - static BOOL CsrIsConsoleHandle(HANDLE Handle) @@ -30,58 +23,40 @@ CsrIsConsoleHandle(HANDLE Handle) return ((ULONG_PTR)Handle & 0x10000003) == 0x3; } -NTSTATUS -FASTCALL -Win32CsrGetObject( - PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access ) +static VOID +Win32CsrCreateHandleEntry( + PCSRSS_HANDLE Entry, + Object_t *Object, + DWORD Access, + BOOL Inheritable) { - ULONG_PTR h = (ULONG_PTR)Handle >> 2; - - DPRINT("CsrGetObject, Object: %x, %x, %x\n", - Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize - || (*Object = ProcessData->HandleTable[h].Object) == NULL - || ~ProcessData->HandleTable[h].Access & Access) - { - DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - _InterlockedIncrement(&(*Object)->ReferenceCount); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - // DbgPrint( "CsrGetObject returning\n" ); - return STATUS_SUCCESS; + Entry->Object = Object; + Entry->Access = Access; + Entry->Inheritable = Inheritable; + _InterlockedIncrement(&Object->HandleCount); } - -NTSTATUS -FASTCALL -Win32CsrReleaseObjectByPointer( - Object_t *Object) +static VOID +Win32CsrCloseHandleEntry( + PCSRSS_HANDLE Entry) { - unsigned DefIndex; - - /* dec ref count */ - if (_InterlockedDecrement(&Object->ReferenceCount) == 0) + Object_t *Object = Entry->Object; + if (Object != NULL) { - for (DefIndex = 0; DefIndex < ObjectDefinitionsCount; DefIndex++) + Entry->Object = NULL; + /* If the last handle to a screen buffer is closed, delete it */ + if (_InterlockedDecrement(&Object->HandleCount) == 0 + && Object->Type == CONIO_SCREEN_BUFFER_MAGIC) { - if (Object->Type == ObjectDefinitions[DefIndex].Type) - { - (ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object); - return STATUS_SUCCESS; - } + PCSRSS_CONSOLE Console = Object->Console; + EnterCriticalSection(&Console->Lock); + /* TODO: Should delete even the active buffer, but we're not yet ready + * to deal with the case where this results in no buffers left. */ + if (Object != &Console->ActiveBuffer->Header) + ConioDeleteScreenBuffer(Object); + LeaveCriticalSection(&Console->Lock); } - - DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object->Type); } - - return STATUS_SUCCESS; } NTSTATUS @@ -100,10 +75,9 @@ Win32CsrReleaseObject( RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; } - ProcessData->HandleTable[h].Object = NULL; + Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - - return Win32CsrReleaseObjectByPointer(Object); + return STATUS_SUCCESS; } NTSTATUS @@ -114,22 +88,25 @@ Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, DWORD Access, LONG Type) { - NTSTATUS Status; + ULONG_PTR h = (ULONG_PTR)Handle >> 2; - Status = Win32CsrGetObject(ProcessData, Handle, Object, Access); - if (! NT_SUCCESS(Status)) - { - return Status; - } + DPRINT("CsrGetObject, Object: %x, %x, %x\n", + Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); - if ((*Object)->Type != Type) + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize + || (*Object = ProcessData->HandleTable[h].Object) == NULL + || ~ProcessData->HandleTable[h].Access & Access + || (Type != 0 && (*Object)->Type != Type)) { - Win32CsrReleaseObjectByPointer(*Object); + DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; } + _InterlockedIncrement(&(*Object)->Console->ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - EnterCriticalSection(&((*Object)->Lock)); - + EnterCriticalSection(&((*Object)->Console->Lock)); return STATUS_SUCCESS; } @@ -137,8 +114,11 @@ VOID FASTCALL Win32CsrUnlockObject(Object_t *Object) { - LeaveCriticalSection(&(Object->Lock)); - Win32CsrReleaseObjectByPointer(Object); + PCSRSS_CONSOLE Console = Object->Console; + LeaveCriticalSection(&Console->Lock); + /* dec ref count */ + if (_InterlockedDecrement(&Console->ReferenceCount) == 0) + ConioDeleteConsole(&Console->Header); } NTSTATUS @@ -153,27 +133,24 @@ Win32CsrReleaseConsole( RtlEnterCriticalSection(&ProcessData->HandleTableLock); for (i = 0; i < ProcessData->HandleTableSize; i++) - { - if (ProcessData->HandleTable[i].Object != NULL) - Win32CsrReleaseObjectByPointer(ProcessData->HandleTable[i].Object); - } + Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]); ProcessData->HandleTableSize = 0; RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable); ProcessData->HandleTable = NULL; Console = ProcessData->Console; - ProcessData->Console = NULL; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - if (Console != NULL) { - EnterCriticalSection(&Console->Header.Lock); + ProcessData->Console = NULL; + EnterCriticalSection(&Console->Lock); RemoveEntryList(&ProcessData->ProcessEntry); - LeaveCriticalSection(&Console->Header.Lock); - Win32CsrReleaseObjectByPointer(&Console->Header); + LeaveCriticalSection(&Console->Lock); + if (_InterlockedDecrement(&Console->ReferenceCount) == 0) + ConioDeleteConsole(&Console->Header); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_SUCCESS; } - + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_PARAMETER; } @@ -215,11 +192,8 @@ Win32CsrInsertObject( ProcessData->HandleTable = Block; ProcessData->HandleTableSize += 64; } - ProcessData->HandleTable[i].Object = Object; - ProcessData->HandleTable[i].Access = Access; - ProcessData->HandleTable[i].Inheritable = Inheritable; + Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i], Object, Access, Inheritable); *Handle = UlongToHandle((i << 2) | 0x3); - _InterlockedIncrement( &Object->ReferenceCount ); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return(STATUS_SUCCESS); } @@ -256,8 +230,10 @@ Win32CsrDuplicateHandleTable( if (SourceProcessData->HandleTable[i].Object != NULL && SourceProcessData->HandleTable[i].Inheritable) { - TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; - _InterlockedIncrement( &SourceProcessData->HandleTable[i].Object->ReferenceCount ); + Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i], + SourceProcessData->HandleTable[i].Object, + SourceProcessData->HandleTable[i].Access, + SourceProcessData->HandleTable[i].Inheritable); } } RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); @@ -385,9 +361,7 @@ CSR_API(CsrDuplicateHandle) if (NT_SUCCESS(Request->Status) && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) { - /* Close the original handle. This cannot drop the count to 0, since a new handle now exists */ - _InterlockedDecrement(&Entry->Object->ReferenceCount); - Entry->Object = NULL; + Win32CsrCloseHandleEntry(Entry); } RtlLeaveCriticalSection(&ProcessData->HandleTableLock); diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h index 5bcd0c268a9..0bb444003f0 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.h @@ -17,8 +17,8 @@ extern HINSTANCE Win32CsrDllHandle; typedef struct Object_tt { LONG Type; - LONG ReferenceCount; - CRITICAL_SECTION Lock; + struct tagCSRSS_CONSOLE *Console; + LONG HandleCount; } Object_t; typedef struct _CSRSS_HANDLE @@ -48,11 +48,6 @@ NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, DWORD Access, long Type); VOID FASTCALL Win32CsrUnlockObject(Object_t *Object); -NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access); -NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Object); NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); From 85b0f2bc12f3255417494e11721a35435fce0cae Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 06:04:15 +0000 Subject: [PATCH 014/292] [WIN32CSR] Delete even the active screen buffer when all handles are closed. Fixes a winetest. svn path=/trunk/; revision=47318 --- .../subsystems/win32/csrss/win32csr/conio.c | 33 ++++++++++++++----- .../subsystems/win32/csrss/win32csr/conio.h | 4 ++- .../subsystems/win32/csrss/win32csr/handle.c | 10 +++--- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 4b8e65c8cd4..92d68554a53 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -137,6 +137,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, Buffer->CurrentX = 0; Buffer->CurrentY = 0; + InsertHeadList(&Console->BufferList, &Buffer->ListEntry); return STATUS_SUCCESS; } @@ -162,6 +163,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) Console->Header.Console = Console; Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; Console->EarlyReturn = FALSE; + InitializeListHead(&Console->BufferList); Console->ActiveBuffer = NULL; InitializeListHead(&Console->InputEvents); Console->CodePage = GetOEMCP(); @@ -893,11 +895,24 @@ CSR_API(CsrWriteConsole) } VOID WINAPI -ConioDeleteScreenBuffer(Object_t *Object) +ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) { - PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object; - HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); - HeapFree(Win32CsrApiHeap, 0, Buffer); + PCSRSS_CONSOLE Console = Buffer->Header.Console; + + RemoveEntryList(&Buffer->ListEntry); + if (Buffer == Console->ActiveBuffer) + { + /* Deleted active buffer; switch to most recently created */ + Console->ActiveBuffer = NULL; + if (!IsListEmpty(&Console->BufferList)) + { + Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry); + ConioDrawConsole(Console); + } + } + + HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); } VOID FASTCALL @@ -929,9 +944,11 @@ ConioDeleteConsole(Object_t *Object) } ConioCleanupConsole(Console); - ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); - - Console->ActiveBuffer = NULL; + ConioDeleteScreenBuffer(Console->ActiveBuffer); + if (!IsListEmpty(&Console->BufferList)) + { + DPRINT1("BUG: screen buffer list not empty\n"); + } CloseHandle(Console->ActiveEvent); DeleteCriticalSection(&Console->Lock); @@ -1998,7 +2015,7 @@ CSR_API(CsrSetScreenBuffer) /* If old buffer has no handles, it's now unreferenced */ if (Console->ActiveBuffer->Header.HandleCount == 0) { - ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); + ConioDeleteScreenBuffer(Console->ActiveBuffer); } /* tie console to new buffer */ Console->ActiveBuffer = Buff; diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 14abebf8478..8c853689b30 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -46,6 +46,7 @@ typedef struct tagCSRSS_SCREEN_BUFFER USHORT VirtualY; /* top row of buffer being displayed, reported to callers */ CONSOLE_CURSOR_INFO CursorInfo; USHORT Mode; + LIST_ENTRY ListEntry; /* entry in console's list of buffers */ } CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER; typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; @@ -76,6 +77,7 @@ typedef struct tagCSRSS_CONSOLE LIST_ENTRY InputEvents; /* List head for input event queue */ WORD WaitingChars; WORD WaitingLines; /* number of chars and lines in input queue */ + LIST_ENTRY BufferList; /* List of all screen buffers for this console */ PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ WORD Mode; /* Console mode flags */ WORD EchoCount; /* count of chars to echo, in line buffered mode */ @@ -103,7 +105,7 @@ typedef struct ConsoleInput_t NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); VOID WINAPI ConioDeleteConsole(Object_t *Object); -VOID WINAPI ConioDeleteScreenBuffer(Object_t *Buffer); +VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); VOID WINAPI CsrInitConsoleSupport(VOID); void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index a712fd356b2..e7b28b1977b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -49,11 +49,13 @@ Win32CsrCloseHandleEntry( && Object->Type == CONIO_SCREEN_BUFFER_MAGIC) { PCSRSS_CONSOLE Console = Object->Console; + PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object; EnterCriticalSection(&Console->Lock); - /* TODO: Should delete even the active buffer, but we're not yet ready - * to deal with the case where this results in no buffers left. */ - if (Object != &Console->ActiveBuffer->Header) - ConioDeleteScreenBuffer(Object); + /* ...unless it's the only buffer left. Windows allows deletion + * even of the last buffer, but having to deal with a lack of + * any active buffer might be error-prone. */ + if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) + ConioDeleteScreenBuffer(Buffer); LeaveCriticalSection(&Console->Lock); } } From 0b077c296117dcc04cbf7c6280eddc253dc35f2c Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 09:10:02 +0000 Subject: [PATCH 015/292] [WIN32CSR] Implement FILE_SHARE_* flags for console handles. Fixes some more winetests. svn path=/trunk/; revision=47319 --- reactos/dll/win32/kernel32/misc/console.c | 3 +- reactos/include/reactos/subsys/csrss/csrss.h | 13 +- .../subsystems/win32/csrss/win32csr/conio.c | 9 +- .../subsystems/win32/csrss/win32csr/dllmain.c | 4 +- .../subsystems/win32/csrss/win32csr/handle.c | 125 ++++++++++-------- .../win32/csrss/win32csr/win32csr.h | 9 +- 6 files changed, 89 insertions(+), 74 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 594b8ac2abb..419f4373a42 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -1022,6 +1022,7 @@ OpenConsoleW(LPCWSTR wsName, /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */ Request.Data.GetInputHandleRequest.Access = dwDesiredAccess; Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle; + Request.Data.GetInputHandleRequest.ShareMode = dwShareMode; Status = CsrClientCallServer(&Request, NULL, @@ -1033,7 +1034,7 @@ OpenConsoleW(LPCWSTR wsName, return INVALID_HANDLE_VALUE; } - return Request.Data.GetInputHandleRequest.InputHandle; + return Request.Data.GetInputHandleRequest.Handle; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 0119bad99a3..9e87a4d6b81 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -320,15 +320,10 @@ typedef struct { DWORD Access; BOOL Inheritable; - HANDLE InputHandle; -} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE; - -typedef struct -{ - DWORD Access; - BOOL Inheritable; - HANDLE OutputHandle; -} CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; + HANDLE Handle; + DWORD ShareMode; +} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE, + CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; typedef struct { diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 92d68554a53..ee89dad553f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -317,7 +317,8 @@ CSR_API(CsrAllocConsole) &Request->Data.AllocConsoleRequest.InputHandle, &Console->Header, GENERIC_READ | GENERIC_WRITE, - TRUE); + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (! NT_SUCCESS(Status)) { DPRINT1("Failed to insert object\n"); @@ -331,7 +332,8 @@ CSR_API(CsrAllocConsole) &Request->Data.AllocConsoleRequest.OutputHandle, &Console->ActiveBuffer->Header, GENERIC_READ | GENERIC_WRITE, - TRUE); + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to insert object\n"); @@ -1975,7 +1977,8 @@ CSR_API(CsrCreateScreenBuffer) &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header, Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable); + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); } } else diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index a8fdd418161..bd0409c55ca 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -24,8 +24,8 @@ static CSRSS_EXPORTED_FUNCS CsrExports; static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = { - CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), - CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), + CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle), + CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle), CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index e7b28b1977b..87f5c6348a4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -23,17 +23,26 @@ CsrIsConsoleHandle(HANDLE Handle) return ((ULONG_PTR)Handle & 0x10000003) == 0x3; } +static INT +AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change) +{ + Object_t *Object = Entry->Object; + if (Entry->Access & GENERIC_READ) Object->AccessRead += Change; + if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change; + if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change; + if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change; + Object->HandleCount += Change; + return Object->HandleCount; +} + static VOID Win32CsrCreateHandleEntry( - PCSRSS_HANDLE Entry, - Object_t *Object, - DWORD Access, - BOOL Inheritable) + PCSRSS_HANDLE Entry) { - Entry->Object = Object; - Entry->Access = Access; - Entry->Inheritable = Inheritable; - _InterlockedIncrement(&Object->HandleCount); + Object_t *Object = Entry->Object; + EnterCriticalSection(&Object->Console->Lock); + AdjustHandleCounts(Entry, +1); + LeaveCriticalSection(&Object->Console->Lock); } static VOID @@ -43,21 +52,21 @@ Win32CsrCloseHandleEntry( Object_t *Object = Entry->Object; if (Object != NULL) { - Entry->Object = NULL; + PCSRSS_CONSOLE Console = Object->Console; + EnterCriticalSection(&Console->Lock); /* If the last handle to a screen buffer is closed, delete it */ - if (_InterlockedDecrement(&Object->HandleCount) == 0 + if (AdjustHandleCounts(Entry, -1) == 0 && Object->Type == CONIO_SCREEN_BUFFER_MAGIC) { - PCSRSS_CONSOLE Console = Object->Console; PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object; - EnterCriticalSection(&Console->Lock); /* ...unless it's the only buffer left. Windows allows deletion * even of the last buffer, but having to deal with a lack of * any active buffer might be error-prone. */ if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) ConioDeleteScreenBuffer(Buffer); - LeaveCriticalSection(&Console->Lock); } + LeaveCriticalSection(&Console->Lock); + Entry->Object = NULL; } } @@ -163,7 +172,8 @@ Win32CsrInsertObject( PHANDLE Handle, Object_t *Object, DWORD Access, - BOOL Inheritable) + BOOL Inheritable, + DWORD ShareMode) { ULONG i; PCSRSS_HANDLE Block; @@ -194,7 +204,11 @@ Win32CsrInsertObject( ProcessData->HandleTable = Block; ProcessData->HandleTableSize += 64; } - Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i], Object, Access, Inheritable); + ProcessData->HandleTable[i].Object = Object; + ProcessData->HandleTable[i].Access = Access; + ProcessData->HandleTable[i].Inheritable = Inheritable; + ProcessData->HandleTable[i].ShareMode = ShareMode; + Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]); *Handle = UlongToHandle((i << 2) | 0x3); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return(STATUS_SUCCESS); @@ -232,62 +246,60 @@ Win32CsrDuplicateHandleTable( if (SourceProcessData->HandleTable[i].Object != NULL && SourceProcessData->HandleTable[i].Inheritable) { - Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i], - SourceProcessData->HandleTable[i].Object, - SourceProcessData->HandleTable[i].Access, - SourceProcessData->HandleTable[i].Inheritable); + TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; + Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]); } } RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); return(STATUS_SUCCESS); } -CSR_API(CsrGetInputHandle) +CSR_API(CsrGetHandle) { + NTSTATUS Status = STATUS_SUCCESS; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); if (ProcessData->Console) { - Request->Status = Win32CsrInsertObject(ProcessData, - &Request->Data.GetInputHandleRequest.InputHandle, - &ProcessData->Console->Header, - Request->Data.GetInputHandleRequest.Access, - Request->Data.GetInputHandleRequest.Inheritable); - } - else - { - Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; + DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access; + DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode; + + PCSRSS_CONSOLE Console = ProcessData->Console; + Object_t *Object; + + EnterCriticalSection(&Console->Lock); + if (Request->Type == GET_OUTPUT_HANDLE) + Object = &Console->ActiveBuffer->Header; + else + Object = &Console->Header; + + if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) || + ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) || + (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) || + (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0)) + { + DPRINT1("Sharing violation\n"); + Status = STATUS_SHARING_VIOLATION; + } + else + { + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.GetInputHandleRequest.Handle, + Object, + DesiredAccess, + Request->Data.GetInputHandleRequest.Inheritable, + ShareMode); + } + LeaveCriticalSection(&Console->Lock); } RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Request->Status; -} - -CSR_API(CsrGetOutputHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (ProcessData->Console) - { - Request->Status = Win32CsrInsertObject(ProcessData, - &Request->Data.GetOutputHandleRequest.OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, - Request->Data.GetOutputHandleRequest.Access, - Request->Data.GetOutputHandleRequest.Inheritable); - } - else - { - Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - - return Request->Status; + return Status; } CSR_API(CsrCloseHandle) @@ -359,7 +371,8 @@ CSR_API(CsrDuplicateHandle) &Request->Data.DuplicateHandleRequest.Handle, Entry->Object, DesiredAccess, - Request->Data.DuplicateHandleRequest.Inheritable); + Request->Data.DuplicateHandleRequest.Inheritable, + Entry->ShareMode); if (NT_SUCCESS(Request->Status) && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) { diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h index 0bb444003f0..111c27db80a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.h @@ -18,6 +18,8 @@ typedef struct Object_tt { LONG Type; struct tagCSRSS_CONSOLE *Console; + LONG AccessRead, AccessWrite; + LONG ExclusiveRead, ExclusiveWrite; LONG HandleCount; } Object_t; @@ -26,6 +28,7 @@ typedef struct _CSRSS_HANDLE Object_t *Object; DWORD Access; BOOL Inheritable; + DWORD ShareMode; } CSRSS_HANDLE, *PCSRSS_HANDLE; typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); @@ -41,7 +44,8 @@ NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, - BOOL Inheritable); + BOOL Inheritable, + DWORD ShareMode); NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, @@ -53,8 +57,7 @@ NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); -CSR_API(CsrGetInputHandle); -CSR_API(CsrGetOutputHandle); +CSR_API(CsrGetHandle); CSR_API(CsrCloseHandle); CSR_API(CsrVerifyHandle); CSR_API(CsrDuplicateHandle); From 89b45a7e71b9e1de6d02be58246ed55626001480 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 23 May 2010 10:59:41 +0000 Subject: [PATCH 016/292] [kernel32_winetest] - kernel32 tests need a resource file svn path=/trunk/; revision=47322 --- rostests/winetests/kernel32/kernel32.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/rostests/winetests/kernel32/kernel32.rbuild b/rostests/winetests/kernel32/kernel32.rbuild index 71629bc3faa..1b87f4b5414 100644 --- a/rostests/winetests/kernel32/kernel32.rbuild +++ b/rostests/winetests/kernel32/kernel32.rbuild @@ -41,4 +41,5 @@ virtual.c volume.c testlist.c + resource.rc From dcc025f6e3cb9bb9988ef3da47e0782a10cf1b9d Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 May 2010 11:35:08 +0000 Subject: [PATCH 017/292] [WINLOGON] - Set the APPDATA environment variable without loading shell32.dll. This should fix bug #5398. svn path=/trunk/; revision=47324 --- reactos/base/system/winlogon/environment.c | 113 ++++++++++----------- 1 file changed, 52 insertions(+), 61 deletions(-) diff --git a/reactos/base/system/winlogon/environment.c b/reactos/base/system/winlogon/environment.c index 7a22e494d27..972d09c43bc 100644 --- a/reactos/base/system/winlogon/environment.c +++ b/reactos/base/system/winlogon/environment.c @@ -19,25 +19,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(winlogon); /* GLOBALS ******************************************************************/ -typedef HRESULT (WINAPI *PFSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR); - /* FUNCTIONS ****************************************************************/ static VOID BuildVolatileEnvironment(IN PWLSESSION Session, - IN HKEY hKey) + IN HKEY hKeyCurrentUser) { - HINSTANCE hShell32 = NULL; - PFSHGETFOLDERPATHW pfSHGetFolderPathW = NULL; WCHAR szPath[MAX_PATH + 1]; - WCHAR szExpandedPath[MAX_PATH + 1]; LPCWSTR wstr; SIZE_T size; WCHAR szEnvKey[MAX_PATH]; WCHAR szEnvValue[1024]; SIZE_T length; LPWSTR eqptr, endptr; + DWORD dwDisp; + LONG lError; + HKEY hKeyVolatileEnv; + HKEY hKeyShellFolders; + DWORD dwType; + DWORD dwSize; + + /* Create the 'Volatile Environment' key */ + lError = RegCreateKeyExW(hKeyCurrentUser, + L"Volatile Environment", + 0, + NULL, + REG_OPTION_VOLATILE, + KEY_WRITE, + NULL, + &hKeyVolatileEnv, + &dwDisp); + if (lError != ERROR_SUCCESS) + { + WARN("WL: RegCreateKeyExW() failed to create the volatile environment key (Error: %ld)\n", lError); + return; + } /* Parse the environment variables and add them to the volatile environment key */ if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 && @@ -68,7 +85,7 @@ BuildVolatileEnvironment(IN PWLSESSION Session, eqptr++; wcscpy(szEnvValue, eqptr); - RegSetValueExW(hKey, + RegSetValueExW(hKeyVolatileEnv, szEnvKey, 0, REG_SZ, @@ -80,50 +97,44 @@ BuildVolatileEnvironment(IN PWLSESSION Session, } } - /* Load shell32.dll and call SHGetFolderPathW to get the users appdata folder path */ - hShell32 = LoadLibraryW(L"shell32.dll"); - if (hShell32 != NULL) + /* Set the 'APPDATA' environment variable */ + lError = RegOpenKeyExW(hKeyCurrentUser, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, + KEY_READ, + &hKeyShellFolders); + if (lError == ERROR_SUCCESS) { - pfSHGetFolderPathW = (PFSHGETFOLDERPATHW)GetProcAddress(hShell32, - "SHGetFolderPathW"); - if (pfSHGetFolderPathW != NULL) + dwSize = (MAX_PATH + 1) * sizeof(WCHAR); + lError = RegQueryValueExW(hKeyShellFolders, + L"AppData", + NULL, + &dwType, + (LPBYTE)szPath, + &dwSize); + if (lError == ERROR_SUCCESS) { - if (pfSHGetFolderPathW(NULL, - CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, - Session->UserToken, - 0, - szPath) == S_OK) - { - /* FIXME: Expand %USERPROFILE% here. SHGetFolderPathW should do it for us. See Bug #5372.*/ - TRACE("APPDATA path: %S\n", szPath); - ExpandEnvironmentStringsForUserW(Session->UserToken, - szPath, - szExpandedPath, - MAX_PATH); - - /* Add the appdata folder path to the users volatile environment key */ - TRACE("APPDATA expanded path: %S\n", szExpandedPath); - RegSetValueExW(hKey, - L"APPDATA", - 0, - REG_SZ, - (LPBYTE)szExpandedPath, - (wcslen(szExpandedPath) + 1) * sizeof(WCHAR)); - } + TRACE("APPDATA path: %S\n", szPath); + RegSetValueExW(hKeyVolatileEnv, + L"APPDATA", + 0, + REG_SZ, + (LPBYTE)szPath, + (wcslen(szPath) + 1) * sizeof(WCHAR)); } - FreeLibrary(hShell32); + RegCloseKey(hKeyShellFolders); } + + RegCloseKey(hKeyVolatileEnv); } BOOL CreateUserEnvironment(IN PWLSESSION Session) { - HKEY hKey; - DWORD dwDisp; - LONG lError; HKEY hKeyCurrentUser; + LONG lError; TRACE("WL: CreateUserEnvironment called\n"); @@ -135,28 +146,8 @@ CreateUserEnvironment(IN PWLSESSION Session) &hKeyCurrentUser); if (lError == ERROR_SUCCESS) { - /* Create the 'Volatile Environment' key */ - lError = RegCreateKeyExW(hKeyCurrentUser, - L"Volatile Environment", - 0, - NULL, - REG_OPTION_VOLATILE, - KEY_WRITE, - NULL, - &hKey, - &dwDisp); - if (lError == ERROR_SUCCESS) - { - BuildVolatileEnvironment(Session, - hKey); - - RegCloseKey(hKey); - } - else - { - WARN("WL: RegCreateKeyExW() failed (Error: %ld)\n", lError); - } - + BuildVolatileEnvironment(Session, + hKeyCurrentUser); RegCloseKey(hKeyCurrentUser); } From 38734242d52228a30d0e6be026b3e6df5d0a51ac Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 23 May 2010 11:53:01 +0000 Subject: [PATCH 018/292] [win32k] - For the Low Level Mouse Hook (WH_MOUSE_LL), input can come from the mouse driver or mouse_event. Both of which result in a call to UserSetCursorPos. UserMode SetCursorPos API also ends up here. Add BOOL parameter that can be used to determine if hooks are to be called. - Move the code related to calling the hook procedure from MsqInsertSystemMessage into UserSetCursorPos and call the hook procedure here if needed. If hook procedure returns non 0 value. Dont insert the system message. - Fixes a recursive call to the hook procedure resulting thread using to much stack exposed by user32 winetest for input. svn path=/trunk/; revision=47325 --- .../win32/win32k/include/cursoricon.h | 2 +- .../win32/win32k/ntuser/cursoricon.c | 42 +++++++++++++++++-- .../subsystems/win32/win32k/ntuser/input.c | 2 +- .../subsystems/win32/win32k/ntuser/msgqueue.c | 30 ------------- .../win32/win32k/ntuser/simplecall.c | 2 +- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index 280ab555601..f79dca289c8 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -77,7 +77,7 @@ BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxW INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); -BOOL UserSetCursorPos( INT x, INT y); +BOOL UserSetCursorPos( INT x, INT y, BOOL CallHooks); int UserShowCursor(BOOL bShow); diff --git a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c index 3fe0211ea53..2958bdf7690 100644 --- a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c @@ -175,10 +175,12 @@ UserSetCursor( return hOldCursor; } -BOOL UserSetCursorPos( INT x, INT y) +BOOL UserSetCursorPos( INT x, INT y, BOOL CallHooks) { PWINDOW_OBJECT DesktopWindow; PSYSTEM_CURSORINFO CurInfo; + LARGE_INTEGER LargeTickCount; + MSLLHOOKSTRUCT MouseHookData; HDC hDC; MSG Msg; @@ -221,6 +223,9 @@ BOOL UserSetCursorPos( INT x, INT y) gpsi->ptCursor.x = x; gpsi->ptCursor.y = y; + KeQueryTickCount(&LargeTickCount); + Msg.time = MsqCalculateMessageTime(&LargeTickCount); + //Move the mouse pointer GreMovePointer(hDC, x, y); @@ -229,8 +234,39 @@ BOOL UserSetCursorPos( INT x, INT y) Msg.wParam = CurInfo->ButtonsDown; Msg.lParam = MAKELPARAM(x, y); Msg.pt = gpsi->ptCursor; - MsqInsertSystemMessage(&Msg); + MouseHookData.pt.x = LOWORD(Msg.lParam); + MouseHookData.pt.y = HIWORD(Msg.lParam); + switch(Msg.message) + { + case WM_MOUSEWHEEL: + MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg.wParam)); + break; + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_XBUTTONDBLCLK: + case WM_NCXBUTTONDOWN: + case WM_NCXBUTTONUP: + case WM_NCXBUTTONDBLCLK: + MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg.wParam)); + break; + default: + MouseHookData.mouseData = 0; + break; + } + + MouseHookData.flags = 0; + MouseHookData.time = Msg.time; + MouseHookData.dwExtraInfo = 0; + + if (CallHooks) + { + /* If the hook procedure returned non zero, dont send the message */ + if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg.message, (LPARAM) &MouseHookData)) + return FALSE; + } + + MsqInsertSystemMessage(&Msg); return TRUE; } @@ -814,7 +850,7 @@ NtUserClipCursor( CurInfo->CursorClipInfo.Right = min(Rect.right, DesktopWindow->Wnd->rcWindow.right); CurInfo->CursorClipInfo.Bottom = min(Rect.bottom, DesktopWindow->Wnd->rcWindow.bottom); - UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y); + UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); RETURN(TRUE); } diff --git a/reactos/subsystems/win32/win32k/ntuser/input.c b/reactos/subsystems/win32/win32k/ntuser/input.c index 006b0f123b0..8764e19d877 100644 --- a/reactos/subsystems/win32/win32k/ntuser/input.c +++ b/reactos/subsystems/win32/win32k/ntuser/input.c @@ -1128,7 +1128,7 @@ IntMouseInput(MOUSEINPUT *mi) if(mi->dwFlags & MOUSEEVENTF_MOVE) { - UserSetCursorPos(MousePos.x, MousePos.y); + UserSetCursorPos(MousePos.x, MousePos.y, TRUE); } if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN) { diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index 5bfe414b5ed..e71de5475d7 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -171,38 +171,8 @@ MsqInitializeImpl(VOID) VOID FASTCALL MsqInsertSystemMessage(MSG* Msg) { - LARGE_INTEGER LargeTickCount; KIRQL OldIrql; ULONG Prev; - MSLLHOOKSTRUCT MouseHookData; - - KeQueryTickCount(&LargeTickCount); - Msg->time = MsqCalculateMessageTime(&LargeTickCount); - - MouseHookData.pt.x = LOWORD(Msg->lParam); - MouseHookData.pt.y = HIWORD(Msg->lParam); - switch(Msg->message) - { - case WM_MOUSEWHEEL: - MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam)); - break; - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_XBUTTONDBLCLK: - case WM_NCXBUTTONDOWN: - case WM_NCXBUTTONUP: - case WM_NCXBUTTONDBLCLK: - MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam)); - break; - default: - MouseHookData.mouseData = 0; - break; - } - MouseHookData.flags = 0; - MouseHookData.time = Msg->time; - MouseHookData.dwExtraInfo = 0; - if( co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData)) - return; /* * If we got WM_MOUSEMOVE and there are already messages in the diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index 77d8fb9d237..cdd4a22a6b1 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -440,7 +440,7 @@ NtUserCallTwoParam( RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2)); case TWOPARAM_ROUTINE_SETCURSORPOS: - RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2)); + RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE)); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n", From 44ce7e4f5565b8290dde6e6aa89e834e07ff164b Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 15:56:37 +0000 Subject: [PATCH 019/292] [KERNEL32], [WIN32CSR] Implement the CREATE_NO_WINDOW flag which creates a console with an invisible window. svn path=/trunk/; revision=47326 --- reactos/dll/win32/kernel32/misc/console.c | 1 + reactos/dll/win32/kernel32/misc/dllmain.c | 4 +++- reactos/include/reactos/subsys/csrss/csrss.h | 3 ++- reactos/subsystems/win32/csrss/win32csr/conio.c | 6 +++--- reactos/subsystems/win32/csrss/win32csr/guiconsole.c | 9 ++++++--- reactos/subsystems/win32/csrss/win32csr/guiconsole.h | 2 +- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 419f4373a42..9d433ddcfb6 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -1692,6 +1692,7 @@ AllocConsole(VOID) Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher; Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; + Request.Data.AllocConsoleRequest.Visible = TRUE; CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE); diff --git a/reactos/dll/win32/kernel32/misc/dllmain.c b/reactos/dll/win32/kernel32/misc/dllmain.c index ef47c4d538f..bdf6f0d52e4 100644 --- a/reactos/dll/win32/kernel32/misc/dllmain.c +++ b/reactos/dll/win32/kernel32/misc/dllmain.c @@ -150,6 +150,7 @@ BasepInitConsole(VOID) { /* Assume one is needed */ Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; + Request.Data.AllocConsoleRequest.Visible = TRUE; /* Handle the special flags given to us by BasepInitializeEnvironment */ if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) @@ -168,8 +169,9 @@ BasepInitConsole(VOID) else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) { /* We'll get the real one soon */ - DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n"); + DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; + Request.Data.AllocConsoleRequest.Visible = FALSE; } else { diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 9e87a4d6b81..bf1c1e4d231 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -80,7 +80,8 @@ typedef struct typedef struct { PCONTROLDISPATCHER CtrlDispatcher; - BOOL ConsoleNeeded; + BOOLEAN ConsoleNeeded; + BOOLEAN Visible; HANDLE Console; HANDLE InputHandle; HANDLE OutputHandle; diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index ee89dad553f..0ce32c43824 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -142,7 +142,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, } static NTSTATUS WINAPI -CsrInitConsole(PCSRSS_CONSOLE Console) +CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { NTSTATUS Status; SECURITY_ATTRIBUTES SecurityAttributes; @@ -210,7 +210,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) } if (GuiMode) { - Status = GuiInitConsole(Console); + Status = GuiInitConsole(Console, Visible); if (! NT_SUCCESS(Status)) { HeapFree(Win32CsrApiHeap,0, NewBuffer); @@ -286,7 +286,7 @@ CSR_API(CsrAllocConsole) /* insert process data required for GUI initialization */ InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); /* Initialize the Console */ - Status = CsrInitConsole(Console); + Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible); if (!NT_SUCCESS(Status)) { DPRINT1("Console init failed\n"); diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 625b1b52a67..3edccbc7764 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -2070,7 +2070,10 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) if (NULL != NewWindow) { SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); - ShowWindow(NewWindow, SW_SHOW); + if (wParam) + { + ShowWindow(NewWindow, SW_SHOW); + } } return (LRESULT) NewWindow; case PM_DESTROY_CONSOLE: @@ -2250,7 +2253,7 @@ static CSRSS_CONSOLE_VTBL GuiVtbl = }; NTSTATUS FASTCALL -GuiInitConsole(PCSRSS_CONSOLE Console) +GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { HANDLE GraphicsStartupEvent; HANDLE ThreadHandle; @@ -2317,7 +2320,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console) */ GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); /* create console */ - PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console); + PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, Visible, (LPARAM) Console); /* wait untill initialization has finished */ WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.h b/reactos/subsystems/win32/csrss/win32csr/guiconsole.h index 072ef8c8886..705fbba0d92 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.h +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.h @@ -13,6 +13,6 @@ #define CONGUI_UPDATE_TIME 0 #define CONGUI_UPDATE_TIMER 1 -NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console); +NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible); /*EOF*/ From 772c56e48d89536e3f95270ab853c6190bf70b77 Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Sun, 23 May 2010 16:26:11 +0000 Subject: [PATCH 020/292] Perform case insensitive comparison against the selected language id. svn path=/trunk/; revision=47327 --- reactos/base/setup/usetup/interface/usetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 7a97b492c27..f2bbd6492dc 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -829,7 +829,7 @@ SetupStartPage(PINPUT_RECORD Ir) while (ListEntry != NULL) { - if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LanguageList, ListEntry); @@ -843,7 +843,7 @@ SetupStartPage(PINPUT_RECORD Ir) while (ListEntry != NULL) { - if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LayoutList, ListEntry); From fd303a1a462c87c029f871f47184b83b0a5bbb23 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Sun, 23 May 2010 17:01:06 +0000 Subject: [PATCH 021/292] [REGEDIT] - Don't display "finished" message if search is aborted. Patch by Katayama Hirofumi. See issue #5421 for more details. svn path=/trunk/; revision=47328 --- reactos/base/applications/regedit/find.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/base/applications/regedit/find.c b/reactos/base/applications/regedit/find.c index e20d01684f8..e3bb26ee404 100644 --- a/reactos/base/applications/regedit/find.c +++ b/reactos/base/applications/regedit/find.c @@ -684,7 +684,7 @@ BOOL FindNext(HWND hWnd) free(pszFoundValueName); SetFocus(g_pChildWnd->hListWnd); } - return fSuccess; + return fSuccess || s_bAbort; } static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -807,7 +807,7 @@ void FindDialog(HWND hWnd) if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND), hWnd, FindDialogProc, 0) != 0) { - if (FindNext(hWnd) == FALSE) + if (!FindNext(hWnd)) { TCHAR msg[128], caption[128]; From 7a2b3d46d350017b89edf1c972f6644643a5bd34 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Sun, 23 May 2010 17:07:56 +0000 Subject: [PATCH 022/292] [INTL] - Polish translation of Metric and Imperial by Olaf Siejka. svn path=/trunk/; revision=47329 --- reactos/dll/cpl/intl/lang/pl-PL.rc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/intl/lang/pl-PL.rc b/reactos/dll/cpl/intl/lang/pl-PL.rc index a80e5dba5da..3b566acdc75 100644 --- a/reactos/dll/cpl/intl/lang/pl-PL.rc +++ b/reactos/dll/cpl/intl/lang/pl-PL.rc @@ -1,5 +1,5 @@ /* - * translated by Caemyr - Olaf Siejka (Jan, 2008) + * translated by Caemyr - Olaf Siejka (Jan, 2008; May 2010) * Use ReactOS forum PM or IRC to contact me * http://www.reactos.org * IRC: irc.freenode.net #reactos-pl; @@ -195,8 +195,8 @@ STRINGTABLE BEGIN IDS_CUSTOMIZE_TITLE "Dostosuj Ustawienia regionalne" IDS_SPAIN "Hiszpañski (Hiszpania)" - IDS_METRIC "Metric" - IDS_IMPERIAL "Imperial" + IDS_METRIC "Metryczne" + IDS_IMPERIAL "Imperialne" END STRINGTABLE From 4bba2335c00ae1a50809c3b2a7722d5e6f6a9c00 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 May 2010 17:28:06 +0000 Subject: [PATCH 023/292] [SMSS] - Remove the system environment variable PROCESSOR_ARCHITECTURE from the hivesys*.inf files. - Let SMSS add the system environment variables PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER to the registry. svn path=/trunk/; revision=47330 --- reactos/base/system/smss/initenv.c | 97 ++++++++++++++++++++++---- reactos/boot/bootdata/hivesys_arm.inf | 1 - reactos/boot/bootdata/hivesys_i386.inf | 1 - 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/reactos/base/system/smss/initenv.c b/reactos/base/system/smss/initenv.c index 66a0f49ec7f..e97cf28c6aa 100644 --- a/reactos/base/system/smss/initenv.c +++ b/reactos/base/system/smss/initenv.c @@ -29,7 +29,7 @@ SmCreateEnvironment(VOID) static NTSTATUS SmpSetEnvironmentVariable(IN PVOID Context, IN PWSTR ValueName, - IN PVOID ValueData) + IN PWSTR ValueData) { UNICODE_STRING EnvVariable; UNICODE_STRING EnvValue; @@ -37,7 +37,7 @@ SmpSetEnvironmentVariable(IN PVOID Context, RtlInitUnicodeString(&EnvVariable, ValueName); RtlInitUnicodeString(&EnvValue, - (PWSTR)ValueData); + ValueData); return RtlSetEnvironmentVariable(Context, &EnvVariable, &EnvValue); @@ -58,12 +58,93 @@ SmpEnvironmentQueryRoutine(IN PWSTR ValueName, return STATUS_SUCCESS; DPRINT("ValueData '%S'\n", (PWSTR)ValueData); - return SmpSetEnvironmentVariable(Context,ValueName,ValueData); + return SmpSetEnvironmentVariable(Context,ValueName,(PWSTR)ValueData); } NTSTATUS SmSetEnvironmentVariables(VOID) +{ + PWSTR ProcessorArchitecture = L""; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + UNICODE_STRING Identifier; + UNICODE_STRING VendorIdentifier; + UNICODE_STRING ProcessorIdentifier; + WCHAR Buffer[256]; + NTSTATUS Status; + + /* Set the 'PROCESSOR_ARCHITECTURE' system environment variable */ +#ifdef _M_IX86 + ProcessorArchitecture = L"x86"; +#elif _M_MD64 + ProcessorArchitecture = L"AMD64"; +#elif _M_ARM + ProcessorArchitecture = L"ARM"; +#elif _M_PPC + ProcessorArchitecture = L"PPC"; +#else + #error "Unsupported Architecture!\n" +#endif + + RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, + L"Session Manager\\Environment", + L"PROCESSOR_ARCHITECTURE", + REG_SZ, + ProcessorArchitecture, + (wcslen(ProcessorArchitecture) + 1) * sizeof(WCHAR)); + + + /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */ + RtlInitUnicodeString(&Identifier, NULL); + RtlInitUnicodeString(&VendorIdentifier, NULL); + + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); + + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].Name = L"Identifier"; + QueryTable[0].EntryContext = &Identifier; + + QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[1].Name = L"VendorIdentifier"; + QueryTable[1].EntryContext = &VendorIdentifier; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0", + QueryTable, + NULL, + NULL); + if (NT_SUCCESS(Status)) + { + DPRINT("SM: szIdentifier: %wZ\n", &Identifier); + DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier); + + RtlInitEmptyUnicodeString(&ProcessorIdentifier, Buffer, 256 * sizeof(WCHAR)); + + RtlAppendUnicodeStringToString(&ProcessorIdentifier, &Identifier); + RtlAppendUnicodeToString(&ProcessorIdentifier, L", "); + RtlAppendUnicodeStringToString(&ProcessorIdentifier, &VendorIdentifier); + + RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, + L"Session Manager\\Environment", + L"PROCESSOR_IDENTIFIER", + REG_SZ, + ProcessorIdentifier.Buffer, + (wcslen(ProcessorIdentifier.Buffer) + 1) * sizeof(WCHAR)); + } + + RtlFreeUnicodeString(&Identifier); + RtlFreeUnicodeString(&VendorIdentifier); + + return STATUS_SUCCESS; +} + + +/********************************************************************** + * Set environment variables from registry + */ +NTSTATUS +SmUpdateEnvironment(VOID) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; WCHAR ValueBuffer[MAX_PATH]; @@ -106,14 +187,4 @@ SmSetEnvironmentVariables(VOID) return Status; } -/********************************************************************** - * Set environment variables from registry - */ -NTSTATUS -SmUpdateEnvironment(VOID) -{ - /* TODO */ - return STATUS_SUCCESS; -} - /* EOF */ diff --git a/reactos/boot/bootdata/hivesys_arm.inf b/reactos/boot/bootdata/hivesys_arm.inf index 277600b23a6..39e94e157a7 100644 --- a/reactos/boot/bootdata/hivesys_arm.inf +++ b/reactos/boot/bootdata/hivesys_arm.inf @@ -760,7 +760,6 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x0 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PROCESSOR_ARCHITECTURE",0x00020000,"x86" ; Known DLLs diff --git a/reactos/boot/bootdata/hivesys_i386.inf b/reactos/boot/bootdata/hivesys_i386.inf index 05e00057d33..e46e6b3257d 100644 --- a/reactos/boot/bootdata/hivesys_i386.inf +++ b/reactos/boot/bootdata/hivesys_i386.inf @@ -907,7 +907,6 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x0 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PROCESSOR_ARCHITECTURE",0x00020000,"x86" ; Known DLLs From 4b687b279278aa6e38f45d3aa6c95a96b0324c24 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 17:40:54 +0000 Subject: [PATCH 024/292] [KERNEL32], [WIN32CSR] More fixes for console winetest - BasepInitConsole: Initialize console input EXE name - GetConsoleProcessList: Use capture buffer; only copy IDs if buffer has enough room for all of them; return total number of processes. svn path=/trunk/; revision=47331 --- reactos/dll/win32/kernel32/include/kernel32.h | 2 ++ reactos/dll/win32/kernel32/misc/console.c | 34 ++++++++----------- reactos/dll/win32/kernel32/misc/dllmain.c | 7 +++- reactos/include/reactos/subsys/csrss/csrss.h | 7 ++-- .../subsystems/win32/csrss/win32csr/conio.c | 32 +++++++---------- 5 files changed, 39 insertions(+), 43 deletions(-) diff --git a/reactos/dll/win32/kernel32/include/kernel32.h b/reactos/dll/win32/kernel32/include/kernel32.h index 19731210435..59669780806 100755 --- a/reactos/dll/win32/kernel32/include/kernel32.h +++ b/reactos/dll/win32/kernel32/include/kernel32.h @@ -85,6 +85,8 @@ HANDLE WINAPI OpenConsoleW (LPCWSTR wsName, BOOL bInheritHandle, DWORD dwShareMode); +BOOL WINAPI SetConsoleInputExeNameW(LPCWSTR lpInputExeName); + PTEB GetTeb(VOID); HANDLE FASTCALL TranslateStdHandle(HANDLE hHandle); diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 9d433ddcfb6..2d6d5ba8643 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -3753,7 +3753,8 @@ WINAPI GetConsoleProcessList(LPDWORD lpdwProcessList, DWORD dwProcessCount) { - PCSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + CSR_API_MESSAGE Request; ULONG CsrRequest; ULONG nProcesses; NTSTATUS Status; @@ -3764,43 +3765,38 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, return 0; } - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) - + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD))); - if (Request == NULL) + CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD)); + if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE); - Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)); + Request.Data.GetProcessListRequest.nMaxIds = dwProcessCount; + CsrAllocateMessagePointer(CaptureBuffer, + dwProcessCount * sizeof(DWORD), + (PVOID*)&Request.Data.GetProcessListRequest.ProcessId); - Status = CsrClientCallServer(Request, - NULL, + Status = CsrClientCallServer(&Request, + CaptureBuffer, CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) - + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) + sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); SetLastErrorByStatus (Status); nProcesses = 0; } else { - nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied; + nProcesses = Request.Data.GetProcessListRequest.nProcessIdsTotal; if (dwProcessCount >= nProcesses) { - memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD)); + memcpy(lpdwProcessList, Request.Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD)); } } - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - + CsrFreeCaptureBuffer(CaptureBuffer); return nProcesses; } diff --git a/reactos/dll/win32/kernel32/misc/dllmain.c b/reactos/dll/win32/kernel32/misc/dllmain.c index bdf6f0d52e4..5247b649501 100644 --- a/reactos/dll/win32/kernel32/misc/dllmain.c +++ b/reactos/dll/win32/kernel32/misc/dllmain.c @@ -130,6 +130,7 @@ BasepInitConsole(VOID) NTSTATUS Status; BOOLEAN NotConsole = FALSE; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; + LPCWSTR ExeName; WCHAR lpTest[MAX_PATH]; GetModuleFileNameW(NULL, lpTest, MAX_PATH); @@ -183,13 +184,17 @@ BasepInitConsole(VOID) } } - /* Initialize Console Ctrl Handler */ + /* Initialize Console Ctrl Handler and input EXE name */ ConsoleInitialized = TRUE; RtlInitializeCriticalSection(&ConsoleLock); NrAllocatedHandlers = 1; NrCtrlHandlers = 1; CtrlHandlers = InitialHandler; CtrlHandlers[0] = DefaultConsoleCtrlHandler; + + ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\'); + if (ExeName) + SetConsoleInputExeNameW(ExeName + 1); /* Now use the proper console handle */ Request.Data.AllocConsoleRequest.Console = Parameters->ConsoleHandle; diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index bf1c1e4d231..b1867e49f26 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -51,10 +51,9 @@ typedef struct typedef struct { - ULONG nMaxIds; - ULONG nProcessIdsCopied; - ULONG nProcessIdsTotal; - HANDLE ProcessId[0]; + USHORT nMaxIds; + PDWORD ProcessId; + ULONG nProcessIdsTotal; } CSRSS_GET_PROCESS_LIST, *PCSRSS_GET_PROCESS_LIST; typedef struct diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 0ce32c43824..579e4fe07fb 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -2960,22 +2960,27 @@ CSR_API(CsrSetConsoleOutputCodePage) CSR_API(CsrGetProcessList) { - PHANDLE Buffer; + PDWORD Buffer; PCSRSS_CONSOLE Console; PCSRSS_PROCESS_DATA current; PLIST_ENTRY current_entry; - ULONG nItems, nCopied, Length; + ULONG nItems = 0; NTSTATUS Status; + ULONG_PTR Offset; DPRINT("CsrGetProcessList\n"); - Buffer = Request->Data.GetProcessListRequest.ProcessId; Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - nItems = nCopied = 0; - Request->Data.GetProcessListRequest.nProcessIdsCopied = 0; - Request->Data.GetProcessListRequest.nProcessIdsTotal = 0; + Buffer = Request->Data.GetProcessListRequest.ProcessId; + Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) + || Offset & (sizeof(DWORD) - 1)) + { + return STATUS_ACCESS_VIOLATION; + } Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status)) @@ -2983,31 +2988,20 @@ CSR_API(CsrGetProcessList) return Status; } - DPRINT1("Console_Api Ctrl-C\n"); - for(current_entry = Console->ProcessList.Flink; current_entry != &Console->ProcessList; current_entry = current_entry->Flink) { current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if(++nItems < Request->Data.GetProcessListRequest.nMaxIds) + if(++nItems <= Request->Data.GetProcessListRequest.nMaxIds) { - *(Buffer++) = current->ProcessId; - nCopied++; + *Buffer++ = (DWORD)current->ProcessId; } } ConioUnlockConsole(Console); - Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied; Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; - - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE); - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } return STATUS_SUCCESS; } From 88637f32f544fbc26bb58162815cf07dac0109ef Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 May 2010 19:27:04 +0000 Subject: [PATCH 025/292] [SMSS] - Remove the system environment variable OS from the hivesys*.inf files. - Change the type of the system environment variable PATHEXT in the hivesys*.inf files from REG_EXPAND_SZ to REG_SZ. - Let SMSS add the system environment variables OS and NUMBER_OF_PROCESSORS to the registry. svn path=/trunk/; revision=47333 --- reactos/base/system/smss/initenv.c | 117 +++++++++++++++++++++---- reactos/boot/bootdata/hivesys_arm.inf | 3 +- reactos/boot/bootdata/hivesys_i386.inf | 3 +- 3 files changed, 100 insertions(+), 23 deletions(-) diff --git a/reactos/base/system/smss/initenv.c b/reactos/base/system/smss/initenv.c index e97cf28c6aa..6580b4b6716 100644 --- a/reactos/base/system/smss/initenv.c +++ b/reactos/base/system/smss/initenv.c @@ -65,33 +65,116 @@ SmpEnvironmentQueryRoutine(IN PWSTR ValueName, NTSTATUS SmSetEnvironmentVariables(VOID) { - PWSTR ProcessorArchitecture = L""; + SYSTEM_BASIC_INFORMATION BasicInformation; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; UNICODE_STRING Identifier; UNICODE_STRING VendorIdentifier; - UNICODE_STRING ProcessorIdentifier; WCHAR Buffer[256]; + + UNICODE_STRING EnvironmentKeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE EnvironmentKey; + UNICODE_STRING VariableName; + PWSTR VariableData; + NTSTATUS Status; + + Status = NtQuerySystemInformation(SystemBasicInformation, + &BasicInformation, + sizeof(SYSTEM_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to retrieve system basic information (Status %08lx)", Status); + return Status; + } + + RtlInitUnicodeString(&EnvironmentKeyName, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Environment"); + InitializeObjectAttributes(&ObjectAttributes, + &EnvironmentKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the system environment key */ + Status = NtOpenKey(&EnvironmentKey, + GENERIC_WRITE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to open the environment key (Status %08lx)", Status); + return Status; + } + + /* Set the 'NUMBER_OF_PROCESSORS' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"NUMBER_OF_PROCESSORS"); + + swprintf(Buffer, L"%lu", BasicInformation.NumberOfProcessors); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the NUMBER_OF_PROCESSORS environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'OS' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"OS"); + + VariableData = L"ReactOS"; + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + VariableData, + (wcslen(VariableData) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the OS environment variable (Status %08lx)", Status); + goto done; + } + /* Set the 'PROCESSOR_ARCHITECTURE' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_ARCHITECTURE"); + #ifdef _M_IX86 - ProcessorArchitecture = L"x86"; + VariableData = L"x86"; #elif _M_MD64 - ProcessorArchitecture = L"AMD64"; + VariableData = L"AMD64"; #elif _M_ARM - ProcessorArchitecture = L"ARM"; + VariableData = L"ARM"; #elif _M_PPC - ProcessorArchitecture = L"PPC"; + VariableData = L"PPC"; #else #error "Unsupported Architecture!\n" #endif - RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, - L"Session Manager\\Environment", - L"PROCESSOR_ARCHITECTURE", - REG_SZ, - ProcessorArchitecture, - (wcslen(ProcessorArchitecture) + 1) * sizeof(WCHAR)); + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + VariableData, + (wcslen(VariableData) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_ARCHITECTURE environment variable (Status %08lx)", Status); + goto done; + } + +done: + NtClose(EnvironmentKey); /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */ @@ -119,18 +202,14 @@ SmSetEnvironmentVariables(VOID) DPRINT("SM: szIdentifier: %wZ\n", &Identifier); DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier); - RtlInitEmptyUnicodeString(&ProcessorIdentifier, Buffer, 256 * sizeof(WCHAR)); - - RtlAppendUnicodeStringToString(&ProcessorIdentifier, &Identifier); - RtlAppendUnicodeToString(&ProcessorIdentifier, L", "); - RtlAppendUnicodeStringToString(&ProcessorIdentifier, &VendorIdentifier); + swprintf(Buffer, L"%wZ, %wZ", &Identifier, &VendorIdentifier); RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, L"Session Manager\\Environment", L"PROCESSOR_IDENTIFIER", REG_SZ, - ProcessorIdentifier.Buffer, - (wcslen(ProcessorIdentifier.Buffer) + 1) * sizeof(WCHAR)); + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); } RtlFreeUnicodeString(&Identifier); diff --git a/reactos/boot/bootdata/hivesys_arm.inf b/reactos/boot/bootdata/hivesys_arm.inf index 39e94e157a7..dbe7d1b210c 100644 --- a/reactos/boot/bootdata/hivesys_arm.inf +++ b/reactos/boot/bootdata/hivesys_arm.inf @@ -754,12 +754,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","UNC",0x0000 ; System environment settings HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ComSpec",0x00020000,"%SystemRoot%\system32\cmd.exe" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","OS",0x00020000,"ReactOS" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","Path",0x00020000,"%SystemRoot%\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\system32\wbem" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x00020000,"%SystemRoot%" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00000000,".COM;.EXE;.BAT;.CMD" ; Known DLLs diff --git a/reactos/boot/bootdata/hivesys_i386.inf b/reactos/boot/bootdata/hivesys_i386.inf index e46e6b3257d..db355022871 100644 --- a/reactos/boot/bootdata/hivesys_i386.inf +++ b/reactos/boot/bootdata/hivesys_i386.inf @@ -901,12 +901,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","UNC",0x0000 ; System environment settings HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ComSpec",0x00020000,"%SystemRoot%\system32\cmd.exe" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","OS",0x00020000,"ReactOS" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","Path",0x00020000,"%SystemRoot%\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\system32\wbem" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x00020000,"%SystemRoot%" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00000000,".COM;.EXE;.BAT;.CMD" ; Known DLLs From 8f6739ed2e80661998125494fff58bee63ca4b6d Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 May 2010 20:41:03 +0000 Subject: [PATCH 026/292] [REGEDIT] Ignore the case when sorting value names. svn path=/trunk/; revision=47334 --- reactos/base/applications/regedit/listview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/regedit/listview.c b/reactos/base/applications/regedit/listview.c index 6e95a863ff9..12cfa894db6 100644 --- a/reactos/base/applications/regedit/listview.c +++ b/reactos/base/applications/regedit/listview.c @@ -380,7 +380,7 @@ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSor if (g_columnToSort == 2) { /* FIXME: Sort on value */ } - return g_invertSort ? _tcscmp(r->name, l->name) : _tcscmp(l->name, r->name); + return g_invertSort ? _tcsicmp(r->name, l->name) : _tcsicmp(l->name, r->name); } BOOL ListWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result) From 7fa77031b0003ce69f23735cbf91a5e6a9f146be Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 22:38:16 +0000 Subject: [PATCH 027/292] [WIN32CSR] - Make consistent use of RECT/SMALL_RECT structures: a RECT uses pixel coordinates relative to the window client area and is endpoint-exclusive; a SMALL_RECT uses character coordinates relative to the screen buffer and is endpoint-inclusive. - Allow text selections outside of the visible window - Implement GetConsoleSelectionInfo svn path=/trunk/; revision=47335 --- reactos/dll/win32/kernel32/misc/console.c | 16 +- reactos/include/reactos/subsys/csrss/csrss.h | 7 + .../subsystems/win32/csrss/win32csr/conio.c | 249 ++++++++------- .../subsystems/win32/csrss/win32csr/conio.h | 17 +- .../subsystems/win32/csrss/win32csr/dllmain.c | 1 + .../win32/csrss/win32csr/guiconsole.c | 299 ++++++------------ 6 files changed, 257 insertions(+), 332 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 2d6d5ba8643..298f79b8e59 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -3805,15 +3805,23 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, /*-------------------------------------------------------------- * GetConsoleSelectionInfo * - * @unimplemented + * @implemented */ BOOL WINAPI GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo) { - DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_CONSOLE_SELECTION_INFO, CSR_CONSOLE); + NTSTATUS Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + *lpConsoleSelectionInfo = Request.Data.GetConsoleSelectionInfo.Info; + return TRUE; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index b1867e49f26..62fe387633c 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -473,6 +473,11 @@ typedef struct COORD Size; } CSRSS_SET_SCREEN_BUFFER_SIZE, *PCSRSS_SET_SCREEN_BUFFER_SIZE; +typedef struct +{ + CONSOLE_SELECTION_INFO Info; +} CSRSS_GET_CONSOLE_SELECTION_INFO, *PCSRSS_GET_CONSOLE_SELECTION_INFO; + #define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) #define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) @@ -552,6 +557,7 @@ typedef struct #define GENERATE_CTRL_EVENT (0x3E) #define CREATE_THREAD (0x3F) #define SET_SCREEN_BUFFER_SIZE (0x40) +#define GET_CONSOLE_SELECTION_INFO (0x41) /* Keep in sync with definition below. */ #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) @@ -626,6 +632,7 @@ typedef struct _CSR_API_MESSAGE CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; + CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; } Data; } CSR_API_MESSAGE, *PCSR_API_MESSAGE; diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 579e4fe07fb..60b93cf9b3f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -14,14 +14,14 @@ /* GLOBALS *******************************************************************/ -#define ConioInitRect(Rect, Top, Left, Bottom, Right) \ - ((Rect)->top) = Top; \ - ((Rect)->left) = Left; \ - ((Rect)->bottom) = Bottom; \ - ((Rect)->right) = Right +#define ConioInitRect(Rect, top, left, bottom, right) \ + ((Rect)->Top) = top; \ + ((Rect)->Left) = left; \ + ((Rect)->Bottom) = bottom; \ + ((Rect)->Right) = right #define ConioIsRectEmpty(Rect) \ - (((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom)) + (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) @@ -392,7 +392,7 @@ CSR_API(CsrFreeConsole) } static VOID FASTCALL -ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines) +ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines) { /* If we hit bottom, slide the viewable screen */ if (++Buff->CurrentY == Buff->MaxY) @@ -404,14 +404,14 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines) } (*ScrolledLines)++; ClearLineBuffer(Buff); - if (UpdateRect->top != 0) + if (UpdateRect->Top != 0) { - UpdateRect->top--; + UpdateRect->Top--; } } - UpdateRect->left = 0; - UpdateRect->right = Buff->MaxX - 1; - UpdateRect->bottom = Buff->CurrentY; + UpdateRect->Left = 0; + UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Bottom = Buff->CurrentY; } static NTSTATUS FASTCALL @@ -420,16 +420,16 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, { UINT i; PBYTE Ptr; - RECT UpdateRect; + SMALL_RECT UpdateRect; LONG CursorStartX, CursorStartY; UINT ScrolledLines; CursorStartX = Buff->CurrentX; CursorStartY = Buff->CurrentY; - UpdateRect.left = Buff->MaxX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = -1; - UpdateRect.bottom = Buff->CurrentY; + UpdateRect.Left = Buff->MaxX; + UpdateRect.Top = Buff->CurrentY; + UpdateRect.Right = -1; + UpdateRect.Bottom = Buff->CurrentY; ScrolledLines = 0; for (i = 0; i < Length; i++) @@ -454,7 +454,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, /* slide virtual position up */ Buff->CurrentX = Buff->MaxX - 1; Buff->CurrentY--; - UpdateRect.top = min(UpdateRect.top, (LONG)Buff->CurrentY); + UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); } else { @@ -463,8 +463,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); Ptr[0] = ' '; Ptr[1] = Buff->DefaultAttrib; - UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); } continue; } @@ -472,8 +472,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, else if (Buffer[i] == '\r') { Buff->CurrentX = 0; - UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); continue; } /* --- TAB --- */ @@ -481,7 +481,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, { UINT EndX; - UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX); + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); EndX = (Buff->CurrentX + 8) & ~7; if (EndX > Buff->MaxX) { @@ -494,7 +494,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, *Ptr++ = Buff->DefaultAttrib; Buff->CurrentX++; } - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); if (Buff->CurrentX == Buff->MaxX) { if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) @@ -510,8 +510,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, continue; } } - UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); Ptr[0] = Buffer[i]; if (Attrib) @@ -684,16 +684,16 @@ CSR_API(CsrReadConsole) } __inline BOOLEAN ConioGetIntersection( - RECT *Intersection, - RECT *Rect1, - RECT *Rect2) + SMALL_RECT *Intersection, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) { if (ConioIsRectEmpty(Rect1) || (ConioIsRectEmpty(Rect2)) || - (Rect1->top > Rect2->bottom) || - (Rect1->left > Rect2->right) || - (Rect1->bottom < Rect2->top) || - (Rect1->right < Rect2->left)) + (Rect1->Top > Rect2->Bottom) || + (Rect1->Left > Rect2->Right) || + (Rect1->Bottom < Rect2->Top) || + (Rect1->Right < Rect2->Left)) { /* The rectangles do not intersect */ ConioInitRect(Intersection, 0, -1, 0, -1); @@ -701,18 +701,18 @@ __inline BOOLEAN ConioGetIntersection( } ConioInitRect(Intersection, - max(Rect1->top, Rect2->top), - max(Rect1->left, Rect2->left), - min(Rect1->bottom, Rect2->bottom), - min(Rect1->right, Rect2->right)); + max(Rect1->Top, Rect2->Top), + max(Rect1->Left, Rect2->Left), + min(Rect1->Bottom, Rect2->Bottom), + min(Rect1->Right, Rect2->Right)); return TRUE; } __inline BOOLEAN ConioGetUnion( - RECT *Union, - RECT *Rect1, - RECT *Rect2) + SMALL_RECT *Union, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) { if (ConioIsRectEmpty(Rect1)) { @@ -733,10 +733,10 @@ __inline BOOLEAN ConioGetUnion( else { ConioInitRect(Union, - min(Rect1->top, Rect2->top), - min(Rect1->left, Rect2->left), - max(Rect1->bottom, Rect2->bottom), - max(Rect1->right, Rect2->right)); + min(Rect1->Top, Rect2->Top), + min(Rect1->Left, Rect2->Left), + max(Rect1->Bottom, Rect2->Bottom), + max(Rect1->Right, Rect2->Right)); } return TRUE; @@ -746,9 +746,9 @@ __inline BOOLEAN ConioGetUnion( * this is done, to avoid overwriting parts of the source before they are moved. */ static VOID FASTCALL ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, - RECT *SrcRegion, - RECT *DstRegion, - RECT *ClipRegion, + SMALL_RECT *SrcRegion, + SMALL_RECT *DstRegion, + SMALL_RECT *ClipRegion, WORD Fill) { int Width = ConioRectWidth(SrcRegion); @@ -758,14 +758,14 @@ ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, int XDelta, YDelta; int i, j; - SY = SrcRegion->top; - DY = DstRegion->top; + SY = SrcRegion->Top; + DY = DstRegion->Top; YDelta = 1; if (SY < DY) { /* Moving down: work from bottom up */ - SY = SrcRegion->bottom; - DY = DstRegion->bottom; + SY = SrcRegion->Bottom; + DY = DstRegion->Bottom; YDelta = -1; } for (i = 0; i < Height; i++) @@ -773,26 +773,26 @@ ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); - SX = SrcRegion->left; - DX = DstRegion->left; + SX = SrcRegion->Left; + DX = DstRegion->Left; XDelta = 1; if (SX < DX) { /* Moving right: work from right to left */ - SX = SrcRegion->right; - DX = DstRegion->right; + SX = SrcRegion->Right; + DX = DstRegion->Right; XDelta = -1; } for (j = 0; j < Width; j++) { WORD Cell = SRow[SX]; - if (SX >= ClipRegion->left && SX <= ClipRegion->right - && SY >= ClipRegion->top && SY <= ClipRegion->bottom) + if (SX >= ClipRegion->Left && SX <= ClipRegion->Right + && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) { SRow[SX] = Fill; } - if (DX >= ClipRegion->left && DX <= ClipRegion->right - && DY >= ClipRegion->top && DY <= ClipRegion->bottom) + if (DX >= ClipRegion->Left && DX <= ClipRegion->Right + && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) { DRow[DX] = Cell; } @@ -920,7 +920,7 @@ ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console) { - RECT Region; + SMALL_RECT Region; ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); @@ -1362,29 +1362,29 @@ CSR_API(CsrSetCursor) } static VOID FASTCALL -ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length) +ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length) { if (Buff->MaxX <= Start->X + Length) { - UpdateRect->left = 0; + UpdateRect->Left = 0; } else { - UpdateRect->left = Start->X; + UpdateRect->Left = Start->X; } if (Buff->MaxX <= Start->X + Length) { - UpdateRect->right = Buff->MaxX - 1; + UpdateRect->Right = Buff->MaxX - 1; } else { - UpdateRect->right = Start->X + Length - 1; + UpdateRect->Right = Start->X + Length - 1; } - UpdateRect->top = Start->Y; - UpdateRect->bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; - if (Buff->MaxY <= UpdateRect->bottom) + UpdateRect->Top = Start->Y; + UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; + if (Buff->MaxY <= UpdateRect->Bottom) { - UpdateRect->bottom = Buff->MaxY - 1; + UpdateRect->Bottom = Buff->MaxY - 1; } } @@ -1396,7 +1396,7 @@ CSR_API(CsrWriteConsoleOutputChar) PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; DWORD X, Y, Length, CharSize, Written = 0; - RECT UpdateRect; + SMALL_RECT UpdateRect; DPRINT("CsrWriteConsoleOutputChar\n"); @@ -1498,7 +1498,7 @@ CSR_API(CsrFillOutputChar) DWORD X, Y, Length, Written = 0; CHAR Char; PBYTE Buffer; - RECT UpdateRect; + SMALL_RECT UpdateRect; DPRINT("CsrFillOutputChar\n"); @@ -1636,7 +1636,7 @@ CSR_API(CsrWriteConsoleOutputAttrib) PWORD Attribute; int X, Y, Length; NTSTATUS Status; - RECT UpdateRect; + SMALL_RECT UpdateRect; DPRINT("CsrWriteConsoleOutputAttrib\n"); @@ -1705,7 +1705,7 @@ CSR_API(CsrFillOutputAttrib) NTSTATUS Status; int X, Y, Length; UCHAR Attr; - RECT UpdateRect; + SMALL_RECT UpdateRect; PCSRSS_CONSOLE Console; DPRINT("CsrFillOutputAttrib\n"); @@ -2119,9 +2119,9 @@ CSR_API(CsrWriteConsoleOutput) SHORT i, X, Y, SizeX, SizeY; PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; - RECT ScreenBuffer; + SMALL_RECT ScreenBuffer; CHAR_INFO* CurCharInfo; - RECT WriteRegion; + SMALL_RECT WriteRegion; CHAR_INFO* CharInfo; COORD BufferCoord; COORD BufferSize; @@ -2154,15 +2154,12 @@ CSR_API(CsrWriteConsoleOutput) ConioUnlockScreenBuffer(Buff); return STATUS_ACCESS_VIOLATION; } - WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left; - WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top; - WriteRegion.right = Request->Data.WriteConsoleOutputRequest.WriteRegion.Right; - WriteRegion.bottom = Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom; + WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); - WriteRegion.bottom = WriteRegion.top + SizeY - 1; - WriteRegion.right = WriteRegion.left + SizeX - 1; + WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + WriteRegion.Right = WriteRegion.Left + SizeX - 1; /* Make sure WriteRegion is inside the screen buffer */ ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); @@ -2175,11 +2172,11 @@ CSR_API(CsrWriteConsoleOutput) return STATUS_SUCCESS; } - for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++) + for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) { CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - Ptr = ConioCoordToPointer(Buff, WriteRegion.left, Y); - for (X = WriteRegion.left; X <= WriteRegion.right; X++) + Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); + for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) { CHAR AsciiChar; if (Request->Data.WriteConsoleOutputRequest.Unicode) @@ -2200,10 +2197,10 @@ CSR_API(CsrWriteConsoleOutput) ConioUnlockScreenBuffer(Buff); - Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; return STATUS_SUCCESS; } @@ -2248,12 +2245,12 @@ CSR_API(CsrScrollConsoleScreenBuffer) { PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; - RECT ScreenBuffer; - RECT SrcRegion; - RECT DstRegion; - RECT UpdateRegion; - RECT ScrollRectangle; - RECT ClipRectangle; + SMALL_RECT ScreenBuffer; + SMALL_RECT SrcRegion; + SMALL_RECT DstRegion; + SMALL_RECT UpdateRegion; + SMALL_RECT ScrollRectangle; + SMALL_RECT ClipRectangle; NTSTATUS Status; HANDLE ConsoleHandle; BOOLEAN UseClipRectangle; @@ -2277,10 +2274,7 @@ CSR_API(CsrScrollConsoleScreenBuffer) } Console = Buff->Header.Console; - ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left; - ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top; - ScrollRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right; - ScrollRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom; + ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; /* Make sure source rectangle is inside the screen buffer */ ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); @@ -2291,21 +2285,18 @@ CSR_API(CsrScrollConsoleScreenBuffer) } /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.left < 0) + if (ScrollRectangle.Left < 0) { - DestinationOrigin.X -= ScrollRectangle.left; + DestinationOrigin.X -= ScrollRectangle.Left; } - if (ScrollRectangle.top < 0) + if (ScrollRectangle.Top < 0) { - DestinationOrigin.Y -= ScrollRectangle.top; + DestinationOrigin.Y -= ScrollRectangle.Top; } if (UseClipRectangle) { - ClipRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left; - ClipRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top; - ClipRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right; - ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom; + ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) { ConioUnlockScreenBuffer(Buff); @@ -2601,8 +2592,8 @@ CSR_API(CsrReadConsoleOutput) NTSTATUS Status; COORD BufferSize; COORD BufferCoord; - RECT ReadRegion; - RECT ScreenRect; + SMALL_RECT ReadRegion; + SMALL_RECT ScreenRect; DWORD i; PBYTE Ptr; LONG X, Y; @@ -2620,10 +2611,7 @@ CSR_API(CsrReadConsoleOutput) } CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; - ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left; - ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top; - ReadRegion.right = Request->Data.ReadConsoleOutputRequest.ReadRegion.Right; - ReadRegion.bottom = Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom; + ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; Length = BufferSize.X * BufferSize.Y; @@ -2641,8 +2629,8 @@ CSR_API(CsrReadConsoleOutput) SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); - ReadRegion.bottom = ReadRegion.top + SizeY; - ReadRegion.right = ReadRegion.left + SizeX; + ReadRegion.Bottom = ReadRegion.Top + SizeY; + ReadRegion.Right = ReadRegion.Left + SizeX; ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) @@ -2651,12 +2639,12 @@ CSR_API(CsrReadConsoleOutput) return STATUS_SUCCESS; } - for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y) + for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) { CurCharInfo = CharInfo + (i * BufferSize.X); - Ptr = ConioCoordToPointer(Buff, ReadRegion.left, Y); - for (X = ReadRegion.left; X < ReadRegion.right; ++X) + Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); + for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) { if (Request->Data.ReadConsoleOutputRequest.Unicode) { @@ -2675,10 +2663,10 @@ CSR_API(CsrReadConsoleOutput) ConioUnlockScreenBuffer(Buff); - Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; return STATUS_SUCCESS; } @@ -3063,4 +3051,23 @@ CSR_API(CsrSetScreenBufferSize) return Status; } +CSR_API(CsrGetConsoleSelectionInfo) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO)); + if (Console->Selection.dwFlags != 0) + Request->Data.GetConsoleSelectionInfo.Info = Console->Selection; + ConioUnlockConsole(Console); + } + return Status; +} + /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 8c853689b30..8645351f96a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -54,9 +54,9 @@ typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; typedef struct tagCSRSS_CONSOLE_VTBL { VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); - VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, RECT *Block, LONG CursorStartX, LONG CursorStartY, + VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, SMALL_RECT *Block, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length); - VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, RECT *Region); + VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, SMALL_RECT *Region); BOOL (WINAPI *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); BOOL (WINAPI *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, UINT OldCursorX, UINT OldCursorY); @@ -92,6 +92,7 @@ typedef struct tagCSRSS_CONSOLE PCSRSS_CONSOLE_VTBL Vtbl; LIST_ENTRY ProcessList; struct tagALIAS_HEADER *Aliases; + CONSOLE_SELECTION_INFO Selection; } CSRSS_CONSOLE; typedef struct ConsoleInput_t @@ -103,6 +104,13 @@ typedef struct ConsoleInput_t BOOLEAN NotChar; // message should not be used to return a character } ConsoleInput; +/* CONSOLE_SELECTION_INFO dwFlags values */ +#define CONSOLE_NO_SELECTION 0x0 +#define CONSOLE_SELECTION_IN_PROGRESS 0x1 +#define CONSOLE_SELECTION_NOT_EMPTY 0x2 +#define CONSOLE_MOUSE_SELECTION 0x4 +#define CONSOLE_MOUSE_DOWN 0x8 + NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); VOID WINAPI ConioDeleteConsole(Object_t *Object); VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); @@ -155,6 +163,7 @@ CSR_API(CsrSetConsoleOutputCodePage); CSR_API(CsrGetProcessList); CSR_API(CsrGenerateCtrlEvent); CSR_API(CsrSetScreenBufferSize); +CSR_API(CsrGetConsoleSelectionInfo); #define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff)) #define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region)) @@ -172,9 +181,9 @@ CSR_API(CsrSetScreenBufferSize); #define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size) #define ConioRectHeight(Rect) \ - (((Rect)->top) > ((Rect)->bottom) ? 0 : ((Rect)->bottom) - ((Rect)->top) + 1) + (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) #define ConioRectWidth(Rect) \ - (((Rect)->left) > ((Rect)->right) ? 0 : ((Rect)->right) - ((Rect)->left) + 1) + (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) #define ConioLockConsole(ProcessData, Handle, Ptr, Access) \ Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC) diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index bd0409c55ca..2e8947f014a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -81,6 +81,7 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength), CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent), CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize), + CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo), { 0, 0, NULL } }; diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 3edccbc7764..0d063d8b31b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -25,9 +25,6 @@ typedef struct GUI_CONSOLE_DATA_TAG BOOL CursorBlinkOn; BOOL ForceCursorOff; CRITICAL_SECTION Lock; - RECT Selection; - POINT SelectionStart; - BOOL MouseDown; HMODULE ConsoleLibrary; HANDLE hGuiInitEvent; WCHAR FontName[LF_FACESIZE]; @@ -773,7 +770,6 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) GuiData->CursorBlinkOn = TRUE; GuiData->ForceCursorOff = FALSE; - GuiData->Selection.left = -1; DPRINT("Console %p GuiData %p\n", Console, GuiData); Console->PrivateData = GuiData; SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); @@ -790,40 +786,46 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); } -static VOID FASTCALL -GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData) +static VOID +SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) { - RECT oldRect = GuiData->Selection; + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth; + Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight; + Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth; + Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight; +} - if(rc != NULL) +static VOID FASTCALL +GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) +{ + RECT oldRect, newRect; + HWND hWnd = Console->hWindow; + + SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); + + if(coord != NULL) { - RECT changeRect = *rc; + SMALL_RECT rc; + /* exchange left/top with right/bottom if required */ + rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); + rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); - GuiData->Selection = *rc; + SmallRectToRect(Console, &newRect, &rc); - changeRect.left *= GuiData->CharWidth; - changeRect.top *= GuiData->CharHeight; - changeRect.right *= GuiData->CharWidth; - changeRect.bottom *= GuiData->CharHeight; - - if(rc->left != oldRect.left || - rc->top != oldRect.top || - rc->right != oldRect.right || - rc->bottom != oldRect.bottom) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - if(oldRect.left != -1) + if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) { HRGN rgn1, rgn2; - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; - /* calculate the region that needs to be updated */ if((rgn1 = CreateRectRgnIndirect(&oldRect))) { - if((rgn2 = CreateRectRgnIndirect(&changeRect))) + if((rgn2 = CreateRectRgnIndirect(&newRect))) { if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) { @@ -835,21 +837,22 @@ GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData) DeleteObject(rgn1); } } - else - { - InvalidateRect(hWnd, &changeRect, FALSE); - } } + else + { + InvalidateRect(hWnd, &newRect, FALSE); + } + Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; + Console->Selection.srSelection = rc; } - else if(oldRect.left != -1) + else { /* clear the selection */ - GuiData->Selection.left = -1; - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; - InvalidateRect(hWnd, &oldRect, FALSE); + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) + { + InvalidateRect(hWnd, &oldRect, FALSE); + } + Console->Selection.dwFlags = CONSOLE_NO_SELECTION; } } @@ -1005,14 +1008,10 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC, &ps.rcPaint); - if (GuiData->Selection.left != -1) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - RECT rc = GuiData->Selection; - - rc.left *= GuiData->CharWidth; - rc.top *= GuiData->CharHeight; - rc.right *= GuiData->CharWidth; - rc.bottom *= GuiData->CharHeight; + RECT rc; + SmallRectToRect(Console, &rc, &Console->Selection.srSelection); /* invert the selection */ if (IntersectRect(&rc, @@ -1052,51 +1051,29 @@ GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) { /* clear the selection */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); + GuiConsoleUpdateSelection(Console, NULL); } ConioProcessKey(&Message, Console, FALSE); } -static VOID FASTCALL -GuiIntDrawRegion(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region) -{ - RECT RegionRect; - - RegionRect.left = (Region->left - Buff->ShowX) * GuiData->CharWidth; - RegionRect.top = (Region->top - Buff->ShowY) * GuiData->CharHeight; - RegionRect.right = (Region->right + 1 - Buff->ShowX) * GuiData->CharWidth; - RegionRect.bottom = (Region->bottom + 1 - Buff->ShowY) * GuiData->CharHeight; - - InvalidateRect(Wnd, &RegionRect, FALSE); -} - static VOID WINAPI -GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) +GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - - if (NULL != Console->hWindow && NULL != GuiData) - { - GuiIntDrawRegion(Console->ActiveBuffer, GuiData, Console->hWindow, Region); - } + RECT RegionRect; + SmallRectToRect(Console, &RegionRect, Region); + InvalidateRect(Console->hWindow, &RegionRect, FALSE); } static VOID FASTCALL -GuiInvalidateCell(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y) +GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y) { - RECT CellRect; - - CellRect.left = x; - CellRect.top = y; - CellRect.right = x; - CellRect.bottom = y; - - GuiIntDrawRegion(Buff, GuiData, Wnd, &CellRect); + SMALL_RECT CellRect = { x, y, x, y }; + GuiDrawRegion(Console, &CellRect); } static VOID WINAPI -GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY, +GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; @@ -1114,26 +1091,7 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur ScrollRect.left = 0; ScrollRect.top = 0; ScrollRect.right = Console->Size.X * GuiData->CharWidth; - ScrollRect.bottom = Region->top * GuiData->CharHeight; - - if (GuiData->Selection.left != -1) - { - /* scroll the selection */ - if (GuiData->Selection.top > ScrolledLines) - { - GuiData->Selection.top -= ScrolledLines; - GuiData->Selection.bottom -= ScrolledLines; - } - else if (GuiData->Selection.bottom < ScrolledLines) - { - GuiData->Selection.left = -1; - } - else - { - GuiData->Selection.top = 0; - GuiData->Selection.bottom -= ScrolledLines; - } - } + ScrollRect.bottom = Region->Top * GuiData->CharHeight; ScrollWindowEx(Console->hWindow, 0, @@ -1145,21 +1103,21 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur SW_INVALIDATE); } - GuiIntDrawRegion(Buff, GuiData, Console->hWindow, Region); + GuiDrawRegion(Console, Region); - if (CursorStartX < Region->left || Region->right < CursorStartX - || CursorStartY < Region->top || Region->bottom < CursorStartY) + if (CursorStartX < Region->Left || Region->Right < CursorStartX + || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorStartX, CursorStartY); + GuiInvalidateCell(Console, CursorStartX, CursorStartY); } CursorEndX = Buff->CurrentX; CursorEndY = Buff->CurrentY; - if ((CursorEndX < Region->left || Region->right < CursorEndX - || CursorEndY < Region->top || Region->bottom < CursorEndY) + if ((CursorEndX < Region->Left || Region->Right < CursorEndX + || CursorEndY < Region->Top || Region->Bottom < CursorEndY) && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorEndX, CursorEndY); + GuiInvalidateCell(Console, CursorEndX, CursorEndY); } // Set up the update timer (very short interval) - this is a "hack" for getting the OS to @@ -1171,15 +1129,9 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur static BOOL WINAPI GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - RECT UpdateRect; - if (Console->ActiveBuffer == Buff) { - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } return TRUE; @@ -1188,22 +1140,12 @@ GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) static BOOL WINAPI GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - RECT UpdateRect; - if (Console->ActiveBuffer == Buff) { /* Redraw char at old position (removes cursor) */ - UpdateRect.left = OldCursorX; - UpdateRect.top = OldCursorY; - UpdateRect.right = OldCursorX; - UpdateRect.bottom = OldCursorY; - ConioDrawRegion(Console, &UpdateRect); + GuiInvalidateCell(Console, OldCursorX, OldCursorY); /* Redraw char at new position (shows cursor) */ - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } return TRUE; @@ -1229,18 +1171,13 @@ GuiConsoleHandleTimer(HWND hWnd) PCSRSS_CONSOLE Console; PGUI_CONSOLE_DATA GuiData; PCSRSS_SCREEN_BUFFER Buff; - RECT CursorRect; SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); Buff = Console->ActiveBuffer; - CursorRect.left = Buff->CurrentX; - CursorRect.top = Buff->CurrentY; - CursorRect.right = CursorRect.left; - CursorRect.bottom = CursorRect.top; - GuiDrawRegion(Console, &CursorRect); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) @@ -1362,32 +1299,39 @@ GuiConsoleHandleNcDestroy(HWND hWnd) HeapFree(Win32CsrApiHeap, 0, GuiData); } +static COORD +PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) +{ + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + COORD Coord; + Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth); + Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight); + + /* Clip coordinate to ensure it's inside buffer */ + if (Coord.X < 0) Coord.X = 0; + else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1; + if (Coord.Y < 0) Coord.Y = 0; + else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1; + return Coord; +} + static VOID FASTCALL GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) { PCSRSS_CONSOLE Console; PGUI_CONSOLE_DATA GuiData; - POINTS pt; - RECT rc; GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console == NULL || GuiData == NULL) return; - pt = MAKEPOINTS(lParam); - - rc.left = pt.x / GuiData->CharWidth; - rc.top = pt.y / GuiData->CharHeight; - rc.right = rc.left + 1; - rc.bottom = rc.top + 1; - - GuiData->SelectionStart.x = rc.left; - GuiData->SelectionStart.y = rc.top; + Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); SetCapture(hWnd); - GuiData->MouseDown = TRUE; + Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); } static VOID FASTCALL @@ -1395,39 +1339,17 @@ GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) { PCSRSS_CONSOLE Console; PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; + COORD c; GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - pt = MAKEPOINTS(lParam); + c = PointToCoord(Console, lParam); - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); + Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } - - GuiData->MouseDown = FALSE; - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &c); ReleaseCapture(); } @@ -1437,46 +1359,17 @@ GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) { PCSRSS_CONSOLE Console; PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; + COORD c; if (!(wParam & MK_LBUTTON)) return; GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return; + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - pt = MAKEPOINTS(lParam); + c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - if (Console->Size.X < rc.right) - { - rc.right = Console->Size.X; - } - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); - if (Console->Size.Y < rc.bottom) - { - rc.bottom = Console->Size.Y; - } - - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &c); } static VOID FASTCALL @@ -1488,7 +1381,7 @@ GuiConsoleRightMouseDown(HWND hWnd) GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1) + if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) { /* FIXME - paste text from clipboard */ } @@ -1496,7 +1389,7 @@ GuiConsoleRightMouseDown(HWND hWnd) { /* FIXME - copy selection to clipboard */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); + GuiConsoleUpdateSelection(Console, NULL); } } From 4841dde246039b29dc8491390754a651536c4709 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 May 2010 23:41:16 +0000 Subject: [PATCH 028/292] [SMSS] - Add the system environment variables PROCESSOR_LEVEL and PROCESSOR_REVISION. svn path=/trunk/; revision=47336 --- reactos/base/system/smss/initenv.c | 82 +++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/reactos/base/system/smss/initenv.c b/reactos/base/system/smss/initenv.c index 6580b4b6716..24ccc3bb5c4 100644 --- a/reactos/base/system/smss/initenv.c +++ b/reactos/base/system/smss/initenv.c @@ -66,20 +66,27 @@ NTSTATUS SmSetEnvironmentVariables(VOID) { SYSTEM_BASIC_INFORMATION BasicInformation; - + SYSTEM_PROCESSOR_INFORMATION ProcessorInformation; RTL_QUERY_REGISTRY_TABLE QueryTable[3]; UNICODE_STRING Identifier; UNICODE_STRING VendorIdentifier; WCHAR Buffer[256]; - UNICODE_STRING EnvironmentKeyName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE EnvironmentKey; UNICODE_STRING VariableName; PWSTR VariableData; - NTSTATUS Status; + Status = NtQuerySystemInformation(SystemProcessorInformation, + &ProcessorInformation, + sizeof(SYSTEM_PROCESSOR_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to retrieve system processor information (Status %08lx)", Status); + return Status; + } Status = NtQuerySystemInformation(SystemBasicInformation, &BasicInformation, @@ -149,17 +156,28 @@ SmSetEnvironmentVariables(VOID) RtlInitUnicodeString(&VariableName, L"PROCESSOR_ARCHITECTURE"); -#ifdef _M_IX86 - VariableData = L"x86"; -#elif _M_MD64 - VariableData = L"AMD64"; -#elif _M_ARM - VariableData = L"ARM"; -#elif _M_PPC - VariableData = L"PPC"; -#else - #error "Unsupported Architecture!\n" -#endif + switch (ProcessorInformation.ProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_INTEL: + VariableData = L"x86"; + break; + + case PROCESSOR_ARCHITECTURE_PPC: + VariableData = L"PPC"; + break; + + case PROCESSOR_ARCHITECTURE_ARM: + VariableData = L"ARM"; + break; + + case PROCESSOR_ARCHITECTURE_AMD64: + VariableData = L"AMD64"; + break; + + default: + VariableData = L"Unknown"; + break; + } Status = NtSetValueKey(EnvironmentKey, &VariableName, @@ -173,6 +191,42 @@ SmSetEnvironmentVariables(VOID) goto done; } + /* Set the 'PROCESSOR_LEVEL' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_LEVEL"); + + swprintf(Buffer, L"%lu", ProcessorInformation.ProcessorLevel); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_LEVEL environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'PROCESSOR_REVISION' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_REVISION"); + + swprintf(Buffer, L"%04x", ProcessorInformation.ProcessorRevision); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_REVISION environment variable (Status %08lx)", Status); + goto done; + } + done: NtClose(EnvironmentKey); From 975502bb74defdd0e80b2af17cb1970a0a379121 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Mon, 24 May 2010 00:04:56 +0000 Subject: [PATCH 029/292] [WIN32CSR] fix tuiconsole svn path=/trunk/; revision=47337 --- .../subsystems/win32/csrss/win32csr/tuiconsole.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c index 5c03f93d590..c9071686e13 100644 --- a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c @@ -124,17 +124,17 @@ TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) } static void FASTCALL -TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, RECT *Region) +TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region) { UINT SrcDelta, DestDelta; LONG i; PBYTE Src, SrcEnd; - Src = ConioCoordToPointer(Buff, Region->left, Region->top); + Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); SrcDelta = Buff->MaxX * 2; SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; DestDelta = ConioRectWidth(Region) * 2; - for (i = Region->top; i <= Region->bottom; i++) + for (i = Region->Top; i <= Region->Bottom; i++) { memcpy(Dest, Src, DestDelta); Src += SrcDelta; @@ -147,7 +147,7 @@ TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, RECT *Region) } static VOID WINAPI -TuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) +TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) { DWORD BytesReturned; PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; @@ -167,8 +167,8 @@ TuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) DPRINT1("HeapAlloc failed\n"); return; } - ConsoleDraw->X = Region->left; - ConsoleDraw->Y = Region->top; + ConsoleDraw->X = Region->Left; + ConsoleDraw->Y = Region->Top; ConsoleDraw->SizeX = ConioRectWidth(Region); ConsoleDraw->SizeY = ConioRectHeight(Region); ConsoleDraw->CursorX = Buff->CurrentX; @@ -188,7 +188,7 @@ TuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) } static VOID WINAPI -TuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY, +TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { DWORD BytesWritten; From c386b1ee3be514e54f208a5c8ae651d37afb8e13 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 24 May 2010 08:51:52 +0000 Subject: [PATCH 030/292] - Revert 47310. Please find a way to enable kmtest only when building the testing cd image, not the installation/live one. svn path=/trunk/; revision=47338 --- reactos/boot/bootdata/hivesys_i386.inf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/boot/bootdata/hivesys_i386.inf b/reactos/boot/bootdata/hivesys_i386.inf index db355022871..f234ee90b98 100644 --- a/reactos/boot/bootdata/hivesys_i386.inf +++ b/reactos/boot/bootdata/hivesys_i386.inf @@ -1076,11 +1076,11 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 ; Kernel-Mode Tests -HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" -HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ImagePath",0x00020000,"system32\drivers\kmtest.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 +;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 +;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" +;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ImagePath",0x00020000,"system32\drivers\kmtest.sys" +;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 +;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 ; Keyboard class driver HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ErrorControl",0x00010001,0x00000000 From c970cbb191dee51ff7fce4b382ed978f059b371a Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 24 May 2010 12:57:03 +0000 Subject: [PATCH 031/292] [WIN32K] When destroying a window, generate a mouse move message, so that the underlying window is notified about the mouse position and can update the pointer if neccessary. Fixes bug #4499 and bug #3893 See issue #4499 for more details. svn path=/trunk/; revision=47339 --- reactos/subsystems/win32/win32k/ntuser/window.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index e9f64d292f4..ca58a3c9369 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -2674,6 +2674,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) PWND Wnd; HWND hWnd; PTHREADINFO ti; + MSG msg; ASSERT_REFS_CO(Window); // FIXME: temp hack? @@ -2811,6 +2812,13 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) } } + /* Generate mouse move message for the next window */ + msg.message = WM_MOUSEMOVE; + msg.wParam = IntGetSysCursorInfo()->ButtonsDown; + msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y); + msg.pt = gpsi->ptCursor; + MsqInsertSystemMessage(&msg); + if (!IntIsWindow(Window->hSelf)) { return TRUE; From 8a591ca9df518d920b7eaced9496255355026214 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 24 May 2010 13:34:08 +0000 Subject: [PATCH 032/292] [WIN32K / WIN32CSR] Get rid of FASTCALL specifier for static functions and functions with no parameters. svn path=/trunk/; revision=47340 --- .../subsystems/win32/csrss/win32csr/exitros.c | 2 +- .../win32/csrss/win32csr/guiconsole.c | 51 ++++++++++--------- .../win32/win32k/include/cursoricon.h | 7 ++- .../win32/win32k/ntuser/cursoricon.c | 6 +-- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/exitros.c b/reactos/subsystems/win32/csrss/win32csr/exitros.c index 5b1195ec727..ca9fecbc188 100644 --- a/reactos/subsystems/win32/csrss/win32csr/exitros.c +++ b/reactos/subsystems/win32/csrss/win32csr/exitros.c @@ -197,7 +197,7 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void); -static void FASTCALL +static void CallInitCommonControls() { static BOOL Initialized = FALSE; diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 0d063d8b31b..b89edbd304e 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -113,7 +113,7 @@ static const COLORREF s_Colors[] = /* FUNCTIONS *****************************************************************/ -static VOID FASTCALL +static VOID GuiConsoleAppendMenuItems(HMENU hMenu, const GUICONSOLE_MENUITEM *Items) { @@ -168,7 +168,7 @@ GuiConsoleAppendMenuItems(HMENU hMenu, }while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } -static VOID FASTCALL +static VOID GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) { HMENU hMenu; @@ -182,14 +182,14 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) } } -static VOID FASTCALL +static VOID GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) { *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); } -static BOOL FASTCALL +static BOOL GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) { HANDLE hProcessToken = NULL; @@ -245,7 +245,7 @@ GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, return TRUE; } -static BOOL FASTCALL +static BOOL GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) { WCHAR szProcessName[MAX_PATH]; @@ -491,7 +491,7 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) RegCloseKey(hKey); } -static void FASTCALL +static void GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { DWORD dwNumSubKeys = 0; @@ -593,7 +593,7 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA } } } -static VOID FASTCALL +static VOID GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { /* @@ -676,7 +676,7 @@ GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd) SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); } -static BOOL FASTCALL +static BOOL GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) { PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; @@ -797,7 +797,7 @@ SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight; } -static VOID FASTCALL +static VOID GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) { RECT oldRect, newRect; @@ -857,7 +857,7 @@ GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) } -static VOID FASTCALL +static VOID GuiConsolePaint(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HDC hDC, @@ -980,7 +980,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, OldFont); } -static VOID FASTCALL +static VOID GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) { HDC hDC; @@ -1035,7 +1035,7 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) EndPaint(hWnd, &ps); } -static VOID FASTCALL +static VOID GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PCSRSS_CONSOLE Console; @@ -1065,7 +1065,7 @@ GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) InvalidateRect(Console->hWindow, &RegionRect, FALSE); } -static VOID FASTCALL +static VOID GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y) { SMALL_RECT CellRect = { x, y, x, y }; @@ -1165,7 +1165,7 @@ GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) return TRUE; } -static VOID FASTCALL +static VOID GuiConsoleHandleTimer(HWND hWnd) { PCSRSS_CONSOLE Console; @@ -1254,7 +1254,7 @@ GuiConsoleHandleTimer(HWND hWnd) } } -static VOID FASTCALL +static VOID GuiConsoleHandleClose(HWND hWnd) { PCSRSS_CONSOLE Console; @@ -1281,7 +1281,7 @@ GuiConsoleHandleClose(HWND hWnd) LeaveCriticalSection(&Console->Lock); } -static VOID FASTCALL +static VOID GuiConsoleHandleNcDestroy(HWND hWnd) { PCSRSS_CONSOLE Console; @@ -1316,7 +1316,7 @@ PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) return Coord; } -static VOID FASTCALL +static VOID GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) { PCSRSS_CONSOLE Console; @@ -1334,7 +1334,7 @@ GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); } -static VOID FASTCALL +static VOID GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) { PCSRSS_CONSOLE Console; @@ -1354,7 +1354,7 @@ GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) ReleaseCapture(); } -static VOID FASTCALL +static VOID GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) { PCSRSS_CONSOLE Console; @@ -1372,7 +1372,7 @@ GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) GuiConsoleUpdateSelection(Console, &c); } -static VOID FASTCALL +static VOID GuiConsoleRightMouseDown(HWND hWnd) { PCSRSS_CONSOLE Console; @@ -1467,7 +1467,7 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiD CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } -static LRESULT FASTCALL +static LRESULT GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData) { LRESULT Ret = TRUE; @@ -1497,7 +1497,7 @@ GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CON return Ret; } -static VOID FASTCALL +static VOID GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) { PCSRSS_CONSOLE Console; @@ -1520,7 +1520,7 @@ GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) minMaxInfo->ptMaxTrackSize.x = windx; minMaxInfo->ptMaxTrackSize.y = windy; } -static VOID FASTCALL +static VOID GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) { PCSRSS_CONSOLE Console; @@ -1576,6 +1576,7 @@ GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) GuiData->WindowSizeLock = FALSE; } } + VOID FASTCALL GuiConsoleHandleScrollbarMenu() @@ -1694,7 +1695,7 @@ GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD return STATUS_SUCCESS; } -static VOID FASTCALL +static VOID GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) { DWORD windx, windy; @@ -2031,7 +2032,7 @@ GuiConsoleGuiThread(PVOID Data) return 1; } -static BOOL FASTCALL +static BOOL GuiInit(VOID) { WNDCLASSEXW wc; diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index f79dca289c8..851428c6c68 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -69,8 +69,8 @@ typedef struct _SYSTEM_CURSORINFO BOOL ScreenSaverRunning; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; -BOOL FASTCALL InitCursorImpl(); -PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(); +BOOL InitCursorImpl(); +PCURICON_OBJECT IntCreateCurIconHandle(); VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process); BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, @@ -81,8 +81,7 @@ BOOL UserSetCursorPos( INT x, INT y, BOOL CallHooks); int UserShowCursor(BOOL bShow); -PSYSTEM_CURSORINFO FASTCALL -IntGetSysCursorInfo(); +PSYSTEM_CURSORINFO IntGetSysCursorInfo(); #define IntReleaseCurIconObject(CurIconObj) \ UserDereferenceObject(CurIconObj) diff --git a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c index 2958bdf7690..832d820a98e 100644 --- a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c @@ -46,7 +46,7 @@ static LIST_ENTRY gCurIconList; SYSTEM_CURSORINFO gSysCursorInfo; -BOOL FASTCALL +BOOL InitCursorImpl() { ExInitializePagedLookasideList(&gProcessLookasideList, @@ -70,7 +70,7 @@ InitCursorImpl() return TRUE; } -PSYSTEM_CURSORINFO FASTCALL +PSYSTEM_CURSORINFO IntGetSysCursorInfo() { return &gSysCursorInfo; @@ -378,7 +378,7 @@ IntFindExistingCurIconObject(HMODULE hModule, return NULL; } -PCURICON_OBJECT FASTCALL +PCURICON_OBJECT IntCreateCurIconHandle() { PCURICON_OBJECT CurIcon; From d1f4ced4ab172e972e87fe13033536f9157e1d7d Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Mon, 24 May 2010 20:53:32 +0000 Subject: [PATCH 033/292] [USETUP] - Check for required minimum disk space eventually warn the user. - Added Italian and Spanish warnings, the other languages need translation. - Patch by R.T.Sivakumar modified by me. See issue #3302 for more details. svn path=/trunk/; revision=47341 --- reactos/base/setup/usetup/errorcode.h | 1 + reactos/base/setup/usetup/interface/usetup.c | 46 +++++++++++++++++++- reactos/base/setup/usetup/lang/bg-BG.h | 6 +++ reactos/base/setup/usetup/lang/en-US.h | 6 +++ reactos/base/setup/usetup/lang/es-ES.h | 8 +++- reactos/base/setup/usetup/lang/et-EE.h | 6 +++ reactos/base/setup/usetup/lang/fr-FR.h | 6 +++ reactos/base/setup/usetup/lang/it-IT.h | 6 +++ reactos/base/setup/usetup/lang/ja-JP.h | 6 +++ reactos/base/setup/usetup/lang/lt-LT.h | 6 +++ reactos/base/setup/usetup/lang/nl-NL.h | 6 +++ reactos/base/setup/usetup/lang/pl-PL.h | 6 +++ reactos/base/setup/usetup/lang/ru-RU.h | 6 +++ reactos/base/setup/usetup/lang/sk-SK.h | 6 +++ reactos/base/setup/usetup/lang/sv-SE.h | 6 +++ reactos/base/setup/usetup/lang/uk-UA.h | 6 +++ 16 files changed, 130 insertions(+), 3 deletions(-) diff --git a/reactos/base/setup/usetup/errorcode.h b/reactos/base/setup/usetup/errorcode.h index 4ecc11d35d2..79461a7e39c 100644 --- a/reactos/base/setup/usetup/errorcode.h +++ b/reactos/base/setup/usetup/errorcode.h @@ -65,6 +65,7 @@ typedef enum ERROR_UPDATE_LOCALESETTINGS, ERROR_ADDING_KBLAYOUTS, ERROR_UPDATE_GEOID, + ERROR_INSUFFICIENT_DISKSPACE, ERROR_LAST_ERROR_CODE }ERROR_NUMBER; diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index f2bbd6492dc..5284d28bf69 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -31,6 +31,9 @@ #define NDEBUG #include +/* required free disk space in MB */ +#define MINIMUMDISKSIZE 350 + /* GLOBALS ******************************************************************/ HANDLE ProcessHeap; @@ -1381,6 +1384,31 @@ LayoutSettingsPage(PINPUT_RECORD Ir) return DISPLAY_SETTINGS_PAGE; } +static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) +{ + ULONGLONG m; + /* check for unpartitioned space */ + m = PartEntry->UnpartitionedLength; + m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ + if( m > MINIMUMDISKSIZE) + { + return TRUE; + } + + // check for partitioned space + m = PartEntry->PartInfo[0].PartitionLength.QuadPart; + m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ + if( m < MINIMUMDISKSIZE) + { + /* partition is too small so ask for another partion */ + DPRINT1("Partition too small"); + return FALSE; + } + else + { + return TRUE; + } +} static PAGE_NUMBER SelectPartitionPage(PINPUT_RECORD Ir) @@ -1434,9 +1462,13 @@ SelectPartitionPage(PINPUT_RECORD Ir) { if (AutoPartition) { - PPARTENTRY PartEntry = PartEntry = PartitionList->CurrentPartition; + PPARTENTRY PartEntry = PartitionList->CurrentPartition; ULONG MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */ - + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } CreateNewPartition(PartitionList, MaxSize, TRUE); @@ -1446,6 +1478,11 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else { + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } return(SELECT_FILE_SYSTEM_PAGE); } } @@ -1489,6 +1526,11 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } if (PartitionList->CurrentPartition == NULL || PartitionList->CurrentPartition->Unpartitioned == TRUE) { diff --git a/reactos/base/setup/usetup/lang/bg-BG.h b/reactos/base/setup/usetup/lang/bg-BG.h index 23bd1f4ebf3..7063a4d7b78 100644 --- a/reactos/base/setup/usetup/lang/bg-BG.h +++ b/reactos/base/setup/usetup/lang/bg-BG.h @@ -1483,6 +1483,12 @@ MUI_ERROR bgBGErrorEntries[] = "¥ãᯥ譮 ¤®¡ ¢ï­¥ ­  ª« ¢¨ âã୨⥠¯®¤à¥¤¡¨ ¢ ॣ¨áâêà .\n" "ENTER = १ ¯ã᪠­¥ ­  ª®¬¯îâêà " }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " *  â¨á­¥â¥ ª« ¢¨è, §  ¤  ¯à®¤ê«¦¨â¥.", + NULL + }, { //ERROR_UPDATE_GEOID, " áâனª â  ­¥ ¬®¦  ¤  ãáâ ­®¢¨ ®§­ ç¨â¥«ï ­  £¥®£à ä᪮⮠¯®«®¦¥­¨¥.\n" diff --git a/reactos/base/setup/usetup/lang/en-US.h b/reactos/base/setup/usetup/lang/en-US.h index ac694c98c54..ece3f47c66d 100644 --- a/reactos/base/setup/usetup/lang/en-US.h +++ b/reactos/base/setup/usetup/lang/en-US.h @@ -1476,6 +1476,12 @@ MUI_ERROR enUSErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index d951d6b564f..16ce0d1e01c 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -18,7 +18,7 @@ static MUI_ENTRY esESLanguagePageEntries[] = { 6, 8, - "Selecci¢n de idioma", + "Selecci¢n del idioma", TEXT_STYLE_NORMAL }, { @@ -1472,6 +1472,12 @@ MUI_ERROR esESErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "No hay suficiente espacio disponible en la partici¢n seleccionada.\n" + " * Presione una tecla para continuar.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/et-EE.h b/reactos/base/setup/usetup/lang/et-EE.h index 4a1f7bda62b..19d0242cca5 100644 --- a/reactos/base/setup/usetup/lang/et-EE.h +++ b/reactos/base/setup/usetup/lang/et-EE.h @@ -1468,6 +1468,12 @@ MUI_ERROR etEEErrorEntries[] = "Klaviatuuriasetusi ei ännestunud registrisse lisada.\n" "ENTER = Taask„ivita arvuti" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Geograafilist asukohta ei ännestunud seadistada.\n" diff --git a/reactos/base/setup/usetup/lang/fr-FR.h b/reactos/base/setup/usetup/lang/fr-FR.h index ae037aba25f..8e7eb59f9df 100644 --- a/reactos/base/setup/usetup/lang/fr-FR.h +++ b/reactos/base/setup/usetup/lang/fr-FR.h @@ -1484,6 +1484,12 @@ MUI_ERROR frFRErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/it-IT.h b/reactos/base/setup/usetup/lang/it-IT.h index bb220000c84..bc30ae42f59 100644 --- a/reactos/base/setup/usetup/lang/it-IT.h +++ b/reactos/base/setup/usetup/lang/it-IT.h @@ -1472,6 +1472,12 @@ MUI_ERROR itITErrorEntries[] = "Impossibile aggiungere le nazionalit… di tastiera al registro.\n" "INVIO = Riavviare il computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Lo spazio disponibile nella partizione selezionata Š insufficiente.\n" + " * Premere un tasto qualsiasi per continuare.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/ja-JP.h b/reactos/base/setup/usetup/lang/ja-JP.h index af7ccdf2a7e..a697a199565 100644 --- a/reactos/base/setup/usetup/lang/ja-JP.h +++ b/reactos/base/setup/usetup/lang/ja-JP.h @@ -1477,6 +1477,12 @@ MUI_ERROR jaJPErrorEntries[] = "¾¯Ä±¯ÌßÊ geo id ¦ ¾¯Ã² ÃÞ·Ï¾Ý ÃÞ¼À¡\n" "ENTER = ºÝËß­°ÀÉ »²·ÄÞ³" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/lt-LT.h b/reactos/base/setup/usetup/lang/lt-LT.h index a0a9eb485bf..a35dca3e4f7 100644 --- a/reactos/base/setup/usetup/lang/lt-LT.h +++ b/reactos/base/setup/usetup/lang/lt-LT.h @@ -1481,6 +1481,12 @@ MUI_ERROR ltLTErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/nl-NL.h b/reactos/base/setup/usetup/lang/nl-NL.h index eba2d93ad5c..0f0e8651737 100644 --- a/reactos/base/setup/usetup/lang/nl-NL.h +++ b/reactos/base/setup/usetup/lang/nl-NL.h @@ -1499,6 +1499,12 @@ MUI_ERROR nlNLErrorEntries[] = "Setup kan de toetsenbord indelingen niet toevoegen aan de registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup kan de geografische positie niet instellen.\n" diff --git a/reactos/base/setup/usetup/lang/pl-PL.h b/reactos/base/setup/usetup/lang/pl-PL.h index 8d4262d58cd..4fd8b99f7ef 100644 --- a/reactos/base/setup/usetup/lang/pl-PL.h +++ b/reactos/base/setup/usetup/lang/pl-PL.h @@ -1480,6 +1480,12 @@ MUI_ERROR plPLErrorEntries[] = "Instalator nie m¢gˆ doda† ukˆad¢w klawiatury do rejestru.\n" "ENTER = Restart komputera" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Instalator nie m¢gˆ ustawi† lokalizacji geograficznej.\n" diff --git a/reactos/base/setup/usetup/lang/ru-RU.h b/reactos/base/setup/usetup/lang/ru-RU.h index 7e55b9700bb..1fb41377e50 100644 --- a/reactos/base/setup/usetup/lang/ru-RU.h +++ b/reactos/base/setup/usetup/lang/ru-RU.h @@ -1472,6 +1472,12 @@ MUI_ERROR ruRUErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/sk-SK.h b/reactos/base/setup/usetup/lang/sk-SK.h index 5078f08139f..355c4946e64 100644 --- a/reactos/base/setup/usetup/lang/sk-SK.h +++ b/reactos/base/setup/usetup/lang/sk-SK.h @@ -1482,6 +1482,12 @@ MUI_ERROR skSKErrorEntries[] = "Inçtal tor zlyhal pri prid van¡ rozlo§en¡ kl vesnice do registrov.\n" "ENTER = Reçtart poŸ¡taŸa" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Inçtal tor nemohol nastaviœ geo id.\n" diff --git a/reactos/base/setup/usetup/lang/sv-SE.h b/reactos/base/setup/usetup/lang/sv-SE.h index 0dbffdc453c..cc3c3569e30 100644 --- a/reactos/base/setup/usetup/lang/sv-SE.h +++ b/reactos/base/setup/usetup/lang/sv-SE.h @@ -1472,6 +1472,12 @@ MUI_ERROR svSEErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "Setup could not set the geo id.\n" diff --git a/reactos/base/setup/usetup/lang/uk-UA.h b/reactos/base/setup/usetup/lang/uk-UA.h index ba3fd009623..ebdea9232f0 100644 --- a/reactos/base/setup/usetup/lang/uk-UA.h +++ b/reactos/base/setup/usetup/lang/uk-UA.h @@ -1478,6 +1478,12 @@ MUI_ERROR ukUAErrorEntries[] = "¥ ¢¤ «®áì ¤®¤ â¨ à®§ª« ¤ª¨ ª« ¢i âãਠ¤® à¥óáâàã.\n" "ENTER = ¥à¥§ ¢ ­â ¦¨â¨ ª®¬¯'îâ¥à" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { //ERROR_UPDATE_GEOID, "¥ ¢¤ «®áì ¢áâ ­®¢¨â¨ geo id.\n" From 6ed709da3de6c455a43f994d06dea11a8ec71385 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 24 May 2010 21:08:06 +0000 Subject: [PATCH 034/292] [USETUP] - Add german translation of required minimum disk space warning. svn path=/trunk/; revision=47342 --- reactos/base/setup/usetup/lang/de-DE.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/base/setup/usetup/lang/de-DE.h b/reactos/base/setup/usetup/lang/de-DE.h index e21b2ffc001..942890cd2ec 100644 --- a/reactos/base/setup/usetup/lang/de-DE.h +++ b/reactos/base/setup/usetup/lang/de-DE.h @@ -1477,7 +1477,13 @@ MUI_ERROR deDEErrorEntries[] = "Setup konnte den geografischen Standort nicht einstellen.\n" "ENTER = Computer neu starten" }, -{ + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Nicht genug Speicherplatz auf der gew„hlten Partition vorhanden.\n" + " * Eine beliebige Taste zum Fortsetzen drcken.", + NULL + }, + { NULL, NULL } From bd925f8147c78c9b2fc53406a5edd935d5c1a385 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 24 May 2010 21:43:51 +0000 Subject: [PATCH 035/292] [USETUP] Made the 'Copying file...' status line message left aligned like all the other status line messages. svn path=/trunk/; revision=47343 --- reactos/base/setup/usetup/interface/usetup.c | 2 +- reactos/base/setup/usetup/lang/bg-BG.h | 2 +- reactos/base/setup/usetup/lang/cs-CZ.h | 2 +- reactos/base/setup/usetup/lang/de-DE.h | 2 +- reactos/base/setup/usetup/lang/el-GR.h | 2 +- reactos/base/setup/usetup/lang/en-US.h | 2 +- reactos/base/setup/usetup/lang/es-ES.h | 2 +- reactos/base/setup/usetup/lang/et-EE.h | 4 ++-- reactos/base/setup/usetup/lang/fr-FR.h | 2 +- reactos/base/setup/usetup/lang/it-IT.h | 2 +- reactos/base/setup/usetup/lang/ja-JP.h | 2 +- reactos/base/setup/usetup/lang/lt-LT.h | 2 +- reactos/base/setup/usetup/lang/nl-NL.h | 2 +- reactos/base/setup/usetup/lang/pl-PL.h | 2 +- reactos/base/setup/usetup/lang/ru-RU.h | 2 +- reactos/base/setup/usetup/lang/sk-SK.h | 2 +- reactos/base/setup/usetup/lang/sv-SE.h | 2 +- reactos/base/setup/usetup/lang/uk-UA.h | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 5284d28bf69..6fc226aa5d6 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -3163,7 +3163,7 @@ FileCopyCallback(PVOID Context, case SPFILENOTIFY_STARTCOPY: /* Display copy message */ - CONSOLE_SetStatusTextAutoFitX (45 , MUIGetString(STRING_COPYING), (PWSTR)Param1); + CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), (PWSTR)Param1); SetupUpdateMemoryInfo(CopyContext, FALSE); break; diff --git a/reactos/base/setup/usetup/lang/bg-BG.h b/reactos/base/setup/usetup/lang/bg-BG.h index 7063a4d7b78..074f6baac6e 100644 --- a/reactos/base/setup/usetup/lang/bg-BG.h +++ b/reactos/base/setup/usetup/lang/bg-BG.h @@ -1632,7 +1632,7 @@ MUI_STRING bgBGStrings[] = {STRING_TXTSETUPFAILED, "¥ ¡¥ ­ ¬¥à¥­ à §¤¥« '%S'\n¢ TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 ‡ ¯¨á ­  ä ©«: %S"}, + " ‡ ¯¨á ­  ä ©«: %S"}, {STRING_SETUPCOPYINGFILES, "’¥ç¥ § ¯¨á¢ ­¥ ­  ä ©«®¢¥â¥..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/cs-CZ.h b/reactos/base/setup/usetup/lang/cs-CZ.h index b3397e14751..08fedbbafcd 100644 --- a/reactos/base/setup/usetup/lang/cs-CZ.h +++ b/reactos/base/setup/usetup/lang/cs-CZ.h @@ -1622,7 +1622,7 @@ MUI_STRING csCZStrings[] = {STRING_TXTSETUPFAILED, "Nepodaýilo se naj¡t sekci '%S' v souboru\n TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kop¡ruji soubor: %S"}, + " Kop¡ruji soubor: %S"}, {STRING_SETUPCOPYINGFILES, "Instalace kop¡ruje soubory..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/de-DE.h b/reactos/base/setup/usetup/lang/de-DE.h index 942890cd2ec..4686873427a 100644 --- a/reactos/base/setup/usetup/lang/de-DE.h +++ b/reactos/base/setup/usetup/lang/de-DE.h @@ -1621,7 +1621,7 @@ MUI_STRING deDEStrings[] = {STRING_TXTSETUPFAILED, "Setup konnte die '%S'-Sektion\nin TXTSETUP.SIF nicht finden.\n"}, {STRING_COPYING, - "\xB3 Kopiere Datei: %S"}, + " Kopiere Datei: %S"}, {STRING_SETUPCOPYINGFILES, "Setup kopiert Dateien..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/el-GR.h b/reactos/base/setup/usetup/lang/el-GR.h index e04f530f674..66de19aa71a 100644 --- a/reactos/base/setup/usetup/lang/el-GR.h +++ b/reactos/base/setup/usetup/lang/el-GR.h @@ -1644,7 +1644,7 @@ MUI_STRING elGRStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 €¤« š¨á­œ«˜  «¦ ˜¨®œå¦: %S"}, + " €¤« š¨á­œ«˜  «¦ ˜¨®œå¦: %S"}, {STRING_SETUPCOPYINGFILES, "† œš¡˜«á©«˜©ž ˜¤« š¨á­œ  ˜¨®œå˜..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/en-US.h b/reactos/base/setup/usetup/lang/en-US.h index ece3f47c66d..1467dc764dc 100644 --- a/reactos/base/setup/usetup/lang/en-US.h +++ b/reactos/base/setup/usetup/lang/en-US.h @@ -1619,7 +1619,7 @@ MUI_STRING enUSStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index 16ce0d1e01c..4a57ed705c5 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -1620,7 +1620,7 @@ MUI_STRING esESStrings[] = {STRING_TXTSETUPFAILED, "El instalador fall¢ al buscar la secci¢n\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copiando archivo: %S"}, + " Copiando archivo: %S"}, {STRING_SETUPCOPYINGFILES, "El instalador est  copiando archivos..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/et-EE.h b/reactos/base/setup/usetup/lang/et-EE.h index 19d0242cca5..c4dbf422919 100644 --- a/reactos/base/setup/usetup/lang/et-EE.h +++ b/reactos/base/setup/usetup/lang/et-EE.h @@ -1615,9 +1615,9 @@ MUI_STRING etEEStrings[] = {STRING_REBOOTCOMPUTER, "ENTER = Taask„ivita arvuti"}, {STRING_TXTSETUPFAILED, - "TXTSETUP.SIF failist ei leitud '%S' sektsiooni\n"}, + "TXTSETUP.SIF failist ei leitud '%S' sektsiooni\n"}, {STRING_COPYING, - "\xB3 Kopeerimine: %S"}, + " Kopeerimine: %S"}, {STRING_SETUPCOPYINGFILES, "Failide kopeerimine..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/fr-FR.h b/reactos/base/setup/usetup/lang/fr-FR.h index 8e7eb59f9df..c1790341522 100644 --- a/reactos/base/setup/usetup/lang/fr-FR.h +++ b/reactos/base/setup/usetup/lang/fr-FR.h @@ -1633,7 +1633,7 @@ MUI_STRING frFRStrings[] = {STRING_TXTSETUPFAILED, "Setup n'a pu trouver la section '%S'\ndans TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copie du fichier: %S"}, + " Copie du fichier: %S"}, {STRING_SETUPCOPYINGFILES, "Setup copie les fichiers..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/it-IT.h b/reactos/base/setup/usetup/lang/it-IT.h index bc30ae42f59..dc71b330f1f 100644 --- a/reactos/base/setup/usetup/lang/it-IT.h +++ b/reactos/base/setup/usetup/lang/it-IT.h @@ -1621,7 +1621,7 @@ MUI_STRING itITStrings[] = {STRING_TXTSETUPFAILED, "Setup non ha trovato la sezione '%S' \nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copia di: %S"}, + " Copia di: %S"}, {STRING_SETUPCOPYINGFILES, "Copia dei file in corso..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/ja-JP.h b/reactos/base/setup/usetup/lang/ja-JP.h index a697a199565..03b6ec1841d 100644 --- a/reactos/base/setup/usetup/lang/ja-JP.h +++ b/reactos/base/setup/usetup/lang/ja-JP.h @@ -1620,7 +1620,7 @@ MUI_STRING jaJPStrings[] = {STRING_TXTSETUPFAILED, "¾¯Ä±¯ÌßÊ TXTSETUP.SIF É '%S' ¾¸¼®ÝÉ ¹Ý¼­ÂÆ\n¼¯Êß² ¼Ï¼À¡\n"}, {STRING_COPYING, - "\xB3 ºËß° Á­³É ̧²Ù: %S"}, + " ºËß° Á­³É ̧²Ù: %S"}, {STRING_SETUPCOPYINGFILES, "¾¯Ä±¯ÌßÊ Ì§²Ù¦ ºËß° ¼Ã ²Ï½..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/lt-LT.h b/reactos/base/setup/usetup/lang/lt-LT.h index a35dca3e4f7..bb0c26fcc20 100644 --- a/reactos/base/setup/usetup/lang/lt-LT.h +++ b/reactos/base/setup/usetup/lang/lt-LT.h @@ -1630,7 +1630,7 @@ MUI_STRING ltLTStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/nl-NL.h b/reactos/base/setup/usetup/lang/nl-NL.h index 0f0e8651737..2a0b2836b11 100644 --- a/reactos/base/setup/usetup/lang/nl-NL.h +++ b/reactos/base/setup/usetup/lang/nl-NL.h @@ -1648,7 +1648,7 @@ MUI_STRING nlNLStrings[] = {STRING_TXTSETUPFAILED, "Setup kan de '%S' sectie niet vinden\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopieeren bestand: %S"}, + " Kopieeren bestand: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is bestand aan het kopieeren..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/pl-PL.h b/reactos/base/setup/usetup/lang/pl-PL.h index 4fd8b99f7ef..28af7348ae3 100644 --- a/reactos/base/setup/usetup/lang/pl-PL.h +++ b/reactos/base/setup/usetup/lang/pl-PL.h @@ -1629,7 +1629,7 @@ MUI_STRING plPLStrings[] = {STRING_TXTSETUPFAILED, "Instalator nie byˆ w stanie odnale«† sekji '%S'\nw pliku TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopiowanie plik¢w: %S"}, + " Kopiowanie plik¢w: %S"}, {STRING_SETUPCOPYINGFILES, "Instalator kopiuje pliki..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/ru-RU.h b/reactos/base/setup/usetup/lang/ru-RU.h index 1fb41377e50..ddf6062b62a 100644 --- a/reactos/base/setup/usetup/lang/ru-RU.h +++ b/reactos/base/setup/usetup/lang/ru-RU.h @@ -1621,7 +1621,7 @@ MUI_STRING ruRUStrings[] = {STRING_TXTSETUPFAILED, "ணࠬ¬  ãáâ ­®¢ª¨ ­¥ ᬮ£«  ­ ©â¨ ᥪæ¨î '%S'\n¢ ä ©«¥ TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Š®¯¨à®¢ ­¨¥: %S"}, + " Š®¯¨à®¢ ­¨¥: %S"}, {STRING_SETUPCOPYINGFILES, "ணࠬ¬  ãáâ ­®¢ª¨ ª®¯¨àã¥â ä ©«ë..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/sk-SK.h b/reactos/base/setup/usetup/lang/sk-SK.h index 355c4946e64..3a003761748 100644 --- a/reactos/base/setup/usetup/lang/sk-SK.h +++ b/reactos/base/setup/usetup/lang/sk-SK.h @@ -1631,7 +1631,7 @@ MUI_STRING skSKStrings[] = {STRING_TXTSETUPFAILED, "Inçtal tor zlyhal pri h–adan¡ sekcie '%S'\nv s£bore TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kop¡ruje sa s£bor: %S"}, + " Kop¡ruje sa s£bor: %S"}, {STRING_SETUPCOPYINGFILES, "Inçtal tor kop¡ruje s£bory..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/sv-SE.h b/reactos/base/setup/usetup/lang/sv-SE.h index cc3c3569e30..352bb6c8124 100644 --- a/reactos/base/setup/usetup/lang/sv-SE.h +++ b/reactos/base/setup/usetup/lang/sv-SE.h @@ -1620,7 +1620,7 @@ MUI_STRING svSEStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/reactos/base/setup/usetup/lang/uk-UA.h b/reactos/base/setup/usetup/lang/uk-UA.h index ebdea9232f0..1227dfe6188 100644 --- a/reactos/base/setup/usetup/lang/uk-UA.h +++ b/reactos/base/setup/usetup/lang/uk-UA.h @@ -1626,7 +1626,7 @@ MUI_STRING ukUAStrings[] = {STRING_TXTSETUPFAILED, "‚áâ ­®¢«î¢ ç ­¥ §¬i£ §­ ©â¨ ᥪæiî '%S' \n¢ ä ©«i TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Š®¯i­­ï: %S"}, + " Š®¯i­­ï: %S"}, {STRING_SETUPCOPYINGFILES, "‚áâ ­®¢«î¢ ç ª®¯iîó ä ©«¨..."}, {STRING_REGHIVEUPDATE, From 1605abd1bc66316bde23dd82cb0e5543c04cd1bf Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 24 May 2010 22:32:23 +0000 Subject: [PATCH 036/292] [USETUP] Make the required minimum disk space configurable from the txtsetup.sif file. svn path=/trunk/; revision=47345 --- reactos/base/setup/usetup/interface/usetup.c | 25 ++++++++++++++++---- reactos/boot/bootdata/txtsetup.sif | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 6fc226aa5d6..63738b320c4 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -31,8 +31,6 @@ #define NDEBUG #include -/* required free disk space in MB */ -#define MINIMUMDISKSIZE 350 /* GLOBALS ******************************************************************/ @@ -84,6 +82,8 @@ static PGENERIC_LIST LanguageList = NULL; static LANGID LanguageId = 0; +static ULONG RequiredPartitionDiskSpace = ~0; + /* FUNCTIONS ****************************************************************/ static VOID @@ -723,6 +723,7 @@ SetupStartPage(PINPUT_RECORD Ir) UINT ErrorLine; ULONG ReturnSize; PGENERIC_LIST_ENTRY ListEntry; + INT IntValue; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); @@ -803,6 +804,22 @@ SetupStartPage(PINPUT_RECORD Ir) return QUIT_PAGE; } + /* Open 'DiskSpaceRequirements' section */ + if (!SetupFindFirstLineW(SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) + { + MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; + } + + /* Get the 'FreeSysPartDiskSpace' value */ + if (!SetupGetIntField(&Context, 1, &IntValue)) + { + MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; + } + + RequiredPartitionDiskSpace = (ULONG)IntValue; + /* Start PnP thread */ if (hPnpThread != INVALID_HANDLE_VALUE) { @@ -1390,7 +1407,7 @@ static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) /* check for unpartitioned space */ m = PartEntry->UnpartitionedLength; m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ - if( m > MINIMUMDISKSIZE) + if( m > RequiredPartitionDiskSpace) { return TRUE; } @@ -1398,7 +1415,7 @@ static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) // check for partitioned space m = PartEntry->PartInfo[0].PartitionLength.QuadPart; m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ - if( m < MINIMUMDISKSIZE) + if( m < RequiredPartitionDiskSpace) { /* partition is too small so ask for another partion */ DPRINT1("Partition too small"); diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index 35f1c761937..704228d07f7 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -11,6 +11,10 @@ Signature = "$ReactOS$" 6 = Fonts 7 = bin +[DiskSpaceRequirements] +; Required free system partition disk space in MB +FreeSysPartDiskSpace=350 + [SourceDisksFiles] acpi.sys=,,,,,,,,,,,,4 uniata.sys=,,,,,,x,,,,,,4 From d514045177e3d94bb67368fd648a59829bdaebf0 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Tue, 25 May 2010 08:16:09 +0000 Subject: [PATCH 037/292] [USETUP] - Polish and Czech (#5429) translations of required disk space by Maciej Bialas and Radek Liska - Some fixes and updates to Italian and Spanish resources svn path=/trunk/; revision=47346 --- reactos/base/setup/usetup/lang/cs-CZ.h | 14 ++++++++++---- reactos/base/setup/usetup/lang/es-ES.h | 8 ++++---- reactos/base/setup/usetup/lang/it-IT.h | 4 ++-- reactos/base/setup/usetup/lang/pl-PL.h | 4 ++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/reactos/base/setup/usetup/lang/cs-CZ.h b/reactos/base/setup/usetup/lang/cs-CZ.h index 08fedbbafcd..428b0f55fea 100644 --- a/reactos/base/setup/usetup/lang/cs-CZ.h +++ b/reactos/base/setup/usetup/lang/cs-CZ.h @@ -1,7 +1,7 @@ /* FILE: setup/usetup/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) * THANKS TO: preston - * UPDATED: 2008-06-05 + * UPDATED: 2010-05-25 */ #pragma once @@ -1481,8 +1481,14 @@ MUI_ERROR csCZErrorEntries[] = }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "Nepodaýilo se nastavit geo id.\n" + "ENTER = Restartovat poŸ¡taŸ" + }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Na zvolen‚m odd¡lu nen¡ dost voln‚ho m¡sta.\n" + " * PokraŸujte stisknut¡m libovoln‚ kl vesy.", + NULL }, { NULL, @@ -1662,7 +1668,7 @@ MUI_STRING csCZStrings[] = {STRING_HDDINFOUNK1, "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)."}, {STRING_HDDINFOUNK2, - " %c%c Type %lu %I64u %s"}, + " %c%c Typ %lu %I64u %s"}, {STRING_HDINFOPARTDELETE, "na %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) na %wZ."}, {STRING_HDDINFOUNK3, diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index 4a57ed705c5..1d5599f720f 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -1469,8 +1469,8 @@ MUI_ERROR esESErrorEntries[] = }, { //ERROR_ADDING_KBLAYOUTS, - "Setup failed to add keyboard layouts to registry.\n" - "ENTER = Reboot computer" + "El instalador no ha podido agregar los layouts de teclado al registro.\n" + "ENTER = Reiniciar el equipo" }, { //ERROR_INSUFFICIENT_DISKSPACE, @@ -1480,8 +1480,8 @@ MUI_ERROR esESErrorEntries[] = }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "El instalador no ha podido configurar el ID geogr fico.\n" + "ENTER = Reiniciar el equipo" }, { NULL, diff --git a/reactos/base/setup/usetup/lang/it-IT.h b/reactos/base/setup/usetup/lang/it-IT.h index dc71b330f1f..81bb197c760 100644 --- a/reactos/base/setup/usetup/lang/it-IT.h +++ b/reactos/base/setup/usetup/lang/it-IT.h @@ -1480,8 +1480,8 @@ MUI_ERROR itITErrorEntries[] = }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "Setup non ha potuto impostare l'id geografico.\n" + "INVIO = Riavviare il computer" }, { NULL, diff --git a/reactos/base/setup/usetup/lang/pl-PL.h b/reactos/base/setup/usetup/lang/pl-PL.h index 28af7348ae3..104f8a1e41b 100644 --- a/reactos/base/setup/usetup/lang/pl-PL.h +++ b/reactos/base/setup/usetup/lang/pl-PL.h @@ -1482,8 +1482,8 @@ MUI_ERROR plPLErrorEntries[] = }, { //ERROR_INSUFFICIENT_DISKSPACE, - "Not enough free space in the selected partition.\n" - " * Press any key to continue.", + "Brak wystarczaj¥cej wolnej przestrzeni w wybranej partycji.\n" + " * Naci˜nij dowolny klawisz aby kontynuowa†.", NULL }, { From bb079cacb0a6a06e06eab433580d43f68e9550a2 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Tue, 25 May 2010 10:33:13 +0000 Subject: [PATCH 038/292] [win32k] - Minor revert of 47281 to fix OO installer textboxes. svn path=/trunk/; revision=47348 --- reactos/subsystems/win32/win32k/ntuser/window.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index ca58a3c9369..409770d891a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -2228,9 +2228,6 @@ AllocErr: if (Size.cy < MinTrack.y) Size.cy = MinTrack.y; } - if (Size.cx < 0) Size.cx = 0; - if (Size.cy < 0) Size.cy = 0; - Wnd->rcWindow.left = Pos.x; Wnd->rcWindow.top = Pos.y; Wnd->rcWindow.right = Pos.x + Size.cx; From 71d693cef0f72fb06a6d030c98e0ac5cd8527e3f Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 25 May 2010 11:41:29 +0000 Subject: [PATCH 039/292] [WIN32K] Delete old clipregion only and set a new one, if it could be created already, to avoid setting a NULL region. See issue #4431 for more details. svn path=/trunk/; revision=47349 --- .../subsystems/win32/win32k/objects/cliprgn.c | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/cliprgn.c b/reactos/subsystems/win32/win32k/objects/cliprgn.c index c5297c38ba2..77415e686b6 100644 --- a/reactos/subsystems/win32/win32k/objects/cliprgn.c +++ b/reactos/subsystems/win32/win32k/objects/cliprgn.c @@ -60,24 +60,28 @@ CLIPPING_UpdateGCRegion(DC* Dc) NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y); - if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) - { - if (Dc->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) + { + CLIPOBJ *CombinedClip; + + CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount, + CombinedRegion->Buffer, + &CombinedRegion->rdh.rcBound); - Dc->rosdc.CombinedClip = IntEngCreateClipRegion( - CombinedRegion->rdh.nCount, - CombinedRegion->Buffer, - &CombinedRegion->rdh.rcBound); + RGNOBJAPI_Unlock(CombinedRegion); - RGNOBJAPI_Unlock(CombinedRegion); - } + if (!CombinedClip) + { + DPRINT1("IntEngCreateClipRegion() failed\n"); + return ERROR; + } + + if (Dc->rosdc.CombinedClip != NULL) + IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + + Dc->rosdc.CombinedClip = CombinedClip; + } - if ( NULL == Dc->rosdc.CombinedClip ) - { - DPRINT1("IntEngCreateClipRegion() failed\n"); - return ERROR; - } return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y); } @@ -607,9 +611,6 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); - if (pDC->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); - // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build // the rects from region objects rects in pClipRgn->Buffer. // With pDC->co.pClipRgn->Buffer, @@ -619,7 +620,13 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) ((PROSRGNDATA)pDC->prgnRao)->Buffer, &pDC->erclClip); - pDC->rosdc.CombinedClip = co; + if (co) + { + if (pDC->rosdc.CombinedClip != NULL) + IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); + + pDC->rosdc.CombinedClip = co; + } return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y); } From 714a181969bca35c5da6bc0c0c0981f663e6d09c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 25 May 2010 11:55:04 +0000 Subject: [PATCH 040/292] [WIN32K] Refactor NtGdiGradientFill, use 1 SEH block instead of 2, replace IntGdiGradientFill with GreGradientFill, don't lock the DC in UserDrawCaption. svn path=/trunk/; revision=47350 --- .../subsystems/win32/win32k/include/intgdi.h | 11 +- .../subsystems/win32/win32k/ntuser/painting.c | 11 +- .../win32/win32k/objects/fillshap.c | 228 ++++++++---------- 3 files changed, 113 insertions(+), 137 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index 1b7a700c32f..d547ba460d6 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -122,10 +122,15 @@ IntGdiPolyPolygon(DC *dc, PULONG PolyCounts, int Count); -BOOL FASTCALL IntGdiGradientFill(DC *dc, +BOOL +NTAPI +GreGradientFill( + HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, - PVOID pMesh, ULONG uMesh, ULONG ulMode); + ULONG nVertex, + PVOID pMesh, + ULONG nMesh, + ULONG ulMode); /* DC functions */ diff --git a/reactos/subsystems/win32/win32k/ntuser/painting.c b/reactos/subsystems/win32/win32k/ntuser/painting.c index 0e042410757..2564bac103f 100644 --- a/reactos/subsystems/win32/win32k/ntuser/painting.c +++ b/reactos/subsystems/win32/win32k/ntuser/painting.c @@ -1782,7 +1782,6 @@ BOOL UserDrawCaption( static GRADIENT_RECT gcap = {0, 1}; TRIVERTEX vert[2]; COLORREF Colors[2]; - PDC pMemDc; if (Wnd != NULL) { @@ -1835,20 +1834,12 @@ BOOL UserDrawCaption( vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00; vert[1].Alpha = 0; - pMemDc = DC_LockDc(hMemDc); - if(!pMemDc) - { - DPRINT1("%s: Can't lock dc!\n", __FUNCTION__); - goto cleanup; - } - - if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap, + if(!GreGradientFill(hMemDc, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_H)) { DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__); } - DC_UnlockDc(pMemDc); } //if(uFlags & DC_GRADIENT) } diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index aa133f87f52..87304e3c729 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -837,40 +837,36 @@ NtGdiRoundRect( return ret; } -BOOL FASTCALL -IntGdiGradientFill( - DC *dc, +BOOL +NTAPI +GreGradientFill( + HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, + ULONG nVertex, PVOID pMesh, - ULONG uMesh, + ULONG nMesh, ULONG ulMode) { + PDC pdc; SURFACE *psurf; - PPALETTE PalDestGDI; + PPALETTE ppal; EXLATEOBJ exlo; - RECTL Extent; - POINTL DitherOrg; + RECTL rclExtent; + POINTL ptlDitherOrg; ULONG i; - BOOL Ret; + BOOL bRet; HPALETTE hDestPalette; - ASSERT(dc); - ASSERT(pVertex); - ASSERT(uVertex); - ASSERT(pMesh); - ASSERT(uMesh); - - /* check parameters */ - if (ulMode & GRADIENT_FILL_TRIANGLE) + /* Check parameters */ + if (ulMode == GRADIENT_FILL_TRIANGLE) { - PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh; + PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh; - for (i = 0; i < uMesh; i++, tr++) + for (i = 0; i < nMesh; i++, pTriangle++) { - if (tr->Vertex1 >= uVertex || - tr->Vertex2 >= uVertex || - tr->Vertex3 >= uVertex) + if (pTriangle->Vertex1 >= nVertex || + pTriangle->Vertex2 >= nVertex || + pTriangle->Vertex3 >= nVertex) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; @@ -879,10 +875,10 @@ IntGdiGradientFill( } else { - PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh; - for (i = 0; i < uMesh; i++, rc++) + PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh; + for (i = 0; i < nMesh; i++, pRect++) { - if (rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex) + if (pRect->UpperLeft >= nVertex || pRect->LowerRight >= nVertex) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; @@ -890,56 +886,76 @@ IntGdiGradientFill( } } - /* calculate extent */ - Extent.left = Extent.right = pVertex->x; - Extent.top = Extent.bottom = pVertex->y; - for (i = 0; i < uVertex; i++) + /* Lock the output DC */ + pdc = DC_LockDc(hdc); + if (!pdc) { - Extent.left = min(Extent.left, (pVertex + i)->x); - Extent.right = max(Extent.right, (pVertex + i)->x); - Extent.top = min(Extent.top, (pVertex + i)->y); - Extent.bottom = max(Extent.bottom, (pVertex + i)->y); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; } - IntLPtoDP(dc, (LPPOINT)&Extent, 2); - Extent.left += dc->ptlDCOrig.x; - Extent.right += dc->ptlDCOrig.x; - Extent.top += dc->ptlDCOrig.y; - Extent.bottom += dc->ptlDCOrig.y; + if (pdc->dctype == DC_TYPE_INFO) + { + DC_UnlockDc(pdc); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; + } - DitherOrg.x = DitherOrg.y = 0; - IntLPtoDP(dc, (LPPOINT)&DitherOrg, 1); + psurf = pdc->dclevel.pSurface; + if (!psurf) + { + /* Memory DC with no surface selected */ + DC_UnlockDc(pdc); + return TRUE; // CHECKME + } - DitherOrg.x += dc->ptlDCOrig.x; - DitherOrg.y += dc->ptlDCOrig.y; + /* calculate extent */ + rclExtent.left = rclExtent.right = pVertex->x; + rclExtent.top = rclExtent.bottom = pVertex->y; + for (i = 0; i < nVertex; i++) + { + rclExtent.left = min(rclExtent.left, (pVertex + i)->x); + rclExtent.right = max(rclExtent.right, (pVertex + i)->x); + rclExtent.top = min(rclExtent.top, (pVertex + i)->y); + rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y); + } - psurf = dc->dclevel.pSurface; - /* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */ - ASSERT(psurf); + IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2); + rclExtent.left += pdc->ptlDCOrig.x; + rclExtent.right += pdc->ptlDCOrig.x; + rclExtent.top += pdc->ptlDCOrig.y; + rclExtent.bottom += pdc->ptlDCOrig.y; + + ptlDitherOrg.x = ptlDitherOrg.y = 0; + IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1); + ptlDitherOrg.x += pdc->ptlDCOrig.x; + ptlDitherOrg.y += pdc->ptlDCOrig.y; hDestPalette = psurf->hDIBPalette; if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault; - PalDestGDI = PALETTE_LockPalette(hDestPalette); - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0); + ppal = PALETTE_LockPalette(hDestPalette); + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0); - Ret = IntEngGradientFill(&psurf->SurfObj, - dc->rosdc.CombinedClip, - &exlo.xlo, - pVertex, - uVertex, - pMesh, - uMesh, - &Extent, - &DitherOrg, - ulMode); + ASSERT(pdc->rosdc.CombinedClip); + + bRet = IntEngGradientFill(&psurf->SurfObj, + pdc->rosdc.CombinedClip, + &exlo.xlo, + pVertex, + nVertex, + pMesh, + nMesh, + &rclExtent, + &ptlDitherOrg, + ulMode); EXLATEOBJ_vCleanup(&exlo); - if (PalDestGDI) - PALETTE_UnlockPalette(PalDestGDI); + if (ppal) + PALETTE_UnlockPalette(ppal); - return Ret; + return bRet; } BOOL @@ -947,33 +963,19 @@ APIENTRY NtGdiGradientFill( HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, + ULONG nVertex, PVOID pMesh, - ULONG uMesh, + ULONG nMesh, ULONG ulMode) { - DC *dc; - BOOL Ret; + BOOL bRet; PTRIVERTEX SafeVertex; PVOID SafeMesh; - ULONG SizeMesh; - NTSTATUS Status = STATUS_SUCCESS; + ULONG cbVertex, cbMesh; - dc = DC_LockDc(hdc); - if (!dc) + /* Validate parameters */ + if (!pVertex || !nVertex || !pMesh || !nMesh) { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - if (dc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(dc); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } - if (!pVertex || !uVertex || !pMesh || !uMesh) - { - DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } @@ -982,77 +984,55 @@ NtGdiGradientFill( { case GRADIENT_FILL_RECT_H: case GRADIENT_FILL_RECT_V: - SizeMesh = uMesh * sizeof(GRADIENT_RECT); + cbMesh = nMesh * sizeof(GRADIENT_RECT); break; case GRADIENT_FILL_TRIANGLE: - SizeMesh = uMesh * sizeof(TRIVERTEX); + cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE); break; default: - DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } - _SEH2_TRY + cbVertex = nVertex * sizeof(TRIVERTEX); + if (cbVertex + cbMesh <= cbVertex) { - ProbeForRead(pVertex, - uVertex * sizeof(TRIVERTEX), - 1); - ProbeForRead(pMesh, - SizeMesh, - 1); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - SetLastWin32Error(Status); + /* Overflow */ return FALSE; } - if (!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE))) + /* Allocate a kernel mode buffer */ + SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE); + if (!SafeVertex) { - DC_UnlockDc(dc); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex); + SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex); + /* Copy the parameters to kernel mode */ _SEH2_TRY { - /* pointers were already probed! */ - RtlCopyMemory(SafeVertex, - pVertex, - uVertex * sizeof(TRIVERTEX)); - RtlCopyMemory(SafeMesh, - pMesh, - SizeMesh); + ProbeForRead(pVertex, cbVertex, 1); + ProbeForRead(pMesh, cbMesh, 1); + RtlCopyMemory(SafeVertex, pVertex, cbVertex); + RtlCopyMemory(SafeMesh, pMesh, cbMesh); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + ExFreePoolWithTag(SafeVertex, TAG_SHAPE); + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return FALSE;) } _SEH2_END; - if (!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - ExFreePoolWithTag(SafeVertex, TAG_SHAPE); - SetLastNtError(Status); - return FALSE; - } + /* Call the internal function */ + bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode); - Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode); - - DC_UnlockDc(dc); - ExFreePool(SafeVertex); - return Ret; + /* Cleanup and return result */ + ExFreePoolWithTag(SafeVertex, TAG_SHAPE); + return bRet; } BOOL APIENTRY From 7f82a194fa044f87b741d3b642fa9f13a737421c Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Tue, 25 May 2010 13:42:30 +0000 Subject: [PATCH 041/292] [USETUP] - Estonian translation of minimum disk space required by Andres Traks #3302. [USERENV] - Fix mistakenly translated strings "recent" and "sendto" in Italian and Spanish resources, plus another Spanish fix. Several Czech translation updates by Radek Liska #5429. svn path=/trunk/; revision=47351 --- .../applications/games/winemine/lang/cs-CZ.rc | 16 +-- .../base/applications/notepad/lang/cs-CZ.rc | 8 +- reactos/base/applications/paint/lang/cs-CZ.rc | 21 +-- .../base/applications/regedit/lang/cs-CZ.rc | 125 +++++++++--------- .../base/applications/sndvol32/lang/cs-CZ.rc | 12 +- reactos/base/setup/usetup/lang/et-EE.h | 4 +- reactos/dll/shellext/slayer/lang/cs-CZ.rc | 4 +- reactos/dll/win32/shell32/lang/cs-CZ.rc | 4 +- reactos/dll/win32/userenv/lang/es-ES.rc | 6 +- reactos/dll/win32/userenv/lang/it-IT.rc | 4 +- 10 files changed, 104 insertions(+), 100 deletions(-) diff --git a/reactos/base/applications/games/winemine/lang/cs-CZ.rc b/reactos/base/applications/games/winemine/lang/cs-CZ.rc index 3f281c7b317..bd776bafc40 100644 --- a/reactos/base/applications/games/winemine/lang/cs-CZ.rc +++ b/reactos/base/applications/games/winemine/lang/cs-CZ.rc @@ -1,8 +1,8 @@ /* FILE: applications/games/winemine/lang/cs-CZ.rc * PURPOSE: Czech Language File - * TRANSLATOR: Stepan Gabriel - SGABA (sgaba@centrum.cz) + * TRANSLATORS: Stepan Gabriel - SGABA (sgaba@centrum.cz); Radek Liska aka Black_Fox (radekliska at gmail dot com) * TRANSLATED FROM: Slovak translation by Kario (kario@szm.sk) - * UPDATED: 2008-07-06 + * UPDATED: 2010-05-25 * * Czech translation * Copyleft 2007 Kario (kario@szm.sk),2008 SGABA (sgaba@centrum.cz) @@ -15,7 +15,7 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT STRINGTABLE BEGIN IDS_SECONDS, "sek." - IDS_NOBODY, "Nikdo" //windows = Anonym + IDS_NOBODY, "Bezejmenný" //windows = Anonym IDS_ABOUT, "od Joshua Thielena a vývojáøù systému ReactOS" END @@ -36,15 +36,15 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Konec", IDM_EXIT END - POPUP "&Info" //windows = &Pomocník + POPUP "&Nápovìda" //windows = &Pomocník BEGIN - MENUITEM "C&o je hra Miny...", IDM_ABOUT + MENUITEM "&O programu...", IDM_ABOUT END END IDD_TIMES DIALOGEX DISCARDABLE 0, 0, 200, 75 STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT -CAPTION "Nejrychlejší htedaèi min" +CAPTION "Nejrychlejší hledaèi min" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Nejlepší èasy", IDNONE, 10, 10, 182, 45 @@ -66,7 +66,7 @@ STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHEL CAPTION "Blahopøeji!" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Zadejte prosím svoje jméno.", IDIGNORE, 25, 10, 150, 10 + LTEXT "Zadejte prosím svoje jméno", IDIGNORE, 25, 10, 150, 10 EDITTEXT IDC_EDITNAME, 25, 20, 110, 12 DEFPUSHBUTTON "OK", IDOK, 60, 40, 40, 15 END @@ -83,5 +83,5 @@ BEGIN EDITTEXT IDC_EDITCOLS, 49, 35, 30, 12, ES_NUMBER EDITTEXT IDC_EDITMINES, 49, 55, 30, 12, ES_NUMBER DEFPUSHBUTTON "OK", IDOK, 86, 32, 45, 15 - PUSHBUTTON "Zrušit", IDCANCEL, 86, 52, 45, 15 + PUSHBUTTON "Storno", IDCANCEL, 86, 52, 45, 15 END diff --git a/reactos/base/applications/notepad/lang/cs-CZ.rc b/reactos/base/applications/notepad/lang/cs-CZ.rc index e0be8ba66bb..d6dfcd25859 100644 --- a/reactos/base/applications/notepad/lang/cs-CZ.rc +++ b/reactos/base/applications/notepad/lang/cs-CZ.rc @@ -85,12 +85,12 @@ BEGIN END POPUP "&Nápovìda" BEGIN - MENUITEM "&Obsah", CMD_HELP_CONTENTS + MENUITEM "O&bsah", CMD_HELP_CONTENTS MENUITEM "&Najít...", CMD_HELP_SEARCH - MENUITEM "&Pomoc k nápovìdì", CMD_HELP_ON_HELP + MENUITEM "Pomoc k ná&povìdì", CMD_HELP_ON_HELP MENUITEM SEPARATOR - MENUITEM "&O programu" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE + MENUITEM "&O programu..." CMD_ABOUT + MENUITEM "In&fo...", CMD_ABOUT_WINE END END diff --git a/reactos/base/applications/paint/lang/cs-CZ.rc b/reactos/base/applications/paint/lang/cs-CZ.rc index f3a8f3d2501..da0e84b5de3 100644 --- a/reactos/base/applications/paint/lang/cs-CZ.rc +++ b/reactos/base/applications/paint/lang/cs-CZ.rc @@ -49,7 +49,7 @@ BEGIN MENUITEM SEPARATOR POPUP "Lupa" BEGIN - POPUP "User defined" + POPUP "Vlastní nastavení" BEGIN MENUITEM "12,5%", IDM_VIEWZOOM125 MENUITEM "25%", IDM_VIEWZOOM25 @@ -60,8 +60,8 @@ BEGIN MENUITEM "800%", IDM_VIEWZOOM800 END MENUITEM SEPARATOR - MENUITEM "Show grid", IDM_VIEWSHOWGRID - MENUITEM "Show miniature", IDM_VIEWSHOWMINIATURE + MENUITEM "Zobrazit møížku", IDM_VIEWSHOWGRID + MENUITEM "Zobrazit miniaturu", IDM_VIEWSHOWMINIATURE END MENUITEM "Celá obrazovka\tCtrl+F", IDM_VIEWFULLSCREEN END @@ -86,7 +86,7 @@ BEGIN BEGIN MENUITEM "Témata nápovìdy", IDM_HELPHELPTOPICS MENUITEM SEPARATOR - MENUITEM "O programu...", IDM_HELPINFO + MENUITEM "&O programu...", IDM_HELPINFO END END @@ -104,6 +104,7 @@ BEGIN "^A", IDM_EDITSELECTALL "^T", IDM_VIEWTOOLBOX "^L", IDM_VIEWCOLORPALETTE + "^G", IDM_VIEWSHOWGRID "^F", IDM_VIEWFULLSCREEN "^R", IDM_IMAGEROTATEMIRROR "^W", IDM_IMAGECHANGESIZE @@ -140,9 +141,9 @@ BEGIN LTEXT "Datum zmìny:", IDD_ATTRIBUTESTEXT3, 10, 5, 60, 10 LTEXT "Velikost souboru:", IDD_ATTRIBUTESTEXT4, 10, 15, 60, 10 LTEXT "Rozlišení:", IDD_ATTRIBUTESTEXT5, 10, 25, 60, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT6, 60, 5, 90, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT7, 60, 15, 90, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT8, 60, 25, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT6, 60, 5, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT7, 60, 15, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT8, 60, 25, 90, 10 GROUPBOX "Jednotka", IDD_ATTRIBUTESGROUP1, 6, 57, 139, 27 AUTORADIOBUTTON "Palce", IDD_ATTRIBUTESRB1, 12, 69, 35, 10, WS_GROUP AUTORADIOBUTTON "Centimetry", IDD_ATTRIBUTESRB2, 52, 69, 35, 10 @@ -181,7 +182,7 @@ BEGIN IDS_INFOTEXT, "ReactOS Malování je dostupné pod licencí GNU Lesser General Public License (LGPL) verze 3 (viz. www.gnu.org)" IDS_SAVEPROMPTTEXT, "Chcete uložit provedené zmìny v %s?" IDS_DEFAULTFILENAME, "Bez názvu.bmp" - IDS_MINIATURETITLE, "Miniature" + IDS_MINIATURETITLE, "Miniatura" IDS_TOOLTIP1, "Volný výbìr" IDS_TOOLTIP2, "Výbìr" IDS_TOOLTIP3, "Guma" @@ -200,6 +201,6 @@ BEGIN IDS_TOOLTIP16, "Zaoblený obdélník" IDS_OPENFILTER, "Soubory bitmap (*.bmp;*.dib)\1*.bmp;*.dib\1Všechny soubory (*.*)\1*.*\1" IDS_SAVEFILTER, "24bitová bitmapa (*.bmp;*.dib)\1*.bmp;*.dib\1" - IDS_FILESIZE, "%d bytes" - IDS_PRINTRES, "%d x %d pixels per meter" + IDS_FILESIZE, "%d bajtù" + IDS_PRINTRES, "%d x %d pixelù na metr" END diff --git a/reactos/base/applications/regedit/lang/cs-CZ.rc b/reactos/base/applications/regedit/lang/cs-CZ.rc index 8f36dadaf0d..b412af4c186 100644 --- a/reactos/base/applications/regedit/lang/cs-CZ.rc +++ b/reactos/base/applications/regedit/lang/cs-CZ.rc @@ -54,8 +54,8 @@ BEGIN MENUITEM "&Exportovat do souboru registru...", ID_REGISTRY_EXPORTREGISTRYFILE MENUITEM SEPARATOR - MENUITEM "Load Hive...", ID_REGISTRY_LOADHIVE, GRAYED - MENUITEM "Unload Hive...", ID_REGISTRY_UNLOADHIVE, GRAYED + MENUITEM "Naèíst strom registru...", ID_REGISTRY_LOADHIVE, GRAYED + MENUITEM "Uvolnit strom registru...", ID_REGISTRY_UNLOADHIVE, GRAYED MENUITEM SEPARATOR MENUITEM "&Pøipojit síový registr...", ID_REGISTRY_CONNECTNETWORKREGISTRY @@ -79,19 +79,19 @@ BEGIN MENUITEM "&Øetìzec", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Víceøetìzcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiøitelná øetìzcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END MENUITEM SEPARATOR - MENUITEM "&Oprávnìní...", ID_EDIT_PERMISSIONS + MENUITEM "Oprá&vnìní...", ID_EDIT_PERMISSIONS MENUITEM SEPARATOR MENUITEM "&Odstranit\tDel", ID_EDIT_DELETE MENUITEM "&Pøejmenovat", ID_EDIT_RENAME MENUITEM SEPARATOR MENUITEM "Z&kopírovat název klíèe", ID_EDIT_COPYKEYNAME MENUITEM SEPARATOR - MENUITEM "&Hledat\tCtrl+F", ID_EDIT_FIND - MENUITEM "Hledat &další\tF3", ID_EDIT_FINDNEXT + MENUITEM "&Najít\tCtrl+F", ID_EDIT_FIND + MENUITEM "Najít &další\tF3", ID_EDIT_FINDNEXT END POPUP "&Zobrazit" BEGIN @@ -103,10 +103,8 @@ BEGIN END POPUP "&Oblíbené" BEGIN - MENUITEM "&Pøidat k oblíbeným", ID_FAVOURITES_ADDTOFAVOURITES - , GRAYED - MENUITEM "&Odebrat z oblíbených", ID_FAVOURITES_REMOVEFAVOURITE - , GRAYED + MENUITEM "&Pøidat k oblíbeným", ID_FAVOURITES_ADDTOFAVOURITES, GRAYED + MENUITEM "&Odebrat z oblíbených", ID_FAVOURITES_REMOVEFAVOURITE, GRAYED END POPUP "&Nápovìda" BEGIN @@ -135,32 +133,32 @@ BEGIN MENUITEM "&Øetìzec", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Víceøetìzcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiøitelná øetìzcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END END POPUP "" BEGIN - MENUITEM "Expand/Collapse", ID_TREE_EXPANDBRANCH - POPUP "&New" + MENUITEM "Rozbalit/Sbalit", ID_TREE_EXPANDBRANCH + POPUP "&Nový" BEGIN - MENUITEM "&Key", ID_EDIT_NEW_KEY + MENUITEM "&Klíè", ID_EDIT_NEW_KEY MENUITEM SEPARATOR - MENUITEM "&String Value", ID_EDIT_NEW_STRINGVALUE - MENUITEM "&Binary Value", ID_EDIT_NEW_BINARYVALUE - MENUITEM "&DWORD Value", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Øetìzec", ID_EDIT_NEW_STRINGVALUE + MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE + MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Víceøetìzcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiøitelná øetìzcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END - MENUITEM "&Find", ID_EDIT_FIND + MENUITEM "&Najít", ID_EDIT_FIND MENUITEM SEPARATOR - MENUITEM "&Delete", ID_TREE_DELETE - MENUITEM "&Rename", ID_TREE_RENAME + MENUITEM "&Odstranit", ID_TREE_DELETE + MENUITEM "&Pøejmenovat", ID_TREE_RENAME MENUITEM SEPARATOR - MENUITEM "&Export", ID_TREE_EXPORT - MENUITEM "&Permissions...", ID_TREE_PERMISSIONS, GRAYED + MENUITEM "&Exportovat", ID_TREE_EXPORT + MENUITEM "Oprá&vnìní...", ID_TREE_PERMISSIONS, GRAYED MENUITEM SEPARATOR - MENUITEM "&Copy Key Name", ID_EDIT_COPYKEYNAME + MENUITEM "Z&kopírovat název klíèe", ID_EDIT_COPYKEYNAME END END @@ -287,22 +285,22 @@ BEGIN ID_EDIT_DELETE "Smaže výbìr" ID_EDIT_RENAME "Pøejmenuje výbìr" ID_EDIT_COPYKEYNAME "Zkopíruje název klíèe do schránky" - ID_EDIT_FIND "Hledá textový øetìzec v klíèi, položkách, nebo datech" - ID_EDIT_FINDNEXT "Hledá další výskyt textu zadaného v pøedchozím hledání" + ID_EDIT_FIND "Vyhledá textový øetìzec v klíèi, položkách, nebo datech" + ID_EDIT_FINDNEXT "Vyhledá další výskyt textu zadaného v pøedchozím hledání" END STRINGTABLE DISCARDABLE BEGIN - IDS_ERROR "Chyba" - IDS_WARNING "Upozornìní" - IDS_BAD_KEY "Can't query key '%s'" + IDS_ERROR "Chyba" + IDS_WARNING "Upozornìní" + IDS_BAD_KEY "Nelze se dotázat klíèe '%s'" IDS_BAD_VALUE "Nelze se dotázat položky '%s'" IDS_UNSUPPORTED_TYPE "Nelze upravovat klíèe tohoto typu (%ld)" IDS_TOO_BIG_VALUE "Položka je pøíliš velká (%ld)" IDS_MULTI_SZ_EMPTY_STRING "Položky typu REG_MULTI_SZ nemohou obsahovat prázdné øetezce.\nPrázdné øetìzce byly odebrány ze seznamu." - IDS_QUERY_DELETE_KEY_ONE "Are you sure you want to delete this key?" - IDS_QUERY_DELETE_KEY_MORE "Are you sure you want to delete these keys?" - IDS_QUERY_DELETE_KEY_CONFIRM "Confirm Key Delete" + IDS_QUERY_DELETE_KEY_ONE "Opravdu chcete odstranit tento klíè?" + IDS_QUERY_DELETE_KEY_MORE "Opravdu chcete odstranit tyto klíèe?" + IDS_QUERY_DELETE_KEY_CONFIRM "Potvrzení smazání klíèe" IDS_QUERY_DELETE_ONE "Opravdu chcete odstranit tuto položku?" IDS_QUERY_DELETE_MORE "Opravdu chcete odstranit tyto položky?" IDS_QUERY_DELETE_CONFIRM "Potvrzení odstranìní položky" @@ -310,8 +308,8 @@ BEGIN IDS_ERR_DELETEVALUE "Nelze odstranit všechny vybrané položky!" IDS_ERR_RENVAL_CAPTION "Chyba pøi pøejmenování položky" IDS_ERR_RENVAL_TOEMPTY "Nelze pøejmenovat %s. Vybraná položka je prázdná. Vyzkoušejte jiný název." - IDS_NEW_KEY "New Key #%d" - IDS_NEW_VALUE "New Value #%d" + IDS_NEW_KEY "Nový klíè #%d" + IDS_NEW_VALUE "Nová hodnota #%d" END STRINGTABLE DISCARDABLE @@ -328,7 +326,7 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_FLT_REGFILE "Registration File" + IDS_FLT_REGFILE "Soubor registru" IDS_FLT_REGFILES "Soubory registru" IDS_FLT_REGFILES_FLT "*.reg" IDS_FLT_REGEDIT4 "Soubory registru Win9x/NT4 (REGEDIT4)" @@ -362,10 +360,10 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_EXPAND "&Expand" - IDS_COLLAPSE "&Collapse" - IDS_GOTO_SUGGESTED_KEY "&Go to '%s'" - IDS_FINISHEDFIND "Finished searching through the registry." + IDS_EXPAND "&Rozbalit" + IDS_COLLAPSE "&Sbalit" + IDS_GOTO_SUGGESTED_KEY "&Jít na '%s'" + IDS_FINISHEDFIND "Prohledávání registru bylo dokonèeno." END /*****************************************************************/ @@ -376,70 +374,69 @@ END */ IDD_EXPORTRANGE DIALOGEX DISCARDABLE 50, 50, 370, 50 -STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | - WS_BORDER +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Export Range",IDC_STATIC,2,0,366,48 - CONTROL "&All",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON,10,10, 29,11 - CONTROL "S&elected Branch",IDC_EXPORT_BRANCH,"Button",BS_AUTORADIOBUTTON,10,22, 100,11 + GROUPBOX "Rozsah exportu",IDC_STATIC,2,0,366,48 + CONTROL "&Vše",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON,10,10, 29,11 + CONTROL "V&ybraná vìtev",IDC_EXPORT_BRANCH,"Button",BS_AUTORADIOBUTTON,10,22, 100,11 EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12 END IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add to Favorites" +CAPTION "Pøidat do Oblíbených" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,129,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 - LTEXT "&Favorite Name:",IDC_STATIC,7,7,70,10 + PUSHBUTTON "Storno",IDCANCEL,129,24,50,14 + LTEXT "&Název oblíbené položky:",IDC_STATIC,7,7,70,10 EDITTEXT IDC_FAVORITENAME,7,26,110,13,ES_AUTOHSCROLL END IDD_REMOVEFAVORITES DIALOGEX DISCARDABLE 0, 0, 164, 135 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Remove Favorites" +CAPTION "Odebrat z Oblíbených" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,107,114,50,14 - PUSHBUTTON "Cancel",IDCANCEL,7,114,50,14 + PUSHBUTTON "Storno",IDCANCEL,7,114,50,14 CONTROL "List1",IDC_FAVORITESLIST,"SysListView32",LVS_LIST | WS_BORDER | WS_TABSTOP,7,20,150,90 - LTEXT "Select Favorite(s):",IDC_STATIC,7,7,99,12 + LTEXT "Vyberte Oblíbené:",IDC_STATIC,7,7,99,12 END IDD_FIND DIALOGEX DISCARDABLE 0, 0, 254, 82 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" +CAPTION "Najít" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Find Next",IDOK,197,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,197,24,50,14 + DEFPUSHBUTTON "Najít &další",IDOK,197,7,50,14 + PUSHBUTTON "Storno",IDCANCEL,197,24,50,14 GROUPBOX "Look at",IDC_STATIC,7,25,63,51 - LTEXT "Fi&nd what:",IDC_STATIC,7,8,37,10 + LTEXT "&Najít:",IDC_STATIC,7,8,37,10 EDITTEXT IDC_FINDWHAT,47,7,142,13,ES_AUTOHSCROLL - CONTROL "&Keys",IDC_LOOKAT_KEYS,"Button",BS_AUTOCHECKBOX | + CONTROL "&Klíèe",IDC_LOOKAT_KEYS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,35,8 - CONTROL "&Values",IDC_LOOKAT_VALUES,"Button",BS_AUTOCHECKBOX | + CONTROL "&Hodnoty",IDC_LOOKAT_VALUES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,48,36,8 CONTROL "&Data",IDC_LOOKAT_DATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,60,42,8 - CONTROL "Match &whole string only",IDC_MATCHSTRING,"Button", + CONTROL "Hledat pouze &celý øetìzec",IDC_MATCHSTRING,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,83,32,94,13 - CONTROL "Match &case",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX | + CONTROL "Rozlišovat &velikost písmen",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,83,48,90,12 END IDD_FINDING DIALOGEX 0, 0, 145, 50 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" +CAPTION "Najít" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN ICON IDI_REGEDIT,IDC_STATIC,7,7,20,20 - DEFPUSHBUTTON "&Cancel",IDCANCEL,93,29,45,14 - LTEXT "Searching the registry...",IDC_STATIC,33,12,83,8 + DEFPUSHBUTTON "Storno",IDCANCEL,93,29,45,14 + LTEXT "Probíhá prohledávání registru...",IDC_STATIC,33,12,83,8 END /* diff --git a/reactos/base/applications/sndvol32/lang/cs-CZ.rc b/reactos/base/applications/sndvol32/lang/cs-CZ.rc index 9f89248021a..abeec0eb9db 100644 --- a/reactos/base/applications/sndvol32/lang/cs-CZ.rc +++ b/reactos/base/applications/sndvol32/lang/cs-CZ.rc @@ -1,3 +1,9 @@ +/* FILE: applications/sndvol32/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * THANKS TO: Denzil, who translated major part of this file + * UPDATED: 2010-05-25 + */ + LANGUAGE LANG_CZECH, SUBLANG_DEFAULT IDM_MAINMENU MENU DISCARDABLE @@ -5,7 +11,7 @@ BEGIN POPUP "&Nastavení" BEGIN MENUITEM "&Možnosti", IDC_PROPERTIES - MENUITEM "&Rozšíøené nastevení", IDC_ADVANCED_CONTROLS + MENUITEM "&Rozšíøené nastavení", IDC_ADVANCED_CONTROLS MENUITEM SEPARATOR MENUITEM "&Konec", IDC_EXIT END @@ -35,9 +41,9 @@ BEGIN PUSHBUTTON "&Záznam", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON PUSHBUTTON "&Jiné:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED - LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8 + LTEXT "Zobrazit tyto ovladaèe hlasitosti:", IDC_LABELCONTROLS, 7, 109, 162, 8 CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96 PUSHBUTTON "OK", IDOK, 114,226,50,14 - PUSHBUTTON "Zrušit", IDCANCEL, 168,226,50,14 + PUSHBUTTON "Storno", IDCANCEL, 168,226,50,14 END diff --git a/reactos/base/setup/usetup/lang/et-EE.h b/reactos/base/setup/usetup/lang/et-EE.h index c4dbf422919..819a2d47f08 100644 --- a/reactos/base/setup/usetup/lang/et-EE.h +++ b/reactos/base/setup/usetup/lang/et-EE.h @@ -1470,8 +1470,8 @@ MUI_ERROR etEEErrorEntries[] = }, { //ERROR_INSUFFICIENT_DISKSPACE, - "Not enough free space in the selected partition.\n" - " * Press any key to continue.", + "Valitud partitsioonil pole piisavalt ruumi.\n" + " * Vajuta suvalist klahvi, et j„tkata.", NULL }, { diff --git a/reactos/dll/shellext/slayer/lang/cs-CZ.rc b/reactos/dll/shellext/slayer/lang/cs-CZ.rc index 063bad46de8..13eed0328fe 100644 --- a/reactos/dll/shellext/slayer/lang/cs-CZ.rc +++ b/reactos/dll/shellext/slayer/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/shellext/slayer/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-07-27 + * UPDATED: 2010-05-25 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -32,7 +32,7 @@ BEGIN PUSHBUTTON "&Upravit...", IDC_EDIT, 162,24,60,14, WS_DISABLED PUSHBUTTON "S&mazat", IDC_DELETE, 162,42,60,14, WS_DISABLED PUSHBUTTON "&OK", IDOK, 95,116,60,14 - PUSHBUTTON "&Storno", IDCANCEL, 162,116,60,14 + PUSHBUTTON "Storno", IDCANCEL, 162,116,60,14 END STRINGTABLE diff --git a/reactos/dll/win32/shell32/lang/cs-CZ.rc b/reactos/dll/win32/shell32/lang/cs-CZ.rc index 6c80a3e3ce7..dff2e85bff0 100644 --- a/reactos/dll/win32/shell32/lang/cs-CZ.rc +++ b/reactos/dll/win32/shell32/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/win32/shell32/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2010-05-06 + * UPDATED: 2010-05-25 * THANKS TO: navaraf, who translated major part of this file */ @@ -101,7 +101,7 @@ BEGIN DEFPUSHBUTTON "&Ano", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Ano &všem", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Ne", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Storno", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0 END diff --git a/reactos/dll/win32/userenv/lang/es-ES.rc b/reactos/dll/win32/userenv/lang/es-ES.rc index dcfd07f92d8..8d87d2859ad 100644 --- a/reactos/dll/win32/userenv/lang/es-ES.rc +++ b/reactos/dll/win32/userenv/lang/es-ES.rc @@ -27,7 +27,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE BEGIN IDS_PROFILEPATH "%SystemDrive%\\Documents and Settings" - IDS_APPDATA "Application Data" + IDS_APPDATA "Datos de programa" IDS_DESKTOP "Escritorio" IDS_FAVORITES "Favoritos" IDS_STARTMENU "Menu de Inicio" @@ -39,8 +39,8 @@ BEGIN IDS_MYMUSIC "Mis Documentos\\Mi música" IDS_MYVIDEOS "Mis Documentos\\Mis videos" IDS_TEMPLATES "Plantillas" - IDS_RECENT "Documentos recientes" - IDS_SENDTO "Enviar a" + IDS_RECENT "Reciente" + IDS_SENDTO "SendTo" IDS_PRINTHOOD "Impresoras" IDS_NETHOOD "Entorno de red" IDS_LOCALSETTINGS "Configuración local" diff --git a/reactos/dll/win32/userenv/lang/it-IT.rc b/reactos/dll/win32/userenv/lang/it-IT.rc index fa6106f922e..dbbbcfa17f9 100644 --- a/reactos/dll/win32/userenv/lang/it-IT.rc +++ b/reactos/dll/win32/userenv/lang/it-IT.rc @@ -27,8 +27,8 @@ BEGIN IDS_MYMUSIC "Documenti\\Musica" IDS_MYVIDEOS "Documenti\\Video" IDS_TEMPLATES "Modelli" - IDS_RECENT "Dati recenti" - IDS_SENDTO "Invia a" + IDS_RECENT "Recent" + IDS_SENDTO "SendTo" IDS_PRINTHOOD "Stampanti" IDS_NETHOOD "Risorse di rete" IDS_LOCALSETTINGS "Impostazioni locali" From bbe7ec53c56604c66a179bde98be05743a35edb4 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Wed, 26 May 2010 02:04:09 +0000 Subject: [PATCH 042/292] [win32k] - Implement DestroyTimersForWindow and call it instead of MsqRemoveTimersWindow when destroying a window. - Fire NewMessages event when cleaning up thread so that threads dont wait for new messages that will never be received. Fixes a problem where some application that use timers dont completly exit. - IntSetTimer: Dont try to raise a timer from the dead. Once the TMRF_DELETEPENDING flag is set, let it be destroyed. - co_MsqWaitForNewMessages: Call the wait without a timeout value as now when the timer expires the NewMessages event will be set to exit the wait. - Message Queue specific timer code and old time queuing code is now dead. It will be removed later when we are happy with new timer implementation. svn path=/trunk/; revision=47358 --- .../subsystems/win32/win32k/include/timer.h | 1 + .../subsystems/win32/win32k/main/dllmain.c | 1 + .../subsystems/win32/win32k/ntuser/defwnd.c | 4 +- .../subsystems/win32/win32k/ntuser/msgqueue.c | 15 +------ .../subsystems/win32/win32k/ntuser/timer.c | 40 +++++++++++++++---- .../subsystems/win32/win32k/ntuser/window.c | 2 +- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index a41b8c30dbe..8e5bce67c15 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -29,6 +29,7 @@ extern PKTIMER MasterTimer; NTSTATUS FASTCALL InitTimerImpl(VOID); BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti); +BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window); BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer); UINT_PTR FASTCALL IntSetTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type); PTIMER FASTCALL FindSystemTimer(PMSG); diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index 3eb5753d231..88684b6cf80 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -292,6 +292,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread, HOOK_DestroyThreadHooks(Thread); /* Cleanup timers */ DestroyTimersForThread(Win32Thread); + KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); UnregisterThreadHotKeys(Thread); /* what if this co_ func crash in umode? what will clean us up then? */ co_DestroyThreadWindows(Thread); diff --git a/reactos/subsystems/win32/win32k/ntuser/defwnd.c b/reactos/subsystems/win32/win32k/ntuser/defwnd.c index f5e2bd1fc1d..6cf4fd010c6 100644 --- a/reactos/subsystems/win32/win32k/ntuser/defwnd.c +++ b/reactos/subsystems/win32/win32k/ntuser/defwnd.c @@ -67,7 +67,7 @@ IntClientShutdown( co_IntSendMessage(WndChild->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(WndChild->pti->MessageQueue, WndChild->hSelf); + DestroyTimersForWindow(WndChild->pti, WndChild); } lResult = MCSR_SHUTDOWNFINISHED; } @@ -90,7 +90,7 @@ IntClientShutdown( co_IntSendMessage(pWindow->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(pWindow->pti->MessageQueue, pWindow->hSelf); + DestroyTimersForWindow(pWindow->pti, pWindow); } lResult = MCSR_SHUTDOWNFINISHED; } diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index e71de5475d7..fe1d9a80af7 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -1366,19 +1366,8 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil UINT MsgFilterMin, UINT MsgFilterMax) { PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent}; - LARGE_INTEGER TimerExpiry; - PLARGE_INTEGER Timeout; NTSTATUS ret; - if (MsqGetFirstTimerExpiry(MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, &TimerExpiry)) - { - Timeout = &TimerExpiry; - } - else - { - Timeout = NULL; - } - IdlePing(); // Going to wait so send Idle ping. UserLeaveCo(); @@ -1389,11 +1378,9 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil Executive, UserMode, FALSE, - Timeout, + NULL, NULL); - UserEnterCo(); - return ret; } diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index 2d7b8d003d7..e178241f1ea 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -216,7 +216,7 @@ IntSetTimer( PWINDOW_OBJECT Window, } pTmr = FindTimer(Window, IDEvent, Type, FALSE); - if (!pTmr) + if ((!pTmr) || (pTmr->flags & TMRF_DELETEPENDING)) { pTmr = CreateTimer(); if (!pTmr) return 0; @@ -240,10 +240,6 @@ IntSetTimer( PWINDOW_OBJECT Window, pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; - if (pTmr->flags & TMRF_DELETEPENDING) - { - pTmr->flags &= ~TMRF_DELETEPENDING; - } ASSERT(MasterTimer != NULL); // Start the timer thread! @@ -342,6 +338,7 @@ ProcessTimers(VOID) LONG Time; PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr; + LONG TimerCount = 0; if (!pTmr) return; @@ -354,6 +351,7 @@ ProcessTimers(VOID) do { + TimerCount++; if (pTmr->flags & TMRF_WAITING) { pLE = pTmr->ptmrList.Flink; @@ -426,6 +424,7 @@ ProcessTimers(VOID) TimeLast = Time; UserLeave(); + DPRINT("TimerCount = %d\n", TimerCount); } // @@ -524,6 +523,35 @@ if (Ret == 0) ASSERT(FALSE); return Ret; } +BOOL FASTCALL +DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) +{ + PLIST_ENTRY pLE; + PTIMER pTmr = FirstpTmr; + BOOL TimersRemoved = FALSE; + + if ((FirstpTmr == NULL) || (Window == NULL)) + return FALSE; + + KeEnterCriticalRegion(); + + do + { + if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) + { + pTmr->flags &= ~TMRF_READY; + pTmr->flags |= TMRF_DELETEPENDING; + TimersRemoved = TRUE; + } + pLE = pTmr->ptmrList.Flink; + pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); + } while (pTmr != FirstpTmr); + + KeLeaveCriticalRegion(); + + return TimersRemoved; +} + BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti) { @@ -553,7 +581,6 @@ DestroyTimersForThread(PTHREADINFO pti) return TimersRemoved; } - BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) { @@ -568,7 +595,6 @@ IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) return pTmr ? TRUE : FALSE; } - // // // Old Kill Timer diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 409770d891a..6c17e8cb931 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -424,7 +424,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window, if(BelongsToThreadData) co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0); } - MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf); + DestroyTimersForWindow(ThreadData, Window); HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too! /* flush the message queue */ From 1594c9f594b662ed74f37f719889f35b19bf9dbf Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Wed, 26 May 2010 04:57:45 +0000 Subject: [PATCH 043/292] [WIN32CSR] Implement console pausing. [Bug 4739] svn path=/trunk/; revision=47359 --- reactos/dll/win32/kernel32/misc/console.c | 6 ++ reactos/include/reactos/subsys/csrss/csrss.h | 1 + .../subsystems/win32/csrss/win32csr/conio.c | 59 +++++++++++++++++++ .../subsystems/win32/csrss/win32csr/conio.h | 9 +++ .../win32/csrss/win32csr/guiconsole.c | 7 +++ 5 files changed, 82 insertions(+) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 298f79b8e59..aaf48ac882f 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -1467,6 +1467,12 @@ IntWriteConsole(HANDLE hConsoleOutput, max(sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes)); + if (Status == STATUS_PENDING) + { + WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE); + CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent); + continue; + } if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, Request); diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 62fe387633c..0b707582f6f 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -62,6 +62,7 @@ typedef struct BOOL Unicode; ULONG NrCharactersToWrite; ULONG NrCharactersWritten; + HANDLE UnpauseEvent; BYTE Buffer[0]; } CSRSS_WRITE_CONSOLE, *PCSRSS_WRITE_CONSOLE; diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 60b93cf9b3f..51e320fdcef 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -849,6 +849,15 @@ CSR_API(CsrWriteConsole) } Console = Buff->Header.Console; + if (Console->UnpauseEvent) + { + Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, + ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, + SYNCHRONIZE, 0, 0); + ConioUnlockScreenBuffer(Buff); + return NT_SUCCESS(Status) ? STATUS_PENDING : Status; + } + if(Request->Data.WriteConsoleRequest.Unicode) { Length = WideCharToMultiByte(Console->OutputCodePage, 0, @@ -953,6 +962,7 @@ ConioDeleteConsole(Object_t *Object) } CloseHandle(Console->ActiveEvent); + if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); DeleteCriticalSection(&Console->Lock); RtlFreeUnicodeString(&Console->Title); IntDeleteAllAliases(Console->Aliases); @@ -967,6 +977,26 @@ CsrInitConsoleSupport(VOID) /* Should call LoadKeyboardLayout */ } +VOID FASTCALL +ConioPause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags |= Flags; + if (!Console->UnpauseEvent) + Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +VOID FASTCALL +ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags &= ~Flags; + if (Console->PauseFlags == 0 && Console->UnpauseEvent) + { + SetEvent(Console->UnpauseEvent); + CloseHandle(Console->UnpauseEvent); + Console->UnpauseEvent = NULL; + } +} + static VOID FASTCALL ConioProcessChar(PCSRSS_CONSOLE Console, ConsoleInput *KeyEventRecord) @@ -974,6 +1004,35 @@ ConioProcessChar(PCSRSS_CONSOLE Console, BOOL updown; ConsoleInput *TempInput; + if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && + KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + { + WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; + if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) + { + DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; + if (Console->Mode & ENABLE_LINE_INPUT && + (vk == VK_PAUSE || (vk == 'S' && + (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && + !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) + { + ConioPause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; + } + } + else + { + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + { + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; + } + } + } + if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) { switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 8645351f96a..9b0c6905ce8 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -93,6 +93,8 @@ typedef struct tagCSRSS_CONSOLE LIST_ENTRY ProcessList; struct tagALIAS_HEADER *Aliases; CONSOLE_SELECTION_INFO Selection; + BYTE PauseFlags; + HANDLE UnpauseEvent; } CSRSS_CONSOLE; typedef struct ConsoleInput_t @@ -111,10 +113,17 @@ typedef struct ConsoleInput_t #define CONSOLE_MOUSE_SELECTION 0x4 #define CONSOLE_MOUSE_DOWN 0x8 +/* PauseFlags values (internal only) */ +#define PAUSED_FROM_KEYBOARD 0x1 +#define PAUSED_FROM_SCROLLBAR 0x2 +#define PAUSED_FROM_SELECTION 0x4 + NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); VOID WINAPI ConioDeleteConsole(Object_t *Object); VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); VOID WINAPI CsrInitConsoleSupport(VOID); +VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags); +VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags); void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index b89edbd304e..5398fd40a4e 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -844,6 +844,7 @@ GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) } Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; Console->Selection.srSelection = rc; + ConioPause(Console, PAUSED_FROM_SELECTION); } else { @@ -853,6 +854,7 @@ GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) InvalidateRect(hWnd, &oldRect, FALSE); } Console->Selection.dwFlags = CONSOLE_NO_SELECTION; + ConioUnpause(Console, PAUSED_FROM_SELECTION); } } @@ -1803,6 +1805,11 @@ GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam) case SB_THUMBTRACK: sInfo.nPos = sInfo.nTrackPos; + ConioPause(Console, PAUSED_FROM_SCROLLBAR); + break; + + case SB_THUMBPOSITION: + ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); break; case SB_TOP: From 7c79bc896d51973f87896675509552d74b83fb8e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 26 May 2010 10:40:15 +0000 Subject: [PATCH 044/292] [FREETYPE] Patch by Jerome Gardou: Update freetype to 2.3.9 The FT_MulFix patch is not neccessary anymore, the 1BPP -> 8BPP conversion patch will be applied again right after this. See issue #4537 for more details. svn path=/trunk/; revision=47360 --- reactos/lib/3rdparty/freetype/ChangeLog | 5173 ++++++++++++++++- reactos/lib/3rdparty/freetype/ChangeLog.21 | 8 +- reactos/lib/3rdparty/freetype/ChangeLog.22 | 14 +- reactos/lib/3rdparty/freetype/Jamfile | 4 +- reactos/lib/3rdparty/freetype/README | 12 +- reactos/lib/3rdparty/freetype/README.git | 46 + reactos/lib/3rdparty/freetype/autogen.sh | 121 +- reactos/lib/3rdparty/freetype/configure | 34 +- .../lib/3rdparty/freetype/devel/ftoption.h | 62 +- reactos/lib/3rdparty/freetype/freetype.def | 6 + reactos/lib/3rdparty/freetype/freetype.rbuild | 13 +- .../include/freetype/config/ftconfig.h | 161 +- .../include/freetype/config/ftheader.h | 119 +- .../include/freetype/config/ftmodule.h | 36 +- .../include/freetype/config/ftoption.h | 75 +- .../include/freetype/config/ftstdlib.h | 11 +- .../freetype/include/freetype/freetype.h | 952 ++- .../freetype/include/freetype/ftadvanc.h | 179 + .../freetype/include/freetype/ftbbox.h | 8 +- .../freetype/include/freetype/ftbdf.h | 89 +- .../freetype/include/freetype/ftbitmap.h | 41 +- .../freetype/include/freetype/ftcache.h | 93 +- .../freetype/include/freetype/ftchapters.h | 3 + .../freetype/include/freetype/ftcid.h | 166 + .../freetype/include/freetype/ftgasp.h | 15 +- .../freetype/include/freetype/ftglyph.h | 84 +- .../freetype/include/freetype/ftgxval.h | 10 +- .../freetype/include/freetype/ftgzip.h | 2 +- .../freetype/include/freetype/ftimage.h | 288 +- .../freetype/include/freetype/ftincrem.h | 454 +- .../freetype/include/freetype/ftlcdfil.h | 16 +- .../freetype/include/freetype/ftlist.h | 14 +- .../freetype/include/freetype/ftlzw.h | 2 +- .../freetype/include/freetype/ftmac.h | 28 +- .../3rdparty/freetype/include/freetype/ftmm.h | 28 +- .../freetype/include/freetype/ftmodapi.h | 81 +- .../freetype/include/freetype/ftotval.h | 15 +- .../freetype/include/freetype/ftoutln.h | 72 +- .../freetype/include/freetype/ftpfr.h | 16 +- .../freetype/include/freetype/ftrender.h | 37 +- .../freetype/include/freetype/ftsizes.h | 12 +- .../freetype/include/freetype/ftsnames.h | 13 +- .../freetype/include/freetype/ftstroke.h | 66 +- .../freetype/include/freetype/ftsynth.h | 27 +- .../freetype/include/freetype/ftsystem.h | 8 +- .../freetype/include/freetype/fttypes.h | 25 +- .../freetype/include/freetype/ftwinfnt.h | 63 +- .../freetype/include/freetype/ftxf86.h | 7 +- .../include/freetype/internal/autohint.h | 26 + .../include/freetype/internal/ftcalc.h | 28 +- .../include/freetype/internal/ftdebug.h | 34 +- .../include/freetype/internal/ftdriver.h | 194 +- .../include/freetype/internal/ftgloadr.h | 24 +- .../include/freetype/internal/ftmemory.h | 4 +- .../include/freetype/internal/ftobjs.h | 583 +- .../include/freetype/internal/ftpic.h | 67 + .../include/freetype/internal/ftrfork.h | 16 +- .../include/freetype/internal/ftserv.h | 293 + .../include/freetype/internal/fttrace.h | 8 +- .../include/freetype/internal/internal.h | 1 + .../include/freetype/internal/psaux.h | 30 +- .../include/freetype/internal/pshints.h | 47 +- .../freetype/internal/services/svbdf.h | 20 + .../freetype/internal/services/svcid.h | 83 + .../freetype/internal/services/svgldict.h | 22 + .../include/freetype/internal/services/svmm.h | 25 + .../freetype/internal/services/svpostnm.h | 21 + .../freetype/internal/services/svpscmap.h | 37 +- .../freetype/internal/services/svpsinfo.h | 34 +- .../freetype/internal/services/svsfnt.h | 22 + .../freetype/internal/services/svttcmap.h | 32 +- .../freetype/internal/services/svttglyf.h | 19 + .../freetype/include/freetype/internal/sfnt.h | 135 + .../include/freetype/internal/t1types.h | 30 +- .../include/freetype/internal/tttypes.h | 8 +- .../freetype/include/freetype/t1tables.h | 246 +- .../freetype/include/freetype/ttnameid.h | 297 +- .../freetype/include/freetype/tttables.h | 38 +- .../freetype/include/freetype/tttags.h | 10 +- reactos/lib/3rdparty/freetype/modules.cfg | 54 +- .../lib/3rdparty/freetype/src/autofit/Jamfile | 6 +- .../lib/3rdparty/freetype/src/autofit/afcjk.c | 96 +- .../lib/3rdparty/freetype/src/autofit/afcjk.h | 22 +- .../3rdparty/freetype/src/autofit/afdummy.c | 6 +- .../3rdparty/freetype/src/autofit/afdummy.h | 3 +- .../3rdparty/freetype/src/autofit/afglobal.c | 69 +- .../3rdparty/freetype/src/autofit/afglobal.h | 8 +- .../3rdparty/freetype/src/autofit/afhints.c | 19 +- .../3rdparty/freetype/src/autofit/afhints.h | 12 +- .../3rdparty/freetype/src/autofit/afindic.c | 26 +- .../3rdparty/freetype/src/autofit/afindic.h | 3 +- .../3rdparty/freetype/src/autofit/aflatin.c | 131 +- .../3rdparty/freetype/src/autofit/aflatin.h | 9 +- .../3rdparty/freetype/src/autofit/aflatin2.c | 152 +- .../3rdparty/freetype/src/autofit/aflatin2.h | 3 +- .../3rdparty/freetype/src/autofit/afloader.c | 55 +- .../3rdparty/freetype/src/autofit/afmodule.c | 15 +- .../3rdparty/freetype/src/autofit/afmodule.h | 4 +- .../lib/3rdparty/freetype/src/autofit/afpic.c | 92 + .../lib/3rdparty/freetype/src/autofit/afpic.h | 64 + .../3rdparty/freetype/src/autofit/aftypes.h | 68 +- .../3rdparty/freetype/src/autofit/afwarp.c | 2 +- .../3rdparty/freetype/src/autofit/autofit.c | 1 + .../3rdparty/freetype/src/autofit/module.mk | 2 +- .../lib/3rdparty/freetype/src/base/Jamfile | 26 +- .../lib/3rdparty/freetype/src/base/basepic.c | 83 + .../lib/3rdparty/freetype/src/base/basepic.h | 62 + .../lib/3rdparty/freetype/src/base/ftadvanc.c | 163 + .../lib/3rdparty/freetype/src/base/ftbase.c | 11 +- .../lib/3rdparty/freetype/src/base/ftbase.h | 57 + .../lib/3rdparty/freetype/src/base/ftbbox.c | 21 +- .../lib/3rdparty/freetype/src/base/ftbitmap.c | 43 +- .../lib/3rdparty/freetype/src/base/ftcalc.c | 217 +- .../lib/3rdparty/freetype/src/base/ftcid.c | 117 + .../lib/3rdparty/freetype/src/base/ftdbgmem.c | 9 +- .../lib/3rdparty/freetype/src/base/ftdebug.c | 8 +- .../lib/3rdparty/freetype/src/base/ftfstype.c | 62 + .../lib/3rdparty/freetype/src/base/ftgloadr.c | 7 + .../lib/3rdparty/freetype/src/base/ftglyph.c | 95 +- .../lib/3rdparty/freetype/src/base/ftinit.c | 119 +- .../lib/3rdparty/freetype/src/base/ftlcdfil.c | 16 +- .../lib/3rdparty/freetype/src/base/ftmac.c | 297 +- reactos/lib/3rdparty/freetype/src/base/ftmm.c | 4 +- .../lib/3rdparty/freetype/src/base/ftobjs.c | 679 ++- .../lib/3rdparty/freetype/src/base/ftotval.c | 3 +- .../lib/3rdparty/freetype/src/base/ftoutln.c | 70 +- .../lib/3rdparty/freetype/src/base/ftpatent.c | 18 +- .../lib/3rdparty/freetype/src/base/ftpfr.c | 33 +- .../lib/3rdparty/freetype/src/base/ftpic.c | 54 + .../lib/3rdparty/freetype/src/base/ftrfork.c | 189 +- .../lib/3rdparty/freetype/src/base/ftsnames.c | 94 + .../lib/3rdparty/freetype/src/base/ftstream.c | 64 +- .../lib/3rdparty/freetype/src/base/ftstroke.c | 189 +- .../lib/3rdparty/freetype/src/base/ftsynth.c | 55 +- .../lib/3rdparty/freetype/src/base/ftsystem.c | 11 +- .../lib/3rdparty/freetype/src/base/fttrigon.c | 10 +- .../lib/3rdparty/freetype/src/base/rules.mk | 20 +- reactos/lib/3rdparty/freetype/src/bdf/bdf.h | 6 +- .../lib/3rdparty/freetype/src/bdf/bdfdrivr.c | 85 +- .../lib/3rdparty/freetype/src/bdf/bdfdrivr.h | 4 + .../lib/3rdparty/freetype/src/bdf/bdflib.c | 87 +- .../lib/3rdparty/freetype/src/bdf/module.mk | 2 +- .../lib/3rdparty/freetype/src/bdf/rules.mk | 7 +- .../3rdparty/freetype/src/cache/ftcbasic.c | 96 +- .../3rdparty/freetype/src/cache/ftccache.c | 23 +- .../3rdparty/freetype/src/cache/ftccache.h | 11 +- .../3rdparty/freetype/src/cache/ftccback.h | 4 +- .../lib/3rdparty/freetype/src/cache/ftccmap.c | 52 +- .../3rdparty/freetype/src/cache/ftcglyph.c | 4 +- .../3rdparty/freetype/src/cache/ftcglyph.h | 9 +- .../3rdparty/freetype/src/cache/ftcimage.c | 6 +- .../3rdparty/freetype/src/cache/ftcmanag.c | 65 +- .../lib/3rdparty/freetype/src/cache/ftcmru.c | 8 +- .../lib/3rdparty/freetype/src/cache/ftcmru.h | 7 +- .../3rdparty/freetype/src/cache/ftcsbits.c | 17 +- .../lib/3rdparty/freetype/src/cache/rules.mk | 10 +- reactos/lib/3rdparty/freetype/src/cff/Jamfile | 2 +- reactos/lib/3rdparty/freetype/src/cff/cff.c | 1 + .../lib/3rdparty/freetype/src/cff/cffcmap.c | 25 +- .../lib/3rdparty/freetype/src/cff/cffcmap.h | 6 +- .../lib/3rdparty/freetype/src/cff/cffdrivr.c | 329 +- .../lib/3rdparty/freetype/src/cff/cffdrivr.h | 3 +- .../lib/3rdparty/freetype/src/cff/cffgload.c | 724 ++- .../lib/3rdparty/freetype/src/cff/cffgload.h | 17 +- .../lib/3rdparty/freetype/src/cff/cffload.c | 98 +- .../lib/3rdparty/freetype/src/cff/cffload.h | 8 +- .../lib/3rdparty/freetype/src/cff/cffobjs.c | 433 +- .../lib/3rdparty/freetype/src/cff/cffobjs.h | 22 +- .../lib/3rdparty/freetype/src/cff/cffparse.c | 469 +- .../lib/3rdparty/freetype/src/cff/cffparse.h | 35 +- .../lib/3rdparty/freetype/src/cff/cffpic.c | 99 + .../lib/3rdparty/freetype/src/cff/cffpic.h | 80 + .../lib/3rdparty/freetype/src/cff/cfftypes.h | 10 +- .../lib/3rdparty/freetype/src/cff/module.mk | 2 +- .../lib/3rdparty/freetype/src/cid/cidgload.c | 59 +- .../lib/3rdparty/freetype/src/cid/cidload.c | 36 +- .../lib/3rdparty/freetype/src/cid/cidobjs.c | 87 +- .../lib/3rdparty/freetype/src/cid/cidparse.c | 9 +- .../lib/3rdparty/freetype/src/cid/cidriver.c | 109 +- .../lib/3rdparty/freetype/src/cid/cidriver.h | 4 + .../lib/3rdparty/freetype/src/cid/cidtoken.h | 13 +- .../lib/3rdparty/freetype/src/cid/module.mk | 2 +- .../3rdparty/freetype/src/gxvalid/gxvbsln.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvcommn.c | 47 +- .../3rdparty/freetype/src/gxvalid/gxvcommn.h | 21 +- .../3rdparty/freetype/src/gxvalid/gxvfeat.c | 7 +- .../3rdparty/freetype/src/gxvalid/gxvjust.c | 26 +- .../3rdparty/freetype/src/gxvalid/gxvkern.c | 4 +- .../3rdparty/freetype/src/gxvalid/gxvlcar.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvmod.h | 4 + .../3rdparty/freetype/src/gxvalid/gxvmort.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvmort.h | 2 +- .../3rdparty/freetype/src/gxvalid/gxvmort0.c | 6 +- .../3rdparty/freetype/src/gxvalid/gxvmort1.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvmort2.c | 4 +- .../3rdparty/freetype/src/gxvalid/gxvmort4.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvmort5.c | 6 +- .../3rdparty/freetype/src/gxvalid/gxvmorx.c | 9 +- .../3rdparty/freetype/src/gxvalid/gxvmorx0.c | 4 +- .../3rdparty/freetype/src/gxvalid/gxvmorx1.c | 16 +- .../3rdparty/freetype/src/gxvalid/gxvmorx2.c | 4 +- .../3rdparty/freetype/src/gxvalid/gxvmorx5.c | 6 +- .../3rdparty/freetype/src/gxvalid/gxvopbd.c | 12 +- .../3rdparty/freetype/src/gxvalid/gxvprop.c | 8 +- .../3rdparty/freetype/src/gxvalid/gxvtrak.c | 2 +- .../3rdparty/freetype/src/gxvalid/module.mk | 2 +- .../lib/3rdparty/freetype/src/gzip/adler32.c | 2 +- .../lib/3rdparty/freetype/src/gzip/ftgzip.c | 18 +- .../lib/3rdparty/freetype/src/gzip/inftrees.c | 3 + .../lib/3rdparty/freetype/src/gzip/zconf.h | 8 +- .../lib/3rdparty/freetype/src/gzip/zutil.c | 8 +- .../lib/3rdparty/freetype/src/gzip/zutil.h | 2 +- reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c | 9 +- .../lib/3rdparty/freetype/src/lzw/ftzopen.c | 9 +- .../lib/3rdparty/freetype/src/lzw/ftzopen.h | 10 +- .../lib/3rdparty/freetype/src/otvalid/Jamfile | 2 +- .../3rdparty/freetype/src/otvalid/module.mk | 2 +- .../3rdparty/freetype/src/otvalid/otvalid.c | 3 +- .../3rdparty/freetype/src/otvalid/otvalid.h | 8 +- .../3rdparty/freetype/src/otvalid/otvbase.c | 6 +- .../3rdparty/freetype/src/otvalid/otvcommn.c | 65 +- .../3rdparty/freetype/src/otvalid/otvcommn.h | 57 +- .../3rdparty/freetype/src/otvalid/otvgdef.c | 11 +- .../3rdparty/freetype/src/otvalid/otvgpos.c | 52 +- .../3rdparty/freetype/src/otvalid/otvgsub.c | 35 +- .../3rdparty/freetype/src/otvalid/otvjstf.c | 4 +- .../3rdparty/freetype/src/otvalid/otvmath.c | 452 ++ .../3rdparty/freetype/src/otvalid/otvmod.c | 52 +- .../3rdparty/freetype/src/otvalid/otvmod.h | 4 + .../3rdparty/freetype/src/otvalid/rules.mk | 9 +- .../lib/3rdparty/freetype/src/pcf/module.mk | 2 +- reactos/lib/3rdparty/freetype/src/pcf/pcf.h | 4 +- .../lib/3rdparty/freetype/src/pcf/pcfdrivr.c | 107 +- .../lib/3rdparty/freetype/src/pcf/pcfdrivr.h | 4 + .../lib/3rdparty/freetype/src/pcf/pcfread.c | 63 +- .../lib/3rdparty/freetype/src/pcf/pcfutil.c | 8 +- .../lib/3rdparty/freetype/src/pcf/pcfutil.h | 6 +- .../lib/3rdparty/freetype/src/pcf/rules.mk | 11 +- .../lib/3rdparty/freetype/src/pfr/module.mk | 2 +- .../lib/3rdparty/freetype/src/pfr/pfrcmap.c | 11 +- .../lib/3rdparty/freetype/src/pfr/pfrdrivr.c | 11 +- .../lib/3rdparty/freetype/src/pfr/pfrdrivr.h | 4 + .../lib/3rdparty/freetype/src/pfr/pfrgload.c | 2 +- .../lib/3rdparty/freetype/src/pfr/pfrload.c | 15 +- .../lib/3rdparty/freetype/src/pfr/pfrobjs.c | 11 +- .../lib/3rdparty/freetype/src/pfr/pfrsbit.c | 28 +- .../lib/3rdparty/freetype/src/pfr/pfrtypes.h | 6 +- .../3rdparty/freetype/src/psaux/afmparse.c | 38 +- .../3rdparty/freetype/src/psaux/afmparse.h | 4 +- .../lib/3rdparty/freetype/src/psaux/module.mk | 2 +- .../3rdparty/freetype/src/psaux/psauxmod.h | 4 + .../lib/3rdparty/freetype/src/psaux/psconv.c | 22 +- .../lib/3rdparty/freetype/src/psaux/psconv.h | 6 +- .../lib/3rdparty/freetype/src/psaux/psobjs.c | 89 +- .../lib/3rdparty/freetype/src/psaux/psobjs.h | 2 +- .../lib/3rdparty/freetype/src/psaux/t1cmap.c | 26 +- .../3rdparty/freetype/src/psaux/t1decode.c | 365 +- .../3rdparty/freetype/src/pshinter/Jamfile | 2 +- .../3rdparty/freetype/src/pshinter/module.mk | 2 +- .../3rdparty/freetype/src/pshinter/pshalgo.c | 85 +- .../3rdparty/freetype/src/pshinter/pshalgo.h | 4 +- .../3rdparty/freetype/src/pshinter/pshinter.c | 1 + .../3rdparty/freetype/src/pshinter/pshmod.c | 17 +- .../3rdparty/freetype/src/pshinter/pshmod.h | 2 +- .../3rdparty/freetype/src/pshinter/pshpic.c | 67 + .../3rdparty/freetype/src/pshinter/pshpic.h | 53 + .../3rdparty/freetype/src/pshinter/pshrec.c | 101 +- .../3rdparty/freetype/src/pshinter/pshrec.h | 6 +- .../lib/3rdparty/freetype/src/psnames/Jamfile | 2 +- .../3rdparty/freetype/src/psnames/module.mk | 2 +- .../3rdparty/freetype/src/psnames/psmodule.c | 234 +- .../3rdparty/freetype/src/psnames/psmodule.h | 2 +- .../3rdparty/freetype/src/psnames/psnames.c | 1 + .../lib/3rdparty/freetype/src/psnames/pspic.c | 77 + .../lib/3rdparty/freetype/src/psnames/pspic.h | 54 + .../3rdparty/freetype/src/psnames/pstables.h | 9 +- .../lib/3rdparty/freetype/src/raster/Jamfile | 2 +- .../lib/3rdparty/freetype/src/raster/ftmisc.h | 30 +- .../3rdparty/freetype/src/raster/ftraster.c | 1010 ++-- .../3rdparty/freetype/src/raster/ftrend1.c | 46 +- .../3rdparty/freetype/src/raster/ftrend1.h | 4 +- .../3rdparty/freetype/src/raster/module.mk | 2 +- .../lib/3rdparty/freetype/src/raster/raster.c | 1 + .../3rdparty/freetype/src/raster/rastpic.c | 89 + .../3rdparty/freetype/src/raster/rastpic.h | 50 + .../lib/3rdparty/freetype/src/raster/rules.mk | 2 +- .../lib/3rdparty/freetype/src/sfnt/Jamfile | 2 +- .../lib/3rdparty/freetype/src/sfnt/module.mk | 2 +- .../lib/3rdparty/freetype/src/sfnt/rules.mk | 9 +- .../lib/3rdparty/freetype/src/sfnt/sfdriver.c | 215 +- .../lib/3rdparty/freetype/src/sfnt/sfdriver.h | 2 +- reactos/lib/3rdparty/freetype/src/sfnt/sfnt.c | 1 + .../lib/3rdparty/freetype/src/sfnt/sfntpic.c | 101 + .../lib/3rdparty/freetype/src/sfnt/sfntpic.h | 88 + .../lib/3rdparty/freetype/src/sfnt/sfobjs.c | 294 +- .../lib/3rdparty/freetype/src/sfnt/ttbdf.c | 16 +- .../lib/3rdparty/freetype/src/sfnt/ttcmap.c | 1455 ++++- .../lib/3rdparty/freetype/src/sfnt/ttcmap.h | 40 + .../lib/3rdparty/freetype/src/sfnt/ttcmapc.h | 55 + .../lib/3rdparty/freetype/src/sfnt/ttkern.c | 42 +- .../lib/3rdparty/freetype/src/sfnt/ttload.c | 197 +- .../lib/3rdparty/freetype/src/sfnt/ttmtx.c | 21 +- .../lib/3rdparty/freetype/src/sfnt/ttpost.c | 16 +- .../lib/3rdparty/freetype/src/sfnt/ttsbit.c | 30 +- .../lib/3rdparty/freetype/src/sfnt/ttsbit.h | 4 +- .../lib/3rdparty/freetype/src/sfnt/ttsbit0.c | 179 +- .../lib/3rdparty/freetype/src/smooth/Jamfile | 2 +- .../3rdparty/freetype/src/smooth/ftgrays.c | 445 +- .../3rdparty/freetype/src/smooth/ftgrays.h | 1 + .../3rdparty/freetype/src/smooth/ftsmooth.c | 72 +- .../3rdparty/freetype/src/smooth/ftsmooth.h | 8 +- .../lib/3rdparty/freetype/src/smooth/ftspic.c | 97 + .../lib/3rdparty/freetype/src/smooth/ftspic.h | 50 + .../3rdparty/freetype/src/smooth/module.mk | 6 +- .../lib/3rdparty/freetype/src/smooth/smooth.c | 1 + .../3rdparty/freetype/src/tools/apinames.c | 8 +- .../3rdparty/freetype/src/tools/chktrcmp.py | 114 + .../freetype/src/tools/docmaker/content.py | 258 +- .../freetype/src/tools/docmaker/docbeauty.py | 32 +- .../freetype/src/tools/docmaker/docmaker.py | 17 +- .../freetype/src/tools/docmaker/formatter.py | 46 +- .../freetype/src/tools/docmaker/sources.py | 113 +- .../freetype/src/tools/docmaker/tohtml.py | 261 +- .../freetype/src/tools/docmaker/utils.py | 22 +- .../freetype/src/tools/ftrandom/ftrandom.c | 10 +- .../3rdparty/freetype/src/tools/glnames.py | 13 +- .../3rdparty/freetype/src/tools/test_afm.c | 2 +- .../3rdparty/freetype/src/truetype/Jamfile | 2 +- .../3rdparty/freetype/src/truetype/module.mk | 2 +- .../3rdparty/freetype/src/truetype/truetype.c | 1 + .../3rdparty/freetype/src/truetype/ttdriver.c | 147 +- .../3rdparty/freetype/src/truetype/ttdriver.h | 2 +- .../3rdparty/freetype/src/truetype/ttgload.c | 306 +- .../3rdparty/freetype/src/truetype/ttgload.h | 16 +- .../3rdparty/freetype/src/truetype/ttgxvar.c | 99 +- .../3rdparty/freetype/src/truetype/ttgxvar.h | 2 +- .../3rdparty/freetype/src/truetype/ttinterp.c | 129 +- .../3rdparty/freetype/src/truetype/ttobjs.c | 130 +- .../3rdparty/freetype/src/truetype/ttobjs.h | 42 +- .../3rdparty/freetype/src/truetype/ttpic.c | 79 + .../3rdparty/freetype/src/truetype/ttpic.h | 59 + .../3rdparty/freetype/src/truetype/ttpload.c | 81 +- .../lib/3rdparty/freetype/src/type1/module.mk | 2 +- .../lib/3rdparty/freetype/src/type1/t1afm.c | 15 +- .../3rdparty/freetype/src/type1/t1driver.c | 58 +- .../3rdparty/freetype/src/type1/t1driver.h | 4 + .../lib/3rdparty/freetype/src/type1/t1gload.c | 129 +- .../lib/3rdparty/freetype/src/type1/t1gload.h | 9 +- .../lib/3rdparty/freetype/src/type1/t1load.c | 134 +- .../lib/3rdparty/freetype/src/type1/t1objs.c | 137 +- .../lib/3rdparty/freetype/src/type1/t1parse.c | 50 +- .../lib/3rdparty/freetype/src/type1/t1parse.h | 6 +- .../3rdparty/freetype/src/type1/t1tokens.h | 13 +- .../3rdparty/freetype/src/type42/module.mk | 2 +- .../lib/3rdparty/freetype/src/type42/rules.mk | 5 +- .../3rdparty/freetype/src/type42/t42drivr.c | 56 +- .../3rdparty/freetype/src/type42/t42drivr.h | 4 + .../3rdparty/freetype/src/type42/t42objs.c | 89 +- .../3rdparty/freetype/src/type42/t42parse.c | 45 +- .../3rdparty/freetype/src/type42/t42types.h | 6 +- .../3rdparty/freetype/src/winfonts/module.mk | 2 +- .../3rdparty/freetype/src/winfonts/winfnt.c | 67 +- .../3rdparty/freetype/src/winfonts/winfnt.h | 4 + 363 files changed, 22117 insertions(+), 6291 deletions(-) create mode 100644 reactos/lib/3rdparty/freetype/README.git create mode 100644 reactos/lib/3rdparty/freetype/include/freetype/ftadvanc.h create mode 100644 reactos/lib/3rdparty/freetype/include/freetype/ftcid.h create mode 100644 reactos/lib/3rdparty/freetype/include/freetype/internal/ftpic.h create mode 100644 reactos/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h create mode 100644 reactos/lib/3rdparty/freetype/src/autofit/afpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/autofit/afpic.h create mode 100644 reactos/lib/3rdparty/freetype/src/base/basepic.c create mode 100644 reactos/lib/3rdparty/freetype/src/base/basepic.h create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftadvanc.c create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftbase.h create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftcid.c create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftfstype.c create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/base/ftsnames.c create mode 100644 reactos/lib/3rdparty/freetype/src/cff/cffpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/cff/cffpic.h create mode 100644 reactos/lib/3rdparty/freetype/src/otvalid/otvmath.c create mode 100644 reactos/lib/3rdparty/freetype/src/pshinter/pshpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/pshinter/pshpic.h create mode 100644 reactos/lib/3rdparty/freetype/src/psnames/pspic.c create mode 100644 reactos/lib/3rdparty/freetype/src/psnames/pspic.h create mode 100644 reactos/lib/3rdparty/freetype/src/raster/rastpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/raster/rastpic.h create mode 100644 reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.h create mode 100644 reactos/lib/3rdparty/freetype/src/sfnt/ttcmapc.h create mode 100644 reactos/lib/3rdparty/freetype/src/smooth/ftspic.c create mode 100644 reactos/lib/3rdparty/freetype/src/smooth/ftspic.h create mode 100644 reactos/lib/3rdparty/freetype/src/tools/chktrcmp.py create mode 100644 reactos/lib/3rdparty/freetype/src/truetype/ttpic.c create mode 100644 reactos/lib/3rdparty/freetype/src/truetype/ttpic.h diff --git a/reactos/lib/3rdparty/freetype/ChangeLog b/reactos/lib/3rdparty/freetype/ChangeLog index cd5a4df4cc1..0407890537c 100644 --- a/reactos/lib/3rdparty/freetype/ChangeLog +++ b/reactos/lib/3rdparty/freetype/ChangeLog @@ -1,3 +1,5040 @@ +2009-10-10 Werner Lemberg + + * Version 2.3.11 released. + ========================== + + + Tag sources with `VER-2-3-11'. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.11. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.10/2.3.11/, s/2310/2311/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 11. + + * builds/unix/configure.raw (version_info): Set to 9:22:3. + +2009-10-10 Werner Lemberg + + * docs/CHANGES, docs/release: Updated. + +2009-10-10 suzuki toshiya + + * src/pcf/pcfread.c (pcf_get_properties): Fix a bug in the nprops + truncation. Reported by Martin von Gagern and Peter Volkov. + https://bugs.gentoo.org/288357 and https://bugs.gentoo.org/288256 + +2009-10-06 Werner Lemberg + + * Version 2.3.10 released. + ========================== + + + Tag sources with `VER-2-3-10'. + + * builds/toplevel.mk (major, minor, patch): Fix regexp to allow more + than a single digit. + (dist): We now use git. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.10. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.9/2.3.10/, s/239/2310/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 10. + + * builds/unix/configure.raw (version_info): Set to 9:21:3. + +2009-10-06 Werner Lemberg + + Fix `make multi'. + + * src/cache/ftccache.c, src/cache/ftcsbits.c (FT_COMPONENT): Define. + + * src/sfnt/sfdriver.c: Include FT_INTERNAL_DEBUG_H. + +2009-09-27 suzuki toshiya + + [cache] Fix Savannah bug #27441, clean up Redhat bugzilla #513582. + Tricky casts in FTC_{CACHE,GCACHE,MRULIST}_LOOKUP_CMP() are removed. + Now these functions should be called with FTC_Node or FTC_MruNode + variable, and the caller should cast them to appropriate pointers to + concrete data. These tricky casts can GCC-4.4 optimizer (-O2) + confused and the crashing binaries are generated. + + * src/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Drop tricky cast. + Now the 4th argument `node' of this function should be typed as + FTC_MruNode. + + * src/cache/ftcglyph.h (FTC_GCACHE_LOOKUP_CMP): For inline + implementation, new temporal variable FTC_MruNode `_mrunode' to take + the pointer from FTC_MRULIST_LOOKUP_CMP(). For non-inline + implementation, tricky cast is dropped. + + * src/cache/ftcmanag.c (FTC_SIZE_NODE): New macro casting + to FTC_SizeNode. + (FTC_Manager_LookupSize): Replace FTC_SizeNode `node' by FTC_MruNode + `mrunode', and FTC_SIZE_NODE() is inserted. + (FTC_FACE_NODE): New macro casting to FTC_FaceNode. + (FTC_Manager_LookupFace) Replace FTC_FaceNode `node' by FTC_MruNode + `mrunode', and FTC_FACE_NODE() is inserted. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): Change the type of + `node' from FTC_INode to FTC_Node. Extra casting macro FTC_NODE() + is dropped. + (FTC_ImageCache_LookupScaler): Ditto. + (FTC_SBitCache_Lookup): Change the type of `node' from FTC_SNode to + FTC_Node. Extra casting macro FTC_NODE() is dropped. FTC_SNODE() + is inserted. + (FTC_SBitCache_LookupScaler): Ditto. + + * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Change the type of + `node' from FTC_CMapNode to FTC_Node. Extra casting macro + FTC_NODE() is dropped, FTC_CMAP_NODE() is inserted. + +2009-09-25 suzuki toshiya + + [cache, psaux, type1] Fix for multi build. + In multi build, some cpp functions are left as unresolved symbols. + + * src/cache/ftcbasic.c: Include FT_INTERNAL_DEBUG_H for FT_TRACE1(). + + * src/psaux/t1decode.c: Include FT_INTERNAL_CALC_H for + FIXED_TO_INT(). + * src/type1/t1gload.c: Ditto. + * src/type1/t1objs.c: Ditto. + +2009-09-25 suzuki toshiya + + [autofit] Fix for multi build. + + * src/autofit/afmodule.h: Include FT_INTERNAL_OBJECTS_H to use + FT_DECLARE_MODULE() macro in multi build. + + * src/autofit/aflatin.c: Include to handle + FT_ADVANCES_H correctly in multi build. + +2009-09-24 suzuki toshiya + + [cache] Check the face filled by FTC_Manager_LookupFace(). + + * src/cache/ftcbasic.c (ftc_basic_family_get_count): Return + immediately if FTC_Manager_LookupFace() fills face by NULL. Such + case can occur when the code is optimized by GCC-4.2.x. + +2009-09-23 Werner Lemberg + + * docs/CHANGES: Updated. + +2009-09-12 Werner Lemberg + + [raster] Fix 5-levels grayscale output. + This was broken since version 2.3.0. + + * src/raster/ftraster.c (count_table): Use pre-2.3.0 values (which + were then computed dynamically). + (Vertical_Gray_Sweep_Step): Updated. + + (ft_black_render): Initialize `worker->gray_lines' (problem found by + valgrind). + + (FT_RASTER_OPTION_ANTI_ALIASING, DEBUG_RASTER): Dont' #undef, just + comment out. + +2009-09-12 suzuki toshiya + + Improve configure.raw for cross build. + + * builds/unix/configure.raw: Remove temporal files created by the + suffix checking for CC_BUILD. Set XX_ANSIFLAGS and XX_CFLAGS when + cross compiler is GCC. AC_PROG_CC checks whether the cross compiler + is GCC, its result is stored in GCC. + +2009-09-12 suzuki toshiya + + [BDF] Modify hash API to take size_t value instead of void *. + + The hash API in BDF driver is designed to be generic, it takes + void * typed data. But BDF driver always gives an unsigned long + integer (the index to a property). To reduce non-essential + casts from unsigned long to void* and from void* to unsigned + long, the hash API is changed to take size_t integer. + The issue of incompatible cast between unsigned long and void* + on LLP64 platform is reported by NightStrike from MinGW-Win64 + project. See + http://lists.gnu.org/archive/html/freetype/2009-09/msg00000.html + + * src/bdf/bdf.h: The type of hashnode->data is changed from + void* to size_t. + + * src/bdf/bdflib.c (hash_insert): Get size_t data, instead of + void* data. + (bdf_create_property): Get the name length of new property by + size_t variable, with a cut-off at FT_ULONG_MAX. + (_bdf_set_default_spacing): Get the name length of the face by + size_t variable, with a cut-off at 256. + (bdf_get_property): Get the property id by size_t variable to + reduce the casts between 32-bit prop ID & hashnode->data during + simple copying. + (_bdf_add_property): Ditto. + (_bdf_parse_start): Calculate the index to the property array + by size_t variable. + (bdf_get_font_property): Drop a cast to unsigned long. + +2009-09-10 suzuki toshiya + + [Win64] Improve the computation of random seed from stack address. + + On LLP64 platform, the conversion from pointer to FT_Fixed need + to drop higher 32-bit. Explict casts are required. Reported by + NightStrike from MinGW-w64 project. See + http://lists.gnu.org/archive/html/freetype/2009-09/msg00000.html + + * src/cff/cffgload.c: Convert the pointers to FT_Fixed explicitly. + + * src/psaux/t1decode.c: Ditto. + + +2009-09-03 Werner Lemberg + + [raster] Improvements for stand-alone mode. + + * src/raster/rules.mk: Don't handle ftmisc.h. It is needed for + stand-alone mode only. + + * src/raster/ftmisc.h (FT_MemoryRec , FT_Alloc_Func, FT_Free_Func, + FT_Realloc_Func): Copy declarations from ftsystem.h. + +2009-09-02 Bram Tassyns + + Improve vertical metrics calculation (Savannah bug #27364). + + The calculation of `vertBearingX' is not defined in the OTF font + spec so FreeType does a `best effort' attempt. However, this value + is defined in the PDF and PostScript specs, and that algorithm is + better than the one FreeType currently uses: + + FreeType: Use the middle of the bounding box as the X coordinate + of the vertical origin. + + Adobe PDF spec: Use the middle of the horizontal advance vector as + the X coordinate of the vertical origin. + + FreeType's algorithm goes wrong if you have a really small glyph + (like the full-width, circle-like dot at the end of the sentence, as + used in CJK scripts) with large bearings. With the FreeType + algorithm this dot gets centered on the baseline; with the PDF + algorithm it gets the correct location (in the top right). Note + that this is a serious issue, it's like printing the dot at the end + of a Roman sentence at the center of the textline instead of on the + baseline like it should. So i believe the PDF spec's algorithm + should be used in FreeType as well. + + The `vertBearingY' value for such small glyphs is also very strange + if no `vmtx' information is present, since the height of the bbox is + not representable for the height of the glyph visually (the + whitespace up to the baseline is part of the glyph). The fix also + includes some code for a better estimate of `vertBearingY'. + + * src/base/ftobjs.c (ft_synthesize_vertical_metrics): `vertBearingX' + is now calculated as described by the Adobe PDF Spec. Estimate for + `vertBearingY' now works better for small glyphs completely above or + below the baseline into account. + + * src/cff/cffgload.c (cff_slot_load): `vertBearingX' is now + calculated as described by the Adobe PDF Spec. Vertical metrics + information was always ignored when FT_CONFIG_OPTION_OLD_INTERNALS + was not defined. + + * src/truetype/ttgload.c (compute_glyph_metrics): `vertBearingX' is + now calculated as described by the Adobe PDF Spec. + +2009-09-01 John Tytgat + + Fix custom cmap for empty Type 1 font (Savannah bug #27294). + + * include/freetype/internal/t1types.h (T1_EncodingRecRec_): Update + comment to reflect revised code_last meaning. + * src/type1/t1load.c (T1_Open_Face), src/type42/t42objs.c + (T42_Open_Face): Assign max_char as highest character code + 1 and + use this for T1_EncodingRecRec_::code_last. + * src/psaux/t1cmap.c (t1_cmap_custom_init): Follow revised + T1_EncodingRecRec_::code_last meaning. + +2009-08-25 Werner Lemberg + + Fix rendering of horizontally compressed CFFs. + Bug reported by Ivan Nincic . + + * src/cff/cffgload.c (cff_slot_load): Thinko: Check `xx' element of + `font_matrix' also. + + * docs/CHANGES: Updated. + +2009-08-03 suyu0925@gmail.com + + Don't call `ft_fseek' every time when executing `ft_fread'. + + * src/base/ftstream.c (FT_Stream_Seek), src/base/ftsystem.c + (ft_ansi_stream_io): Implement it. + +2009-07-31 suzuki toshiya + + sfnt: Cast a charcode to 32-bit in cmap format 14 parser. + + * src/sfnt/ttcmap.c (tt_cmap14_char_var_index, + tt_cmap14_char_var_isdefault, tt_cmap14_char_variants, + tt_cmap14_variant_chars): Correct mismatches from + FT_CMap_CharVarIndexFunc prototype, FT_ULong arguments + are replaced by FT_UInt32 arguments. + +2009-07-31 suzuki toshiya + + sfnt: Cast a charcode to 32-bit in cmap format 12 parser. + + * src/sfnt/ttcmap.c (tt_cmap12_char_next): + Insert explicit cast from FT_UFast to FT_UInt32 + for return value. + +2009-07-31 suzuki toshiya + + psaux: Fix a few casts to FT_Int32 value. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): + Fix a few casts setting `value' from FT_Long to FT_Int32, + because `value' is typed as FT_Int32 since 2009-06-22. + +2009-07-31 suzuki toshiya + + sfnt: Fix a data type mismatching with its source. + + * src/sfnt/ttcmap.c (tt_cmap13_char_next): Fix the + type of `gindex' from FT_ULong to FT_UInt because + it is set by FT_UInt tt_cmap13_char_map_binary() or + TT_CMap13->cur_gindex. + +2009-07-31 suzuki toshiya + + sfnt: Extend a few local variables to load 32-bit values. + + * src/sfnt/ttkern.c (tt_face_load_kern): Extend `count' + and `kern' to load 32-bit values. + +2009-07-31 suzuki toshiya + + pfr: Extend `num_aux' to take 32-bit value. + + * src/pfr/pfrload.c (pfr_phy_font_load): Extend + `num_aux' to load 32-bit value. + +2009-07-31 suzuki toshiya + + pcf: Truncate FT_ULong `nprops' to fit to int PCF_Face->nprops. + + * src/pcf/pcfread.c (pcf_get_properties): Load `nprops' + as FT_ULong value from PCF file, but truncate it as + int to fit PCF_Face->nprops. The number of truncated + properties is shown in the trace message. + +2009-07-31 suzuki toshiya + + gxvalid: Extend a few local variables to reduce the casts. + + * src/gxvalid/gxvmorx.c (gxv_morx_subtables_validate): + Extend `type' and `rest' to take FT_ULong values. + +2009-07-31 suzuki toshiya + + gxvalid: Extend `settingTable' to take 32-bit offset. + + * src/gxvalid/gxvfeat.c (gxv_feat_name_validate): + Extend `settingTable' to take 32-bit offset. + +2009-07-31 suzuki toshiya + + autofit: Cast FT_Long glyph_count to compare with FT_UInt GID. + + * src/autofit/afglobal.c (af_face_globals_is_digit, + af_face_globals_compute_script_coverage): Cast FT_Long + globals->glyph_count to FT_ULong, to compare with FT_UInt + gindex. + +2009-07-31 suzuki toshiya + + smooth: Exclude 16-bit system in invalid pitch/height check. + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): + pitch and height are typed as FT_UInt but checked to fit + 16-bit range, to avoid the overflows. On 16-bit system, + this checking inserts a conditional that never occurs. + +2009-07-03 suzuki toshiya + + cff: Type large constants > 0x7FFF as long for 16-bit systems. + + * src/cff/cffload.c (cff_charset_load): Type large + constants > 0x7FFF as long, because normal constants + are typed signed integer that is less than 0x8000 on + 16-bit systems. + +2009-07-31 suzuki toshiya + + base: Remove an unused variable. + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Remove an + unused variable `library'. glyph->library is used. + +2009-07-31 suzuki toshiya + + cache: Check higher bits in flags for non ILP32 systems. + + 4 public functions ought to take FT_ULong flags, but take + FT_UInt flags. To keep binary compatibility, we drop higher + bits on non ILP32 platforms, + ILP64 systems: No drop occurs. + LP64 systems: Higher bits are not used. + 16-bit systems: Drop can occur. + See + http://lists.gnu.org/archive/html/freetype-devel/2008-12/msg00065.html + These functions will be refined to take FT_ULong flags in + next bump with incompatible API change. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): + Check `flags' in `type', the 2nd argument. + (FTC_SBitCache_Lookup): Ditto. + (FTC_ImageCache_LookupScaler): Check `load_flags', + the 3rd argument. + (FTC_SBitCache_LookupScaler): Ditto. + +2009-07-31 suzuki toshiya + + sfnt: Ignore invalid GIDs in glyph name lookup. + + * include/freetype/internal/fttrace.h: + New trace module for sfdriver.c is added. + + * src/sfnt/sfdriver.c (sfnt_get_name_index): + Restrict glyph name lookup to FT_UInt GID. + Genuine TrueType can hold 16-bit glyphs. + +2009-07-31 suzuki toshiya + + pcf: Fix a comparison between FT_Long and FT_ULong. + + * src/pcf/pcfread.c (pcf_get_bitmaps): Return an error + if PCF_Face->nemetrics is negative. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `nFeatureFlags' size up to 32-bit. + + * src/gxvalid/gxvmort.c (gxv_mort_featurearray_validate): + Extend the 3rd argument `nFeatureFlags' to FT_ULong. + * src/gxvalid/gxvmort.h: Ditto. + +2009-07-31 suzuki toshiya + + sfnt: Insert explicit cast for LP64 system. + + * src/sfnt/ttkern.c (tt_face_load_kern): Insert + cast from unsigned long to FT_UInt32. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `just' table size upto 32-bit. + + * src/gxvalid/gxvjust.c (gxv_just_validate): + The type of `offset' is changed from FT_UInt to + FT_Offset, for 16-bit platforms. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `trak' table size upto 32-bit. + + * src/gxvalid/gxvtrak.c (gxv_trak_validate): + The type of `offset' is changed from FT_UInt to + FT_Offset, for 16-bit platforms. + +2009-07-31 suzuki toshiya + + type1: Fix a data type mismatching with its source. + + * include/freetype/internal/t1types.h: The type of + T1_Face->buildchar is matched with T1_Decorder->top. + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_KernItem->offset + is extended from FT_UInt32 to FT_Offset, because it is + calculated with the pointer difference, in + pfr_extra_item_load_kerning_pairs(). + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_PhysFont->chars_offset + is extended from FT_UInt32 to FT_Offset, because it is + calculated with the pointer difference in pfr_phy_font_load(). + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_PhyFont->bct_offset + is extended from FT_UInt32 to FT_Long, because it is + loaded by FT_STREAM_POS() in pfr_phy_font_load(). + +2009-07-31 suzuki toshiya + + smooth: Improve the format in debug message. + + * src/smooth/ftgrays.c (gray_dump_cells): Improve the + format specifications to dump variables. + +2009-07-31 suzuki toshiya + + sfnt: Fix a data type mismatching with its source. + + * src/sfnt/sfobjs.c (sfnt_load_face): The type of + local `flags' is matched with FT_Face->face_flags. + +2009-07-31 suzuki toshiya + + psaux: Fix a data type mismatching with its source. + + * include/freetype/internal/psaux.h: The type of + T1_DecorderRec.buildchar is matched with + T1_DecorderRec.top. + +2009-07-31 suzuki toshiya + + truetype: Extend TrueType GX packed deltas to FT_Offset. + + * src/truetype/ttgxvar.c (ft_var_readpackeddeltas): + The type of 2nd argument `delta_cnt' is changed from + FT_Int to FT_Offset, because its source can be cvt + table size calculated from stream position. + +2009-07-31 suzuki toshiya + + truetype: Extend mmvar_len to hold size_t values. + + * src/truetype/ttgxvar.h: The type of + GX_BlendRec.mmvar_len is changed from FT_Int to + FT_Offset, because TT_Get_MM_Var() calculates it + by sizeof() results. + +2009-07-31 suzuki toshiya + + truetype: Check invalid function number in IDEF instruction. + + * src/truetype/ttinterp.c (Ins_IDEF): Check + if the operand fits to 8-bit opcode limitation. + +2009-07-31 suzuki toshiya + + truetype: Check invalid function number in FDEF instruction. + + * src/truetype/ttinterp.c (Ins_FDEF): Check + if the operand fits 16-bit function number. + +2009-07-31 suzuki toshiya + + truetype: Truncate the deltas of composite glyph at 16-bit values. + + * src/truetype/ttgload.c (load_truetype_glyph): + Insert cast from FT_Long (deltas[i].{x,y}) to + FT_Int16 in the summation of deltas[] for composite + glyphs. Because deltas[i] is typed as FT_Pos, + its component x, y are typed as FT_Long, but + their sources are always FT_Int16 when they are + loaded by ft_var_readpackeddeltas(). However, + the limitation about the summed deltas is unclear. + +2009-07-31 suzuki toshiya + + truetype: Truncate the instructions upto 16-bit per a glyph. + + * src/truetype/ttgload.c (TT_Hint_Glyph): Truncate + the instructions upto 16-bit length per a glyph. + +2009-07-31 suzuki toshiya + + truetype: Cast the numerical operands to 32-bit for LP64 systems. + + * src/truetype/ttinterp.c (Ins_SPHIX, INS_MIAP, + Ins_MIRP): Insert cast from long (args[], the + operands passed to TrueType operator) to FT_Int32 + (the argument of TT_MulFix14()). + +2009-07-31 suzuki toshiya + + truetype: Cast the project vector to 32-bit for LP64 system. + + * src/truetype/ttinterp.c (Project, DualProject): + Insert casts from FT_Pos (the arguments `dx', `dy') + to FT_UInt32 (the argument to TT_DotFix14()). + +2009-07-31 suzuki toshiya + + truetype: Cast the scaling params to 32-bit for LP64 system. + + * src/truetype/ttgload.c (TT_Process_Composite_Component): + Insert casts from long (return value of FT_MulFix()) to + FT_Int32 (the argument to FT_SqrtFixed()). + +2009-07-31 suzuki toshiya + + sfnt: Cast a character code to FT_UInt32 for LP64 system. + + * src/sfnt/ttcmap.c (tt_cmap14_char_map_nondef_binary, + tt_cmap14_variants, tt_cmap14_char_variants, + tt_cmap14_def_char_count, tt_cmap14_get_def_chars, + tt_cmap14_get_nondef_chars, tt_cmap14_variant_chars) + Insert casts when FT_UInt32 variable is loaded by + TT_NEXT_{UINT24|ULONG}. Because most of them are + compared with FT_UInt32 values in public API, replacing + FT_UFast is not recommended. + +2009-07-31 suzuki toshiya + + sfnt: Cast a character code to FT_UInt32 for LP64 system. + + * src/sfnt/ttcmap.c (tt_cmap4_init, tt_cmap4_next): + Insert the casts from unsigned long constant to + FT_UInt32. + +2009-07-31 suzuki toshiya + + sfnt: Extend TT_BDF->strings_size to FT_ULong for huge BDF. + + * include/freetype/internal/tttypes.h: The type + of TT_BDF->string_size is extended from FT_UInt32 + to FT_ULong, because BDF specification does not + restrict the length of string. + * src/sfnt/ttbdf.c: The scratch variable `strings' + to load TT_BDF->string_size is matched with + TT_BDF->string_size. + +2009-07-31 suzuki toshiya + + psaux: Handle the string length by FT_Offset variables. + + * src/psaux/afmparse.c (afm_parser_next_key, + afm_tokenize, afm_parse_track_kern, + afm_parse_kern_pairs, afm_parse_kern_data, + afm_parser_skip_section, afm_parser_parse): + The length of key is handled by FT_Offset, + instead of FT_UInt. Although the length of + PostScript strings or name object is 16-bit, + AFM_STREAM_KEY_LEN() calculates the length + from the pointer difference. + + * src/psaux/afmparse.h (afm_parser_next_key): + Ditto. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfread.c (pcf_get_bitmaps): The types + of `nbitmaps', `i', `sizebitmaps' are matched with + the type of area FT_Bitmap.pitch * FT_Bitmap.rows. + +2009-07-31 suzuki toshiya + + pcf: Handle the string length by size_t variables. + + * src/pcf/pcfread.c (pcf_interpret_style): The types + of nn, len, lengths[4] are changed to size_t, because + they are loaded by (or compared with) ft_strlen(). + + * src/pcf/pcfutil.c (BitOrderInvert, TwoByteSwap, + FourByteSwap): The type of the 2nd argument `nbytes' + is changed to size_t, for similarity with ANSI C + string functions. + + * src/pcf/pcfdrivr.c (PCF_Glyph_Load): The type of + `bytes' is changed to FT_Offset, because it is passed + to FT_ALLOC(), via ft_glyphslot_alloc_bitmap(). At + least, using unsigned type is better. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfread.c (pcf_seek_to_table_type, + pcf_has_table_type): The type of 3rd argument + `ntables' is matched with PCF_Toc->count. + +2009-07-31 suzuki toshiya + + otvalid: Truncate the glyph index to 16-bit. + + * src/otvalid/otvalid.c (otv_validate): Checks + face->num_glyphs does not exceed 16-bit limit, + pass FT_UInt num_glyphs to backend functions + otv_{GPOS|GSUB|GDEF|JSTF|MATH}_validate(). + +2009-07-31 suzuki toshiya + + cache: Insert explict casts for LP64 systems. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup, + FTC_SBitCache_Lookup): The type of FTC_ImageType->width + is FT_Int, so the cast to unsigned larger type FT_ULong + is introduced for the comparisons with 0x10000L for + LP64 platform. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftccache.h: The type of return value + by FTC_Node_WeightFunc function is changed to + FT_Offset. The type of FTC_CacheClass->cache_size + is changed to FT_Offset, too. + + * src/cache/ftccback.h (ft_inode_weight, + ftc_snode_weight): Ditto. + + * src/cache/ftccmap.c (ftc_cmap_node_weight): Ditto. + + * src/cache/ftcimage.c (ftc_inode_weight, + FTC_INode_Weight): Ditto. + + * src/cache/ftcsbits.c (ftc_snode_weight, + FTC_SNode_Weight): Ditto. + + * src/cache/ftcmru.h: The type of + FTC_MruListClass->node_size is changed to FT_Offset, + because it is passed to FT_ALLOC() to specify the + size of buffer. + +2009-07-31 suzuki toshiya + + XXX_cmap_encoding_char_next() return FT_UInt32 values. + + * include/freetype/internal/services/svpscmap.h: + The size of the charcode value returned by + the function typed PS_Unicodes_CharNextFunc is + matched with its input charcode value. + + * src/cff/cffmap.c (cff_cmap_encoding_char_next, + cff_cmap_unicode_char_next): Ditto. + + * src/pfr/pfrmap.c (pfr_cmap_encoding_char_next): + Ditto. + + * src/psaux/t1cmap.c (t1_cmap_std_char_next, + t1_cmap_custom_char_next, t1_cmap_unicode_char_next): + Ditto. + + * src/psnames/psmodule.c (ps_unicodes_char_next): + Ditto. + + * src/winfonts/winfnt.c (fnt_cmap_char_next): + Ditto. + + * src/sfnt/ttcmap.c (tt_cmap0_char_next, + tt_cmap2_char_next, tt_cmap4_char_next, + tt_cmap6_char_next, tt_cmap10_char_next, + tt_cmap12_char_next, tt_cmap13_char_next): Ditto. + (tt_cmap14_char_variants): Handle base unicode + codepoint by FT_UInt32 variable to avoid overflow + on 16-bit platforms. + (tt_cmap14_ensure): The type of `num_results' is + extend to FT_UInt32, to cover unsigned 32-bit + `numVarSelectorRecords' in cmap14 table header. + +2009-07-31 suzuki toshiya + + truetype: Extend TT_Face->num_locations for broken TTFs. + + * include/freetype/internal/tttypes.h: + TT_Face->num_locations are extended from FT_UInt + to FT_ULong, to stand with broken huge loca table. + Some people insists there are broken TTF including + the glyphs over 16-bit limitation, in PRC market. + * src/truetype/ttpload.c (tt_face_load_loca): + Remove unrequired 16-bit truncation for FT_UInt + TT_Face->num_locations. + +2009-07-31 suzuki toshiya + + smooth: Fix some data types mismatching with their sources. + + * src/smooth/ftgrays.c: The type of `TCoord' is + matched to `TPos', because they are mixed in + gray_set_cell(). The type of TCell->x is extended + to `TPos', because gray_find_cell() sets it by + TWorker.ex. The type of TCell->cover is extended + to `TCoord', because gray_render_scanline() adds + TCoord value to it. The type of TWork.cover is matched + with TCell->cover. The types of + TWork.{max_cells,num_cells} are changed to FT_PtrDist, + because they are calculated from the memory addresses. + The type of TWork.ycount is changed to TPos, because + it is calculated from TPos variables. + (gray_find_cell): The type of `x' is matched with + its initial value ras.ex. + (gray_render_scanline): The types of `mod', `lift' + and `rem' are changed to TCoord, because their values + are set with explicit casts to TCoord. When ras.area + is updated by the differential values including + `delta', they are explicitly casted to TArea, because + the type of `delta' is not TArea but TCoord. + (gray_render_line): The type of `mod' is extended + from int to TCoord, because (TCoord)dy is added to mod. + (gray_hline): The argument `acount' is extended to + TCoord, to match with the parameters in the callers. + +2009-07-31 suzuki toshiya + + cff: Fix some data types mismatching with their sources. + + * src/cff/cffobjs.c (cff_face_init): The type of + `scaling' is matched with the scaling parameter + in FT_Matrix_Multiply_Scaled() and + FT_Vector_Transform_Scaled(). + + * src/cff/cffparse.c (cff_parse_real): The type of + `power_ten', `scaling', `exponent_add', + `integer_length', `fraction_length', + `new_fraction_length' and `shift' are matched with + the type of `exponent' to avoid unexpected truncation. + (cff_parse_fixed_scaled): The type of `scaling' is + matched with the `scaling' argument to + cff_parse_real(). + (cff_parse_fixed_dynamic): Ditto. + (cff_parse_font_matrix): The type of `scaling' is + matched with the `scaling' argument to + cff_parse_dynamic(). + +2009-07-31 suzuki toshiya + + autofit: Fix some data types mismatching with their sources. + + * src/autofit/afglobal.c: Correct the type of + AF_FaceGlobalsRec.glyph_count to match with + FT_Face->num_glyphs. + (af_face_globals_compute_script_coverage): + Insert explicit cast to compare + FT_Long AF_FaceGlobalsRec.glyph_count versus + FT_UInt gindex. The type of `nn' is changed + to scan glyph index upto AF_FaceGlobalsRec.glyph_count. + (af_face_globals_get_metrics): The type of `script_max' + is changed to cover size_t value. Insert explicit cast + to compare FT_Long AF_FaceGlobalsRec.glyph_count versus + FT_UInt gindex. + + * src/autofit/afhints.c (af_axis_hints_new_segment): + Insert explicit cast to calculate `big_max' from + integer and size_t values. + (af_axis_hints_new_edge): Ditto. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): + The type of `best_y' is matched to FT_Vector.y. + (af_latin_compute_stem_width): The type of `delta' is + matched to `dist' and `org_dist'. + +2009-07-31 suzuki toshiya + + autofit: Count the size of the memory object by ptrdiff_t. + + * src/autofit/afcjk.c (af_cjk_hint_edges): The + number of edges `n_edges' should be counted by + FT_PtrDist variable instead of FT_Int. + + * src/autofit/aflatin.c (af_latin_hint_edges): + Ditto. + + * src/autofit/aftypes.h: In AF_ScriptClassRec, + the size of metric `script_metrics_size' should + be counted by FT_Offset variable instead of FT_UInt. + + * src/autofit/afhints.c + (af_glyph_hints_align_strong_points): The cursors + for the edges `min', `max', `mid' in the memory + buffer should be typed FT_PtrDist. + +2009-07-31 suzuki toshiya + + autofit: Fix for unused variable `first'. + + * src/autofit/afhints.c (af_glyph_hints_reload): Insert + FT_UNUSED() to hide the unused variable warning. + +2009-07-31 suzuki toshiya + + Improve bitmap size or pixel variables for 16-bit systems. + + * include/freetype/config/ftstdlib.h: Introduce + FT_INT_MIN, to use in signed integer overflow in + 16-bit and 64-bit platforms. + + * include/freetype/internal/fttrace.h: Add a tracer + to ftsynth.c. + + * src/base/ftbitmap.c (FT_Bitmap_Embolden): Check + invalid strength causing integer overflow on 16-bit + platform. + + * src/base/ftcalc.c (ft_corner_orientation): Change + the internal calculation from FT_Int to FT_Long, to + avoid an overflow on 16-bit platforms. The caller of + this function should use only the sign of result, + so the cast to FT_Int is acceptable. + + * src/base/ftsynth.c: Introduce a tracer for synth module. + (FT_GlyphSlot_Embolden): Check invalid strength causing + integer overflow on 16-bit platform. + + * src/bdf/bdfdrivr.c (BDF_Face_Init): The glyph index + in FT2 API is typed as FT_UInt, although BDF driver + can handle unsigned long glyph index internally. To + avoid integer overflow on 16-bit platform, too large + glyph index should be excluded. + (BDF_Glyph_Load): The glyph pitch in FT2 is typed as + FT_UInt, although BDF driver can handle unsigned long + glyph pitch internally. To avoid integer overflow on + 16-bit platform, too large glyph pitch should not be + returned. + + * src/pfr/pfrsbit.c (pfr_slot_load_bitmap): The glyph + pitch in FT2 is typed as FT_UInt, although PFR font + format can include huge bitmap glyph with 24-bit pitch + (however, a glyph spends 16.7 pixel, it's not realistic). + To avoid integer overflow on 16-bit platform, huge + bitmap glyph should be excluded. + + * src/smooth/ftgrays.c (gray_hline): As FT_Span.x is + truncated to fit its type (16-bit short), FT_Span.y + should be truncated to fit its type (FT_Int). + + * src/cff/cffdrivr.c (cff_get_ros): CFF specification + defines the supplement in ROS as a real number. + Truncate it to fit public FT2 API. + + * src/cff/cffparse.c (cff_parse_cid_ros): Warn the + supplement if it is truncated or rounded in cff_get_ros(). + + * src/cff/cfftypes.h: Change the type of internal variable + `supplement' from FT_Long to FT_ULong to fit the signedness + to the type in public API. + +2009-07-31 suzuki toshiya + + psaux: Prevent invalid arguments to afm_parser_read_vals(). + + * src/psaux/afmparse.c (afm_parser_read_vals): Change + the type of `n' to prevent negative number how many + arguments should be parsed. + + * src/psaux/afmparse.h (afm_parser_read_vals): Ditto. + +2009-07-31 suzuki toshiya + + base: Prevent some overflows on LP64 systems. + + * src/base/ftadvance.c (FT_Get_Advances): Cast the + unsigned long constant FT_LOAD_ADVANCE_ONLY to FT_UInt32 + for LP64 platforms. + + * src/base/ftcalc.c (FT_Sqrt32): All internal variables + are changed to FT_UInt32 from FT_ULong. + (FT_MulDiv): Insert casts to FT_Int32 for LP64 platforms. + This function is designed for 32-bit integer, although + their arguments and return value are FT_Long. + + * src/base/ftobjs.c (FT_Get_Char_Index): Check `charcode' + is within unsigned 32-bit integer for LP64 platforms. + (FT_Face_GetCharVariantIndex): Check `charcode' and + `variantSelector' are within 32-bit integer for LP64 + platforms. + (FT_Face_GetCharsOfVariant): Check `variantSelector' is + within unsigned 32-bit integer for LP64 platforms. + + * src/base/fttrigon.c (ft_trig_downscale): The FT_Fixed + variable `val' and unsigned long constant FT_TRIG_SCALE + are casted to FT_UInt32, when calculates FT_UInt32. + (FT_Vector_Rotate): The long constant 1L is casted to + FT_Int32 to calculate FT_Int32 `half'. + +2009-07-31 suzuki toshiya + + cff: Cast the long variables to 32-bit for LP64 systems. + + * src/cff/cffdrivr.c (cff_get_advances): Insert + explicit cast to modify a 32-bit flag by unsigned + long constant. + + * src/cff/cffobjs.c (cff_face_init): Ditto. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): + Replace the casts to FT_Long by the casts to FT_Int32 + for LP64 platforms. + +2009-07-31 suzuki toshiya + + pcf: Improve PCF_PropertyRec.value names on LP64 platforms. + + * src/pcf/pcf.h: In PCF_PropertyRec.value, the member + `integer' is replaced by `l', `cardinal' is replaced + by `ul', to fix the difference between the name and + the types on LP64 platforms. + + * src/pcf/pcfdrivr.c (pcf_get_bdf_property): Reflect + PCF_PropertyRec.value change, with appropriate casts + to FT_Int32/FT_UInt32. Their destinations + BDF_PropertyRec.{integer|cardinal} are public and + explicitly defined as FT_Int32/FT_UInt32. + + * src/pcf/pcfread.c (pcf_get_properties, pcf_load_font): + Reflect PCF_PropertyRec.value change. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfdrivr.c (pcf_cmap_char_index): The type of + `code' is matched to PCF_Encoding->enc. + (pcf_cmap_char_next): The type of `charcode' is matched + to PCF_Encoding->enc. When *acharcode is set by charcode, + an overflow is checked and casted to unsigned 32-bit + integer. + +2009-07-31 suzuki toshiya + + bdf: Improve bdf_property_t.value names for LP64 platforms. + + * src/bdf/bdf.h: In bdf_property_t.value, the member + `int32' is replaced by `l', `card32' is replaced by + `ul', to fix the difference between the name and the + types on LP64 platforms. + + * src/bdf/bdfdrivr.c (BDF_Face_Init): Reflect + bdf_property_t.value change. + (bdf_get_bdf_property): Reflect bdf_property_t.value + change, with appropriate casts to FT_Int32/FT_UInt32. + Their destinations BDF_PropertyRec.{integer|cardinal} + are public and explicitly defined as FT_Int32/FT_UInt32. + + * src/bdf/bdflib.c (_bdf_add_property): Reflect + bdf_property_t.value change. + +2009-07-31 suzuki toshiya + + bdf: Fix some data types mismatching with their sources. + + * src/bdf/bdrdrivr.c (bdf_cmap_char_index): The type + of `code' is matched with BDF_encoding_el->enc. + (bdf_cmap_char_next): The type of `charcode' is + matched with BDF_encoding_el->enc. When *acharcode + is set by charcode, an overflow is checked and + casted to unsigned 32-bit integer. + +2009-07-31 suzuki toshiya + + autofit: Improve Unicode range definitions. + + * src/autofit/aftypes.h (AF_UNIRANGE_REC): New macro + to declare a range by two unsigned 32-bit integer, + to avoid 64-bit range definition on LP64 platforms. + + * src/autofit/aflatin.c (af_latin_uniranges): Ditto. + + * src/autofit/aflatin2.c (af_latin2_uniranges): Ditto. + + * src/autofit/afindic.c (af_indic_uniranges): Ditto. + + * src/autofit/afcjk.c (af_cjk_uniranges): Declare + the ranges by AF_UNIRANGE_REC. + +2009-07-31 suzuki toshiya + + smooth: Fix a data type mismatching with its source. + + * src/smooth/ftgrays.c (gray_sweep): The type of + `area' is matched with the 3rd argument `area' + of gray_hline(). + +2009-07-31 suzuki toshiya + + smooth: Fix a data type mismatching with its source. + + * src/smooth/ftgrays.c (gray_render_line): The type + of `area' is matched with TWorker.area. + +2009-07-31 suzuki toshiya + + cache: Disable the legacy compatibility if 16-bit system. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): Exclude + the legacy behaviour from 16-bit platform, because the + current hack cannot detect the caller uses this function + via legacy convension. + (FTC_SBitCache_Lookup): Ditto. + +2009-07-31 suzuki toshiya + + cache: Check 32-bit glyph index on 16-bit systems. + + * src/cache/ftcbasic.c (ftc_basic_family_get_count): + Check overflow caused by the face including large + number of glyphs > 64k. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftccache.c (ftc_cache_resize): The types of + `p', `mask', `count' are matched with FTC_Cache->{p,mask}. + (FTC_Cache_Clear): The type of `old_index' is matched to + FTC_Cache->{p,mask}. + + * src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): The type + of `_idx' is matched with FTC_Cache->{p,mask}. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftcsbits.c (ftc_snode_load): The types + of `xadvance' and `yadvance' are matched with + FT_GlyphSlot->advance.{x|y}. + +2009-07-31 suzuki toshiya + + cache: Cast NULL to a required function type explicitly. + + * src/cache/ftcmanag.c (FTC_Manager_RemoveFaceID): + Insert explicit cast from NULL to function type. + +2009-07-31 suzuki toshiya + + fttypes.h: Cast FT_MAKE_TAG output to FT_Tag exlicitly. + + * include/freetype/fttypes.h (FT_MAKE_TAG): + Cast the result to FT_Tag. + +2009-07-31 suzuki toshiya + + psnames: Handle Unicode codepoints by FT_UInt32 variables. + + * src/psnames/psmodule.c (BASE_GLYPH): Cast the result + to unsigned 32-bit integer for LP64 platform. + (ps_unicode_value): Return the value by unsigned 32-bit + integer instead of unsigned long. + +2009-07-31 suzuki toshiya + + psaux: Use size_t variable to pass the buffer size. + + * src/psaux/psaux.h (to_bytes): The type of `max_bytes' + (the argument to pass the buffer size) is changed to + size_t, to match with ANSI C string functions. + + * src/psaux/psconv.h (PS_Conv_StringDecode, + PS_Conv_ASCIIHexDecode, PS_Conv_EexecDecode): Ditto. + + * src/psaux/psconv.c (PS_Conv_StringDecode, + PS_Conv_ASCIIHexDecode, PS_Conv_EexecDecode): Ditto. + + * src/psaux/psobjs.h (ps_parser_to_bytes): Ditto. + + * src/psaux/psobjs.c (ps_parser_to_bytes): Ditto. + +2009-07-31 suzuki toshiya + + type1: Use size_t variable to pass the string length. + + * psaux.h: The type of `len' (the argument to pass + the buffer size to the function in AFM_ParserRec) + is changed to size_t, to match with ANSI C string + functions. + + * t1afm.c (t1_get_index): Ditto. + + * test_afm.c (dummy_get_index): Ditto. + + * afmparse.c (afm_parser_read_vals): To call + AFM_ParserRec.get_index, the length of token + `len' is casted to size_t. + +2009-07-31 suzuki toshiya + + cid: Fix some data types mismatching with their sources. + + * src/cid/cidparse.c (cid_parser_new): The types of + `read_len' and `stream_len' are matched to + FT_Stream->size. Unrequired cast is removed. + +2009-07-31 suzuki toshiya + + cff: Fix for unused variable `rest'. + + * src/cff/cffparse.c (cff_parse_real): Insert + FT_UNUSED() to hide the unused variable warning. + +2009-07-31 suzuki toshiya + + cff: Fix some data types mismatching with their sources. + + * src/cff/cffgload.c (cff_slot_load): The types of + `top_upm' and `sub_upm' are matched with + CFF_FontRecDict->units_per_em. + + * src/cff/cffobjs.c (cff_size_select): Ditto. + (cff_size_request): Ditto. + +2009-07-31 suzuki toshiya + + bdf: Fix some data types mismatching with their sources. + + * bdflib.c (_bdf_list_ensure): The type of `num_items' + is matched with _bdf_list_t.used. Also the types of + `oldsize', `newsize', `bigsize' are matched too. + (_bdf_readstream): `cursor' is used as an offset to + the pointer, it should be typed as FT_Offset. Also + the types of `bytes', `start', `end', `avail' are matched. + + * bdfdrivr.c: The type of BDF_CMap->num_encodings is + matched with FT_CMap->clazz->size. + (bdf_cmap_char_index): The types of `min', `max', `mid' + are matched with BDF_CMap->num_encodings. The type of + `result' is matched with encoding->glyph. + (bdf_cmap_char_next): Ditto, the type of `code' is + matched with BDF_encoding_el.enc. + (bdf_interpret_style): The type of `lengths' is changed + to size_t, to take the value by ft_strlen(). Also the + types of `len', `nn', `mm' are matched. + +2009-07-31 suzuki toshiya + + sfnt: Count the size of the memory object by ptrdiff_t. + + * src/sfnt/ttbdf.c (tt_face_find_bdf_prop): The type of + `peroperty_len' is changed from FT_UInt to FT_Offset, + to match with size_t, which is appropriate type for the + object in the memory buffer. + +2009-07-31 suzuki toshiya + + lzw: Count the size of the memory object by ptrdiff_t. + + * src/lzw/ftzopen.h: The types of FT_LzwState->{buf_total, + stack_size} are changed from FT_UInt to FT_Offset, to match + with size_t, which is appropriate type for the object in + the memory buffer. + + * src/lzw/ftzopen.c (ft_lzwstate_stack_grow): The types of + `old_size' and `new_size' are changed from FT_UInt to + FT_Offset, to match with size_t, which is appropriate type + for the object in the memory buffer. + +2009-07-31 suzuki toshiya + + otvalid: Count the table size on memory by ptrdiff_t. + + * src/otvalid/otvgpos.c (otv_ValueRecord_validate): + Change the type of table size from FT_UInt to + FT_PtrDist because it is calculated by the memory + addresses. + +2009-07-31 suzuki toshiya + + otvalid: Prevent an overflow by GPOS/GSUB 32b-bit offset. + + * src/otvalid/otvgpos.c (otv_ExtensionPos_validate): + Extend ExtensionOffset from FT_UInt to FT_ULong, to + cover 32-bit offset on 16-bit platform. + + * src/otvalid/otvgsub.c (otv_ExtensionSubst_validate): + Ditto. + +2009-07-31 suzuki toshiya + + ftobjs.c: Prevent an overflow in glyph index handling. + + * src/base/ftobjs.c (FT_Face_GetCharsOfVariant): + Improve the cast in comparison to avoid the truncation. + +2009-07-31 suzuki toshiya + + Improve the variable types in raccess_make_file_name(). + + * src/base/ftrfork.c (raccess_make_file_name): + Change the type of cursor variable `tmp' to const char*, + to prevent the unexpected modification of original pathname. + (raccess_make_file_name): Change the type of new_length + to size_t. + +2009-07-31 suzuki toshiya + + ftpatent.c: Fix for unused variable `error'. + + * src/base/ftpatent.c (_tt_check_patents_in_range): + Fix warning for unused variable `error'. + +2009-07-31 suzuki toshiya + + type1: Check invalid string longer than PostScript limit. + + * src/type1/t1afm.c (t1_get_index): Check invalid string + which exceeds the limit of PostScript string/name objects. + +2009-07-31 suzuki toshiya + + gzip: Use FT2 zcalloc() & zfree() in ftgzip.c by default. + + * src/gzip/ftgzip.c (zcalloc, zcfree): Disable all + zcalloc() & zfree() by zlib in zutil.c, those in + ftgzip.c by FT2 are enabled by default. To use + zlib zcalloc() & zfree(), define USE_ZLIB_ZCALLOC. + See discussion: + http://lists.gnu.org/archive/html/freetype-devel/2009-02/msg00000.html + +2009-07-31 suzuki toshiya + + gzip: Distinguish PureC from TurboC on MSDOS. + + * src/gzip/zutil.c (zcalloc, zcfree): Enable only for + MSDOS platform. + +2009-07-31 suzuki toshiya + + gxvalid: Insert PureC pragma to allow unevaluated variables. + + * builds/atari/ATARI.H: Insert PureC pragma not to + warn against set-but-unevaluated variable in gxvalid + module. + +2009-07-31 suzuki toshiya + + gxvalid: Pass the union by the pointer instead of the value. + + * src/gxvalid/gxvcommn.h: + - Declare new type `GXV_LookupValueCPtr'. + - Update the type of the 2nd argument to pass GXV_LookupValueDesc + data to the function prototyped as GXV_Lookup_Value_Validate_Func, + from GXV_LookupValueDesc to GXV_LookupValueCPtr. + - Likewise for the function prototyped as + GXV_Lookup_Fmt4_Transit_Func. + + - Declare new type `GXV_StateTable_GlyphOffsetCPtr'. + - Update the type of the 3rd argument to pass + GXV_StateTable_GlyphOffsetDesc data to the function prototyped + as GXV_StateTable_Entry_Validate_Func, from + GXV_StateTable_GlyphOffsetDesc to GXV_StateTable_GlyphOffsetCPtr. + + - Declare new type `GXV_XStateTable_GlyphOffsetCPtr'. + - Update the type of the 3rd argument to pass + GXV_XStateTable_GlyphOffsetDesc data to the function prototyped + as GXV_XStateTable_Entry_Validate_Func, + from GXV_XStateTable_GlyphOffsetDesc + to GXV_XStateTable_GlyphOffsetCPtr. + + * src/gxvalid/gxvcommn.c (gxv_LookupTable_fmt0_validate, + gxv_XClassTable_lookupval_validate, + gxv_XClassTable_lookupfmt4_transit): + Update from GXV_LookupValueDesc to GXV_LookupValueCPtr. + + * src/gxvalid/gxvbsln.c (gxv_bsln_LookupValue_validate, + gxv_bsln_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvjust.c + (gxv_just_pcTable_LookupValue_entry_validate, + gxv_just_classTable_entry_validate, + gxv_just_wdcTable_LookupValue_validate): Ditto. + + * src/gxvalid/gxvkern.c + (gxv_kern_subtable_fmt1_entry_validate): Ditto. + + * src/gxvalid/gxvlcar.c (gxv_lcar_LookupValue_validate, + gxv_lcar_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvopbd.c (gxv_opbd_LookupValue_validate, + gxv_opbd_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvprop.c (gxv_prop_LookupValue_validate, + gxv_prop_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvmort4.c + (gxv_mort_subtable_type4_lookupval_validate): Ditto. + + * src/gxvalid/gxvmort0.c + (gxv_mort_subtable_type0_entry_validate): Update + from GXV_StateTable_GlyphOffsetDesc + to GXV_StateTable_GlyphOffsetCPtr. + + * src/gxvalid/gxvmort1.c + (gxv_mort_subtable_type1_entry_validate): Ditto. + + * src/gxvalid/gxvmort2.c + (gxv_mort_subtable_type2_entry_validate): Ditto. + + * src/gxvalid/gxvmort5.c + (gxv_mort_subtable_type5_entry_validate): Ditto. + + * src/gxvalid/gxvmorx2.c + (gxv_morx_subtable_type2_entry_validate): Ditto. + + * src/gxvalid/gxvmorx5.c + (gxv_morx_subtable_type5_entry_validate): Ditto. + + * src/gxvalid/gxvmorx1.c + (gxv_morx_subtable_type1_entry_validate): Ditto. + (gxv_morx_subtable_type1_LookupValue_validate, + gxv_morx_subtable_type1_LookupFmt4_transit): + Update from GXV_LookupValueDesc to GXV_LookupValueCPtr. + + * src/gxvalid/gxvmorx0.c + (gxv_morx_subtable_type0_entry_validate): Update + from GXV_XStateTable_GlyphOffsetDesc + to GXV_XStateTable_GlyphOffsetCPtr. + +2009-07-29 Fabrice Bellet + + Fix Redhat bugzilla #513582 and Savannah bug #26849. + + * src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP) : Fix + aliasing bug. + +2009-07-19 Werner Lemberg + + Document recent library changes. + + * docs/CHANGES: Do it. + +2009-07-17 Werner Lemberg + + Fix Savannah bug #23786. + + * src/truetype/ttobjs.c (tt_size_init_bytecode): Don't reset x_ppem + and y_ppem. Otherwise the `*_CVT_Stretched' functions in ttinterp.c + get never called. + An anonymous guy suggested this change on Savannah, and it seems to + be the right solution. + +2009-07-15 Werner Lemberg + + * docs/release: Updated. + +2009-07-15 Werner Lemberg + + README.CVS -> README.git + + * README.CVS: Renamed to... + * README.git: This. + Updated. + +2009-07-15 suzuki toshiya + + Borland C++ compiler patch proposed by Mirco Babin. + http://lists.gnu.org/archive/html/freetype/2009-07/msg00016.html. + + * builds/exports.mk: Delete unused flags, CCexe_{CFLAGS,LDFLAGS}. + Fix APINAMES_C and APINAMES_EXE pathnames to reflect the platform + specific pathname syntax. + * builds/compiler/bcc.mk: Remove unused flag, CCexe_LDFLAGS. + Define TE = `-e' separately (bcc32 cannot specify the pathname of + binary executable by T = `-o'). + Extend the large page size in linking freetype.lib. + Add extra CLEAN target to delete bcc specific temporary files. + * builds/compiler/bcc-dev.mk: Ditto. + +2009-07-14 Werner Lemberg + + Fix Savannah bug #27026. + + * builds/win32/vc2005/freetype.sln: Use correct version number. + +2009-07-12 suzuki toshiya + + Add a script to check the undefined and unused trace macros. + + * src/tools/chktrcmp.py: A script to check trace_XXXX macros + that are used in C source but undefined in fttrace.h, or + defined in fttrace.h but unused in C sources. See + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00013.html. + * docs/DEBUG: Mention on chktrcmp.py. + * docs/release: Ditto. + +2009-07-09 Werner Lemberg + + [ftraster] Make it compile again with -D_STANDALONE_. + + * src/raster/ftraster.c [_STANDALONE_]: Define + FT_CONFIG_STANDARD_LIBRARY_H. + Include `string.h'. + Don't include `rastpic.h'. + Define FT_DEFINE_RASTER_FUNCS. + +2009-07-09 suzuki toshiya + + smooth: Check glyph size by width/height, instead of pitch/height. + Suggested by der Mouse . + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Improve + the check for too large glyph. Replace the pair of `pitch' and + `height' by the pair of `width' and `height'. `pitch' cannot + be greater than `height'. The required is checking the product + `pitch' * `height' <= FT_ULONG_MAX, but we use cheap checks for + the realistic case only. + +2009-07-09 suzuki toshiya + + Register 2 missing trace components, t1afm and ttbdf. + + * include/freetype/internal/fttrace.h: Add FT_TRACE_DEF( t1afm ) + and FT_TRACE_DEF( ttbdf ). See + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00013.html + +2009-07-09 suzuki toshiya + + Register a trace component for ftgloadr.c. + + * include/freetype/internal/fttrace.h: Add FT_TRACE_DEF( gloader ). + The macro `trace_gloader' was already used in the initial version + on 2002-02-24. + +2009-07-08 suzuki toshiya + + Prevent the overflows by a glyph with too many points or contours. + The bug is reported by Boris Letocha . See + http://lists.gnu.org/archive/html/freetype-devel/2009-06/msg00031.html + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00002.html + + * include/freetype/ftimage.h (FT_OUTLINE_CONTOURS_MAX, + FT_OUTLINE_POINTS_MAX): New macros to declare the maximum + values of FT_Outline.{n_contours,n_points}. + * src/base/ftgloadr.c (FT_GlyphLoader_CheckPoints): Check the + total numbers of points and contours cause no overflows in + FT_Outline.{n_contours,n_points}. + + * include/freetype/internal/ftgloadr.h (FT_GLYPHLOADER_CHECK_P, + FT_GLYPHLOADER_CHECK_C): Compare the numbers of points and + contours as unsigned long number, instead of signed int, to + prevent the overflows on 16-bit systems. + +2009-07-05 Bram Tassyns + + Improve compatibility to Acroread. + This fixes Savannah bug #26944. + + * src/cff/cffload.c (cff_charset_compute_cids): For multiple GID to + single CID mappings, make the lowest value win. + +2009-06-28 suzuki toshiya + + ftpatent: Fix a bug by wrong usage of service->table_info(). + http://lists.gnu.org/archive/html/freetype-devel/2008-12/msg00039.html + + * include/freetype/internal/services/svsfnt.h: Extend + FT_SFNT_TableInfoFunc() to take new argument to obtain the offset + to the specified table. + * src/sfnt/sfdriver.c (sfnt_table_info): Extend to return the + table-offset to the caller function. + * src/base/ftpatent.c (_tt_check_patents_in_table): Use new + service->table_info(). + * src/base/ftobjs.c (FT_Sfnt_Table_Info): Synchronize to new + service->table_info(). + +2009-06-28 Werner Lemberg + + [psaux, cff] Protect against nested `seac' calls. + + * include/freetype/internal/psaux.h (T1_Decoder), src/cff/cffgload.h + (CFF_Decoder): Add `seac' boolean variable. + + * src/cff/cffgload.c (cff_operator_seac), src/psaux/t1decode.c + (t1operator_seac): Use it. + +2009-06-28 Werner Lemberg + + Thinko. + + * src/psaux/t1decode.c (t1operator_seac) + [FT_CONFIG_OPTION_INCREMENTAL]: Test for existence of incremental + interface. + +2009-06-28 Werner Lemberg + + * devel/ftoption.h [FT_CONFIG_OPTION_INCREMENTAL]: Define. + +2009-06-27 suzuki toshiya + + Add tools to preprocess the source files for AtariST PureC. + + * builds/atari/deflinejoiner.awk: New file to filter C source files + for broken C preprocessor of PureC compiler. + + * builds/atari/gen-purec-patch.sh: New file to generate a patch set + for PureC, by using deflinejoiner.awk. + +2009-06-27 suzuki toshiya + + Keep existing modules.cfg in the building tree. + + * configure: If `configure' is executed outside of the source tree, + an existing `modules.cfg' file in the build directory should be + kept, not overwritten by the version in the source tree. + +2009-06-27 suzuki toshiya + + Filter --srcdir= option before invoking builds/unix/configure. + + * configure: If builds/unix/configure is invoked with --srcdir + option, the option should take `builds/unix' directory instead of + the top source directory. Thus the configure script in the top + directory should modify the --srcdir= option if + `builds/unix/configure' is invoked. + +2009-06-27 suzuki toshiya + + Improve configure.raw for cross-building on exe-suffixed systems. + + * builds/unix/configure.raw: Fix a bug in sed script to extract + native suffix for binary executables, patch by Peter Breitenlohner. + http://lists.gnu.org/archive/html/freetype-devel/2009-04/msg00036.html + +2009-06-26 Werner Lemberg + + [truetype] Remove TT_SubGlyphRec. + + * src/truetype/ttobjs.h (TT_SubGlyphRec): Removed, unused. + +2009-06-26 Werner Lemberg + + * */*: For warning messages, replace FT_ERROR with FT_TRACE0. + + FT_ERROR is now used only if a function produces a non-zero `error' + value. + + Formatting, improving and harmonizing debug strings. + +2009-06-25 Werner Lemberg + + Provide version information better. + + * src/base/ftinit.c (FT_Init_FreeType): Don't set version here + but... + * src/base/ftobjs.c (FT_New_Library): Here. + +2009-06-22 Werner Lemberg + + Use 16.16 format while parsing Type 1 charstrings. + This fixes Savannah bug #26867. + + Previously, only integers have been used which can lead to serious + rounding errors. + + However, fractional values are only used internally; after the + charstrings (of either Type 1 or 2) have been processed, the + resulting coordinates get rounded to integers currently -- before + applying scaling. This should be fixed; at the same time a new load + flag should be introduced, to be used in combination with + FT_LOAD_NO_SCALE, which indicates that font units are returned in + 16.16 format. Similarly, the incremental interface should be + extended to allow fractional values for metrics. + + * include/freetype/internal/psaux.h (T1_BuilderRec): Remove `shift' + field. + * include/freetype/internal/pshints.h (T1_Hints_SetStemFunc, + T1_Hints_SetStem3Func): Use FT_Fixed for coordinates. + + * src/psaux/psobjs.c: Include FT_INTERNAL_CALC_H. + (t1_build_add_point): Always convert fixed to integer. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): + Use 16.16 format everywhere (except for large integers followed by a + `div'). + [CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS]: Remove #ifdef and activate + code uncoditionally. + Add support for random numbers and update remaining code + accordingly; this should work now. + (t1_operator_seac): Updated. + * src/psaux/pshrec.c: Include FT_INTERNAL_CALC_H. + (ps_hints_t1stem3, t1_hints_stem): Updated. + + * src/cid/cidgload.c: Include FT_INTERNAL_CALC_H. + (cid_load_glyph) [FT_CONFIG_OPTION_INCREMENTAL], + (cid_face_compute_max_advance, cid_slot_load_glyph): Updated. + + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String) + [FT_CONFIG_OPTION_INCREMENTAL], (T1_Get_Advances, T1_Load_Glyph): + Updated. + * src/type1/t1load.c: Include FT_INTERNAL_CALC_H. + * src/type1/t1objs.c (T1_Face_Init): Updated. + +2009-06-21 Werner Lemberg + + * src/pshinter/pshrec.c: Use PSH_Err_Ok. + +2009-06-21 Werner Lemberg + + Code beautification. + + * src/type1/t1load.c (FT_INT_TO_FIXED): Removed. + Replace everywhere with INT_TO_FIXED. + (FT_FIXED_TO_INT): Move to ... + * include/freetype/internal/ftcalc.h (FIXED_TO_INT): Here. + Update all users. + +2009-06-20 Werner Lemberg + + Remove unused variables. + + * include/freetype/internal/psaux.h (T1_BuilderRec), + src/cff/cffgload.h (CFF_Builder): Remove `last'. + Update all users. + +2009-06-20 Werner Lemberg + + [psaux] Check large integers while parsing charstrings. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Large + integers must be followed by a `div' operator. + +2009-06-20 Werner Lemberg + + [cff] Revert last change. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): Do it. + Next time, don't confuse Type 2 charstring opcodes with TOP DICT + values... + +2009-06-20 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_metrics_check_digits): Fix + compiler warning. + +2009-06-20 Werner Lemberg + + * builds/compiler/gcc.mk (CFLAGS): Use -O3, not -O6. + +2009-06-19 Werner Lemberg + + [cff] Fix handling of reserved byte 0xFF. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): Abort if byte + 0xFF is encountered. + +2009-06-19 Werner Lemberg + + Improve debug messages for Type1 charstrings. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Emit newlines + after instructions. + Prettify output. + +2009-06-19 Werner Lemberg + + More ftgray fixes for FT_STATIC_RASTER. + Problems reported by suyu@cooee.cn. + + * src/smooth/ftgrays.c (gray_move_to, gray_raster_render): Use + RAS_VAR. + +2009-06-18 Werner Lemberg + + * docs/CHANGES: Updated. + +2009-06-18 Werner Lemberg + + Fix B/W rasterization of subglyphs with different drop-out modes. + + Normally, the SCANMODE instruction (if present) to set the drop-out + mode in a TrueType font is located in the `prep' table only and thus + valid for all glyphs. However, there are fonts like `pala.ttf' + which additionally contain this instruction in the hinting code of + some glyphs (but not all). As a result it can happen that a + composite glyph needs multiple drop-out modes for its subglyphs + since the rendering state gets reset for each subglyph. + + FreeType collects the hinted outlines from all subglyphs, then it + sends the data to the rasterizer. It also sends the drop-out mode + -- after hinting has been applied -- and here is the error: It sends + the drop-out mode of the last subglyph only; drop-out modes of all + other subglyphs are lost. + + This patch fixes the problem; it adds a second, alternative + mechanism to pass the drop-out mode: For each contour, the + rasterizer now checks the first `tags' array element. If bit 2 is + set, bits 5-7 contain the contour's drop-out mode, overriding the + global drop-out mode. + + * include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro. + + * src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in + `tags[0]'. + + * src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom): + Use bits 3-5 instead of 0-2. + (New_Profile): Set the drop-out mode in the profile's `flags' field. + (Decompose_Curve): Check `tags[0]' and set `dropOutControl' if + necessary. + (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out + mode. + +2009-06-16 Werner Lemberg + + Improve scan conversion rules 4 and 6. + + Two new constraints are introduced to better identify a `stub' -- a + concept which is only vaguely described in the OpenType + specification. The old code was too rigorous and suppressed more + pixel than it should. + + . The intersection of the two profiles with the scanline is less + than a half pixel. Code related to this was already present in + the sources but has been commented out. + + . The endpoint of the original contour forming a profile has a + distance (`overshoot') less than half a pixel to the scanline. + + Note that the two additional conditions fix almost all differences + to the Windows rasterizer, but some problematic cases remain. + + * src/raster/ftraster.c (Overshoot_Top, Overshoot_Bottom): New + macros for the `flags' field in the `TProfile' structure. + (IS_BOTTOM_OVERSHOOT, IS_TOP_OVERSHOOT): New macros. + (New_Profile, End_Profile): Pass overshoot flag as an argument and + set it accordingly. + Update callers. + (Vertical_Sweep_Drop, Horizontal_Sweep_Drop): Implement the two new + constraints. + +2009-06-11 Werner Lemberg + + Increase precision for B/W rasterizer. + + * src/raster/ftraster.c (Set_High_Precision): Add two more bits to + the precision. This corrects rendering of some small glyphs, for + example, glyph `xi' in verdana.ttf at 13 ppem. Testing with ftbench + on my GNU/Linux box I don't see a performance degradation. + +2009-06-08 Michael Zucchi + + Handle FT_STROKER_LINECAP_BUTT. + This fixes Savannah bug #26757. + + * src/base/ftstroke.c (ft_stroker_cap): Implement it. + +2009-06-07 Harald Fernengel + + Fix some potential out-of-memory crashes. + + * src/base/ftobjs.c (ft_glyphslot_done): Check `slot->internal'. + * src/base/ftstream.c (FT_Stream_ReleaseFrame): Check `stream'. + * src/truetype/ttinterp.c (TT_New_Context): Avoid double-free of + `exec' in case of failure. + +2009-06-07 Werner Lemberg + + Simplify math. + Suggested by Alexei Podtelezhnikov . + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Do it. + +2009-06-04 Werner Lemberg + + Preparation for fixing scan conversion rules 4 and 6. + + * src/raster/ftraster.c (TFlow): Replace enumeration with... + (Flow_Up): This macro. + (TProfile): Replace `flow' member with `flags' bit field. + Update all affected code. + +2009-05-29 James Cloos + + Enable autohinting for glyphs rotated by multiples of 90°. + + * src/base/ftobjs.c (FT_Load_Glyph): Alter check for permitted + matrices to allow rotations by multiples of 90°, not only unrotated, + possibly slanted matrices. + +2009-05-28 Werner Lemberg + + Remove compiler warning. + Reported by Krzysztof Kowalczyk . + + * src/autofit/aflatin2.c (af_latin2_hint_edges): Move declaration of + `n_edges' into `#if' block. + +2009-05-28 Werner Lemberg + + Make compilation work with FT_CONFIG_OPTION_USE_ZLIB not defined. + Reported by Krzysztof Kowalczyk . + + * src/pcf/pcfdrivr.c (PCF_Face_Init) [!FT_CONFIG_OPTION_USE_ZLIB]: + Make it work. + Simplify #ifdef logic. + +2009-05-22 Werner Lemberg + + Improve b/w rasterizer. + Problem reported by Krzysztof Kotlenga . + + * src/raster/raster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): For smart drop-out mode, if + intersections are equally distant relative to next pixel center, + select the left pixel, not the right one. + +2009-05-19 Werner Lemberg + + Fix Savannah bug #26600. + + * src/type42/t42parse.c (t42_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + +2009-04-30 Werner Lemberg + + Document recent changes to ftview. + + * docs/CHANGES: Do it. + +2009-04-27 Werner Lemberg + + autohinter: Don't change digit widths if all widths are the same. + This fixes FreeDesktop bug #21197. + + * src/autofit/afglobal.c (AF_DIGIT): New macro. + (af_face_globals_compute_script_coverage): Mark ASCII digits in + `glyph_scripts' array. + (af_face_globals_get_metrics): Updated. + (af_face_globals_is_digit): New function. + * src/autofit/afglobal.h: Updated. + (AF_ScriptMetricsRec): Add `digits_have_same_width' flag. + + * src/autofit/aflatin.c: Include FT_ADVANCES_H. + (af_latin_metrics_check_digits): New function. + (af_latin_metrics_init): Use it. + * src/autofit/aflatin.h: Updated. + * src/autofit/afcjk.c (af_cjk_metrics_init): Updated. + + * src/autofit/aflatin2.c: Similar changes as with aflatin.c. + + * src/autofit/afloader.c (af_loader_load_g): Test digit width. + + * docs/CHANGES: Document it. + +2009-04-26 Werner Lemberg + + Make ftgrays compile with _STANDALONE_ and FT_STATIC_RASTER again. + Problems reported by suyu@cooee.cn. + + * src/smooth/ftgrays.c (FT_DEFINE_OUTLINE_FUNCS, + FT_DEFINE_RASTER_FUNCS) [_STANDALONE_]: Define. + [!_STANDALONE_]: Include ftspic.h only here. + (ras): Define/declare after definition of `TWorker'. + Use `RAS_VAR_' where necessary. + +2009-04-21 Karl Berry + + Fix AC_CHECK_FT2. + + * builds/unix/freetype2.m4: Only check PATH for freetype-config if + we did not already find it from a prefix option. + +2009-04-05 Oran Agra + + Add #error to modules and files that do not support PIC yet. + + When FT_CONFIG_OPTION_PIC is defined the following files will + create #error: + * src/bdf/bdfdrivr.h + * src/cache/ftcmanag.c + * src/cid/cidriver.h + * src/gxvalid/gxvmod.h + * src/gzip/ftgzip.c + * src/lzw/ftlzw.c + * src/otvalid/otvmod.h + * src/pcf/pcfdrivr.h + * src/pfr/pfrdrivr.h + * src/psaux/psauxmod.h + * src/type1/t1driver.h + * src/type42/t42drivr.h + * src/winfonts/winfnt.h + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in autofit module. + + * include/freetype/internal/autohint.h add macros to init + instances of FT_AutoHinter_ServiceRec. + + * src/autofit/afmodule.h declare autofit_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/autofit/afmodule.c when FT_CONFIG_OPTION_PIC is defined + af_autofitter_service and autofit_module_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from afpic.h in order to access them. + + * src/autofit/aftypes.h add macros to init and declare + instances of AF_ScriptClassRec. + + * src/autofit/afcjk.h declare af_cjk_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afcjk.c when FT_CONFIG_OPTION_PIC is defined + af_cjk_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/afdummy.h declare af_dummy_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afdummy.c when FT_CONFIG_OPTION_PIC is defined + af_dummy_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/afindic.h declare af_indic_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afindic.c when FT_CONFIG_OPTION_PIC is defined + af_indic_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/aflatin.h declare af_latin_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/aflatin.c when FT_CONFIG_OPTION_PIC is defined + af_latin_script_class struct will have function to init it instead of + being allocated in the global scope. + Change af_latin_blue_chars to be PIC-compatible by being a two + dimentional array rather than array of pointers. + + + * src/autofit/aflatin2.h declare af_latin2_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/aflatin2.c when FT_CONFIG_OPTION_PIC is defined + af_latin2_script_class struct will have function to init it instead of + being allocated in the global scope. + Change af_latin2_blue_chars to be PIC-compatible by being a two + dimentional array rather than array of pointers. + + * src/autofit/afglobal.c when FT_CONFIG_OPTION_PIC is defined + af_script_classes array initialization was moved to afpic.c and + is later refered using macros defeined in afpic.h. + + New Files: + * src/autofit/afpic.h declare struct to hold PIC globals for autofit + module and macros to access them. + * src/autofit/afpic.c implement functions to allocate, destroy and + initialize PIC globals for autofit module. + + * src/autofit/autofit.c add new file to build: afpic.c. + * src/autofit/jamfile add new files to FT2_MULTI build: afpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in pshinter module. + + * include/freetype/internal/pshints.h add macros to init + instances of PSHinter_Interface. + + * src/pshinter/pshmod.h declare pshinter_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/pshinter/pshmod.c when FT_CONFIG_OPTION_PIC is defined + pshinter_interface and pshinter_module_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from pshpic.h in order to access them. + + New Files: + * src/pshinter/pshpic.h declare struct to hold PIC globals for pshinter + module and macros to access them. + * src/pshinter/pshpic.c implement functions to allocate, destroy and + initialize PIC globals for pshinter module. + + * src/pshinter/pshinter.c add new file to build: pshpic.c. + * src/pshinter/jamfile add new files to FT2_MULTI build: pshpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in psnames module. + + * include/freetype/internal/services/svpscmap.h add macros to init + instances of FT_Service_PsCMapsRec. + + * src/psnames/psmodule.h declare psnames_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/psnames/psmodule.c when FT_CONFIG_OPTION_PIC is defined + pscmaps_interface and pscmaps_services structs + and psnames_module_class array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from pspic.h in order to access them. + + New Files: + * src/psnames/pspic.h declare struct to hold PIC globals for psnames + module and macros to access them. + * src/psnames/pspic.c implement functions to allocate, destroy and + initialize PIC globals for psnames module. + + * src/psnames/psnames.c add new file to build: pspic.c. + * src/psnames/jamfile add new files to FT2_MULTI build: pspic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in raster renderer. + + * src/raster/ftrend1.h declare ft_raster1_renderer_class + and ft_raster5_renderer_class + using macros from ftrender.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/smooth/ftrend1.c when FT_CONFIG_OPTION_PIC is defined + ft_raster1_renderer_class and ft_raster5_renderer_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + Macros will be used from rastpic.h in order to access + ft_standard_raster from the pic_container (allocated in ftraster.c). + In ft_raster1_render when PIC is enabled, the last letter of + module_name is used to verfy the renderer class rather than the + class pointer. + + * src/raster/ftraster.c when FT_CONFIG_OPTION_PIC is defined + ft_standard_raster struct will have function to init it + instead of being allocated in the global scope. + + New Files: + * src/raster/rastpic.h declare struct to hold PIC globals for raster + renderer and macros to access them. + * src/raster/rastpic.c implement functions to allocate, destroy and + initialize PIC globals for raster renderer. + + * src/raster/raster.c add new file to build: rastpic.c. + * src/raster/jamfile add new files to FT2_MULTI build: rastpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in smooth renderer. + + * src/smooth/ftsmooth.h declare ft_smooth_renderer_class, + ft_smooth_lcd_renderer_class and ft_smooth_lcd_v_renderer_class + using macros from ftrender.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/smooth/ftsmooth.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + ft_smooth_renderer_class, ft_smooth_lcd_renderer_class + and ft_smooth_lcd_v_renderer_class + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from ftspic.h in order to access + ft_grays_raster from the pic_container (allocated in ftgrays.c). + + * src/smooth/ftgrays.h include FT_CONFIG_CONFIG_H + * src/smooth/ftgrays.c when FT_CONFIG_OPTION_PIC is NOT defined + func_interface was moved from gray_convert_glyph_inner function + to the global scope. + When FT_CONFIG_OPTION_PIC is defined + func_interface and ft_grays_raster structs + will have functions to init them + instead of being allocated in the global scope. + And func_interface will be allocated on the stack of + gray_convert_glyph_inner. + + New Files: + * src/smooth/ftspic.h declare struct to hold PIC globals for smooth + renderer and macros to access them. + * src/smooth/ftspic.c implement functions to allocate, destroy and + initialize PIC globals for smooth renderer. + + * src/smooth/smooth.c add new file to build: ftspic.c. + * src/smooth/jamfile add new files to FT2_MULTI build: ftspic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in cff driver. + + * include/freetype/internal/services/svcid.h add macros to init + instances of FT_Service_CIDRec. + * include/freetype/internal/services/svpsinfo.h add macros to init + instances of FT_Service_PsInfoRec. + + * src/cff/cffcmap.h declare cff_cmap_encoding_class_rec + and cff_cmap_unicode_class_rec using macros from + ftobjs.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/cff/cffcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + cff_cmap_encoding_class_rec and cff_cmap_unicode_class_rec + will have functions to init or create and destroy them + instead of being allocated in the global scope. + + * src/cff/cffdrivr.h declare cff_driver_class using macros from + ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/cff/cffdrivr.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + cff_service_glyph_dict, cff_service_ps_info, cff_service_ps_name + cff_service_get_cmap_info, cff_service_cid_info, cff_driver_class, + and cff_services array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from cffpic.h in order to access them + from the pic_container. + Use macros from cffpic.h in order to access the + structs allocated in cffcmap.c + + * src/cff/cffobjs.c Use macros from cffpic.h in order to access the + structs allocated in cffcmap.c + + * src/cff/parser.c when FT_CONFIG_OPTION_PIC is defined + implement functions to create and destroy cff_field_handlers array + instead of being allocated in the global scope. + And macros will be used from cffpic.h in order to access it + from the pic_container. + + New Files: + * src/cff/cffpic.h declare struct to hold PIC globals for cff + driver and macros to access them. + * src/cff/cffpic.c implement functions to allocate, destroy and + initialize PIC globals for cff driver. + + * src/cff/cff.c add new file to build: cffpic.c. + * src/cff/jamfile add new files to FT2_MULTI build: cffpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in sfnt driver. + + * include/freetype/internal/services/svbdf.h add macros to init + instances of FT_Service_BDFRec. + * include/freetype/internal/services/svgldict.h add macros to init + instances of FT_Service_GlyphDictRec. + * include/freetype/internal/services/svpostnm.h add macros to init + instances of FT_Service_PsFontNameRec. + * include/freetype/internal/services/svsfnt.h add macros to init + instances of FT_Service_SFNT_TableRec. + * include/freetype/internal/services/svttcmap.h add macros to init + instances of FT_Service_TTCMapsRec. + * include/freetype/internal/sfnt.h add macros to init + instances of SFNT_Interface. + + * src/sfnt/sfdriver.h declare sfnt_module_class using macros from + ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/sfnt/sfdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + sfnt_service_sfnt_table, sfnt_service_glyph_dict, sfnt_service_ps_name + tt_service_get_cmap_info, sfnt_service_bdf, sfnt_interface, + sfnt_module_class, and sfnt_services array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from sfntpic.h in order to access them + from the pic_container. + + * src/sfnt/ttcmap.h add macros to init + instances of TT_CMap_ClassRec. + * src/sfnt/ttcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + tt_cmap0_class_rec, tt_cmap2_class_rec, tt_cmap4_class_rec + tt_cmap6_class_rec, tt_cmap8_class_rec, tt_cmap10_class_rec, + tt_cmap12_class_rec, tt_cmap14_class_rec and tt_cmap_classes array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from sfntpic.h in order to access them + from the pic_container. + The content of tt_cmap_classes is now described in the + new file 'ttcmapc.h'. + + New Files: + * src/sfnt/sfntpic.h declare struct to hold PIC globals for sfnt + driver and macros to access them. + * src/sfnt/sfntpic.c implement functions to allocate, destroy and + initialize PIC globals for sfnt driver. + * src/sfnt/ttcmapc.h describing the content of + tt_cmap_classes allocated in ttcmap.c + + * src/sfnt/sfnt.c add new file to build: sfntpic.c. + * src/sfnt/jamfile add new files to FT2_MULTI build: sfntpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in truetype driver. + + * include/freetype/internal/services/svmm.h add macros to init + instances of FT_Service_MultiMastersRec. + * include/freetype/internal/services/svttglyf.h add macros to init + instances of FT_Service_TTGlyfRec. + + * src/truetype/ttdriver.h declare tt_driver_class using macros from + ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/truetype/ttdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + tt_service_gx_multi_masters, tt_service_truetype_glyf, tt_driver_class + and tt_services array, + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from ttpic.h in order to access them + from the pic_container. + * src/truetype/ttobjs.c change trick_names array to be + PIC-compatible by being a two dimentional array rather than array + of pointers. + + New Files: + * src/truetype/ttpic.h declare struct to hold PIC globals for truetype + driver and macros to access them. + * src/truetype/ttpic.c implement functions to allocate, destroy and + initialize PIC globals for truetype driver. + + * src/truetype/truetype.c add new file to build: ttpic.c. + * src/truetype/jamfile add new files to FT2_MULTI build: ttpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support and infrastructure in base. + + * include/freetype/config/ftoption.h add FT_CONFIG_OPTION_PIC + * include/freetype/internal/ftobjs.h Add pic_container member to + FT_LibraryRec. + Add macros to declare and init instances of FT_CMap_ClassRec. + Add macros to init instances of FT_Outline_Funcs and FT_Raster_Funcs. + Add macros to declare, allocate and initialize modules + (FT_Module_Class). + Add macros to declare, allocate and initialize renderers + (FT_Renderer_Class). + Add macro to init instances of FT_Glyph_Class. + Add macros to declare, allocate and initialize drivers + (FT_Driver_ClassRec). + * include/freetype/internal/ftpic.h new file to declare the + FT_PIC_Container struct and the functions to allocate and detroy it. + * include/freetype/internal/ftserv.h add macros to allocate and + destory arrays of FT_ServiceDescRec. + * include/freetype/internal/internal.h define macro to include + ftpic.h. + + New Files: + * src/base/ftpic.c implement functions to allocate and destory the + global pic_container. + * src/base/basepic.h declare struct to hold PIC globals for base and + macros to access them. + * src/base/basepic.c implement functions to allocate, destroy and + initialize PIC globals for base. + + * src/base/ftinit.c when FT_CONFIG_OPTION_PIC is defined implement + functions that allocate and destroy ft_default_modules according to + FT_CONFIG_MODULES_H in the pic_container instead of the global scope + and use macro from basepic.h to access it. + * src/base/ftobjs.c add calls to the functions that allocate and + destroy the global pic_container when the library is created and + destroyed. + + * src/base/jamfile add new files to FT2_MULTI build: + ftpic.c and basepic.c. + * src/base/ftbase.c add new files to build: + ftpic.c and basepic.c. + + * src/base/ftglyph.c when FT_CONFIG_OPTION_PIC is defined + ft_bitmap_glyph_class and ft_outline_glyph_class will be allocated + in the pic_container instead of the global scope and use macros from + basepic.h to access them. + * src/base/ftbbox.c allocate bbox_interface stract on the stack + instead of the global scope when FT_CONFIG_OPTION_PIC is defined. + * src/base/ftstroke.c access ft_outline_glyph_class allocated in + ftglyph.c via macros from basepic.h + +2009-04-05 Oran Agra + + Preparing changes in cff parser later needed for PIC version. + + * src/cff/cffload.c, src/cff/cffload.h, src/cff/cffobjs.c, + src/cff/cffparse.c, src/cff/cffparse.h: Add library pointer to + 'CFF_ParserRec' set by `cff_parser_init'. + Route library pointer from 'cff_face_init' to 'cff_subfont_load' + for `cff_parser_init'. + + * src/cff/cffparse.c (CFF_Field_Handler): Move it to... + * src/cff/cffparse.h: This file, to be used by other C files. + +2009-04-05 Oran Agra + + Minor change in ftstroke.c. + + * src/base/ftstroke.c (FT_StrokerRec): Replace `memory' member with + `library' needed for PIC version. + Update all callers. + +2009-04-04 Werner Lemberg + + ftnames.c -> ftsnames.c + + * src/base/ftnames.c: Rename to... + * src/base/ftsnames.c: This. + * src/base/Jamfile, src/base/rules.mk, src/base/ftbase.c: Updated. + +2009-04-04 Werner Lemberg + + Add support for cmap type 13. + + * devel/ftoption.h, include/freetype/config/ftoption.h + (TT_CONFIG_CMAP_FORMAT_13): New macro. + + * src/sfnt/ttcmap.c (TT_CMap13Rec, tt_cmap13_init, + tt_cmap13_validate, tt_cmap13_char_index, tt_cmap13_char_next, + tt_cmap13_get_info, tt_cmap13_char_map_def_binary, + tt_cmap14_class_rec): New functions and structures for cmap 13 + support. + (tt_cmap_classes): Register tt_cmap13_class_rec. + + * docs/CHANGES: Mention cmap 13 support. + +2009-04-01 Werner Lemberg + + Ignore empty contours in CFF glyphs. + + Problem reported by Albert Astals Cid . + + * src/cff/cffgload.c (cff_builder_close_contour): Synchronize with + t1_builder_close_contour. + +2009-03-21 Werner Lemberg + + Another redundant header inclusion. + + * src/truetype/ttgxvar.c: Fix Ghostscript Coverity issue #4041. + +2009-03-21 Werner Lemberg + + Remove redundant header inclusions. + + This covers many Ghostscript Coverity issues. + + * src/*: Do it. + +2009-03-21 Werner Lemberg + + Fix Ghostscript Coverity issue #3904. + + * src/truetype/ttgxvar.c (ft_var_readpackedpoints): Protect against + invalid values of `runcnt'. + +2009-03-20 Werner Lemberg + + Fix `make multi' run. + + * src/smooth/ftsmooth.h: Include FT_INTERNAL_DEBUG_H. + +2009-03-20 Werner Lemberg + + Fix Savannah bug #25923. + + * src/cache/ftccmap.c (FTC_CMAP_HASH): Fix typo. + +2009-03-20 Werner Lemberg + + Protect against too large glyphs. + + Problem reported by Tavis Ormandy . + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Don't allow + `pitch' or `height' to be larger than 0xFFFF. + +2009-03-20 Werner Lemberg + Tavis Ormandy + + Fix validation for various cmap table formats. + + * src/sfnt/ttcmap.c (tt_cmap8_validate, tt_cmap10_validate, + tt_cmap12_validate): Check `length' correctly. + (tt_cmap_14_validate): Check `length' and `numMappings' correctly. + +2009-03-20 Werner Lemberg + + Protect against malformed compressed data. + + * src/lzw/ftzopen.c (ft_lzwstate_io): Test whether `state->prefix' is + zero. + +2009-03-20 Werner Lemberg + + Protect against invalid SID values in CFFs. + + Problem reported by Tavis Ormandy . + + * src/cff/cffload.c (cff_charset_load): Reject SID values larger + than 64999. + +2009-03-19 Vincent Richomme + + Update WinCE Visual C project files. + + * builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2008-ce/freetype.vcproj: Add missing base extension + files. + +2009-03-19 Werner Lemberg + + Remove unused Win32 code. + + * builds/wince/ftdebug.c: Remove code guarded with `!_WIN32_WCE'. + Since Win32 is handled separately this is no longer needed. + +2009-03-19 Vincent Richomme + + Make `gzip' module compile on WinCE. + + * src/gzip/zconf.h [_WIN32_WCE]: Define NO_ERRNO_H. + +2009-03-19 Werner Lemberg + + Remove unused WinCE code. + + * builds/win32/ftdebug.c: Remove code guarded with `_WIN32_WCE'. + Since WinCE is handled separately this is no longer needed. + +2009-03-16 Werner Lemberg + + docmaker: Don't ignore single-line code blocks. + + * src/tools/docmaker/content.py (DocBlock::_init__): Fix change from + 2009-01-31. + +2009-03-15 Steve Langasek + + Use __asm__ for declaring assembly instead of asm. + + * builds/unix/ftconfig.in (FT_MulFix_arm): Use __asm__ instead of + asm on arm, fixing a build failure on armel with -pedantic. + +2009-03-14 Werner Lemberg + + Fix valgrind warning. + + * src/sfnt/ttsbit0.c (tt_sbit_decoder_load_bit_aligned): Don't read + past the end of the frame. + +2009-03-12 Werner Lemberg + + * Version 2.3.9 released. + ========================= + + + Tag sources with `VER-2-3-9'. + +2009-03-12 Werner Lemberg + + * builds/unix/freetype2.in: Move @FT2_EXTRA_LIBS@ to `Libs.private'. + +2009-03-12 Werner Lemberg + + Fix some FreeType Coverity issues as reported for Ghostscript. + + * src/base/ftobjs.c (FT_New_Face, FT_New_Memory_Face): Initialize + `args.stream' (#3874, #3875). + (open_face_PS_from_sfnt_stream): Improve error management (#3786). + * src/base/ftmm.c (ft_face_get_mm_service): Fix check of `aservice' + (#3870). + * src/base/ftstroke.c (ft_stroke_border_get_counts): Remove dead + code (#3790). + * src/base/ftrfork.c (raccess_guess_apple_generic): Check error + value of `FT_Stream_Skip' (#3784). + + * src/type1/t1gload.c (T1_Load_Glyph): Check `size' before accessing + it (#3872) + + * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Check `face' before accessing + it (#3871). + * src/pcf/pcfread.c (pcf_get_metrics): Handle return value of + `pcf_get_metric' (#3789, #3782). + (pcf_get_properties): Use FT_STREAM_SKIP (#3783). + + * src/cache/ftcmanag.c (FTC_Manager_RegisterCache): Fix check of + `acache' (#3797) + + * src/cff/cffdrivr.c (cff_ps_get_font_info): Fix check of `cff' + (#3796). + * src/cff/cffgload.c (cff_decoder_prepare): Check `size' (#3795). + * src/cff/cffload.c (cff_index_get_pointers): Add comment (#3794). + + * src/bdf/bdflib.c (_bdf_add_property): Check `fp->value.atom' + (#3793). + (_bdf_parse_start): Add comment (#3792). + + * src/raster/ftraster.c (Finalize_Profile_Table): Check + `ras.fProfile' (#3791). + + * src/sfnt/ttsbit.c (Load_SBit_Image): Use FT_STREAM_SKIP (#3785). + + * src/gzip/ftgzip.c (ft_gzip_get_uncompressed_size): Properly ignore + seek error (#3781). + +2009-03-11 Michael Toftdal + + Extend CID service functions to handle CID-keyed CFFs as CID fonts. + + * include/freetype/ftcid.h (FT_Get_CID_Is_Internally_CID_keyed, + FT_Get_CID_From_Glyph_Index): New functions. + + * include/freetype/internal/services/svcid.h + (FT_CID_GetIsInternallyCIDKeyedFunc, + FT_CID_GetCIDFromGlyphIndexFunc): New function typedefs. + (CID Service): Use them. + + * src/base/ftcid.c: Include FT_CID_H. + (FT_Get_CID_Is_Internally_CID_keyed, FT_Get_CID_From_Glyph_Index): + New functions. + + * src/cff/cffdrivr.c (cff_get_is_cid, cff_get_cid_from_glyph_index): + New functions. + (cff_service_cid_info): Add them. + * src/cff/cffload.c (cff_font_load): Don't free `font->charset.sids' + -- it is needed for access as a CID-keyed font. It gets deleted + later on. + + * src/cid/cidriver.c (cid_get_is_cid, cid_get_cid_from_glyph_index): + New functions. + (cid_service_cid_info): Add them. + + * docs/CHANGES: Updated. + +2009-03-11 Bram Tassyns + + Fix Savannah bug #25597. + + * src/cff/cffparse.c (cff_parse_real): Don't allow fraction_length + to become larger than 9. + +2009-03-11 Werner Lemberg + + Fix Savannah bug #25814. + + * builds/unix/freetype2.in: As suggested in the bug report, move + @LIBZ@ to `Libs.private'. + +2009-03-11 Werner Lemberg + + Fix Savannah bug #25781. + We now simply check for a valid `offset', no longer handling `delta + = 1' specially. + + * src/sfnt/ttcmap.c (tt_cmap4_validate): Don't check `delta' for + last segment. + (tt_cmap4_set_range, tt_cmap4_char_map_linear, + tt_cmap4_char_map_binary): Check offset. + +2009-03-11 Werner Lemberg + + * src/base/Jamfile: Fix handling of ftadvanc.c. + Reported by Oran Agra . + +2009-03-10 Vincent Richomme + + Restructure Win32 and Wince compiler support. + + * src/builds/win32: Remove files for WinCE. + Move VC 2005 support to a separate directory. + Add directory for VC 2008 support. + + * src/builds/wince: New directory hierarchy for WinCE compilers + (VC 2005 and VC 2008). + +2009-03-09 Werner Lemberg + + More preparations for 2.3.9 release. + + * docs/CHANGES: Updated. + + * Jamfile, README: s/2.3.8/2.3.9/, s/238/239/. + +2009-03-09 Werner Lemberg + + * src/sfnt/rules.mk (SFNT_DRV_H): Add ttsbit0.c. + +2009-03-09 Alexey Kryukov + + Fix handling of EBDT formats 8 and 9 (part 2). + + This patch fixes the following problems in ttsbit0.c: + + . Bitmaps for compound glyphs were never allocated. + + . `SBitDecoder' refused to load metrics if some other metrics have + already been loaded. This condition certainly makes no sense for + recursive calls, so I've just disabled it. Another possibility + would be resetting `decoder->metrics_loaded' to false before + loading each composite component. However, we must restore the + original metrics after finishing the recursion; otherwise we can + get a misaligned glyph. + + . `tt_sbit_decoder_load_bit_aligned' incorrectly handled `x_pos', + causing some glyph components to be shifted too far to the right + (especially noticeable for small sizes). + + Note that support for grayscale bitmaps (not necessarily compound) is + completely broken in ttsbit0.c. + + * src/sfnt/tt_sbit_decoder_load_metrics: Always load metrics. + (tt_sbit_decoder_load_bit_aligned): Handle `x_pos' correctly in case + of `h == height'. + (tt_sbit_decoder_load_compound): Reset metrics after loading + components. + Allocate bitmap. + +2009-03-09 Werner Lemberg + + * builds/unix/configure.raw (version_info): Set to 9:20:3. + +2009-03-03 David Turner + + Protect SFNT kerning table parser against malformed tables. + + This closes Savannah BUG #25750. + + * src/sfnt/ttkern.c (tt_face_load_kern, tt_face_get_kerning): Fix a + bug where a malformed table would be successfully loaded but later + crash the engine during parsing. + +2009-03-03 David Turner + + Update documentation and bump version number to 2.3.9. + + * include/freetype/freetype.h: Bump patch version to 9. + * docs/CHANGES: Document the ABI break in 2.3.8. + * docs/VERSION.DLL: Update version numbers table for 2.3.9. + +2009-03-03 David Turner + + Remove ABI-breaking field in public PS_InfoFontRec definition. + + Instead, we define a new internal PS_FontExtraRec structure to + hold the additional field, then place it in various internal + positions of the corresponding FT_Face derived objects. + + * include/freetype/t1tables.h (PS_FontInfoRec): Remove the + `fs_type' field from the public structure. + * include/freetype/internal/psaux.h (T1_FieldLocation): New + enumeration `T1_FIELD_LOCATION_FONT_EXTRA'. + * include/freetype/internal/t1types.h (PS_FontExtraRec): New + structure. + (T1_FontRec, CID_FaceRec): Add it. + + * src/cid/cidload.c (cid_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + * src/cid/cidtoken.h, src/type1/t1tokens.h, src/type42/t42parse.c: + Adjust FT_STRUCTURE and T1CODE properly to handle `FSType'. + * src/type1/t1load.c (t1_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + + * include/freetype/internal/services/svpsinfo.h (PsInfo service): + Add `PS_GetFontExtraFunc' function typedef. + + * src/base/ftfstype.c: Include FT_INTERNAL_SERVICE_H and + FT_SERVICE_POSTSCRIPT_INFO_H. + (FT_Get_FSType_Flags): Use POSTSCRIPT_INFO service. + + * src/cff/cffdrivr.c (cff_service_ps_info): Updated. + * src/cid/cidriver.c (cid_ps_get_font_extra): New function. + (cid_service_ps_info): Updated. + * src/type1/t1driver.c (t1_ps_get_font_extra): New function. + (t1_service_ps_info): Updated. + * src/type42/t42drivr.c (t42_ps_get_font_extra): New function. + (t42_service_ps_info): Updated. + +2009-03-02 Alexey Kryukov + + Fix handling of EBDT formats 8 and 9. + + The main cycle in `blit_sbit' makes too many iterations: it actually + needs the count of lines in the source bitmap rather than in the + target image. + + * src/sfnt/ttsbit.c (blit_sbit) [FT_CONFIG_OPTION_OLD_INTERNALS]: + Add parameter `source_height' and use it for main loop. + (Load_SBit_Single) [FT_CONFIG_OPTION_OLD_INTERNALS]: Updated. + +2009-02-23 Werner Lemberg + + Fix Savannah bug #25669. + + * src/base/ftadvanc.h (FT_Get_Advances): Fix serious typo. + + * src/base/ftobjs.c (FT_Select_Metrics, FT_Request_Metrics): Fix + scaling factor for non-scalable fonts. + + * src/cff/cffdrivr.c (cff_get_advances): Use correct advance width + value to prevent incorrect scaling. + + * docs/CHANGES: Document it. + +2009-02-15 Matt Godbolt + + Fix Savannah bug #25588. + + * builds/unix/ftconfig.in (FT_MulFix_arm): Use correct syntax for + `orr' instruction. + +2009-02-11 Werner Lemberg + + * src/truetype/ttobjs.c (tt_check_trickyness): Add `DFKaiShu'. + Reported by David Bevan . + +2009-02-09 Werner Lemberg + + Fix Savannah bug #25495. + + * src/sfnt/sfobjs.c (sfnt_load_face): Test for bitmap strikes before + setting metrics and bbox values. This ensures that the check for a + font with neither a `glyf' table nor bitmap strikes can be performed + early enough to set metrics and bbox values too. + +2009-02-04 Werner Lemberg + + Fix Savannah bug #25480. + + * builds/unix/freetype-config.in: For --ftversion, don't use $prefix + but $includedir. + +2009-01-31 Werner Lemberg + + Minor docmaker improvements. + + * src/tools/docmaker/content.py (DocBlock::__init__): Ignore empty + code blocks. + +2009-01-25 Werner Lemberg + + Fix SCANCTRL handling in TTFs. + Problem reported by Alexey Kryukov . + + * src/truetype/ttinterp.c (Ins_SCANCTRL): Fix threshold handling. + +2009-01-23 Werner Lemberg + + Move FT_Get_FSType_Flags to a separate file. + Problem reported by Mickey Gabel . + + * src/base/ftobjs.c (FT_Get_FSType_Flags): Move to... + * src/base/ftfstype.c: This new file. + + * modules.cfg (BASE_EXTENSION): Add ftfstype.c. + + * docs/INSTALL.ANY: Updated. + + * builds/mac/*.txt, builds/amiga/*makefile*, + builds/win32/{visualc,visualce}/freetype.*, builds/symbian/*: + Updated. + +2009-01-22 suzuki toshiya + + * builds/unix/ftsystem.c (FT_Stream_Open): Fix 2 error + messages ending without "\n". + +2009-01-22 suzuki toshiya + + Fix Savannah bug #25347. + + * src/base/ftobjs.c (open_face_PS_from_sfnt_stream): Rewind + the stream to the original position passed to this function, + when ft_lookup_PS_in_sfnt_stream() failed. + (Mac_Read_sfnt_Resource): Rewind the stream to the head of + sfnt resource body, when open_face_PS_from_sfnt_stream() + failed. + +2009-01-19 Michael Lotz + + Fix Savannah bug #25355. + + * include/freetype/config/ftconfig.h (FT_MulFix_i386): Make + assembler code work with gcc 2.95.3 (as used by the Haiku project). + Add `cc' register to the clobber list. + +2009-01-18 Werner Lemberg + + Protect FT_Get_Next_Char. + + * src/sfnt/ttcmap.c (tt_cmap4_set_range): Apply fix similar to + change from 2008-07-22. + + Patch from Ronen Ghoshal . + +2009-01-18 Werner Lemberg + + Implement FT_Get_Name_Index for SFNT driver. + + * src/sfnt/sfdriver.c (sfnt_get_name_index): New function. + (sfnt_service_glyph_dict): Use it. + + Problem reported by Truc Truong . + +2009-01-18 Werner Lemberg + + * include/freetype/ftstroke.h (FT_Outline_GetInsideBorder): Fix + documentation. Problem reported by Truc Truong . + + * docs/CHANGES: Updated. + +2009-01-14 Werner Lemberg + + * Version 2.3.8 released. + ========================= + + + Tag sources with `VER-2-3-8'. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.8. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.7/2.3.8/, s/237/238/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 8. + + * builds/unix/configure.raw (version_info): Set to 9:19:3. + + * docs/release: Updated. + +2009-01-14 Werner Lemberg + + * builds/toplevel.mk (dist): Compress better. + +2009-01-13 Werner Lemberg + + * src/base/ftobjs.c (FT_Get_FSType_Flags): Cast for compilation + with C++. + +2009-01-13 Werner Lemberg + + Don't use stdlib.h and friends directly. + Reported by Mickey Gabel . + + * src/base/ftdbgmem.c: s//FT_CONFIG_STANDARD_LIBRARY_H/. + + * src/gzip/ftgzip.c, src/lzw/ftlzw.c, src/raster/ftmisc.h: + s//FT_CONFIG_STANDARD_LIBRARY_H/. + + * src/autofit/aftypes.h, src/autofit/afhints.c, + src/pshinter/pshalgo.c: s//FT_CONFIG_STANDARD_LIBRARY_H/ + + * src/lzw/ftlzw.c, src/base/ftdbgmem.c: Don't include stdio.h. + +2009-01-12 Werner Lemberg + + Avoid compiler warnings. + + * */*: s/do ; while ( 0 )/do { } while ( 0 )/. + Reported by Sean McBride . + +2009-01-12 Werner Lemberg + + Fix stdlib dependencies. + + Problem reported by Mickey Gabel . + + * include/freetype/config/ftstdlib.h (ft_exit): Removed. Unused. + + * src/autofit/afhints.c, src/base/ftlcdfil.c, src/smooth/ftsmooth.c: + s/memcpy/ft_memcpy/. + * src/psaux/t1decode.c: s/memset/ft_memset/, s/memcpy/ft_memcpy/. + +2009-01-11 Werner Lemberg + + * docs/formats.txt: Add link to PCF specification. + + * include/freetype/ftbdf.h (FT_Get_BDF_Property): Improve + documentation. + +2009-01-09 suzuki toshiya + + * src/base/ftadvanc.c (_ft_face_scale_advances, FT_Get_Advance, + FT_Get_Advances): Change the type of load_flags from FT_UInt32 to + FT_Int32, to match with the flags for FT_Load_Glyph(). + * src/cff/cffdrivr.c (cff_get_advances): Ditto. + * src/truetype/ttdriver.c (tt_get_advances): Ditto. + * include/freetype/ftadvanc.h (FT_Get_Advance, FT_Get_Advances): + Ditto. + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + Ditto. + +2009-01-09 Daniel Zimmermann + + * src/gxvalid/gxvmort.c (gxv_mort_feature_validate): Fix wrong + length check. From Savannah patch #6682. + +2009-01-09 Werner Lemberg + + Fix problem with T1_FIELD_{NUM,FIXED}_TABLE2. + + * src/psaux/psobjs.c (ps_parser_load_field_table): Don't handle + `count_offset' if it is zero (i.e., unused). Otherwise, the first + element of the structure which holds the data is erroneously + modified. Problem reported by Chi Nguyen . + +2009-01-09 suzuki toshiya + + * src/base/ftadvanc.c (_ft_face_scale_advances, FT_Get_Advance, + FT_Get_Advances): Extend the type of load_flags from FT_UInt to + FT_UInt32, to pass 32-bit flags on 16bit platforms. + * src/cff/cffdrivr.c (cff_get_advances): Ditto. + * src/truetype/ttdriver.c (tt_get_advances): Ditto. + * include/freetype/ftadvanc.h (FT_Get_Advance, FT_Get_Advances): + Ditto. + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + Ditto. + +2009-01-09 suzuki toshiya + + * src/base/ftobjs.c (FT_Done_Library): Issue an error message when + FT_Done_Face() cannot free all faces. If the list of the opened + faces includes broken face which FT_Done_Face() cannot free, + FT_Done_Library() retries FT_Done_Face() and it can fall into + an endless loop. See the discussion: + http://lists.gnu.org/archive/html/freetype-devel/2008-09/msg00047.html + http://lists.gnu.org/archive/html/freetype-devel/2008-10/msg00000.html + +2009-01-07 Werner Lemberg + + * docs/CHANGES: Document new key `a' in ftdiff. + +2009-01-06 Werner Lemberg + + * autogen.sh: Don't use GNUisms while calling sed. Problem reported + by Sean McBride. + +2009-01-06 Werner Lemberg + + * src/base/ftbitmap.c (FT_Bitmap_Convert): Handle FT_PIXEL_MODE_LCD + and FT_PIXEL_MODE_LCD_V. Problem reported by Chi Nguyen + . + +2009-01-06 Diego Pettenò + + * builds/unix/configure.raw: Don't call AC_CANONICAL_BUILD and + AC_CANONICAL_TARGET and use $host_os only. A nice explanation for + this change can be found at + http://blog.flameeyes.eu/s/canonical-target. + + From Savannah patch #6712. + +2009-01-06 Sean McBride + + * src/base/ftdbgmem.c (_debug_mem_dummy): Make it static. + + * src/base/ftmac.c: Remove some #undefs. + +2008-12-26 Werner Lemberg + + Set `face_index' field in FT_Face for all font formats. + + * cff/cffobjs.c (cff_face_init), winfonts/winfnt.c (FNT_Face_Init), + sfnt/sfobjs.c (sfnt_init_face): Do it. + + * docs/CHANGES: Document it. + +2008-12-22 Steve Grubb + + * builds/unix/ftsystem.c (FT_Stream_Open): Reject zero-length files. + Patch from Savannah bug #25151. + +2008-12-21 Werner Lemberg + + * src/pfr/pfrdrivr.c, src/winfonts/winfnt.c, src/cache/ftcmanag.c, + src/smooth/ftgrays.c, src/base/ftobjc.s, src/sfobjs.c: + s/_Err_Bad_Argument/_Err_Invalid_Argument/. The former is for + errors in the bytecode interpreter only. + +2008-12-21 Werner Lemberg + + * src/base/ftpfr.c (FT_Get_PFR_Metrics): Protect against NULL + arguments. + Fix return value for non-PFR fonts. Both problems reported by Chi + Nguyen . + +2008-12-21 anonymous + + FT_USE_MODULE declares things as: + + extern const FT_Module_Class + + (or similar for C++). However, the actual types of the variables + being declared are often different, e.g., FT_Driver_ClassRec or + FT_Renderer_Class. (Some are, indeed, FT_Module_Class.) + + This works with most C compilers (since those structs begin with an + FT_Module_Class struct), but technically it's undefined behavior. + + To quote the ISO/IEC 9899:TC2 final committee draft, section 6.2.7 + paragraph 2: + + All declarations that refer to the same object or function shall + have compatible type; otherwise, the behavior is undefined. + + (And they are not compatible types.) + + Most C compilers don't reject (or even detect!) code which has this + issue, but the GCC LTO development branch compiler does. (It + outputs the types of the objects while generating .o files, along + with a bunch of other information, then compares them when doing the + final link-time code generation pass.) + + Patch from Savannah bug #25133. + + * src/base/ftinit.c (FT_USE_MODULE): Include variable type. + + * builds/amiga/include/freetype/config/ftmodule.h, + include/freetype/config/ftmodule.h, */module.mk: Updated to declare + pass correct types to FT_USE_MODULE. + +2008-12-21 Hongbo Ni + + * src/autofit/aflatin.c (af_latin_hint_edges), + src/autofit/aflatin2.c (af_latin2_hint_edges), src/autofit/afcjk.c + (af_cjk_hint_edges): Protect against division by zero. This fixes + Savannah bug #25124. + +2008-12-18 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-12-18 Bevan, David + + Provide API for accessing embedding and subsetting restriction + information. + + * include/freetype.h (FT_FSTYPE_INSTALLABLE_EMBEDDING, + FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING, + FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING, FT_FSTYPE_EDITABLE_EMBEDDING, + FT_FSTYPE_NO_SUBSETTING, FT_FSTYPE_BITMAP_EMBEDDING_ONLY): New + macros. + (FT_Get_FSType_Flags): New function declaration. + + * src/base/ftobjs.c (FT_Get_FSType_Flags): New function. + + * src/cid/cidtoken.h, src/type1/t1tokens.h, src/type42/t42parse.c + (t42_keywords): Handle `FSType'. + + * include/freetype/t1tables.h (PS_FontInfoRec): Add `fs_type' field. + +2008-12-17 Werner Lemberg + + * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Don't use internal + macros so that copying the source code into an application works + out of the box. + +2008-12-17 Werner Lemberg + + * include/freetype/ftsynth.h, src/base/ftsynth.c: Move + FT_GlyphSlot_Own_Bitmap to... + * include/freetype/ftbitmap.h, src/base/ftbitmap.c: These files. + + * docs/CHANGES: Document it. + +2008-12-10 Werner Lemberg + + Generalize the concept of `tricky' fonts by introducing + FT_FACE_FLAG_TRICKY to indicate that the font format's hinting + engine is necessary for correct rendering. + + At the same time, slightly modify the behaviour of tricky fonts: + FT_LOAD_NO_HINTING is now ignored. To really force raw loading + of tricky fonts (without hinting), both FT_LOAD_NO_HINTING and + FT_LOAD_NO_AUTOHINT must be used. + + Finally, tricky TrueType fonts always use the bytecode interpreter + even if the patented code is used. + + * include/freetype/freetype.h (FT_FACE_FLAG_TRICKY, FT_IS_TRICKY): + New macros. + + * src/truetype/ttdriver.c (Load_Glyph): Handle new load flags + semantics as described above. + + * src/truetype/ttobjs.c (tt_check_trickyness): New function, using + code of ... + (tt_face_init): This function, now simplified and updated to new + semantics. + + * src/base/ftobjs.c (FT_Load_Glyph): Don't use autohinter for tricky + fonts. + + * docs/CHANGES: Document it. + +2008-12-09 Werner Lemberg + + Really fix Savannah bug #25010: An SFNT font with neither outlines + nor bitmaps can be considered as containing space `glyphs' only. + + * src/truetype/ttpload.c (tt_face_load_loca): Handle the case where + a `glyf' table is missing. + + * src/truetype/ttgload.c (load_truetype_glyph): Abort if we have no + `glyf' table but a non-zero `loca' entry. + (tt_loader_init): Handle missing `glyf' table. + + * src/base/ftobjs.c (FT_Load_Glyph): Undo change 2008-12-05. + + * src/sfnt/sfobjs.c (sfnt_load_face): A font with neither outlines + nor bitmaps is scalable. + +2008-12-05 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_uniranges): Add more ranges. This + fixes Savannah bug #21190 which also provides a basic patch. + +2008-12-05 Werner Lemberg + + * include/freetype/freetype.h (FT_LOAD_ADVANCE_ONLY): Use value + 0x100 instead of 0x10000; the latter value is already occupied by + FT_LOAD_TARGET_LIGHT. Bug reported by James Cloos. + + + Handle SFNT with neither outlines nor bitmaps. This fixes Savannah + bug #25010. + + * src/base/ftobjs.c (FT_Load_Glyph): Reject fonts with neither + outlines nor bitmaps. + + * src/sfnt/sfobjs.c (sfnt_load_face): Don't return an error if there + is no table with glyphs. + + + * src/sfnt/ttload.c (tt_face_lookup_table): Improve debugging + message. + +2008-12-01 Werner Lemberg + + GDEF tables need `glyph_count' too for validation. Problem reported + by Chi Nguyen . + + * src/otvalid/otvgdef.c (otv_GDEF_validate), src/otvalid/otvalid.h + (otv_GDEF_validate), src/otvalid/otvmod.c (otv_validate): Pass + `glyph_count'. + +2008-11-29 Werner Lemberg + + * src/autofit/afcjk.c, src/base/ftoutln.c, src/base/ftrfork.c, + src/bdf/bdfdrivr.c, src/gxvalid/gxvmorx.c, src/otvalid/otvmath.c, + src/pcf/pcfdrivr.c, src/psnames/pstables.h, src/smooth/ftgrays.c, + src/tools/glnames.py, src/truetype/ttinterp.c, src/type1/t1load.c, + src/type42/t42objs.c, src/winfonts/winfnt.c: Fix compiler warnings + (Atari PureC). + +2008-11-29 James Cloos + + * src/type/t1load.c (mm_axis_unmap): Revert previous patch and fix + it correctly by using FT_INT_TO_FIXED (FreeType expects 16.16 values + in the /BlendDesignMap space). + +2008-11-29 James Cloos + + * src/type1/t1load.c (mm_axis_unmap): `blend_points' is FT_Fixed*, + whereas `design_points' is FT_Long*. Therefore, return blend rather + than design points. + +2008-11-27 Werner Lemberg + + * src/cff/cffparse.c (cff_parse_real): Handle more than nine + significant digits correctly. This fixes Savannah bug #24953. + +2008-11-25 Daniel Zimmermann + + * src/base/ftstream.c (FT_Stream_ReadFields): Don't access stream + before the NULL check. From Savannah patch #6681. + +2008-11-24 Werner Lemberg + + Fixes from the gnuwin32 port. + + * src/base/ftlcdfil.c: s/EXPORT/EXPORT_DEF/. + + * src/base/ftotval.c: Include FT_OPENTYPE_VALIDATE_H. + + * src/psaux/psobjs.c (ps_table_add): Check `length'. + +2008-11-15 Werner Lemberg + + * src/truetype/ttinterp.c (tt_default_graphics_state): The default + value for `scan_type' is zero, as confirmed by Greg Hitchcock from + Microsoft. Problem reported by Michal Nowakowski + . + +2008-11-12 Tor Andersson + + * src/cff/cffdrivr.c (cff_get_cmap_info): Initialize `format' field. + This fixes Savannah bug #24819. + +2008-11-08 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): Remove #if 0/#endif guards + since OpenType version 1.5 has been released. + + * include/ttnameid.h (TT_NAME_ID_WWS_FAMILY, + TT_NAME_ID_WWS_SUBFAMILY): New macros for OpenType 1.5. + (TT_URC_COPTIC, TT_URC_VAI, TT_URC_NKO, TT_URC_BALINESE, + TT_URC_PHAGSPA, TT_URC_NON_PLANE_0, TT_URC_PHOENICIAN, + TT_URC_TAI_LE, TT_URC_NEW_TAI_LUE, TT_URC_BUGINESE, + TT_URC_GLAGOLITIC, TT_URC_YIJING, TT_URC_SYLOTI_NAGRI, + TT_URC_LINEAR_B, TT_URC_ANCIENT_GREEK_NUMBERS, TT_URC_UGARITIC, + TT_URC_OLD_PERSIAN, TT_URC_SHAVIAN, TT_URC_OSMANYA, + TT_URC_CYPRIOT_SYLLABARY, TT_URC_KHAROSHTHI, TT_URC_TAI_XUAN_JING, + TT_URC_CUNEIFORM, TT_URC_COUNTING_ROD_NUMERALS, TT_URC_SUNDANESE, + TT_URC_LEPCHA, TT_URC_OL_CHIKI, TT_URC_SAURASHTRA, TT_URC_KAYAH_LI, + TT_URC_REJANG, TT_URC_CHAM, TT_URC_ANCIENT_SYMBOLS, + TT_URC_PHAISTOS_DISC, TT_URC_OLD_ANATOLIAN, TT_URC_GAME_TILES): New + macros for OpenType 1.5. + +2008-11-08 Wenlin Institute + + * src/base/ftobjs.c (ft_glyphslot_free_bitmap): Protect against + slot->internal == NULL. Reported by Graham Asher. + +2008-11-08 Werner Lemberg + + * src/sfnt/sfobjs.c (tt_face_get_name): Modified to return an error + code so that memory allocation problems can be distinguished from + missing table entries. Reported by Graham Asher. + (GET_NAME): New macro. + (sfnt_load_face): Use it. + +2008-11-05 Werner Lemberg + + * devel/ftoption.h, include/freetype/config/ftoption.h + [TT_CONFIG_OPTION_BYTECODE_INTERPRETER]: Undefine + TT_CONFIG_OPTION_UNPATENTED_HINTING. This fixes the return value of + `FT_Get_TrueType_Engine_Type' (and makes it work as documented). + Reported in bug #441638 of bugzilla.novell.com. + + * docs/CHANGES: Document it. + +2008-11-03 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Use an endless loop. There are + fonts (like HELVI.PFB version 003.001, used on OS/2) which define + some `subrs' elements more than once. Problem reported by Peter + Weilbacher . + +2008-10-15 Graham Asher + + * src/sfnt/ttpost.c (tt_post_default_names): Add `const'. + +2008-10-15 David Turner + + * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Disambiguate for + meddlesome compilers' warning against `for ( ...; ...; ...) ;'. + +2008-10-14 Werner Lemberg + + * src/cff/cffobjs.c (cff_face_init): Remove compiler warning. + Suggested by Bram Tassyns in Savannah patch #6651. + +2008-10-12 Graham Asher + + * src/sfnt/sfobjs.c (sfnt_load_face): Fix computation of + `underline_position'. + +2008-10-12 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-10-09 suzuki toshiya + + Fix Savannah bug #24468. + + According to include/freetype/internal/ftobjs.h, the appropriate + type to interchange single character codepoint is FT_UInt32. It + should be distinguished from FT_UInt which can be 16bit integer. + + * src/sfnt/ttcmap.c (tt_cmap4_char_map_linear): Change the type + of the second argument `pcharcode' from FT_UInt* to FT_UInt32*. + (tt_cmap4_char_map_binary): Ditto. + (tt_cmap14_get_nondef_chars): Change the type of return value + from FT_UInt* to FT_UInt32*. + +2008-10-08 John Tytgat + + Fix Savannah bug #24485. + + * src/type1/t1load.c (parse_charstrings): Assure that we always have + a .notdef glyph. + +2008-10-05 suzuki toshiya + + * src/base/ftmac.c: Include FT_TRUETYPE_TAGS_H for multi build. + * builds/mac/ftmac.c: Ditto. + +2008-10-05 suzuki toshiya + + * include/freetype/tttags.h (TTAG_TYP1, TTAG_typ1): Fix definitions. + * src/base/ftobjs.c: Include FT_TRUETYPE_TAGS_H. + +2008-10-05 suzuki toshiya + + * src/sfnt/sfobjs.c (sfnt_open_font): Allow `typ1' version tag in + the beginning of sfnt container. + * src/sfnt/ttload.c (check_table_dir): Return + `SFNT_Err_Table_Missing' when sfnt table directory structure is + correct but essential tables for TrueType fonts (`head', `bhed' or + `SING') are missing. Other errors are returned by + SFNT_Err_Unknown_File_Format. + + * src/base/ftobjs.c (FT_Open_Face): When TrueType driver returns + `FT_Err_Table_Missing', try `open_face_PS_from_sfnt_stream'. It is + enabled only when old mac font support is configured. + +2008-10-04 suzuki toshiya + + * include/freetype/tttags.h (TTAG_CID, TTAG_FOND, TTAG_LWFN, + TTAG_POST, TTAG_sfnt, TTAG_TYP1, TTAG_typ1): New tags to simplify + the repeated calculations of these values in ftobjs.c and ftmac.c. + * src/base/ftobjs.c: Replace all FT_MAKE_TAG by new tags. + * src/base/ftmac.c: Ditto. + * builds/mac/ftmac.c: Ditto. + +2008-10-04 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt_stream): Remove wrong + initialization of *is_sfnt_cid. + +2008-10-04 Werner Lemberg + + * src/base/ftobjs.c (open_face_PS_from_sfnt_stream): Remove compiler + warnings. + +2008-10-04 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Replaced by... + (ft_lookup_PS_in_sfnt_stream): This. + (open_face_PS_from_sfnt_stream): New function. It checks whether + the stream is sfnt-wrapped Type1 PS font or sfnt-wrapped CID-keyed + font, then try to open a face for given face_index. + (Mac_Read_sfnt_Resource): Replace the combination of + `ft_lookup_PS_in_sfnt' and `open_face_from_buffer' by + `open_face_PS_from_sfnt_stream'. + * src/base/ftmac.c (FT_New_Face_From_SFNT): Ditto. + * builds/mac/ftmac.c (FT_New_Face_From_SFNT): Ditto. + * src/base/ftbase.h: Remove `ft_lookup_PS_in_sfnt' and add + `open_face_PS_from_sfnt_stream'. + +2008-10-03 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Set *is_sfnt_cid to + FALSE if neither `CID ' nor `TYP1' is found in the sfnt container. + +2008-10-03 suzuki toshiya + + * include/freetype/config/ftconfig.h: Define FT_MACINTOSH when SC or + MrC compiler of MPW is used. These compilers do not define the + macro __APPLE__ by themselves. + * builds/unix/ftconfig.in: Ditto. + * builds/vms/ftconfig.h: Ditto. + * src/base/ftbase.c: Use FT_MACINTOSH instead of __APPLE__, to + include ftmac.c if FreeType 2 is built by MPW. + * src/base/ftobjs.c: Use FT_MACINTOSH instead of __APPLE__, to + enable shared functions for ftmac.c if FreeType 2 is built by MPW. + + * builds/mac/ftmac.c: Include ftbase.h. + (memory_stream_close): Removed. + (new_memory_stream): Ditto. + (open_face_from_buffer): Removed. Use the implementation in + ftobjs.c. + (ft_lookup_PS_in_sfnt): Ditto. + + * builds/mac/FreeType.m68k_far.make.txt: Build ftmac.c as an + included part of ftbase.c, to share the functions in ftobjs.c. The + rule compiling ftmac.c separately is removed and the rule copying + ftbase.c from src/base/ftbase.c to builds/mac/ftbase.c is added. + * builds/mac/FreeType.m68k_cfm.make.txt: Ditto. + * builds/mac/FreeType.ppc_classic.make.txt: Ditto. + * builds/mac/FreeType.ppc_carbon.make.txt: Ditto. + +2008-10-02 Bram Tassyns + + * src/cff/cffgload.c (cff_slot_load): Map CID 0 to GID 0. This + fixes Savannah bug #24430. + +2008-10-02 Werner Lemberg + + * builds/freetype.mk (BASE_H): Rename to... + (INTERNAL_H): This. + (FREETYPE_H): Updated. + * src/base/rules.mk: (BASE_OBJ_S, OBJ_DIR/%.$O): Add BASE_H. + * src/bdf/rules.mk (BDF_DRV_H): Add bdferror.h. + * src/cache/rules.mk (CACHE_DRV_H): Add ftccache.h and ftcsbits.h. + * src/pcf/rules.mk (PCF_DRV_H): Add pcfread.h. + * src/raster/rules.mk (RASTER_DRV_H): Add ftmisc.h. + * src/type42/rules.mk (T42_DRV_H): Add t42types.h. + +2008-10-02 suzuki toshiya + + * src/base/ftbase.h: New file to declare the private utility + functions shared by the sources of base modules. Currently, + `ft_lookup_PS_in_sfnt' and `open_face_from_buffer' are declared to + share between ftobjs.c and ftmac.c. + + * src/base/rule.mk: Add ftbase.h. + + * src/base/ftobjs.c: Include ftbase.h. + (memory_stream_close): Build on any platform when old MacOS font + support is enabled. + (new_memory_stream): Ditto. + (open_face_from_buffer): Build on any platform when old MacOS font + support is enabled. The counting of the face in a font file is + slightly different between Carbon-dependent parser and Carbon-free + parser. They are merged with the platform-specific conditional. + (ft_lookup_PS_in_sfnt): Ditto. + + * src/base/ftmac.c: Include ftbase.h. + (memory_stream_close): Removed. + (new_memory_stream): Ditto. + (open_face_from_buffer): Removed. Use the implementation in + ftobjs.c. + (ft_lookup_PS_in_sfnt): Ditto. + +2008-10-02 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): `psnames_error' is only needed + if TT_CONFIG_OPTION_POSTSCRIPT_NAMES is defined. + +2008-10-01 Werner Lemberg + + * src/truetype/ttobjs.c (tt_face_done), src/cff/cffobjs.c + (cff_face_done), src/pfr/pfrobjs.c (pfr_face_done), + src/pcf/pcfdrivr.c (PCF_Face_Done), src/cid/cidobjs.c + (cid_face_done), src/bdf/bdfdrivr. (BDF_Face_Done), + src/sfnt/sfobjs.c (sfnt_face_done): Protect against face == 0. + Reported by Graham Asher. + +2008-09-30 suzuki toshiya + + * src/base/rules.mk: Add conditional source to BASE_SRC, for `make + multi' on Mac OS X. If the macro $(ftmac_c) is defined, + $(BASE_DIR)/$(ftmac_c) is added to BASE_SRC. In a normal build, the + lack of ftmac.c in BASE_SRC is not serious because ftbase.c includes + ftmac.c. + * builds/unix/unix-def.in: Add a macro definition of $(ftmac_c). + * builds/unix/configure.raw: Add procedure to set up appropriate + value of $(ftmac_c) with the consideration of the availability of + Carbon framework. + +2008-09-30 suzuki toshiya + + * src/base/Jamfile: Add target for multi build by jam on Mac OS X. + * src/base/ftobjs.c (FT_New_Face): Fix the condition to include this + function for MPW building. It is synchronized the condition to + include ftmac.c source into ftbase.c. + +2008-09-22 Werner Lemberg + + * src/cff/cffgload.c (CFF_Operator, cff_argument_counts, + cff_decoder_parse_charstrings): Handle (invalid) + `callothersubr' and `pop' instructions. + +2008-09-22 John Tytgat + + Fix Savannah bug #24307. + + * include/freetype/internal/t1types.h (CID_FaceRec), + src/type42/t42types.h (T42_FaceRec): Comment out `afm_data'. + +2008-09-21 Werner Lemberg + + * src/smooth/ftgrays.c (gray_raster_render): Don't dereference + `target_map' if FT_RASTER_FLAG_DIRECT is set. Problem reported by + Stephan T. Lavavej . + +2008-09-21 suzuki toshiya + + * src/otvalid/Jamfile: Add missing target `otvmath' for multi build + by jam. + * src/sfnt/Jamfile: Add missing target `ttmtx' for multi build by + jam. + +2008-09-20 Werner Lemberg + + * src/smooth/ftgrays.c (gray_find_cell): Fix threshold. The values + passed to this function are already `normalized'. Problem reported + by Stephan T. Lavavej . + + * docs/CHANGES: Document it. + +2008-09-20 Werner Lemberg + + * src/base/ftoutln.c: Include FT_INTERNAL_DEBUG_H. + (FT_Outline_Decompose): Decorate with tracing messages. + + * src/smooth/ftgrays.c [DEBUG_GRAYS]: Replace with + FT_DEBUG_LEVEL_TRACE. + [_STANDALONE_ && FT_DEBUG_LEVEL_TRACE]: Include stdio.h and + stdarg.h. + + (FT_TRACE) [_STANDALONE_]: Remove. + (FT_Message) [_STANDALONE_ && FT_DEBUG_LEVEL_TRACE]: New function. + (FT_TRACE5, FT_TRACE7) [_STANDALONE_]: New macros. + (FT_ERROR) [_STANDALONE_]: Updated. + + (gray_hline) [FT_DEBUG_LEVEL_TRACE]: Fix condition. + Use FT_TRACE7. + (gray_dump_cells): Make it `static void'. + (gray_convert_glyph): Use FT_TRACE7. + + (FT_Outline_Decompose) [_STANDALONE_]: Synchronize with version in + ftoutln.c. + + * src/base/ftadvanc.c (FT_Get_Advance, FT_Get_Advances): Use + FT_ERROR_BASE. + + * docs/formats.txt: Updated. + +2008-09-19 suzuki toshiya + + * src/base/ftmac.c: Import sfnt-wrapped Type1 and sfnt-wrapped + CID-keyed font support. + * builds/mac/ftmac.c: Ditto. + +2008-09-19 suzuki toshiya + + * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Fix double free bug in + sfnt-wrapped Type1 and sfnt-wrapped CID-keyed font support code. + `open_face_from_buffer' frees the passed buffer if it cannot open a + face from the buffer, so the caller must not free it. + +2008-09-19 suzuki toshiya + + * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Add initial support + for sfnt-wrapped Type1 and sfnt-wrapped CID-keyed font. + (ft_lookup_PS_in_sfnt): New function to look up `TYP1' or `CID ' + table in sfnt table directory. It is used before loading TrueType + font driver. + + * docs/CHANGES: Add note about the current status of sfnt-wrapped + Type1 and sfnt-wrapped CID-keyed font support. + +2008-09-18 Werner Lemberg + + * src/base/ftsystem.c (FT_Done_Memory): Use ft_sfree directly for + orthogonality (ft_free and ft_sfree could belong to different memory + pools). This fixes Savannah bug #24297. + +2008-09-18 suzuki toshiya + + * src/cff/cffobjs.c (cff_face_init): Use TTAG_OTTO defined + in ttags.h instead of numerical value 0x4F54544FL. + +2008-09-16 Werner Lemberg + + * src/cff/cffgload.h, src/cff/cffgload.c + (cff_decoder_set_width_only): Eliminate function call. + +2008-09-15 George Williams + + Fix Savannah bug #24179, reported by Bram Tassyns. + + * src/type1/t1load.c (mm_axis_unmap, T1_Get_MM_Var): Fix computation + of default values. + +2008-09-15 Werner Lemberg + + * src/tools/glnames.py (main): Surround `ft_get_adobe_glyph_index' + and `ft_adobe_glyph_list' with FT_CONFIG_OPTION_ADOBE_GLYPH_LIST to + prevent unconditional definition. This fixes Savannah bug #24241. + + * src/psnames/pstables.h: Regenerated. + +2008-09-13 Werner Lemberg + + * autogen.sh, builds/unix/configure.raw, + include/freetype/config/ftconfig.h, builds/unix/ftconfig.in: Minor + beautifying. + + * include/freetype/ftadvanc.h, include/freetype/ftgasp.h, + include/freetype/ftlcdfil.h: Protect against FreeType 1. + Some other minor fixes. + + * devel/ftoption.h: Synchronize with + include/freetype/config/ftoption.h. + +2008-09-11 Werner Lemberg + + * src/base/ftbase.c: Include ftadvanc.c. + +2008-09-11 suzuki toshiya + + * builds/unix/ftconfig.in: Duplicate the cpp computation of + FT_SIZEOF_{INT|LONG} from include/freetype/config/ftconfig.h. + (FT_USE_AUTOCONF_SIZEOF_TYPES): New macro. If defined, the cpp + computation is disabled and the statically configured sizes are + used. This fixes Savannah bug #21250. + + * builds/unix/configure.raw: Add the checks to compare the cpp + computation results of the bit length of int and long versus the + sizes detected by running `configure'. If the results are + different, FT_USE_AUTOCONF_SIZEOF_TYPES is defined to prioritize the + results. + New option --{enable|disable}-biarch-config is added to define or + undefine FT_USE_AUTOCONF_SIZEOF_TYPES manually. + +2008-09-05 suzuki toshiya + + * builds/unix/configure.raw: Clear FT2_EXTRA_LIBS when Carbon or + ApplicationService framework is missing. Although this value is not + used in building of FreeType2, it is written in `freetype2.pc' and + `freetype-config'. + +2008-09-01 david turner + + * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Accept a negative cmap + index to mean `use default cached FT_Face's charmap'. This fixes + Savannah bug #22625. + * include/freetype/ftcache.h: Document it. + + + Make FT_MulFix an inlined function. This is done to speed up + FreeType a little (on x86 3% when loading+hinting, 10% when + rendering, ARM savings are more important though). Disable this by + undefining FT_CONFIG_OPTION_INLINE_MULFIX. + + Use of assembler code can now be controlled with + FT_CONFIG_OPTION_NO_ASSEMBLER. + + * include/freetype/config/ftconfig.h, builds/unix/ftconfig.in + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MulFix_arm): New assembler + implementation. + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MulFix_i386): Assembler + implementation taken from `ftcalc.c'. + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MULFIX_ASSEMBLER): New macro + which is defined to the platform-specific assembler implementation + of FT_MulFix. + [FT_CONFIG_OPTION_INLINE_MULFIX && FT_MULFIX_ASSEMBLER] + (FT_MULFIX_INLINED): New macro. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_NO_ASSEMBLER, + FT_CONFIG_OPTION_INLINE_MULFIX): New macros. + + * include/freetype/freetype.h: Updated to handle FT_MULFIX_INLINED. + + * src/base/ftcalc.c: Updated to use FT_MULFIX_ASSEMBLER and + FT_MULFIX_INLINED. + + + Add a new header named FT_ADVANCES_H declaring some new APIs to + extract the advances of one or more glyphs without necessarily + loading their outlines. Also provide `fast loaders' for the + TrueType, Type1, and CFF font drivers (more to come later). + + * src/base/ftadvanc.c, include/freetype/ftadvanc.h: New files. + + * include/freetype/config/ftheader.h (FT_ADVANCES_H): New macro. + * include/freetype/freetype.h (FT_LOAD_ADVANCE_ONLY): New macro. + + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + `flags' and `advances' are now of type `FT_UInt' and `FT_Fixed', + respectively. + + * src/base/Jamfile (_sources), src/base/rules.mk (BASE_SRC): Add + ftadvanc.c. + + * src/cff/cffdrivr.c (cff_get_advances): New function. + (cff_driver_class): Register it. + + * src/cff/cffgload.c (cff_decoder_set_width_only): New function. + (cff_decoder_parse_charstrings): Handle `width_only'. + (cff_slot_load): Handle FT_LOAD_ADVANCE_ONLY. + + * src/cff/cffgload.h (cff_decoder): New element `width_only'. + (cff_decoder_set_width_only): New declaration. + + * src/truetype/ttdriver.c (tt_get_advances): New function. + (tt_driver_class): Register it. + + * src/truetype/ttgload.c (Get_HMetrics, Get_VMetrics): Renamed to... + (TT_Get_HMetrics, TT_Get_VMetrics): This. + Update callers. + * src/truetype/ttgload.h: Declare them. + + * src/type1/t1gload.h, src/type1/t1gload.c (T1_Get_Advances): New + function. + * src/type1/t1driver.c (t1_driver_class): Register T1_Get_Advances. + + + Add checks for minimum version of the `autotools' stuff. + + * autogen.sh: Implement it. + (get_major_version, get_minor_version, get_patch_version, + compare_to_minimum_version, check_tool_version): New auxiliary + functions. + + * README.CVS: Document it. + +2008-08-29 suzuki toshiya + + * src/sfnt/sfobjs.c (sfnt_open_font): Use TTAG_OTTO defined in + ttags.h instead of FT_MAKE_TAG( 'O', 'T', 'T', 'O' ). + +2008-08-28 Werner Lemberg + + * src/type1/t1load.c (parse_encoding): Protect against infinite + loop. This fixes Savannah bug #24150 (where a patch has been posted + too). + +2008-08-23 Werner Lemberg + + * src/type/t1afm.c (compare_kern_pairs), src/pxaux/afmparse.c + (afm_compare_kern_pairs): Fix comparison. This fixes Savannah bug + #24119. + +2008-08-19 suzuki toshiya + + * src/base/ftobjs.c (FT_Stream_New): Initialize *astream always, + even if passed library or arguments are invalid. This fixes a bug + that an uninitialized stream is freed when an invalid library handle + is passed. Originally proposed by Mike Fabian, 2008/08/18 on + freetype-devel. + (FT_Open_Face): Ditto (stream). + (load_face_in_embedded_rfork): Ditto (stream2). + +2008-08-18 suzuki toshiya + + * src/base/ftmac.c: Add a fallback to guess the availability of the + `ResourceIndex' type. It is used when built without configure + (e.g., a build with Jam). + * builds/mac/ftmac.c: Ditto. + * builds/unix/configure.raw: Set HAVE_TYPE_RESOURCE_INDEX to 1 or 0 + explicitly, even if `ResourceIndex' is unavailable. + +2008-08-18 suzuki toshiya + + * builds/unix/configure.raw: In checking of Mac OS X features, + all-in-one header file `Carbon.h' is replaced by the minimum + header file `CoreServices.h', similar to current src/base/ftmac.c. + +2008-08-18 suzuki toshiya + + * src/sfnt/ttcmap.c (tt_cmap2_validate): Skip the validation of + sub-header when its code_count is 0. Many Japanese Dynalab fonts + include such an empty sub-header (code_count == 0, first_code == 0 + delta == 0, but offset != 0) as the second sub-header in SJIS cmap. + +2008-08-04 Werner Lemberg + + * src/type1/t1tokens.h: Handle `ForceBold' keyword. This fixes + Savannah bug #23995. + + * src/cid/cidload.c (parse_expansion_factor): New callback function. + (cid_field_records): Use it for `ExpansionFactor'. + * src/cod/cidtoken.h: Handle `ForceBold' keyword. + Don't handle `ExpansionFactor'. + +2008-08-04 Bram Tassyns + + * src/cff/cffparse.c (cff_parse_fixed_scaled): Fix thinko which + resulted in incorrect scaling. This fixes Savannah bug #23973. + +2008-08-04 Werner Lemberg + + Be more tolerant w.r.t. invalid entries in SFNT table directory. + + * src/sfnt/ttload.c (check_table_dir): Ignore invalid entries and + adjust table count. + Add more trace messages. + (tt_face_load_font_dir): Updated. + +2008-07-30 Werner Lemberg + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): No longer + assume that the first argument on the stack is the bottom-most + element. Two reasons: + + o According to people from Adobe it is missing in the Type 2 + specification that pushing of additional, superfluous arguments + on the stack is prohibited. + + o Acroread in general handles fonts differently, namely by popping + the number of arguments needed for a particular operand (as a PS + interpreter would do). In case of buggy fonts this causes a + different interpretation which of the elements on the stack are + superfluous and which not. + + Since there are CFF subfonts (embedded in PDFs) which rely on + Acroread's behaviour, FreeType now does the same. + +2008-07-27 Werner Lemberg + + Add extra mappings for `Tcommaaccent' and `tcommaaccent'. This + fixes Savannah bug #23940. + + * src/psnames/psmodule.c (WGL_EXTRA_LIST_SIZE): Rename to... + (EXTRA_GLYPH_LIST_SIZE): This. + Increase by 2. + (ft_wgl_extra_unicodes): Rename to... + (ft_extra_glyph_unicodes): This. + Add two code values. + (ft_wgl_extra_glyph_names): Rename to... + (ft_extra_glyph_names): This. + Add two glyphs. + (ft_wgl_extra_glyph_name_offsets): Rename to... + (ft_extra_glyph_name_offsets): This. + Add two offsets. + + (ps_check_wgl_name, ps_check_wgl_unicode): Rename to... + (ps_check_extra_glyph_name, ps_check_extra_glyph_unicode): This. + Updated. + (ps_unicodes_init): Updated. + +2008-07-26 Werner Lemberg + + * src/cff/cffgload.c (cff_decoder_prepare, + cff_decoder_parse_charstrings): Improve debug output. + +2008-07-22 Martin McBride + + * src/sfnt/ttcmap.c (tt_cmap4_validate, tt_cmap4_char_map_linear, + tt_cmap4_char_map_binary): Handle fonts which treat the last segment + specially. According to the specification, such fonts would be + invalid but acroread accepts them. + +2008-07-16 Jon Foster + + * src/pfr/pfrdrivr.c (pfr_get_advance): Fix off-by-one error. + + * src/base/ftcalc.c (FT_MulFix): Fix portability issue. + + * src/sfnt/ttpost.c (MAC_NAME) [!FT_CONFIG_OPTION_POSTSCRIPT_NAMES]: + Fix compiler warning. + +2008-07-16 Werner Lemberg + + Handle CID-keyed fonts wrapped in an SFNT (with cmaps) correctly. + + * src/cff/cffload.c (cff_font_load): Pass `pure_cff'. + Invert sids table only if `pure_cff' is set. + * src/cff/cffload.h: Udpated. + + * src/cff/cffobjs.c (cff_face_init): Updated. + Set FT_FACE_FLAG_CID_KEYED only if pure_cff is set. + + * docs/CHANGES: Updated. + +2008-07-09 Werner Lemberg + + * src/truetype/ttpload.c (tt_face_load_loca): Handle buggy fonts + where num_locations < num_glyphs. Problem reported by Ding Li. + +2008-07-05 Werner Lemberg + + Since FreeType uses `$(value ...)', we now need GNU make 3.80 or + newer. This fixes Savannah bug #23648. + + * configure: zsh doesn't like ${1+"$@"}. + Update needed GNU make version. + * builds/toplevel.mk: Check for `$(eval ...)'. + * docs/INSTALL.GNU, docs/INSTALL.CROSS, docs/INSTALL.UNIX: Document + it. + +2008-07-04 Werner Lemberg + + * src/raster/ftraster.c (Draw_Sweep): If span is smaller than one + pixel, only check for dropouts if neither start nor end point lies + on a pixel center. This fixes Savannah bug #23762. + +2008-06-29 Werner Lemberg + + * Version 2.3.7 released. + ========================= + + + Tag sources with `VER-2-3-7'. + + * docs/CHANGES, docs/VERSION.DLL: Update documentation and bump + version number to 2.3.7. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.6/2.3.7/, s/236/237/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 7. + + * builds/unix/configure.raw (version_info): Set to 9:18:3. + + * docs/release: Updated. + +2008-06-28 Werner Lemberg + + * src/ftglyph.c (FT_Matrix_Multiply, FT_Matrix_Invert): Move to... + * src/ftcalc.c: Here. This fixes Savannah bug #23729. + +2008-06-27 Werner Lemberg + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Test for intersections which + degenerate to a single point can be ignored; this has been confirmed + by Greg Hitchcock from Microsoft. (This was commented out code.) + +2008-06-26 Werner Lemberg + + Improve navigation in API reference. + + * src/tools/docmaker/tohtml.py (html_header_3): Renamed to... + (html_header_6): This. + (html_header_3, html_header_3i, html_header_4, html_header_5, + html_header_5t): New strings. + (toc_footer_start, toc_footer_end): New strings. + (HtmlFormatter::html_header): Updated. + (HtmlFormatter::html_index_header, HtmlFormatter::html_toc_header): + New strings. + (HtmlFormatter::index_enter): Use `html_index_header'. + (HtmlFormatter::index_exit): Print `html_footer'. + (HtmlFormatter::toc_enter): Use `html_toc_header'. + (HtmlFormatter::toc_exit): Print proper footer. + + Convert ~ to non-breakable space. + + * src/tools/docmaker/tohtml.py (make_html_para): Implement it. + Update header files accordingly. + +2008-06-24 suzuki toshiya + + * builds/unix/configure.raw: Check type `ResourceIndex' explicitly + and define HAVE_TYPE_RESOURCE_INDEX if it is defined. Mac OS X 10.5 + bundles 10.4u SDK with MAC_OS_X_VERSION_10_5 macro but without + ResourceIndex type definition. The macro does not inform the type + availability. + * src/base/ftmac.c: More parentheses are inserted to clarify the + conditionals to disable legacy APIs in `10.5 and later' cases. If + HAVE_TYPE_RESOURCE_INDEX is not defined, ResourceIndex is defined. + +2008-06-24 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_SCANTYPE): Don't check rendering + mode. + + * src/raster/ftraster.c (Render_Glyph, Render_Gray_Glyph, + Draw_Sweep): No-dropout mode is value 2, not value 0. + (Draw_Sweep): Really skip dropout handling for no-dropout mode. + +2008-06-24 Werner Lemberg + + * src/psaux/psobjs.c (t1_builder_close_contour): Don't add contour + if it consists of one point only. Based on a patch from Savannah + bug #23683 (from John Tytgat). + +2008-06-22 Werner Lemberg + + * src/truetype/ttgload.c (TT_Load_Glyph): Protect bytecode stuff + with IS_HINTED. + + * docs/CHANGES: Updated. + +2008-06-22 suzuki toshiya + + * builds/unix/configure.raw: If CFLAGS has `-isysroot XXX' option + but LDFLAGS does not, import it to LDFLAGS. The option is used to + specify non-default SDK on Mac OS X (e.g., universal binary SDK for + Mac OS X 10.4 on PowerPC platform). Although Apple TechNote 2137 + recommends to add the option only to CFLAGS, LDFLAGS should include + it because libfreetype.la is built with -no-undefined. This fixes a + bug reported by Ryan Schmidt in MacPorts, + http://trac.macports.org/ticket/15331. + +2008-06-21 Werner Lemberg + + Enable access to the various dropout rules of the B&W rasterizer. + Pass dropout rules from the TT bytecode interpreter to the + rasterizer. + + * include/freetype/ftimage.h (FT_OUTLINE_SMART_DROPOUTS, + FT_OUTLINE_EXCLUDE_STUBS): New flags for for FT_Outline. + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Use same mode numbers as given in the + OpenType specification. + Fix mode 4 computation. + (Render_Glyph, Render_Gray_Glyph): Handle new outline flags. + + * src/truetype/ttgload.c (TT_Load_Glyph) Convert scan conversion + mode to FT_OUTLINE_XXX flags. + + * src/truetype/ttinterp.c (Ins_SCANCTRL): Enable ppem check. + +2008-06-19 Werner Lemberg + + * src/cff/cffobjs.c (cff_face_init): Compute final + `dict->units_per_em' value before assigning it to + `cffface->units_per_EM'. Otherwise, CFFs without subfonts are + scaled incorrectly if the font matrix is non-standard. This fixes + Savannah bug #23630. + + * docs/CHANGES: Updated. + +2008-06-19 Werner Lemberg + + * src/type/t1objs.c (T1_Face_Init): Slightly improve algorithm fix + from 2008-06-19. + +2008-06-18 Werner Lemberg + + * src/type/t1objs.c (T1_Face_Init): Fix change from 2008-03-21. + Reported by Peter Weilbacher . + + * docs/CHANGES: Updated. + +2008-06-15 George Williams + + * src/otvalid/otvgpos.c (otv_MarkBasePos_validate): Set + `valid->extra2' to 1. This is undocumented in the OpenType 1.5 + specification. + +2008-06-15 Werner Lemberg + + * src/base/ftcalc.c (FT_MulFix) : Protect registers correctly + from clobbering. Patch from Savannah bug report #23556. + + * docs/CHANGES: Document it. + +2008-06-10 Werner Lemberg + + * autogen.sh: Add option `--install' to libtoolize. + +2008-06-10 Werner Lemberg + + * Version 2.3.6 released. + ========================= + + + Tag sources with `VER-2-3-6'. + + * docs/CHANGES, docs/VERSION.DLL: Update documentation and bump + version number to 2.3.6. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.5/2.3.6/, s/235/236/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 6. + + * builds/unix/configure.raw (version_info): Set to 9:17:3. + + + * include/freetype/internal/psaux.h (T1_BuilderRec): Remove `scale_x' + and `scale_y'. + * src/cff/cffgload.h (CFF_Builder): Remove `scale_x' and `scale_y'. + + + * src/cff/cffparse.c: Include FT_INTERNAL_DEBUG_H. + * src/cff/cffobjs.h: Include FT_INTERNAL_POSTSCRIPT_HINTS_H. + +2008-06-10 Werner Lemberg + + * src/base/ftobjs.c (open_face): Check `clazz->init_face' and + `clazz->done_face'. + +2008-06-09 VaDiM + + Support debugging on WinCE. From Savannah patch #6536; this fixes + bug #23497. + + * builds/win32/ftdebug.c (OutputDebugStringEx): New function/macro + as a replacement for OutputDebugStringA (which WinCE doesn't have). + Update all callers. + (ft_debug_init) [_WIN32_CE]: WinCE apparently doesn't have + environment variables. + +2008-06-09 Werner Lemberg + + * README.CVS: Updated. + + * builds/unix/configure.raw, builds/unix/freetype-config.in: Updated + for newer versions of autoconf and friends. + +2008-06-08 Werner Lemberg + + * src/type1/t1parse.h (T1_ParserRec): Make `base_len' and + `private_len' unsigned. + + * src/type1/t1parse.c (read_pfb_tag): Make `asize' unsigned and read + it as such. + (T1_New_Parser, T1_Get_Private_Dict): Make `size' unsigned. + + + * src/base/ftstream.c (FT_Stream_Skip): Reject negative values. + + + * src/type1/t1load.c (parse_blend_design_positions): Check `n_axis' + for sane value. + Fix typo. + + + * src/psaux/psobjs.c (ps_table_add): Check `idx' correctly. + + + * src/truetype/ttinterp (Ins_SHC): Use BOUNDS() to check + `last_point'. + + + * src/sfnt/ttload.c (tt_face_load_max_profile): Limit + `maxTwilightPoints'. + +2008-06-06 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_IP): Handle case `org_dist == 0' + correctly. This fixes glyphs `t' and `h' of Arial Narrow at 12ppem. + +2008-06-03 Werner Lemberg + + * include/freetype/ftcache.h (FTC_FaceID): Change type back to + FT_Pointer. Reported by Ian Britten . + +2008-06-02 Werner Lemberg + + Emit header info for defined FreeType objects in reference. + + * src/tools/docmaker/content.py (re_header_macro): New regexp. + (ContentProcessor::__init__): Initialize new dictionary `headers'. + (DocBlock::__init__): Collect macro header definitions. + + * src/tools/docmaker/tohtml.py (header_location_header, + header_location_footer): New strings. + (HtmlFormatter::__init__): Pass `headers' dictionary. + (HtmlFormatter::print_html_field): Don't emit paragraph tags. + (HtmlFormatter::print_html_field_list): Emit empty paragraph. + (HtmlFormatter::block_enter): Emit header info. + +2008-06-01 Werner Lemberg + + * include/freetype/config/ftheader.h (FT_UNPATENTED_HINTING_H, + FT_INCREMENTAL_H): Added. + +2008-05-28 Werner Lemberg + + * src/tools/docmaker/sources.py (SourceBlock::__init__): While + looking for markup tags, return immediately as soon a single one is + found. + +2008-05-28 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_MD): The MD instruction also uses + original, unscaled input values. Confirmed by Greg Hitchcock from + Microsoft. + +2008-05-27 Werner Lemberg + + * src/tools/docmaker/tohtml.py (block_footer_start, + block_footer_middle): Beautify output. + +2008-05-25 Werner Lemberg + + * src/raster/ftraster.c (fc_black_render): Return 0 when we are + trying to render into a zero-width/height bitmap, not an error code. + + * src/truetype/ttgload.c (load_truetype_glyph): Move initialization + of the graphics state for subglyphs to... + (TT_Hint_Glyph): This function. + Hinting instructions for a composite glyph apparently refer to the + just hinted subglyphs, not the unhinted, unscaled outline. This + seems to fix Savannah bugs #20973 and (at least partially) #23310. + +2008-05-20 suzuki toshiya + + * src/base/ftmac.c (FT_New_Face_From_Suitcase): Check if valid + `aface' is returned by FT_New_Face_From_FOND(). The patch was + proposed by an anonymous reporter of Savannah bug #23204. + +2008-05-18 Werner Lemberg + + * src/pshinter/pshalgo.c (ps_hints_apply): Reset scale values after + correction for pixel boundary. Without this patch, the effect can + be cumulative under certain circumstances, making glyphs taller and + taller after each call. This fixes Savannah bug #19976. + +2008-05-18 Werner Lemberg + + * src/base/ftdebug.c (FT_Message, FT_Panic): Send output to stderr. + This fixes Savannah bug #23280. + + * docs/CHANGES: Updated. + +2008-05-18 David Turner + + * src/psnames/psmodule.c (ft_wgl_extra_unicodes, + ft_wgl_extra_glyph_names, ft_wgl_extra_glyph_name_offsets, + ps_check_wgl_name, ps_check_wgl_unicode): Use `static' to make + declarations non-global. + + * src/type1/t1load.c: Add missing comment. + +2008-05-17 Sam Hocevar + + * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Handle zero-contour + glyphs correctly. Patch from Savannah bug #23277. + +2008-05-16 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-05-16 Sergey Tolstov + + Improve support for WGL4 encoded fonts. + + * src/psnames/psmodule.c (WGL_EXTRA_LIST_SIZE): New macro. + (ft_wgl_extra_unicodes, ft_wgl_extra_glyph_names, + ft_wgl_extra_glyph_name_offsets): New arrays. + (ps_check_wgl_name, ps_check_wgl_unicode): New functions. + (ps_unicodes_init): Use them to add additional Unicode mappings. + +2008-05-15 Werner Lemberg + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : `closepath' without a path is a no-op, not an error + (cf. the PS reference manual). + + Reported by Martin McBride. + +2008-05-15 Werner Lemberg + + * builds/toplevel.mk (CONFIG_GUESS, CONFIG_SUB): Updated. + +2008-05-15 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Accept fonts with a subrs array + which contains a single but empty entry. This is technically + invalid (since it must end with `return'), but... + + Reported by Martin McBride. + +2008-05-14 Werner Lemberg + + Finish fix of scaling bug of CID-keyed CFF subfonts. + + * include/freetype/internal/ftcalc.h, src/base/ftcalc.c + (FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled): New + functions. + + * src/cff/cffobjs.h (CFF_Internal): New struct. It is used to + provide global hinting data for both the top-font and all subfonts + (with proper scaling). + + * src/cff/cffobjs.c (cff_make_private_dict): New function, using + code from `cff_size_init'. + (cff_size_init, cff_size_done, cff_size_select, cff_size_request): + Use CFF_Internal and handle subfonts. + (cff_face_init): Handle top-dict and subfont matrices correctly; + apply some heuristic in case of unlikely matrix concatenation + results. This has been discussed with people from Adobe (thanks + goes mainly to David Lemon) who confirm that the CFF specs are fuzzy + and not correct. + + * src/cff/cffgload.h (cff_decoder_prepare): Add `size' argument. + + * src/cff/cffgload.c (cff_builder_init): Updated. + (cff_decoder_prepare): Handle hints globals for subfonts. + Update all callers. + (cff_slot_load): Handling scaling of subfonts properly. + + * src/cff/cffparse.c (cff_parse_fixed_dynamic): New function. + (cff_parse_font_matrix): Use it. + + * src/cff/cfftypes.h (CFF_FontDictRec): Make `units_per_em' + FT_ULong. + + * docs/CHANGES: Document it. + +2008-05-13 Werner Lemberg + + * src/winfonts/winfnt.c (fnt_face_get_dll_font, FNT_Face_Init): + Handle case `face_index < 0'. + * docs/CHANGES: Document it. + +2008-05-04 Werner Lemberg + + First steps to fix the scaling bug of CID-keyed CFF subfonts, + reported by Ding Li on 2008/03/28 on freetype-devel. + + * src/base/cff/cffparse.c (power_tens): New array. + (cff_parse_real): Rewritten to introduce a fourth parameter which + returns the `scaling' of the real number so that we have no + precision loss. This is not used yet. + Update all callers. + (cff_parse_fixed_thousand): Replace with... + (cff_parse_fixed_scaled): This function. Update all callers. + +2008-05-03 Werner Lemberg + + * src/base/ftobjs.c (FT_Load_Glyph): Call the auto-hinter without + transformation since it recursively calls FT_Load_Glyph. This fixes + Savannah bug #23143. + +2008-04-26 Werner Lemberg + + * include/freetype/internal/psaux.h (T1_BuilderRec): Mark `scale_x' + and `scale_y' as obsolete since they aren't used. + * src/psaux/psobjs.c (t1_builder_init): Updated. + + * src/cff/cffgload.h (CFF_Builder): Mark `scale_x' and `scale_y' as + obsolete since they aren't used. + * src/cff/cffgload.c (cff_builder_init): Updated. + +2008-04-14 Werner Lemberg + + * src/pcf/pcfdrivr.c (PCF_Face_Init): Protect call to + `FT_Stream_OpenLZW' with `FT_CONFIG_OPTION_USE_LZ'. From Savannah + bug #22909. + +2008-04-13 Werner Lemberg + + * src/psaux/psconv.c (PS_Conv_ToFixed): Increase precision if + integer part is zero. + +2008-04-01 Werner Lemberg + + Fix compilation with g++ 4.1 (with both `single' and `multi' + targets). + + * src/base/ftobjs.c (FT_Open_Face): Don't define a variable in block + which is crossed by a `goto'. + + * src/otvalid/otvalid.h (otv_MATH_validate): Add prototype. + +2008-03-31 Werner Lemberg + + Fix support for subsetted CID-keyed CFFs. + + * include/freetype/freetype.h (FT_FACE_FLAG_CID_KEYED, + FT_IS_CID_KEYED): New macros. + + * src/cff/cffobjs.c (cff_face_init): Set number of glyphs to the + maximum CID value in CID-keyed CFFs. + Handle FT_FACE_FLAG_CID_KEYED flag. + + * docs/CHANGES: Document it. + + + Fix CFF font matrix calculation and improve precision. + + * src/cff/cffparse.c (cff_parse_real): Increase precision if integer + part is zero. + (cff_parse_font_matrix): Simplify computation of `units_per_em'; + this prevents overflow also. + + + Support FT_Get_CID_Registry_Ordering_Supplement for PS CID fonts. + + * src/cid/cidriver.c: Include FT_SERVICE_CID_H. + (cid_get_ros): New function. + (cid_service_cid_info): New service structure. + (cid_services): Register it. + +2008-03-23 Werner Lemberg + + Adjustments for Visual C++ 8.0, as reported by Rainer Deyke. + + * builds/compiler/visualc.mk (CFLAGS): Remove /W5. + (ANSIFLAGS): Add _CRT_SECURE_NO_DEPRECATE. + +2008-03-21 Laurence Darby + + * src/type1/t1objs.c (T1_Face_Init): Use `/Weight'. Patch from + Savannah bug #22675. + +2008-03-13 Derek Clegg + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Fix named style loop. + Patch from Savannah bug #22541. + +2008-03-03 Masatoshi Kimura + + * src/sfnt/ttcmap.c (tt_cmap14_char_map_nondef_binary, + tt_cmap14_find_variant): Return correct value. + (tt_cmap14_variant_chars): Fix check for `di'. + +2008-02-29 Wermer Lemberg + + * docs/CHANGES: Updated. + +2008-02-29 Wolf + + Add build support for symbian platform. From Savannah bug #22440. + + * builds/symbian/*: New files. + +2008-02-21 suzuki toshiya + + * src/base/ftmac.c (parse_fond): Fix a bug of PostScript font name + synthesis. For any face of a specified FOND, always the name for + the first face was used. Except of a FOND that refers multiple + Type1 font files, wrong synthesized font names are not used at all, + so this is an invisible bug. A few limit checks are added too. + + * builds/mac/ftmac.c: Ditto. + +2008-02-21 suzuki toshiya + + * builds/unix/configure.raw: Split compiler option to link Carbon + frameworks to one option for CoreServices framework and another + option for ApplicationServices framework. The split options can be + managed by GNU libtool to avoid unrequired duplication when FreeType + is linked with other applications. Suggested by Daniel Macks, + Savannah bug #22366. + +2008-02-18 Victor Stinner + + * src/truetype/ttinterp.c (Ins_IUP): Check number of points. Fix + from Savannah bug #22356. + +2008-02-17 Jonathan Blow + + * src/autofit/afloader.c (af_loader_load_g, af_loader_load_glyph): + Check for valid callback pointers. + +2008-02-15 suzuki toshiya + + * src/base/ftmac.c (FT_New_Face_From_SFNT): Check the sfnt resource + handle by its value instead of ResError(), fix provided by Deron + Kazmaier. According to the Resource Manager Reference, + GetResource(), Get1Resource(), GetNamedResource(), + Get1NamedResource() and RGetResource() set noErr but return NULL + handle when they can not find the requested resource. These + functions never return undefined values, so it is sufficient to + check if the handle is not NULL. + + * builds/mac/ftmac.c (FT_New_Face_From_SFNT): Ditto. + +2008-02-14 suzuki toshiya + + * src/base/ftbase.c: is replaced by "ftmac.c" as other + inclusion styles. Now it always includes src/base/ftmac.c; + builds/mac/ftmac.c is never included in any configuration. + + * builds/unix/configure.raw: Print warning if configure is executed + with options to specify Carbon functionalities explicitly. + + * docs/INSTALL.MAC: Note that legacy builds/mac/ftmac.c is not + included automatically and manual replacement is required. + +2008-02-11 Werner Lemberg + + * builds/modules.mk (CLOSE_MODULE, REMOVE_MODULE), builds/detect.mk + (dos_setup), builds/freetype.mk (clean_project_dos, + distclean_project_dos): Don't use \ but $(SEP). Reported by Duncan + Murdoch. + +2008-01-18 Sylvain Pasche + + * src/base/ftlcdfil.c (_ft_lcd_filter_legacy): Updated comment to + mention intra-pixel algorithm. + + * include/freetype/freetype.h (FT_Render_Mode): Mention that + FT_Library_SetLcdFilter can be used to reduce fringes. + +2008-01-16 Werner Lemberg + + * src/raster/ftraster.c (ft_black_render): Check `outline' before + using it. Reported by Allan Yang. + +2008-01-12 Werner Lemberg + + * src/raster/ftraster.c (FT_CONFIG_OPTION_5_GRAY_LEVELS): Remove. + +2008-01-12 Allan Yang, Jian Hua - SH + + * src/raster/ftraster.c (ft_black_init) + [FT_RASTER_OPTION_ANTI_ALIASING]: Fix compilation. + +2008-01-10 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph): Handle the case + where the number of contours in a simple glyph is zero (and which + does contain an entry in the `glyf' table). This fixes Savannah bug + #21990. + +2008-01-04 suzuki toshiya + + Formatting suggested by Sean McBride. + + * builds/mac/ftmac.c: Formatting (tab expanded). + * src/autofit/afindic.c: Ditto. + * src/base/ftcid.c: Ditto. + * src/base/ftmac.c: Ditto. + +2007-12-30 Werner Lemberg + + * src/smooth/ftgrays.c (gray_raster_render): Check `outline' + correctly. + +2007-12-21 suzuki toshiya + + Improvement of POSIX resource-fork accessor to load unsorted + references in a resource. In HelveLTMM (resource-fork PostScript + Type1 font bundled with Mac OS X since 10.3.x), the appearance order + of PFB chunks is not sorted; sorting the chunks by reference IDs is + required. + + * include/freetype/internal/ftrfork.h (FT_RFork_Ref): New structure + type to store a pair of reference ID and offset to the chunk. + + * src/base/ftrfork.c (ft_raccess_sort_ref_by_id): New function to + sort FT_RFork_Ref by their reference IDs. + + (FT_Raccess_Get_DataOffsets): Returns an array of offsets that is + sorted by reference ID. + +2007-12-14 Werner Lemberg + + * src/cff/cffparse.c (cff_parse_real): Don't apply `power_ten' + division too early; otherwise the most significant digit(s) of the + final result are lost as the value is truncated to an integer. This + fixes Savannah bug #21794 (where the patch has been posted too). + +2007-12-06 Fix <4d876b82@gmail.com> + + Pass options from one configure script to another as-is (not + expanded). This is needed for options like + --includedir='${prefix}/include'. + + * builds/unix/detect.mk, configure: Prevent argument expansion in + call to the (real) `configure' script. + +2007-12-06 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph): Fix compilation if + TT_USE_BYTECODE_INTERPRETER isn't defined. + +2007-12-06 Werner Lemberg + + There exist CFFs which contain opcodes for the Type 1 operators + `hsbw' and `closepath' which are both invalid in Type 2 charstrings. + However, it doesn't harm to support them. + + * src/cff/cffgload.c (CFF_Operator): Add `cff_op_hsbw' and + `cff_op_closepath.' + (cff_argument_counts): Ditto. + + (cff_decoder_parse_charstrings): Handle Type 1 opcodes 9 (closepath) + and 13 (hsbw) which are invalid in Type 2 charstrings. + +2007-12-06 suzuki toshiya + + * src/base/ftrfork.c (raccess_guess_darwin_newvfs): New function to + support new pathname syntax `..namedfork/rsrc' to access a resource + fork on Mac OS X. The legacy syntax `/rsrc' does not work on + case-sensitive HFS+. + (raccess_guess_darwin_hfsplus): Fix a bug in the calculation of + buffer size to store a pathname. + * include/freetype/internal/ftrfork.h: Increment the number of + resource fork guessing rule. + +2007-12-06 suzuki toshiya + + * builds/unix/configure.raw: Improve the compile tests to search + Carbon functions. + * builds/mac/ftmac.c: Import fixes for Carbon incompatibilities + proposed by Sean McBride from src/base/ftmac.c (see 2007-11-16). + +2007-12-06 suzuki toshiya + + The documents and comments for Mac OS X are improved by Sean + McBride. + + * src/base/ftmac.c: Fix a comment. + * include/freetype/ftmac.h: Ditto. + * docs/INSTALL.MAC: Improve English and add comment on lowest + system version specified by MACOSX_DEPLOYMENT_TARGET. + +2007-12-04 Werner Lemberg + + * src/cff/cffload.c (cff_subfont_load): Don't use logical OR to + concatenate error codes. + * src/sfnt/ttsbit.c (Load_SBit_Range): Ditto. + +2007-12-04 Graham Asher + + * src/truetype/ttobjs.c (tt_face_init): Don't use logical OR to + concatenate error codes. + +2007-12-04 Sean McBride + + * src/pfr/pfrgload.c (pfr_glyph_load_compound): Remove compiler + warning. + +2007-11-20 suzuki toshiya + + Fix MacOS legacy font support by Masatake Yamato on Mac OS X. It is + not working since 2.3.5. In FT_Open_New(), if FT_New_Stream() + cannot mmap() the specified file and cannot seek to head of the + specified file, it returns NULL stream and FT_Open_New() returns the + error immediately. On MacOS, most legacy MacOS fonts fall into such + a scenario because their data forks are zero-sized and cannot be + sought. To proceed to guessing of resource fork fonts, the + functions for legacy MacOS font must properly handle the NULL stream + returned by FT_New_Stream(). + + * src/base/ftobjs.c (IsMacBinary): Return error + FT_Err_Invalid_Stream_Operation immediately when NULL stream is + passed. + (FT_Open_Face): Even when FT_New_Stream() returns an error, proceed + to fallback. Originally, legacy MacOS font is tested in the cases + of FT_Err_Invalid_Stream_Operation (occurs when data fork is empty) + or FT_Err_Unknown_File_Format (occurs when AppleSingle header or + .dfont header is combined). Now the case of + FT_Err_Cannot_Open_Stream is included. + + * src/base/ftrfork.c (FT_Raccess_Guess): When passed stream is NULL, + skip FT_Stream_Seek(), which seeks to the head of stream, and + proceed to unit testing of raccess_guess_XXX(). FT_Stream_Seek() + for a NULL stream causes a Bus error on Mac OS X. + (raccess_guess_apple_double): Return FT_Err_Cannot_Open_Stream + immediately if passed stream is NULL. + (raccess_guess_apple_single): Ditto. + +2007-11-16 suzuki toshiya + + Fix for Carbon incompatibilities since Mac OS X 10.5, + proposed by Sean McBride. + + * doc/INSTALL.MAC: Comment on MACOSX_DEPLOYMENT_TARGET. + + * include/freetype/ftmac.h: Deprecate FT_New_Face_From_FOND and + FT_GetFilePath_From_Mac_ATS_Name. Since Mac OS X 10.5, calling + Carbon functions from a forked process is classified as unsafe + by Apple. All Carbon-dependent functions should be deprecated. + + * src/base/ftmac.c: Use essential header files + and + instead of + all-in-one header file . + + Include and replace HFS_MAXPATHLEN by Apple + genuine macro PATH_MAX. + + Add fallback macro for kATSOptionFlagsUnRestrictedScope which + is not found in Mac OS X 10.0. + + Multi-character constants ('POST', 'sfnt' etc) are replaced by + 64bit constants calculated by FT_MAKE_TAG() macro. + + For the index in the segment of resource fork, new portable + type ResourceIndex is introduced for better compatibility. + This type is since Mac OS X 10.5, so it is defined as short + when built on older platforms. + + (FT_ATSFontGetFileReference): If build target is only the systems + 10.5 and newer, it calls Apple genuine ATSFontGetFileReference(). + + (FT_GetFile_From_Mac_ATS_Name): Return an error if system is 10.5 + and newer or 64bit platform, because legacy type FSSpec type is + removed completely. + + (FT_New_Face_From_FSSpec): Ditto. + +2007-11-01 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_done_face): Check `sfnt' everywhere. This + fixes Savannah bug #21485. + +2007-10-29 Daniel Svoboda + + * src/winfonts/winfnt.c (FNT_Face_Init): Check first that the driver + can handle the font at all, then check `face_index'. Otherwise, the + driver might return the wrong error code. This fixes Savannah bug + #21468. + +2007-10-21 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): Support bit 9 and prepare + support for bit 8 of the `fsSelection' field in the `OS/2' table. + MS is already using this; hopefully, this becomes part of OpenType + 1.5. + Prepare also support for `name' IDs 21 (WWS_FAMILY) and 22 + (WWS_SUBFAMILY). + +2007-10-20 Werner Lemberg + + * src/tools/docmaker/tohtml.py (html_header_2): Fix typo. + Add `td.left' element to CSS. + (toc_section_enter): Use it. + +2007-10-18 David Turner + + * include/freetype/freetype.h, src/base/ftobjs.c: Rename API + functions related to cmap type 14 support to the + `FT_Object_ActionName' scheme: + + FT_Get_Char_Variant_index -> FT_Face_GetCharVariantIndex + FT_Get_Char_Variant_IsDefault -> FT_Face_GetCharVariantIsDefault + FT_Get_Variant_Selectors -> FT_Face_GetVariantSelectors + FT_Get_Variants_Of_Char -> FT_Face_GetVariantsOfChar + FT_Get_Chars_Of_Variant -> FT_Face_GetCharsOfVariant + + Update documentation accordingly. + + * src/sfnt/ttcmap.c: Stronger cmap 14 validation. + Make the code a little more consistent with FreeType coding + conventions and modify the cmap14 functions that returned a newly + allocated array to use a persistent vector from the TT_CMap14 object + instead. + + (TT_CMap14Rec): Provide array and auxiliary data for result. + (tt_cmap14_done, tt_cmap14_ensure): New functions. + + (tt_cmap14_init, tt_cmap14_validate, tt_cmap14_char_map_def_binary, + tt_cmap14_char_map_nondef_binary, tt_cmap14_find_variant, + tt_cmap14_char_var_index, tt_cmap14_variants, + tt_cmap14_char_variants, tt_cmap14_def_char_count, + tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars, + tt_cmap14_variant_chars, tt_cmap14_class_rec): Updated and improved. + +2007-10-15 George Williams + + Add support for cmap type 14. + + * devel/ftoption.h, include/freetype/config/ftoption.h + (TT_CONFIG_CMAP_FORMAT_14): New macro. + + * include/freetype/internal/ftobjs.h (FT_CMap_CharVarIndexFunc, + FT_CMap_CharVarIsDefaultFunc, FT_CMap_VariantListFunc, + FT_CMap_CharVariantListFunc, FT_CMap_VariantCharListFunc): New + support function prototypes. + (FT_CMap_ClassRec): Add them. + Update all users. + + * include/freetype/ttnameid.h (TT_APPLE_ID_VARIANT_SELECTOR): New + macro. + + * include/freetype/freetype.h (FT_Get_Char_Variant_Index, + FT_Get_Char_Variant_IsDefault, FT_Get_Variant_Selectors, + FT_Get_Variants_Of_Char, FT_Get_Chars_Of_Variant): New API + functions. + + * src/base/ftobjs.c (find_variant_selector_charmap): New auxiliary + function. + (FT_Set_Charmap): Disallow cmaps of type 14. + (FT_Get_Char_Variant_Index, FT_Get_Char_Variant_IsDefault, + FT_Get_Variant_Selectors, FT_Get_Variants_Of_Char, + FT_Get_Chars_Of_Variant): New API functions. + + * src/sfnt/ttcmap.c (TT_PEEK_UINT24, TT_NEXT_UINT24): New macros. + + (TT_CMap14Rec, tt_cmap14_init, tt_cmap14_validate, + tt_cmap14_char_index, tt_cmap14_char_next, tt_cmap14_get_info, + tt_cmap14_char_map_def_binary, tt_cmap14_char_map_nondef_binary, + tt_cmap14_find_variant, tt_cmap14_char_var_index, + tt_cmap14_char_var_isdefault, tt_cmap14_variants, + tt_cmap14_char_variants, tt_cmap14_def_char_count, + tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars, + tt_cmap14_variant_chars, tt_cmap14_class_rec): New functions and + structures for cmap 14 support. + (tt_cmap_classes): Register tt_cmap14_class_rec. + (tt_face_build_cmaps): One more error message. + + * docs/CHANGES: Mention cmap 14 support. + +2007-10-01 Werner Lemberg + + * src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4 + charmap fails, do the loop again while searching a UCS-2 charmap. + This favours MS charmaps over Apple ones. + +2007-08-29 suzuki toshiya + + * src/base/ftmac.c: Introduction of abstract `short' data types, + ResFileRefNum and ResID. These types were introduced for Copland, + then backported to MPW. The variables exchanged with FileManager + QuickDraw frameworks are redefined by these data types. Patch was + proposed by Sean McBride. + * builds/mac/ftmac.c: Ditto. + +2007-08-18 Werner Lemberg + + * src/otvalid/otvcmmn.c (otv_x_y_ux_sy): Skip context glyphs. Found + by Imran Yousaf. Fixes Savannah bug #20773. + + (otv_Lookup_validate): Correct handling of LookupType. Found by + Imran Yousaf. Fixes Savannah bug #20782. + +2007-08-17 George Williams + + * src/otvalid/otvgsub.c (otv_SingleSubst_validate): Fix handling of + SingleSubstFormat1. + +2007-08-11 suzuki toshiya + + * builds/unix/configure.raw: Fix a bug which sets CC_BUILD by + ${build-gcc} (unchecked) instead of by ${build}-gcc (checked). + Found by Ryan Hill. + +2007-08-11 George Williams + + * src/otvalid/otvcommn.c, src/otvalid/otvcommn.h + (otv_Coverage_validate): Add fourth argument to pass an expected + count value. Update all users. + Check glyph IDs. + (otv_ClassDef_validate): Check `StartGlyph'. + + * src/otvalid/otvgsub.c (otv_SingleSubst_validate): More glyph ID + checks. + + * src/otvalid/otvmath.c (otv_MathConstants_validate): There are only + 56 constants. + (otv_GlyphAssembly_validate, otv_MathGlyphConstruction_validate): + Check glyph IDs. + +2007-08-08 Werner Lemberg + + * src/otvalid/otvbase.c, src/otvalid/otvcommn.c, + src/otvalid/otvgdef.c, src/otvalid/otvgpos.c, src/otvalid/otvgsub.c, + src/otvalid/otvjstf.c: s/FT_INVALID_DATA/FT_INVALID_FORMAT/ where + appropriate. Reported by George. + + * include/freetype/internal/fttrace.h: Define `trace_otvmath'. + + * src/otvalid/rules.mk (OTV_DRV_SRC): Add otvmath.c. + + * docs/CHANGES: Updated. + +2007-08-08 George Williams + + Add `MATH' validating support to otvalid module. + + * include/freetype/tttags.h (TTAG_MATH): New macro. + * include/freetype/ftotval.h (FT_VALIDATE_MATH): New macro. + (FT_VALIDATE_OT): Updated. + + * src/otvalid/otmath.c: New file. + + * src/otvalid/otvalid.c: Include otvmath.c. + * src/otvalid/otvmod.c (otv_validate): Handle `MATH' table. + +2007-08-04 Werner Lemberg + + * builds/unix/configure.raw: Add call to AC_LIBTOOL_WIN32_DLL. + Fixes Savannah bug #20686. + +2007-08-03 Werner Lemberg + + * src/psnames/psmodule.c: Fix usage of + FT_CONFIG_OPTION_POSTSCRIPT_NAMES macro. Reported by Graham Asher. + +2007-07-31 suzuki toshiya + + * src/base/ftmac.c (open_face_from_buffer): The argument + `driver_name' is typed as `const char*' to match with the + callers in FT_New_Face_From_LWFN and FT_New_Face_From_SFNT. + This is same with open_face_from_buffer in src/base/ftobjs.c. + Found and fixed by Sean McBride. + +2007-07-28 Werner Lemberg + + * src/raster/ftraster.c (count_table): Make it conditional. + * src/base/ftobjs.c (FT_New_Library): Check FT_RENDER_POOL_SIZE with + a preprocessor statement. + +2007-07-27 Werner Lemberg + + * src/base/ftoutln.c (FT_Outline_Translate): Check `outline' before + first usage. From Savannah patch #6115. + +2007-07-16 Werner Lemberg + + * docs/CHANGES: Updated. + +2007-07-16 Derek Clegg + + Add new service for getting the ROS from a CID font. + + * include/freetype/config/ftheader.h (FT_CID_H): New macro. + * include/freetype/ftcid.h: New file. + + * include/freetype/internal/ftserv.h (FT_SERVIVE_CID_H): New macro. + * include/freetype/internal/services/svcid.h: New file. + + * src/base/ftcid.c: New file. + + * src/cff/cffdrivr.c: Include FT_SERVICE_CID_H. + (cff_get_ros): New function. + (cff_service_cid_info): New service structure. + (cff_services): Register it. + + * src/cff/cffload.c (cff_font_done): Free registry and ordering. + + * src/cff/cfftypes.h (CFF_FontRec): Add `registry' and `ordering'. + + * modules.cfg (BASE_EXTENSIONS): Add ftcid.c. + +2007-07-11 Derek Clegg + + Add support for postscript name service to CFF driver. + + * src/cff/cffdrivr.c: Include FT_SERVICE_POSTSCRIPT_NAME_H. + (cff_get_ps_name): New function. + (cff_service_ps_name): New service structure. + (cff_services): Register it. + +2007-07-07 Werner Lemberg + + * src/base/ftglyph.c (FT_Glyph_Copy): Fix initialization of + `target'. Reported by Sean McBride. + +2007-07-06 Werner Lemberg + + * src/pfr/pfrcmap.c: Include pfrerror.h. + + * src/autofit/afindic.c: Add some external declarations to pacify + `make multi' compilation. + + * src/cid/cidgload.c (cid_load_glyph): Pacify compiler. + + * src/cff/cffdrivr.c (cff_ps_get_font_info), src/cff/cffobjs.c + (cff_strcpy), include/freetype/internal/ftmemory.h (FT_MEM_STRDUP), + src/autofit/aflatin.c (af_latin_hints_compute_edges), + src/autofit/afcjk.c (af_cjk_hints_compute_edges), src/sfnt/ttmtx.c + (tt_face_get_metrics), src/base/ftobjs.c (open_face) + [FT_CONFIG_OPTION_INCREMENTAL]: Fix compilation with C++ compiler. + + * docs/release: Mention test compilation targets. + +2007-07-04 Werner Lemberg + + * docs/PROBLEMS: Mention that some PS based fonts can't be + handled correctly by FreeType. + + * src/truetype/ttgload.c (load_truetype_glyph): Always allow a + recursion depth of 1. This was the maximum value in TrueType 1.0, + and some older fonts don't set this field correctly. + + * src/gxvalid/gxvmort1.c + (gxv_mort_subtable_type1_substTable_validate): Fix tracing message. + +2007-07-03 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initialize + `round' to pacify compiler. + 2007-07-02 Werner Lemberg @@ -564,7 +5601,7 @@ * src/base/ftglyph.c (FT_Glyph_Copy): Always set second argument to zero in case of error. This fixes Savannah bug #19689. -2007-04-25 Boris Letocha +2007-04-25 Boris Letocha * src/truetype/ttobjs.c: Fix a typo that created a speed regression in the TrueType bytecode loader. @@ -1363,7 +6400,7 @@ * src/base/ftmac.c: Specialized for Mac OS X only. * builds/unix/ftconfig.in: Fixed for ppc64 missing Carbon framework. - * builds/unix/configure.raw: Ditto. When explicit switches for + * builds/unix/configure.raw: Ditto. When explicit switches for FSSpec/FSRef/QuickDraw/ATS availability are given to configure, builds/mac/ftmac.c is used instead of default src/base/ftmac.c. @@ -1922,22 +6959,22 @@ Fix miscellaneous compiler warnings. - * freetype2/include/freetype/internal/ftobjs.h: Close comment with - `*/' to avoid `/* in comment' compiler warning. + * include/freetype/internal/ftobjs.h: Close comment with `*/' to + avoid `/* in comment' compiler warning. - * freetype2/src/base/ftdbgmem.c (ft_mem_table_get_source): Turn cast + * src/base/ftdbgmem.c (ft_mem_table_get_source): Turn cast `(FT_UInt32)(void*)' into `(FT_UInt32)(FT_PtrDist)(void*)' since on 64-bit platforms void* is larger than FT_UInt32. - * freetype2/src/base/ftobjs.c (t_validator_error): Cast away + * src/base/ftobjs.c (t_validator_error): Cast away volatileness of argument to ft_longjmp. Spotted by Werner `Putzfrau' Lemberg. - * freetype2/src/bdf/bdflib.c (bdf_load_font): Initialize local + * src/bdf/bdflib.c (bdf_load_font): Initialize local variable `lineno'. - * freetype2/src/gxvalid/gxvmod.c (classic_kern_validate): Mark local - variable `error' as volatile. + * src/gxvalid/gxvmod.c (classic_kern_validate): Mark local variable + `error' as volatile. 2006-08-27 Werner Lemberg @@ -1950,30 +6987,29 @@ about addresses of volatile objects passed as function arguments as non-volatile pointers. - * freetype2/include/freetype/internal/ftvalid.h: Make FT_Validator - typedef a pointer to a volatile object. + * include/freetype/internal/ftvalid.h: Make FT_Validator typedef a + pointer to a volatile object. - * freetype2/src/gxvalid/gxvmod.c (gxv_load_table): Make function - argument `table' a pointer to a volatile object. + * src/gxvalid/gxvmod.c (gxv_load_table): Make function argument + `table' a pointer to a volatile object. - * freetype2/src/otvalid/otvmod.c (otv_load_table): Make function - argument `table' a pointer to a volatile object. + * src/otvalid/otvmod.c (otv_load_table): Make function argument + `table' a pointer to a volatile object. 2006-08-18 Jens Claudius - * freetype2/src/gxvalid/gxvmod.c (GXV_TABLE_DECL): Mark local - variable `_sfnt' as volatile since it must keep its value across - a call to ft_setjmp. + * src/gxvalid/gxvmod.c (GXV_TABLE_DECL): Mark local variable `_sfnt' + as volatile since it must keep its value across a call to ft_setjmp. (gxv_validate): Same for local variables `memory' and `valid'. (classic_kern_validate): Same for local variables `memory', `ckern', and `valid'. - * freetype2/src/otvalid/otvmod.c (otv_validate): Same for function - parameter `face' and local variables `base', `gdef', `gpos', `gsub', - `jstf', and 'valid'. + * src/otvalid/otvmod.c (otv_validate): Same for function parameter + `face' and local variables `base', `gdef', `gpos', `gsub', `jstf', + and 'valid'. - * freetype2/src/sfnt/ttcmap.c (tt_face_build_cmaps): Same for - local variable `cmap'. + * src/sfnt/ttcmap.c (tt_face_build_cmaps): Same for local variable + `cmap'. 2006-08-16 David Turner @@ -1984,7 +7020,7 @@ buggy by design. Always return -1. - Improvements to native TrueType hinting. This is a first try, + Improvements to native TrueType hinting. This is a first try, controlled by the FIX_BYTECODE macro in src/truetype/ttinterp.c. * include/freetype/internal/ftgloadr.h (FT_GlyphLoadRec): Add member @@ -2030,44 +7066,43 @@ `ft_validator_run' wrapping `setjmp' can cause a crash, as found by Jens: - http://lists.nongnu.org/archive/html/freetype-devel/2006-08/msg00004.htm. + http://lists.gnu.org/archive/html/freetype-devel/2006-08/msg00004.htm. - * freetype2/src/otvalid/otvmod.c: Replace `ft_validator_run' by - `ft_setjmp'. It reverts the change introduced on 2005-08-20. + * src/otvalid/otvmod.c: Replace `ft_validator_run' by `ft_setjmp'. + It reverts the change introduced on 2005-08-20. - * freetype2/src/gxvalid/gxvmod.c: Ditto. + * src/gxvalid/gxvmod.c: Ditto. 2006-08-13 Jens Claudius - * freetype2/include/freetype/internal/psaux.h: (T1_TokenType): Add + * finclude/freetype/internal/psaux.h: (T1_TokenType): Add T1_TOKEN_TYPE_KEY. (T1_FieldRec): Add `dict'. (T1_FIELD_DICT_FONTDICT, T1_FIELD_DICT_PRIVATE): New macros. (T1_NEW_XXX, T1_FIELD_XXX): Update to take the dictionary where a PS keyword is expected as an additional argument. - * freetype2/src/cid/cidload.c: (cid_field_records): Adjust - invocations of T1_FIELD_XXX. + * src/cid/cidload.c: (cid_field_records): Adjust invocations of + T1_FIELD_XXX. - * freetype2/src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX. + * src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX. - * freetype2/src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing. + * src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing. (ps_parser_to_token): Report a PostScript key as T1_TOKEN_TYPE_KEY, not T1_TOKEN_TYPE_ANY. (ps_parser_load_field): Make sure a token that should be a string or name is really a string or name. Avoid memory leak if a keyword has been already encountered and its value is overwritten. - * freetype2/src/type1/t1load.c: (t1_keywords): Adjust invocations of + * src/type1/t1load.c: (t1_keywords): Adjust invocations of T1_FIELD_XXX. (parse_dict): Ignore keywords that occur in the wrong dictionary (e.g., in `Private' instead of `FontDict'). - * freetype2/src/type1/t1tokens.h: Adjust invocations of - T1_FIELD_XXX. + * src/type1/t1tokens.h: Adjust invocations of T1_FIELD_XXX. - * freetype2/src/type42/t42parse.c: (t42_keywords): Adjust - invocations of T1_FIELD_XXX. + * src/type42/t42parse.c: (t42_keywords): Adjust invocations of + T1_FIELD_XXX. 2006-07-18 Jens Claudius @@ -2078,19 +7113,18 @@ Call the finisher for T1_Decoder in `cid_face_compute_max_advance' and `T1_Compute_Max_Advance'. - * freetype2/include/freetype/internal/psaux.h (T1_DecoderRec): - Remove field `face', add `len_buildchar'. + * include/freetype/internal/psaux.h (T1_DecoderRec): Remove field + `face', add `len_buildchar'. - * freetype2/include/freetype/internal/t1types.h (T1_FaceRec): Add - field `buildchar'. + * include/freetype/internal/t1types.h (T1_FaceRec): Add field + `buildchar'. - * freetype2/src/cid/cidgload.c (cid_face_compute_max_advance): Call - finisher for T1_Decoder. + * src/cid/cidgload.c (cid_face_compute_max_advance): Call finisher + for T1_Decoder. (cid_slot_load_glyph): Do not ignore failure when initializing the T1_Decoder. - * freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): - Updated. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Updated. (t1_decoder_init): Remove initialization of fields `buildchar' and `len_buildchar'. (t1_decoder_done): Remove deallocation of field `buildchar'. @@ -2102,46 +7136,45 @@ `len_buildchar'; make sure to call finisher for T1_Decoder even in case of error. - * freetype2/src/type1/t1load.c (T1_Open_Face): Allocate new field - `buildchar' of T1_FaceRec. + * src/type1/t1load.c (T1_Open_Face): Allocate new field `buildchar' + of T1_FaceRec. - * freetype2/src/type1/t1objs.c (T1_Face_Done): Free new field - `buildchar' of T1_FaceRec. + * src/type1/t1objs.c (T1_Face_Done): Free new field `buildchar' of + T1_FaceRec. 2006-07-14 Jens Claudius - * freetype2/include/freetype/internal/psaux.h: New macros - IS_PS_NEWLINE, IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, - IS_PS_XDIGIT, and IS_PS_BASE85 (from freetype2/src/psaux/psconv.h). + * include/freetype/internal/psaux.h: New macros IS_PS_NEWLINE, + IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, + and IS_PS_BASE85 (from src/psaux/psconv.h). (T1_FieldLocation): Add T1_FIELD_LOCATION_LOADER, T1_FIELD_LOCATION_FACE, and T1_FIELD_LOCATION_BLEND. (T1_DecoderRec): New fields `buildchar' and `face'. (IS_PS_TOKEN): New macro. - * freetype2/include/freetype/internal/t1types.h (T1_FaceRec): New - fields `ndv_idx', `cdv_idx', and `len_buildchar'. + * include/freetype/internal/t1types.h (T1_FaceRec): New fields + `ndv_idx', `cdv_idx', and `len_buildchar'. - * freetype2/include/freetype/t1tables.h (PS_BlendRec): New fields + * include/freetype/t1tables.h (PS_BlendRec): New fields `default_design_vector' and `num_default_design_vector'. - * freetype2/src/psaux/psconv.h: Move macros IS_PS_NEWLINE, - IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, - and IS_PS_BASE85 to freetype2/include/freetype/internal/psaux.h. + * src/psaux/psconv.h: Move macros IS_PS_NEWLINE, IS_PS_SPACE, + IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, and + IS_PS_BASE85 to include/freetype/internal/psaux.h. - * freetype2/src/psaux/psobjs.c (ps_parser_to_token_array): Allow - `token' argument to be NULL if we want only to count the number of - tokens. + * src/psaux/psobjs.c (ps_parser_to_token_array): Allow `token' + argument to be NULL if we want only to count the number of tokens. (ps_tocoordarray): Allow `coords' argument to be NULL if we just want to skip the array. (ps_tofixedarray): Allow `values' argument to be NULL if we just want to skip the array. - * freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add - support for (partially commented out) othersubrs 19-25, 27, and 28. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add support + for (partially commented out) othersubrs 19-25, 27, and 28. (t1_decoder_init): Initialize new fields `face' and `buildchar'. (t1_decoder_done): Release new field `buildchar'. - * freetype2/src/type1/t1load.c (parse_buildchar, parse_private): New + * src/type1/t1load.c (parse_buildchar, parse_private): New functions. (t1_keywords): Register them. (t1_allocate_blend): Updated. @@ -2156,12 +7189,12 @@ `len_buildchar'. Remove `keywords_flags'. - * freetype2/src/type1/t1load.h (T1_LoaderRect): New field + * src/type1/t1load.h (T1_LoaderRect): New field `keywords_encountered'. (T1_PRIVATE, T1_FONTDIR_AFTER_PRIVATE): New macros. - * freetype2/src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: - New entries for parsing /NDV, /CDV, and /DesignVector. + * src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: New + entries for parsing /NDV, /CDV, and /DesignVector. 2006-07-07 Werner Lemberg @@ -2230,7 +7263,7 @@ 2006-06-24 Eugeniy Meshcheryakov Fix two hinting bugs as reported in - http://lists.nongnu.org/archive/html/freetype-devel/2006-06/msg00057.html. + http://lists.gnu.org/archive/html/freetype-devel/2006-06/msg00057.html. * include/freetype/internal/tttypes.h (TT_GlyphZoneRec): Add `first_point' member. @@ -2441,7 +7474,7 @@ ---------------------------------------------------------------------------- -Copyright 2006, 2007 by +Copyright 2006, 2007, 2008, 2009 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/reactos/lib/3rdparty/freetype/ChangeLog.21 b/reactos/lib/3rdparty/freetype/ChangeLog.21 index 3a1bcf0c11d..d6371d17583 100644 --- a/reactos/lib/3rdparty/freetype/ChangeLog.21 +++ b/reactos/lib/3rdparty/freetype/ChangeLog.21 @@ -922,7 +922,7 @@ (tt_driver_class): Updated. * src/truetype/ttgload.c (TT_Get_Metrics): Renamed to... - (tt_face_get_metrics): This. Provide version for FT_OPTIMIZE_MEMORY. + (tt_face_get_metrics): This. Provide version for FT_OPTIMIZE_MEMORY. Update all callers. (Get_Advance_Widths): Replaced with... (Get_Advance_WidthPtr): This. Provide version for @@ -1221,7 +1221,7 @@ 2004-11-16 Owen Taylor * builds/unix/freetype-config.in: Suppress -L$libdir for - /usr/lib64 as well as /usr/lib. (Reported by Dan Winship - + /usr/lib64 as well as /usr/lib. (Reported by Dan Winship - https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=139199) 2004-11-11 Werner Lemberg @@ -3554,7 +3554,7 @@ - the image and sbit cache are now abstract classes, that can be extended much more easily by client applications - - better performance in certain areas. Further optimizations + - better performance in certain areas. Further optimizations to come shortly anyway... - the FTC_CMapCache_Lookup function has changed its signature, @@ -9423,7 +9423,7 @@ ---------------------------------------------------------------------------- -Copyright 2002, 2003, 2004, 2005, 2007 by +Copyright 2002, 2003, 2004, 2005, 2007, 2008 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/reactos/lib/3rdparty/freetype/ChangeLog.22 b/reactos/lib/3rdparty/freetype/ChangeLog.22 index 22bf4f91895..4144288a5bf 100644 --- a/reactos/lib/3rdparty/freetype/ChangeLog.22 +++ b/reactos/lib/3rdparty/freetype/ChangeLog.22 @@ -199,7 +199,7 @@ * src/base/ftmac.c (read_lwfn): Catch integer overflow. * src/base/ftrfork.c (raccess_guess_darwin_hfsplus): Ditto. * src/base/ftutil.c: Remove special code for FT_STRICT_ALIASING. - (ft_mem_alloc. ft_mem_realloc, ft_mem_qrealloc): Rewrite. + (ft_mem_alloc, ft_mem_realloc, ft_mem_qrealloc): Rewrite. * include/freetype/ftstream.h (FT_FRAME_ENTER, FT_FRAME_EXIT, @@ -2301,7 +2301,7 @@ 2005-09-19 David Somers - * freetype2/src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a + * src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a font to have no `head' table if tables `SING' and `META' are present; this is to support `SING Glyphlet'. @@ -2320,9 +2320,9 @@ http://www.adobe.com/products/indesign/sing_gaiji.html - * freetype2/include/freetype/ttags.h (TTAG_SING, TTAG_META): New - macros for the OpenType tables `SING' and `META'. These two tables - are used in SING Glyphlet Format fonts. + * include/freetype/ttags.h (TTAG_SING, TTAG_META): New macros for + the OpenType tables `SING' and `META'. These two tables are used in + SING Glyphlet Format fonts. 2005-09-09 Werner Lemberg @@ -2808,7 +2808,7 @@ . loader->pp3.y and loader->pp4.y are in 26.6 format, not in font units. . As we use the glyph's cbox to calculate the top bearing now - there iss no need to adjust `top'. + there is no need to adjust `top'. 2005-06-15 Werner Lemberg @@ -2821,7 +2821,7 @@ ---------------------------------------------------------------------------- -Copyright 2005, 2006, 2007 by +Copyright 2005, 2006, 2007, 2008 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/reactos/lib/3rdparty/freetype/Jamfile b/reactos/lib/3rdparty/freetype/Jamfile index ad1341ed369..ac327b812e0 100644 --- a/reactos/lib/3rdparty/freetype/Jamfile +++ b/reactos/lib/3rdparty/freetype/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 top Jamfile. # -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -194,7 +194,7 @@ rule RefDoc actions RefDoc { - python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.5 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h + python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.11 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h } RefDoc refdoc ; diff --git a/reactos/lib/3rdparty/freetype/README b/reactos/lib/3rdparty/freetype/README index 82d0003374a..f63c8fc4602 100644 --- a/reactos/lib/3rdparty/freetype/README +++ b/reactos/lib/3rdparty/freetype/README @@ -9,8 +9,8 @@ is called `libttf'. They are *not* compatible! - FreeType 2.3.5 - ============== + FreeType 2.3.11 + =============== Please read the docs/CHANGES file, it contains IMPORTANT INFORMATION. @@ -26,9 +26,9 @@ and download one of the following files. - freetype-doc-2.3.5.tar.bz2 - freetype-doc-2.3.5.tar.gz - ftdoc235.zip + freetype-doc-2.3.11.tar.bz2 + freetype-doc-2.3.11.tar.gz + ftdoc2311.zip Bugs @@ -51,7 +51,7 @@ ---------------------------------------------------------------------- -Copyright 2006, 2007 by +Copyright 2006, 2007, 2008, 2009 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/reactos/lib/3rdparty/freetype/README.git b/reactos/lib/3rdparty/freetype/README.git new file mode 100644 index 00000000000..bb36cf7b303 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/README.git @@ -0,0 +1,46 @@ +The git archive doesn't contain pre-built configuration scripts for +UNIXish platforms. To generate them say + + sh autogen.sh + +which in turn depends on the following packages: + + automake (1.10.1) + libtool (2.2.4) + autoconf (2.62) + +The versions given in parentheses are known to work. Newer versions +should work too, of course. Note that autogen.sh also sets up proper +file permissions for the `configure' and auxiliary scripts. + +The autogen.sh script now checks the version of above three packages +whether they match the numbers above. Otherwise it will complain and +suggest either upgrading or using an environment variable to point to +a more recent version of the required tool(s). + +Note that `aclocal' is provided by the `automake' package on Linux, +and that `libtoolize' is called `glibtoolize' on Darwin (OS X). + + +For static builds which don't use platform specific optimizations, no +configure script is necessary at all; saying + + make setup ansi + make + +should work on all platforms which have GNU make (or makepp). + + +---------------------------------------------------------------------- + +Copyright 2005, 2006, 2007, 2008, 2009 by +David Turner, Robert Wilhelm, and Werner Lemberg. + +This file is part of the FreeType project, and may only be used, +modified, and distributed under the terms of the FreeType project +license, LICENSE.TXT. By continuing to use, modify, or distribute +this file you indicate that you have read the license and understand +and accept it fully. + + +--- end of README.CVS --- diff --git a/reactos/lib/3rdparty/freetype/autogen.sh b/reactos/lib/3rdparty/freetype/autogen.sh index d8fb5b2ec6d..16c335fd5c9 100644 --- a/reactos/lib/3rdparty/freetype/autogen.sh +++ b/reactos/lib/3rdparty/freetype/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright 2005, 2006, 2007 by +# Copyright 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,12 +20,120 @@ run () fi } +get_major_version () +{ + echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/g' +} + +get_minor_version () +{ + echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g' +} + +get_patch_version () +{ + # tricky: some version numbers don't include a patch + # separated with a point, but something like 1.4-p6 + patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'` + if test "$patch" = "$1"; then + patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\-p\([0-9][0-9]*\).*/\1/g'` + # if there isn't any patch number, default to 0 + if test "$patch" = "$1"; then + patch=0 + fi + fi + echo $patch +} + +# $1: version to check +# $2: minimum version + +compare_to_minimum_version () +{ + MAJOR1=`get_major_version $1` + MAJOR2=`get_major_version $2` + if test $MAJOR1 -lt $MAJOR2; then + echo 0 + return + else + if test $MAJOR1 -gt $MAJOR2; then + echo 1 + return + fi + fi + + MINOR1=`get_minor_version $1` + MINOR2=`get_minor_version $2` + if test $MINOR1 -lt $MINOR2; then + echo 0 + return + else + if test $MINOR1 -gt $MINOR2; then + echo 1 + return + fi + fi + + PATCH1=`get_patch_version $1` + PATCH2=`get_patch_version $2` + if test $PATCH1 -lt $PATCH2; then + echo 0 + else + echo 1 + fi +} + +# check the version of a given tool against a minimum version number +# +# $1: tool path +# $2: tool usual name (e.g. `aclocal') +# $3: tool variable (e.g. `ACLOCAL') +# $4: minimum version to check against +# $5: option field index used to extract the tool version from the +# output of --version + +check_tool_version () +{ + field=$5 + if test "$field"x = x; then + field=4 # default to 4 for all GNU autotools + fi + version=`$1 --version | head -1 | cut -d ' ' -f $field` + version_check=`compare_to_minimum_version $version $4` + if test "$version_check"x = 0x; then + echo "ERROR: Your version of the \`$2' tool is too old." + echo " Minimum version $4 is required (yours is version $version)." + echo " Please upgrade or use the $3 variable to point to a more recent one." + echo "" + exit 1 + fi +} + if test ! -f ./builds/unix/configure.raw; then echo "You must be in the same directory as \`autogen.sh'." echo "Bootstrapping doesn't work if srcdir != builddir." exit 1 fi +# On MacOS X, the GNU libtool is named `glibtool'. +HOSTOS=`uname` +LIBTOOLIZE=libtoolize +if test "$HOSTOS"x = Darwinx; then + LIBTOOLIZE=glibtoolize +fi + +if test "$ACLOCAL"x = x; then + ACLOCAL=aclocal +fi + +if test "$AUTOCONF"x = x; then + AUTOCONF=autoconf +fi + +check_tool_version $ACLOCAL aclocal ACLOCAL 1.10.1 +check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4 +check_tool_version $AUTOCONF autoconf AUTOCONF 2.62 + # This sets freetype_major, freetype_minor, and freetype_patch. eval `sed -nf version.sed include/freetype/freetype.h` @@ -38,17 +146,10 @@ cd builds/unix echo "generating \`configure.ac'" sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \ - < configure.raw > configure.ac - -# On MacOS X, the GNU libtool is named `glibtool'. -HOSTOS=`uname` -LIBTOOLIZE=libtoolize -if test "$HOSTOS"x = Darwinx; then - LIBTOOLIZE=glibtoolize -fi + < configure.raw > configure.ac run aclocal -I . --force -run $LIBTOOLIZE --force --copy +run $LIBTOOLIZE --force --copy --install run autoconf --force chmod +x mkinstalldirs diff --git a/reactos/lib/3rdparty/freetype/configure b/reactos/lib/3rdparty/freetype/configure index f251ae417a4..2efa2696797 100644 --- a/reactos/lib/3rdparty/freetype/configure +++ b/reactos/lib/3rdparty/freetype/configure @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2002, 2003, 2004, 2005, 2006 by +# Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,7 +21,7 @@ fi if test -z "`$GNUMAKE -v 2>/dev/null | grep GNU`"; then if test -z "`$GNUMAKE -v 2>/dev/null | grep makepp`"; then - echo "GNU make (>= 3.79.1) or makepp (>= 1.19) is required to build FreeType2." >&2 + echo "GNU make (>= 3.80) or makepp (>= 1.19) is required to build FreeType2." >&2 echo "Please try" >&2 echo " \`GNUMAKE= $0'." >&2 echo "or >&2" @@ -67,12 +67,25 @@ ft2_dir=`(dirname "$0") 2>/dev/null || abs_curr_dir=`pwd` abs_ft2_dir=`cd "$ft2_dir" && pwd` +# `--srcdir=' option can override abs_ft2_dir + +if test $# -gt 0; then + for x in "$@"; do + case x"$x" in + x--srcdir=*) + abs_ft2_dir=`echo $x | sed 's/^--srcdir=//'` ;; + esac + done +fi + # build a dummy Makefile if we are not building in the source tree if test "$abs_curr_dir" != "$abs_ft2_dir"; then mkdir reference - echo "Copying \`modules.cfg'" - cp $abs_ft2_dir/modules.cfg $abs_curr_dir + if test ! -r $abs_curr_dir/modules.cfg; then + echo "Copying \`modules.cfg'" + cp $abs_ft2_dir/modules.cfg $abs_curr_dir + fi echo "Generating \`Makefile'" echo "TOP_DIR := $abs_ft2_dir" > Makefile echo "OBJ_DIR := $abs_curr_dir" >> Makefile @@ -92,9 +105,16 @@ fi # call make CFG= -for x in ${1+"$@"}; do - CFG="$CFG \"$x\"" -done +# work around zsh bug which doesn't like `${1+"$@"}' +case $# in +0) ;; +*) for x in "$@"; do + case x"$x" in + x--srcdir=* ) CFG="$CFG '$x'/builds/unix" ;; + *) CFG="$CFG '$x'" ;; + esac + done ;; +esac CFG=$CFG $GNUMAKE setup unix # eof diff --git a/reactos/lib/3rdparty/freetype/devel/ftoption.h b/reactos/lib/3rdparty/freetype/devel/ftoption.h index 6cf1af23610..d4fee59537b 100644 --- a/reactos/lib/3rdparty/freetype/devel/ftoption.h +++ b/reactos/lib/3rdparty/freetype/devel/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -112,7 +112,28 @@ FT_BEGIN_HEADER /* file `ftconfig.h' either statically or through the */ /* `configure' script on supported platforms. */ /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX /*************************************************************************/ @@ -163,7 +184,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ @@ -204,27 +225,27 @@ FT_BEGIN_HEADER /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* Undefine this macro if you do not want `psnames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ @@ -240,12 +261,12 @@ FT_BEGIN_HEADER /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -294,7 +315,7 @@ FT_BEGIN_HEADER /* This allows FreeType to be used with the PostScript language, using */ /* the GhostScript interpreter. */ /* */ -/* #define FT_CONFIG_OPTION_INCREMENTAL */ +#define FT_CONFIG_OPTION_INCREMENTAL /*************************************************************************/ @@ -418,7 +439,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ + /* `freetype/ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -436,6 +457,8 @@ FT_BEGIN_HEADER #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 /*************************************************************************/ @@ -466,9 +489,9 @@ FT_BEGIN_HEADER /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ /* of the TrueType bytecode interpreter is used that doesn't implement */ /* any of the patented opcodes and algorithms. Note that the */ - /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */ - /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, either define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ /* */ /* This macro is only useful for a small number of font files (mostly */ @@ -624,11 +647,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Compile autofit module with CJK script support. */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ /* */ #define AF_CONFIG_OPTION_CJK - /*************************************************************************/ /* */ /* Compile autofit module with Indic script support. */ @@ -648,15 +671,16 @@ FT_BEGIN_HEADER * is recommended to disable the macro since it reduces the library's code * size and activates a few memory-saving optimizations as well. */ -#undef FT_CONFIG_OPTION_OLD_INTERNALS +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* - * This variable is defined if either unpatented or native TrueType + * This macro is defined if either unpatented or native TrueType * hinting is requested by the definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING #elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING #define TT_USE_BYTECODE_INTERPRETER #endif diff --git a/reactos/lib/3rdparty/freetype/freetype.def b/reactos/lib/3rdparty/freetype/freetype.def index e6896e69e2b..1f5895f9b92 100644 --- a/reactos/lib/3rdparty/freetype/freetype.def +++ b/reactos/lib/3rdparty/freetype/freetype.def @@ -40,13 +40,19 @@ EXPORTS FT_Face_CheckTrueTypePatents FT_Face_SetUnpatentedHinting FT_FloorFix + FT_Get_Advance + FT_Get_Advances FT_Get_BDF_Charset_ID FT_Get_BDF_Property FT_Get_CMap_Format FT_Get_CMap_Language_ID FT_Get_Char_Index FT_Get_Charmap_Index + FT_Get_CID_From_Glyph_Index + FT_Get_CID_Is_Internally_CID_keyed + FT_Get_CID_Registry_Ordering_Supplement FT_Get_First_Char + FT_Get_FSType_Flags FT_Get_Glyph FT_Get_Glyph_Name FT_Get_Kerning diff --git a/reactos/lib/3rdparty/freetype/freetype.rbuild b/reactos/lib/3rdparty/freetype/freetype.rbuild index bf7709ede9d..25fbc6065fe 100644 --- a/reactos/lib/3rdparty/freetype/freetype.rbuild +++ b/reactos/lib/3rdparty/freetype/freetype.rbuild @@ -17,23 +17,26 @@ - ftsystem.c - ftinit.c - ftdebug.c - _ftbase_ros.c + ftbase.c ftbbox.c - ftglyph.c ftbdf.c ftbitmap.c + ftdebug.c + ftgasp.c + ftglyph.c ftgxval.c + ftinit.c + ftlcdfil.c ftmm.c ftotval.c ftpatent.c ftpfr.c ftstroke.c ftsynth.c + ftsystem.c fttype1.c ftwinfnt.c + ftxf86.c autofit.c diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h index 1547f5adb14..3c0b8b16412 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,6 +43,7 @@ #include FT_CONFIG_OPTIONS_H #include FT_CONFIG_STANDARD_LIBRARY_H + FT_BEGIN_HEADER @@ -134,18 +135,78 @@ FT_BEGIN_HEADER #else #define FT_MACINTOSH 1 #endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + #endif /*************************************************************************/ /* */ - /* IntN types */ + /*
*/ + /* basic_types */ /* */ - /* Used to guarantee the size of some specific integers. */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ /* */ - typedef signed short FT_Int16; typedef unsigned short FT_UInt16; + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + /* */ + +#endif + #if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) typedef signed int FT_Int32; @@ -160,6 +221,7 @@ FT_BEGIN_HEADER #error "no 32bit type found -- please check your configuration files" #endif + /* look up an integer type that is at least 32 bits */ #if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) @@ -215,17 +277,12 @@ FT_BEGIN_HEADER #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ -#define FT_BEGIN_STMNT do { -#define FT_END_STMNT } while ( 0 ) -#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT - - /*************************************************************************/ /* */ /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable their use if */ - /* __STDC__ is defined. You can however ignore this rule by */ - /* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ + /* is defined. You can however ignore this rule by defining the */ + /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ /* */ #if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) @@ -240,6 +297,86 @@ FT_BEGIN_HEADER #endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#ifdef __GNUC__ + +#if defined( __arm__ ) && !defined( __thumb__ ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + asm __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) ); + return a; + } + +#endif /* __arm__ && !__thumb__ */ + +#if defined( i386 ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER +#endif +#endif + + #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftheader.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftheader.h index b957d05bedd..b63945dcbd3 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftheader.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* */ /* */ /* The following macros are defined to the name of specific */ - /* FreeType 2 header files. They can be used directly in #include */ + /* FreeType~2 header files. They can be used directly in #include */ /* statements as in: */ /* */ /* { */ @@ -85,11 +85,11 @@ /* */ /* There are several reasons why we are now using macros to name */ /* public header files. The first one is that such macros are not */ - /* limited to the infamous 8.3 naming rule required by DOS (and */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ /* */ /* The second reason is that it allows for more flexibility in the */ - /* way FreeType 2 is installed on a given system. */ + /* way FreeType~2 is installed on a given system. */ /* */ /*************************************************************************/ @@ -103,7 +103,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 configuration data. + * FreeType~2 configuration data. * */ #ifndef FT_CONFIG_CONFIG_H @@ -118,7 +118,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 interface to the standard C library functions. + * FreeType~2 interface to the standard C library functions. * */ #ifndef FT_CONFIG_STANDARD_LIBRARY_H @@ -133,7 +133,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 project-specific configuration options. + * FreeType~2 project-specific configuration options. * */ #ifndef FT_CONFIG_OPTIONS_H @@ -148,7 +148,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 modules that are statically linked to new library + * list of FreeType~2 modules that are statically linked to new library * instances in @FT_Init_FreeType. * */ @@ -156,6 +156,7 @@ #define FT_CONFIG_MODULES_H #endif + /* */ /* public headers */ @@ -166,7 +167,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * base FreeType 2 API. + * base FreeType~2 API. * */ #define FT_FREETYPE_H @@ -179,7 +180,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 error codes (and messages). + * list of FreeType~2 error codes (and messages). * * It is included by @FT_FREETYPE_H. * @@ -194,7 +195,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 module error offsets (and messages). + * list of FreeType~2 module error offsets (and messages). * */ #define FT_MODULE_ERRORS_H @@ -207,7 +208,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 interface to low-level operations (i.e., memory management + * FreeType~2 interface to low-level operations (i.e., memory management * and stream i/o). * * It is included by @FT_FREETYPE_H. @@ -239,7 +240,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * basic data types defined by FreeType 2. + * basic data types defined by FreeType~2. * * It is included by @FT_FREETYPE_H. * @@ -254,7 +255,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list management API of FreeType 2. + * list management API of FreeType~2. * * (Most applications will never need to include this file.) * @@ -269,7 +270,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * scalable outline management API of FreeType 2. + * scalable outline management API of FreeType~2. * */ #define FT_OUTLINE_H @@ -295,7 +296,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * module management API of FreeType 2. + * module management API of FreeType~2. * */ #define FT_MODULE_H @@ -308,7 +309,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * renderer module management API of FreeType 2. + * renderer module management API of FreeType~2. * */ #define FT_RENDER_H @@ -321,7 +322,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * types and API specific to the Type 1 format. + * types and API specific to the Type~1 format. * */ #define FT_TYPE1_TABLES_H @@ -383,6 +384,20 @@ #define FT_BDF_H + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H + + /************************************************************************* * * @macro: @@ -468,7 +483,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * API of the optional FreeType 2 cache sub-system. + * API of the optional FreeType~2 cache sub-system. * */ #define FT_CACHE_H @@ -481,7 +496,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `glyph image' API of the FreeType 2 cache sub-system. + * `glyph image' API of the FreeType~2 cache sub-system. * * It is used to define a cache for @FT_Glyph elements. You can also * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to @@ -501,7 +516,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `small bitmaps' API of the FreeType 2 cache sub-system. + * `small bitmaps' API of the FreeType~2 cache sub-system. * * It is used to define a cache for small glyph bitmaps in a relatively * memory-efficient way. You can also use the API defined in @@ -522,7 +537,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `charmap' API of the FreeType 2 cache sub-system. + * `charmap' API of the FreeType~2 cache sub-system. * * This macro is deprecated. Simply include @FT_CACHE_H to have all * charmap-based cache declarations. @@ -538,7 +553,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * Macintosh-specific FreeType 2 API. The latter is used to access + * Macintosh-specific FreeType~2 API. The latter is used to access * fonts embedded in resource forks. * * This header file must be explicitly included by client applications @@ -555,7 +570,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional multiple-masters management API of FreeType 2. + * optional multiple-masters management API of FreeType~2. * */ #define FT_MULTIPLE_MASTERS_H @@ -568,7 +583,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which accesses embedded `name' strings in + * optional FreeType~2 API which accesses embedded `name' strings in * SFNT-based font formats (i.e., TrueType and OpenType). * */ @@ -582,7 +597,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which validates OpenType tables (BASE, GDEF, + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, * GPOS, GSUB, JSTF). * */ @@ -596,7 +611,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat, + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, * mort, morx, bsln, just, kern, opbd, trak, prop). * */ @@ -610,7 +625,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which accesses PFR-specific data. + * FreeType~2 API which accesses PFR-specific data. * */ #define FT_PFR_H @@ -623,7 +638,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which provides functions to stroke outline paths. + * FreeType~2 API which provides functions to stroke outline paths. */ #define FT_STROKER_H @@ -635,7 +650,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs artificial obliquing and emboldening. + * FreeType~2 API which performs artificial obliquing and emboldening. */ #define FT_SYNTHESIS_H @@ -647,7 +662,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which provides functions specific to the XFree86 and + * FreeType~2 API which provides functions specific to the XFree86 and * X.Org X11 servers. */ #define FT_XFREE86_H @@ -660,7 +675,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs trigonometric computations (e.g., + * FreeType~2 API which performs trigonometric computations (e.g., * cosines and arc tangents). */ #define FT_TRIGONOMETRY_H @@ -673,11 +688,35 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs color filtering for subpixel rendering. */ #define FT_LCD_FILTER_H + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_UNPATENTED_HINTING_H + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_INCREMENTAL_H + + /************************************************************************* * * @macro: @@ -685,11 +724,23 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which returns entries from the TrueType GASP table. + * FreeType~2 API which returns entries from the TrueType GASP table. */ #define FT_GASP_H + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H + + /* */ #define FT_ERROR_DEFINITIONS_H diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftmodule.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftmodule.h index d92b0ee6a1a..76d271a74b9 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftmodule.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftmodule.h @@ -10,23 +10,23 @@ * */ -FT_USE_MODULE(autofit_module_class) -FT_USE_MODULE(tt_driver_class) -FT_USE_MODULE(t1_driver_class) -FT_USE_MODULE(cff_driver_class) -FT_USE_MODULE(t1cid_driver_class) -FT_USE_MODULE(pfr_driver_class) -FT_USE_MODULE(t42_driver_class) -FT_USE_MODULE(winfnt_driver_class) -FT_USE_MODULE(pcf_driver_class) -FT_USE_MODULE(psaux_module_class) -FT_USE_MODULE(psnames_module_class) -FT_USE_MODULE(pshinter_module_class) -FT_USE_MODULE(ft_raster1_renderer_class) -FT_USE_MODULE(sfnt_module_class) -FT_USE_MODULE(ft_smooth_renderer_class) -FT_USE_MODULE(ft_smooth_lcd_renderer_class) -FT_USE_MODULE(ft_smooth_lcdv_renderer_class) -FT_USE_MODULE(bdf_driver_class) +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) /* EOF */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h index 5d99ae3c3c2..f7250896681 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -112,7 +112,28 @@ FT_BEGIN_HEADER /* file `ftconfig.h' either statically or through the */ /* `configure' script on supported platforms. */ /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX /*************************************************************************/ @@ -163,7 +184,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ @@ -204,27 +225,27 @@ FT_BEGIN_HEADER /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* Undefine this macro if you do not want `psnames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ @@ -240,12 +261,12 @@ FT_BEGIN_HEADER /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -375,6 +396,20 @@ FT_BEGIN_HEADER #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + /*************************************************************************/ /*************************************************************************/ @@ -418,7 +453,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ + /* `freetype/ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -436,6 +471,8 @@ FT_BEGIN_HEADER #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 /*************************************************************************/ @@ -466,9 +503,9 @@ FT_BEGIN_HEADER /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ /* of the TrueType bytecode interpreter is used that doesn't implement */ /* any of the patented opcodes and algorithms. Note that the */ - /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */ - /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, either define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ /* */ /* This macro is only useful for a small number of font files (mostly */ @@ -505,7 +542,7 @@ FT_BEGIN_HEADER /* ... */ /* } */ /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ +//#define TT_CONFIG_OPTION_UNPATENTED_HINTING /*************************************************************************/ @@ -624,7 +661,8 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Compile autofit module with CJK script support. */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ /* */ #define AF_CONFIG_OPTION_CJK @@ -632,7 +670,7 @@ FT_BEGIN_HEADER /* */ /* Compile autofit module with Indic script support. */ /* */ -/* #define AF_CONFIG_OPTION_INDIC */ +#define AF_CONFIG_OPTION_INDIC /* */ @@ -651,11 +689,12 @@ FT_BEGIN_HEADER /* - * This variable is defined if either unpatented or native TrueType + * This macro is defined if either unpatented or native TrueType * hinting is requested by the definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING #elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING #define TT_USE_BYTECODE_INTERPRETER #endif diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h index f923f3e4cf8..30ec14e74ef 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,12 +54,6 @@ /* In these case, `ftconfig.h' will refuse to compile anyway with a */ /* message like `couldn't find 32-bit type' or something similar. */ /* */ - /* IMPORTANT NOTE: We do not define aliases for heap management and */ - /* i/o routines (i.e. malloc/free/fopen/fread/...) */ - /* since these functions should all be encapsulated */ - /* by platform-specific implementations of */ - /* `ftsystem.c'. */ - /* */ /**********************************************************************/ @@ -67,6 +61,7 @@ #define FT_CHAR_BIT CHAR_BIT #define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX #define FT_ULONG_MAX ULONG_MAX @@ -124,8 +119,6 @@ #define ft_qsort qsort -#define ft_exit exit /* only used to exit from unhandled exceptions */ - /**********************************************************************/ /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/freetype.h b/reactos/lib/3rdparty/freetype/include/freetype/freetype.h index dbca087e5f0..9e74f1158af 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/freetype.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,14 +25,6 @@ #endif - /*************************************************************************/ - /* */ - /* The `raster' component duplicates some of the declarations in */ - /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ - /* */ - /*************************************************************************/ - - #ifndef __FREETYPE_H__ #define __FREETYPE_H__ @@ -60,8 +52,8 @@ FT_BEGIN_HEADER /* */ /* */ /* FreeType assumes that structures allocated by the user and passed */ - /* as arguments are zeroed out except for the actual data. With */ - /* other words, it is recommended to use `calloc' (or variants of it) */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ /* instead of `malloc' for allocation. */ /* */ /*************************************************************************/ @@ -86,10 +78,10 @@ FT_BEGIN_HEADER /* Base Interface */ /* */ /* */ - /* The FreeType 2 base font interface. */ + /* The FreeType~2 base font interface. */ /* */ /* */ - /* This section describes the public high-level API of FreeType 2. */ + /* This section describes the public high-level API of FreeType~2. */ /* */ /* */ /* FT_Library */ @@ -191,6 +183,15 @@ FT_BEGIN_HEADER /* FT_Set_Charmap */ /* FT_Get_Charmap_Index */ /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ + /* FT_FSTYPE_EDITABLE_EMBEDDING */ + /* FT_FSTYPE_NO_SUBSETTING */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ /*************************************************************************/ @@ -386,8 +387,8 @@ FT_BEGIN_HEADER /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ /* */ - /* The @FT_FaceRec details the publicly accessible fields of a given */ - /* face object. */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ /* */ typedef struct FT_FaceRec_* FT_Face; @@ -416,8 +417,8 @@ FT_BEGIN_HEADER /* activated at any given time per face. */ /* */ /* */ - /* The @FT_SizeRec structure details the publicly accessible fields */ - /* of a given size object. */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ /* */ typedef struct FT_SizeRec_* FT_Size; @@ -429,7 +430,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any one of the glyphs contained in its parent */ + /* is possible to load any of the glyphs contained in its parent */ /* face. */ /* */ /* In other words, each time you call @FT_Load_Glyph or */ @@ -438,7 +439,7 @@ FT_BEGIN_HEADER /* other control information. */ /* */ /* */ - /* @FT_GlyphSlotRec details the publicly accessible glyph fields. */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ /* */ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; @@ -469,8 +470,8 @@ FT_BEGIN_HEADER /* the list and automatically activates it. */ /* */ /* */ - /* The @FT_CharMapRec details the publicly accessible fields of a */ - /* given character map. */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ /* */ typedef struct FT_CharMapRec_* FT_CharMap; @@ -485,7 +486,7 @@ FT_BEGIN_HEADER /* used to define `encoding' identifiers (see @FT_Encoding). */ /* */ /* */ - /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ @@ -518,131 +519,132 @@ FT_BEGIN_HEADER /* */ /* Despite the name, this enumeration lists specific character */ /* repertories (i.e., charsets), and not text encoding methods (e.g., */ - /* UTF-8, UTF-16, GB2312_EUC, etc.). */ - /* */ - /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ - /* all character codes must be expressed as FT_Longs. */ + /* UTF-8, UTF-16, etc.). */ /* */ /* Other encodings might be defined in the future. */ /* */ /* */ - /* FT_ENCODING_NONE :: */ - /* The encoding value 0 is reserved. */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ /* */ - /* FT_ENCODING_UNICODE :: */ - /* Corresponds to the Unicode character set. This value covers */ - /* all versions of the Unicode repertoire, including ASCII and */ - /* Latin-1. Most fonts include a Unicode charmap, but not all */ - /* of them. */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ /* */ - /* FT_ENCODING_MS_SYMBOL :: */ - /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols in the 32..255 character code range. For */ - /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ /* */ - /* FT_ENCODING_SJIS :: */ - /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://langsupport.japanreference.com/encoding.shtml'. */ - /* See note on multi-byte encodings below. */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ /* */ - /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ - /* used in mainland China. */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ /* */ - /* FT_ENCODING_BIG5 :: */ - /* Corresponds to an encoding system for Traditional Chinese as used */ - /* in Taiwan and Hong Kong. */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ /* */ - /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Wansung. */ - /* For more information see */ - /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ /* */ - /* FT_ENCODING_JOHAB :: */ - /* The Korean standard character set (KS C-5601-1992), which */ - /* corresponds to MS Windows code page 1361. This character set */ - /* includes all possible Hangeul character combinations. */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ /* */ - /* FT_ENCODING_ADOBE_LATIN_1 :: */ - /* Corresponds to a Latin-1 encoding as defined in a Type 1 */ - /* Postscript font. It is limited to 256 character codes. */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ /* */ - /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Corresponds to the Adobe Standard encoding, as found in Type 1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ /* */ - /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Corresponds to the Adobe Expert encoding, as found in Type 1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ /* */ - /* FT_ENCODING_ADOBE_CUSTOM :: */ - /* Corresponds to a custom encoding, as found in Type 1, CFF, and */ - /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ /* */ - /* FT_ENCODING_APPLE_ROMAN :: */ - /* Corresponds to the 8-bit Apple roman encoding. Many TrueType and */ - /* OpenType fonts contain a charmap for this encoding, since older */ - /* versions of Mac OS are able to use it. */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ - /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was never used nor reported by */ - /* FreeType. Don't use or test for it. */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ /* */ - /* FT_ENCODING_MS_SJIS :: */ - /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ /* */ - /* FT_ENCODING_MS_GB2312 :: */ - /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ /* */ - /* FT_ENCODING_MS_BIG5 :: */ - /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ /* */ - /* FT_ENCODING_MS_WANSUNG :: */ - /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ /* */ - /* FT_ENCODING_MS_JOHAB :: */ - /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ /* */ /* */ - /* By default, FreeType automatically synthetizes a Unicode charmap */ - /* for Postscript fonts, using their glyph names dictionaries. */ - /* However, it also reports the encodings defined explicitly in the */ - /* font file, for the cases when they are needed, with the Adobe */ - /* values as well. */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ /* */ - /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ - /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ - /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out which */ - /* encoding is really present. If, for example, the `cs_registry' */ - /* field is `KOI8' and the `cs_encoding' field is `R', the font is */ - /* encoded in KOI8-R. */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ /* */ - /* FT_ENCODING_NONE is always set (with a single exception) by the */ - /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ - /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ - /* which encoding is really present. For example, */ - /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ - /* Russian). */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ /* */ - /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ - /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ - /* FT_ENCODING_APPLE_ROMAN). */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ /* */ - /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function c */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID which may be */ - /* needed to be able to distinguish Apple encoding variants. See */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* be needed to be able to distinguish Apple encoding variants. See */ /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ /* */ - /* to get an idea how to do that. Basically, if the language ID is 0, */ - /* don't use it, otherwise subtract 1 from the language ID. Then */ - /* examine `encoding_id'. If, for example, `encoding_id' is */ - /* @TT_MAC_ID_ROMAN and the language ID (minus 1) is */ - /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ - /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ - /* variant the Arabic encoding. */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ /* */ typedef enum FT_Encoding_ { @@ -753,7 +755,7 @@ FT_BEGIN_HEADER /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ /* model private data of a given @FT_Face object. */ /* */ - /* This structure might change between releases of FreeType 2 and is */ + /* This structure might change between releases of FreeType~2 and is */ /* not generally available to client applications. */ /* */ typedef struct FT_Face_InternalRec_* FT_Face_Internal; @@ -774,7 +776,7 @@ FT_BEGIN_HEADER /* a font file. */ /* */ /* face_index :: The index of the face in the font file. It */ - /* is set to 0 if there is only one face in */ + /* is set to~0 if there is only one face in */ /* the font file. */ /* */ /* face_flags :: A set of bit flags that give important */ @@ -790,6 +792,9 @@ FT_BEGIN_HEADER /* `num_fixed_sizes'), it is set to the number */ /* of outline glyphs. */ /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ /* family_name :: The face's family name. This is an ASCII */ /* string, usually in English, which describes */ /* the typeface's family (like `Times New */ @@ -799,6 +804,8 @@ FT_BEGIN_HEADER /* provide localized and Unicode versions of */ /* this string. Applications should use the */ /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ /* */ /* style_name :: The face's style name. This is an ASCII */ /* string, usually in English, which describes */ @@ -836,9 +843,13 @@ FT_BEGIN_HEADER /* descender'. Only relevant for scalable */ /* formats. */ /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ /* units_per_EM :: The number of font units per EM square for */ /* this face. This is typically 2048 for */ - /* TrueType fonts, and 1000 for Type 1 fonts. */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ /* Only relevant for scalable formats. */ /* */ /* ascender :: The typographic ascender of the face, */ @@ -874,7 +885,7 @@ FT_BEGIN_HEADER /* scalable formats. */ /* */ /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It's the */ + /* underline line for this face. It is the */ /* center of the underlining stem. Only */ /* relevant for scalable formats. */ /* */ @@ -889,8 +900,8 @@ FT_BEGIN_HEADER /* charmap :: The current active charmap for this face. */ /* */ /* */ - /* Fields may be changed after a call to @FT_Attach_File or */ - /* @FT_Attach_Stream. */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ /* */ typedef struct FT_FaceRec_ { @@ -1019,6 +1030,36 @@ FT_BEGIN_HEADER /* the SFNT `gasp' table only if the native TrueType hinting engine */ /* (with the bytecode interpreter) is available and active. */ /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to autohint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are six TrueType fonts in the list of tricky */ + /* fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1031,8 +1072,8 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) #define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) #define FT_FACE_FLAG_HINTER ( 1L << 11 ) - - /* */ +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) /************************************************************************* @@ -1087,7 +1128,7 @@ FT_BEGIN_HEADER * * @description: * A macro that returns true whenever a face object contains a scalable - * font face (true for TrueType, Type 1, Type 42, CID, OpenType/CFF, + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, * and PFR font formats. * */ @@ -1143,8 +1184,6 @@ FT_BEGIN_HEADER #define FT_HAS_FIXED_SIZES( face ) \ ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) - /* */ - /************************************************************************* * @@ -1187,9 +1226,41 @@ FT_BEGIN_HEADER ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( face->face_flags & FT_FACE_FLAG_TRICKY ) + + /*************************************************************************/ /* */ - /* */ + /* */ /* FT_STYLE_FLAG_XXX */ /* */ /* */ @@ -1198,11 +1269,17 @@ FT_BEGIN_HEADER /* */ /* */ /* FT_STYLE_FLAG_ITALIC :: */ - /* Indicates that a given face is italicized. */ + /* Indicates that a given face style is italic or oblique. */ /* */ /* FT_STYLE_FLAG_BOLD :: */ /* Indicates that a given face is bold. */ /* */ + /* */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ #define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) #define FT_STYLE_FLAG_BOLD ( 1 << 1 ) @@ -1214,7 +1291,7 @@ FT_BEGIN_HEADER /* */ /* */ /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ - /* model private data of a given FT_Size object. */ + /* model private data of a given @FT_Size object. */ /* */ typedef struct FT_Size_InternalRec_* FT_Size_Internal; @@ -1345,7 +1422,7 @@ FT_BEGIN_HEADER /* */ /* */ /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ - /* model private data of a given FT_GlyphSlot object. */ + /* model private data of a given @FT_GlyphSlot object. */ /* */ typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; @@ -1401,7 +1478,7 @@ FT_BEGIN_HEADER /* Only relevant for outline glyphs. */ /* */ /* advance :: This is the transformed advance width for the */ - /* glyph. */ + /* glyph (in 26.6 fractional pixel format). */ /* */ /* format :: This field indicates the format of the image */ /* contained in the glyph slot. Typically */ @@ -1425,7 +1502,7 @@ FT_BEGIN_HEADER /* bitmap_top :: This is the bitmap's top bearing expressed in */ /* integer pixels. Remember that this is the */ /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y-coordinates being */ + /* glyph scanline, upwards y~coordinates being */ /* *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ @@ -1448,7 +1525,7 @@ FT_BEGIN_HEADER /* */ /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type 1 charstrings, etc.). */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ /* This field is a pointer to such data. */ /* */ /* control_len :: This is the length in bytes of the control */ @@ -1470,15 +1547,15 @@ FT_BEGIN_HEADER /* */ /* If @FT_Load_Glyph is called with default flags (see */ /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ - /* its native format (e.g., an outline glyph for TrueType and Type 1 */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ /* formats). */ /* */ /* This image can later be converted into a bitmap by calling */ /* @FT_Render_Glyph. This function finds the current renderer for */ - /* the native image's format then invokes it. */ + /* the native image's format, then invokes it. */ /* */ /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then convert it into a */ + /* the slot's face transformation fields, then converting it into a */ /* bitmap that is returned in `slot->bitmap'. */ /* */ /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ @@ -1573,7 +1650,12 @@ FT_BEGIN_HEADER /* alibrary :: A handle to a new library object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ + /* */ + /* */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ /* */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); @@ -1592,7 +1674,7 @@ FT_BEGIN_HEADER /* library :: A handle to the target library object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_FreeType( FT_Library library ); @@ -1608,26 +1690,26 @@ FT_BEGIN_HEADER /* @FT_Open_Args structure. */ /* */ /* */ - /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ /* */ - /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ /* */ - /* FT_OPEN_PATHNAME :: Create a new input stream from a C */ - /* path name. */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ /* */ - /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ /* */ - /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ /* */ - /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ /* */ - /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ /* */ - /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ /* */ - /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ /* */ - /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ /* */ /* */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ @@ -1652,8 +1734,8 @@ FT_BEGIN_HEADER /* FT_Parameter */ /* */ /* */ - /* A simple structure used to pass more or less generic parameters */ - /* to @FT_Open_Face. */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ /* */ /* */ /* tag :: A four-byte identification tag. */ @@ -1695,7 +1777,7 @@ FT_BEGIN_HEADER /* */ /* driver :: This field is exclusively used by @FT_Open_Face; */ /* it simply specifies the font driver to use to open */ - /* the face. If set to 0, FreeType tries to load the */ + /* the face. If set to~0, FreeType tries to load the */ /* face with each one of the drivers in its list. */ /* */ /* num_params :: The number of extra parameters. */ @@ -1726,7 +1808,7 @@ FT_BEGIN_HEADER /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ - /* as `const'; this is missing for API backwards compatibility. With */ + /* as `const'; this is missing for API backwards compatibility. In */ /* other words, applications should treat them as read-only. */ /* */ typedef struct FT_Open_Args_ @@ -1758,7 +1840,7 @@ FT_BEGIN_HEADER /* pathname :: A path to the font file. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1766,7 +1848,7 @@ FT_BEGIN_HEADER /* See @FT_Open_Face for more details. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_New_Face( FT_Library library, @@ -1793,7 +1875,7 @@ FT_BEGIN_HEADER /* file_size :: The size of the memory chunk used by the font data. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1801,7 +1883,7 @@ FT_BEGIN_HEADER /* See @FT_Open_Face for more details. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* You must not deallocate the memory before calling @FT_Done_Face. */ @@ -1831,7 +1913,7 @@ FT_BEGIN_HEADER /* be filled by the caller. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1839,7 +1921,7 @@ FT_BEGIN_HEADER /* See note below. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Unlike FreeType 1.x, this function automatically creates a glyph */ @@ -1848,7 +1930,7 @@ FT_BEGIN_HEADER /* */ /* FT_Open_Face can be used to quickly check whether the font */ /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is 0 */ + /* `face_index' field is negative, the function's return value is~0 */ /* if the font format is recognized, or non-zero otherwise; */ /* the function returns a more or less empty face handle in `*aface' */ /* (if `aface' isn't NULL). The only useful field in this special */ @@ -1881,7 +1963,7 @@ FT_BEGIN_HEADER /* filepathname :: The pathname. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_File( FT_Face face, @@ -1896,7 +1978,7 @@ FT_BEGIN_HEADER /* */ /* `Attach' data to a face object. Normally, this is used to read */ /* additional information for the face object. For example, you can */ - /* attach an AFM file that comes with a Type 1 font to get the */ + /* attach an AFM file that comes with a Type~1 font to get the */ /* kerning values and other metrics. */ /* */ /* */ @@ -1907,7 +1989,7 @@ FT_BEGIN_HEADER /* the caller. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* The meaning of the `attach' (i.e., what really happens when the */ @@ -1936,7 +2018,7 @@ FT_BEGIN_HEADER /* face :: A handle to a target face object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Face( FT_Face face ); @@ -1958,7 +2040,7 @@ FT_BEGIN_HEADER /* `available_sizes' field of @FT_FaceRec structure. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, @@ -2044,8 +2126,8 @@ FT_BEGIN_HEADER /* value. */ /* */ /* */ - /* If `width' is zero, then the horizontal scaling value is set */ - /* equal to the vertical scaling value, and vice versa. */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ /* */ typedef struct FT_Size_RequestRec_ { @@ -2055,7 +2137,18 @@ FT_BEGIN_HEADER FT_UInt horiResolution; FT_UInt vertResolution; - } FT_Size_RequestRec, *FT_Size_Request; + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Size_Request */ + /* */ + /* */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; /*************************************************************************/ @@ -2073,7 +2166,7 @@ FT_BEGIN_HEADER /* req :: A pointer to a @FT_Size_RequestRec. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Although drivers may select the bitmap strike matching the */ @@ -2108,7 +2201,7 @@ FT_BEGIN_HEADER /* vert_resolution :: The vertical resolution in dpi. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* If either the character width or height is zero, it is set equal */ @@ -2120,7 +2213,8 @@ FT_BEGIN_HEADER /* A character width or height smaller than 1pt is set to 1pt; if */ /* both resolution values are zero, they are set to 72dpi. */ /* */ - + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Char_Size( FT_Face face, FT_F26Dot6 char_width, @@ -2147,7 +2241,7 @@ FT_BEGIN_HEADER /* pixel_height :: The nominal height, in pixels. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, @@ -2180,12 +2274,17 @@ FT_BEGIN_HEADER /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* The loaded glyph may be transformed. See @FT_Set_Transform for */ /* the details. */ /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2216,7 +2315,7 @@ FT_BEGIN_HEADER /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ @@ -2238,7 +2337,7 @@ FT_BEGIN_HEADER * * @values: * FT_LOAD_DEFAULT :: - * Corresponding to 0, this value is used as the default glyph load + * Corresponding to~0, this value is used as the default glyph load * operation. In this case, the following happens: * * 1. FreeType looks for a bitmap for the glyph corresponding to the @@ -2328,10 +2427,10 @@ FT_BEGIN_HEADER * FT_LOAD_MONOCHROME :: * This flag is used with @FT_LOAD_RENDER to indicate that you want to * render an outline glyph to a 1-bit monochrome bitmap glyph, with - * 8 pixels packed into each byte of the bitmap data. + * 8~pixels packed into each byte of the bitmap data. * * Note that this has no effect on the hinting algorithm used. You - * should use @FT_LOAD_TARGET_MONO instead so that the + * should rather use @FT_LOAD_TARGET_MONO so that the * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: @@ -2350,8 +2449,12 @@ FT_BEGIN_HEADER * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be * used at all. * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * * Besides deciding which hinter to use, you can also decide which * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * */ #define FT_LOAD_DEFAULT 0x0 #define FT_LOAD_NO_SCALE 0x1 @@ -2367,13 +2470,14 @@ FT_BEGIN_HEADER #define FT_LOAD_IGNORE_TRANSFORM 0x800 #define FT_LOAD_MONOCHROME 0x1000 #define FT_LOAD_LINEAR_DESIGN 0x2000 - - /* temporary hack! */ -#define FT_LOAD_SBITS_ONLY 0x4000 #define FT_LOAD_NO_AUTOHINT 0x8000U /* */ + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY 0x100 +#define FT_LOAD_SBITS_ONLY 0x4000 + /************************************************************************** * @@ -2401,7 +2505,7 @@ FT_BEGIN_HEADER * FT_LOAD_TARGET_LIGHT :: * A lighter hinting algorithm for non-monochrome modes. Many * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS X. + * shape. A bit like rendering on Mac OS~X. * * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. * @@ -2437,30 +2541,29 @@ FT_BEGIN_HEADER * * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); * } + * */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) -#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) - -#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) -#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) -#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) -#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) -#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) - /* + /************************************************************************** + * * @macro: * FT_LOAD_TARGET_MODE * * @description: * Return the @FT_Render_Mode corresponding to a given * @FT_LOAD_TARGET_XXX value. + * */ - #define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) - /* */ - /*************************************************************************/ /* */ @@ -2476,9 +2579,9 @@ FT_BEGIN_HEADER /* face :: A handle to the source face object. */ /* */ /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ /* vector. */ /* */ /* */ @@ -2503,17 +2606,19 @@ FT_BEGIN_HEADER /* */ /* */ /* An enumeration type that lists the render modes supported by */ - /* FreeType 2. Each mode corresponds to a specific type of scanline */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ /* conversion performed on the outline. */ /* */ - /* For bitmap fonts the `bitmap->pixel_mode' field in the */ - /* @FT_GlyphSlotRec structure gives the format of the returned */ - /* bitmap. */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ /* */ /* */ /* FT_RENDER_MODE_NORMAL :: */ /* This is the default render mode; it corresponds to 8-bit */ - /* anti-aliased bitmaps, using 256 levels of opacity. */ + /* anti-aliased bitmaps. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ @@ -2522,24 +2627,32 @@ FT_BEGIN_HEADER /* @FT_LOAD_TARGET_XXX for details. */ /* */ /* FT_RENDER_MODE_MONO :: */ - /* This mode corresponds to 1-bit bitmaps. */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ /* */ /* FT_RENDER_MODE_LCD :: */ /* This mode corresponds to horizontal RGB and BGR sub-pixel */ - /* displays, like LCD-screens. It produces 8-bit bitmaps that are */ - /* 3 times the width of the original glyph outline in pixels, and */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ /* which use the @FT_PIXEL_MODE_LCD mode. */ /* */ /* FT_RENDER_MODE_LCD_V :: */ /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ /* (like PDA screens, rotated LCD displays, etc.). It produces */ - /* 8-bit bitmaps that are 3 times the height of the original */ + /* 8-bit bitmaps that are 3~times the height of the original */ /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* */ - /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph are */ - /* _not_ _filtered_ to reduce color-fringes. It is up to the caller */ - /* to perform this pass. */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ /* */ typedef enum FT_Render_Mode_ { @@ -2564,8 +2677,8 @@ FT_BEGIN_HEADER /* @FT_Render_Mode values instead. */ /* */ /* */ - /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ - /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ /* */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO @@ -2591,7 +2704,7 @@ FT_BEGIN_HEADER /* list of possible values. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, @@ -2609,7 +2722,7 @@ FT_BEGIN_HEADER /* */ /* */ /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ - /* distances (value is 0). */ + /* distances (value is~0). */ /* */ /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ /* distances. */ @@ -2687,7 +2800,7 @@ FT_BEGIN_HEADER /* and in pixels for fixed-sizes formats. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Only horizontal layouts (left-to-right & right-to-left) are */ @@ -2712,17 +2825,17 @@ FT_BEGIN_HEADER /* Return the track kerning for a given face object at a given size. */ /* */ /* */ - /* face :: A handle to a source face object. */ + /* face :: A handle to a source face object. */ /* */ - /* point_size :: The point size in 16.16 fractional points. */ + /* point_size :: The point size in 16.16 fractional points. */ /* */ - /* degree :: The degree of tightness. */ + /* degree :: The degree of tightness. */ /* */ /* */ - /* akerning :: The kerning in 16.16 fractional points. */ + /* akerning :: The kerning in 16.16 fractional points. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, @@ -2738,7 +2851,7 @@ FT_BEGIN_HEADER /* */ /* */ /* Retrieve the ASCII name of a given glyph in a face. This only */ - /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns 1. */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ /* */ /* */ /* face :: A handle to a source face object. */ @@ -2753,12 +2866,12 @@ FT_BEGIN_HEADER /* copied to. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* An error is returned if the face doesn't provide glyph names or if */ /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' is set to 0 to indicate an empty name. */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ /* */ /* The glyph name is truncated to fit within the buffer if it is too */ /* long. The returned string is always zero-terminated. */ @@ -2780,14 +2893,14 @@ FT_BEGIN_HEADER /* FT_Get_Postscript_Name */ /* */ /* */ - /* Retrieve the ASCII Postscript name of a given face, if available. */ - /* This only works with Postscript and TrueType fonts. */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ /* */ /* */ /* face :: A handle to the source face object. */ /* */ /* */ - /* A pointer to the face's Postscript name. NULL if unavailable. */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ /* */ /* */ /* The returned pointer is owned by the face and is destroyed with */ @@ -2813,7 +2926,7 @@ FT_BEGIN_HEADER /* encoding :: A handle to the selected encoding. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function returns an error if no charmap in the face */ @@ -2821,7 +2934,8 @@ FT_BEGIN_HEADER /* */ /* Because many fonts contain more than a single cmap for Unicode */ /* encoding, this function has some special code to select the one */ - /* which covers Unicode best. It is thus preferable to */ + /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ + /* is preferred to a UCS-2 cmap). It is thus preferable to */ /* @FT_Set_Charmap in this case. */ /* */ FT_EXPORT( FT_Error ) @@ -2844,13 +2958,15 @@ FT_BEGIN_HEADER /* charmap :: A handle to the selected charmap. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function returns an error if the charmap is not part of */ /* the face (i.e., if it is not listed in the `face->charmaps' */ /* table). */ /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, FT_CharMap charmap ); @@ -2892,13 +3008,13 @@ FT_BEGIN_HEADER /* charcode :: The character code. */ /* */ /* */ - /* The glyph index. 0 means `undefined character code'. */ + /* The glyph index. 0~means `undefined character code'. */ /* */ /* */ /* If you use FreeType to manipulate the contents of font files */ /* directly, be aware that the glyph index returned by this function */ /* doesn't always correspond to the internal indices used within */ - /* the file. This is done to ensure that value 0 always corresponds */ + /* the file. This is done to ensure that value~0 always corresponds */ /* to the `missing glyph'. */ /* */ FT_EXPORT( FT_UInt ) @@ -2920,7 +3036,7 @@ FT_BEGIN_HEADER /* face :: A handle to the source face object. */ /* */ /* */ - /* agindex :: Glyph index of first character code. 0 if charmap is */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ /* empty. */ /* */ /* */ @@ -2945,9 +3061,9 @@ FT_BEGIN_HEADER /* } */ /* } */ /* */ - /* Note that `*agindex' is set to 0 if the charmap is empty. The */ - /* result itself can be 0 in two cases: if the charmap is empty or */ - /* when the value 0 is the first valid character code. */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_First_Char( FT_Face face, @@ -2969,7 +3085,7 @@ FT_BEGIN_HEADER /* char_code :: The starting character code. */ /* */ /* */ - /* agindex :: Glyph index of first character code. 0 if charmap */ + /* agindex :: Glyph index of next character code. 0~if charmap */ /* is empty. */ /* */ /* */ @@ -2980,7 +3096,7 @@ FT_BEGIN_HEADER /* over all character codes available in a given charmap. See the */ /* note for this function for a simple code example. */ /* */ - /* Note that `*agindex' is set to 0 when there are no more codes in */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ /* the charmap. */ /* */ FT_EXPORT( FT_ULong ) @@ -3004,7 +3120,7 @@ FT_BEGIN_HEADER /* glyph_name :: The glyph name. */ /* */ /* */ - /* The glyph index. 0 means `undefined character code'. */ + /* The glyph index. 0~means `undefined character code'. */ /* */ FT_EXPORT( FT_UInt ) FT_Get_Name_Index( FT_Face face, @@ -3046,15 +3162,16 @@ FT_BEGIN_HEADER * * @description: * Retrieve a description of a given subglyph. Only use it if - * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE, or an error is - * returned. + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. * * @input: * glyph :: * The source glyph slot. * * sub_index :: - * The index of subglyph. Must be less than `glyph->num_subglyphs'. + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. * * @output: * p_index :: @@ -3073,7 +3190,7 @@ FT_BEGIN_HEADER * The subglyph transformation (if any). * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be @@ -3091,6 +3208,305 @@ FT_BEGIN_HEADER FT_Matrix *p_transform ); + /*************************************************************************/ + /* */ + /* */ + /* FT_FSTYPE_XXX */ + /* */ + /* */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ + /* more details. */ + /* */ + /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ + /* */ + /* Return the fsType flags for a font. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /*
*/ + /* glyph_variants */ + /* */ + /* */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Report #37, the Ideographic Variation */ + /* Database. To date (October 2007), the character with the most */ + /* variants is U+908A, having 8~such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points which are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points which are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + /*************************************************************************/ /* */ /* <Section> */ @@ -3149,6 +3565,12 @@ FT_BEGIN_HEADER FT_Long c ); + /* */ + + /* The following #if 0 ... #endif is for the documentation formatter, */ + /* hiding the internal `FT_MULFIX_INLINED' macro. */ + +#if 0 /*************************************************************************/ /* */ /* <Function> */ @@ -3182,6 +3604,17 @@ FT_BEGIN_HEADER FT_MulFix( FT_Long a, FT_Long b ); + /* */ +#endif + +#ifdef FT_MULFIX_INLINED +#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) +#else + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); +#endif + /*************************************************************************/ /* */ @@ -3202,8 +3635,8 @@ FT_BEGIN_HEADER /* The result of `(a*0x10000)/b'. */ /* */ /* <Note> */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ - /* 32 bits, then the division is computed directly. Otherwise, we */ + /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ + /* 32~bits, then the division is computed directly. Otherwise, we */ /* use a specialized version of @FT_MulDiv. */ /* */ FT_EXPORT( FT_Long ) @@ -3310,26 +3743,27 @@ FT_BEGIN_HEADER /************************************************************************* * - * @enum: - * FREETYPE_XXX + * @enum: + * FREETYPE_XXX * - * @description: - * These three macros identify the FreeType source code version. - * Use @FT_Library_Version to access them at runtime. + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. * - * @values: - * FREETYPE_MAJOR :: The major version number. - * FREETYPE_MINOR :: The minor version number. - * FREETYPE_PATCH :: The patch level. + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. * - * @note: - * The version number of FreeType if built as a dynamic link library - * with the `libtool' package is _not_ controlled by these three - * macros. */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 3 -#define FREETYPE_PATCH 5 +#define FREETYPE_PATCH 11 /*************************************************************************/ @@ -3386,8 +3820,8 @@ FT_BEGIN_HEADER /* face :: A face handle. */ /* */ /* <Return> */ - /* 1 if this is a TrueType font that uses one of the patented */ - /* opcodes, 0 otherwise. */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ /* */ /* <Since> */ /* 2.3.5 */ @@ -3413,7 +3847,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* The old setting value. This will always be false if this is not */ - /* a SFNT font, or if the unpatented hinter is not compiled in this */ + /* an SFNT font, or if the unpatented hinter is not compiled in this */ /* instance of the library. */ /* */ /* <Since> */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftadvanc.h b/reactos/lib/3rdparty/freetype/include/freetype/ftadvanc.h new file mode 100644 index 00000000000..b2451bec426 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftadvanc.h @@ -0,0 +1,179 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTADVANC_H__ +#define __FTADVANC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. By default, the unhinted advance is returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value, in either font units or 16.16 */ + /* format. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. By default, the unhinted advances are returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advances, in either font units or 16.16 format. */ + /* This array must contain at least `count' elements. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + +/* */ + + +FT_END_HEADER + +#endif /* __FTADVANC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftbbox.h b/reactos/lib/3rdparty/freetype/include/freetype/ftbbox.h index 5f79c327405..01fe3fb0d10 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftbbox.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2001, 2003 by */ +/* Copyright 1996-2001, 2003, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,10 +58,10 @@ FT_BEGIN_HEADER /* FT_Outline_Get_BBox */ /* */ /* <Description> */ - /* Computes the exact bounding box of an outline. This is slower */ + /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ /* algorithm which returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bézier arcs are walked over to */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ /* extract their extrema. */ /* */ /* <Input> */ @@ -71,7 +71,7 @@ FT_BEGIN_HEADER /* abbox :: The outline's exact bounding box. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftbdf.h b/reactos/lib/3rdparty/freetype/include/freetype/ftbdf.h index 9555694811e..4f8baf84017 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftbdf.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,38 +38,39 @@ FT_BEGIN_HEADER /* bdf_fonts */ /* */ /* <Title> */ - /* BDF Files */ + /* BDF and PCF Files */ /* */ /* <Abstract> */ - /* BDF specific API. */ + /* BDF and PCF specific API. */ /* */ /* <Description> */ - /* This section contains the declaration of BDF specific functions. */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ /* */ /*************************************************************************/ - /********************************************************************** - * - * @enum: - * FT_PropertyType - * - * @description: - * A list of BDF property types. - * - * @values: - * BDF_PROPERTY_TYPE_NONE :: - * Value 0 is used to indicate a missing property. - * - * BDF_PROPERTY_TYPE_ATOM :: - * Property is a string atom. - * - * BDF_PROPERTY_TYPE_INTEGER :: - * Property is a 32-bit signed integer. - * - * BDF_PROPERTY_TYPE_CARDINAL :: - * Property is a 32-bit unsigned integer. - */ + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ typedef enum BDF_PropertyType_ { BDF_PROPERTY_TYPE_NONE = 0, @@ -80,15 +81,15 @@ FT_BEGIN_HEADER } BDF_PropertyType; - /********************************************************************** - * - * @type: - * BDF_Property - * - * @description: - * A handle to a @BDF_PropertyRec structure to model a given - * BDF/PCF property. - */ + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ typedef struct BDF_PropertyRec_* BDF_Property; @@ -132,7 +133,7 @@ FT_BEGIN_HEADER * FT_Get_BDF_Charset_ID * * @description: - * Retrieves a BDF font character set identity, according to + * Retrieve a BDF font character set identity, according to * the BDF specification. * * @input: @@ -141,13 +142,13 @@ FT_BEGIN_HEADER * * @output: * acharset_encoding :: - * Charset encoding, as a C string, owned by the face. + * Charset encoding, as a C~string, owned by the face. * * acharset_registry :: - * Charset registry, as a C string, owned by the face. + * Charset registry, as a C~string, owned by the face. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with BDF faces, returning an error otherwise. @@ -164,7 +165,7 @@ FT_BEGIN_HEADER * FT_Get_BDF_Property * * @description: - * Retrieves a BDF property from a BDF or PCF font file. + * Retrieve a BDF property from a BDF or PCF font file. * * @input: * face :: A handle to the input face. @@ -175,13 +176,21 @@ FT_BEGIN_HEADER * aproperty :: The property. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function works with BDF _and_ PCF fonts. It returns an error * otherwise. It also returns an error if the property is not in the * font. * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * * In case of error, `aproperty->type' is always set to * @BDF_PROPERTY_TYPE_NONE. */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftbitmap.h b/reactos/lib/3rdparty/freetype/include/freetype/ftbitmap.h index 337d888eaf2..92742369baa 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftbitmap.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftbitmap.h @@ -2,10 +2,9 @@ /* */ /* ftbitmap.h */ /* */ -/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (specification). */ +/* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,7 +71,7 @@ FT_BEGIN_HEADER /* FT_Bitmap_Copy */ /* */ /* <Description> */ - /* Copies an bitmap into another one. */ + /* Copy a bitmap into another one. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ @@ -83,7 +82,7 @@ FT_BEGIN_HEADER /* target :: A handle to the target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Copy( FT_Library library, @@ -114,14 +113,14 @@ FT_BEGIN_HEADER /* bitmap :: A handle to the target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The current implementation restricts `xStrength' to be less than */ - /* or equal to 8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ /* */ /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ - /* you should call `FT_GlyphSlot_Own_Bitmap' on the slot first. */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, @@ -152,7 +151,7 @@ FT_BEGIN_HEADER /* target :: The target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* It is possible to call @FT_Bitmap_Convert multiple times without */ @@ -170,6 +169,28 @@ FT_BEGIN_HEADER FT_Int alignment ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + /*************************************************************************/ /* */ /* <Function> */ @@ -184,7 +205,7 @@ FT_BEGIN_HEADER /* bitmap :: The bitmap object to be freed. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `library' argument is taken to have access to FreeType's */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftcache.h b/reactos/lib/3rdparty/freetype/include/freetype/ftcache.h index 721aa16f32b..0916d70a37e 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftcache.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,10 +36,10 @@ FT_BEGIN_HEADER * Cache Sub-System * * <Abstract> - * How to cache face, size, and glyph data with FreeType 2. + * How to cache face, size, and glyph data with FreeType~2. * * <Description> - * This section describes the FreeType 2 cache sub-system, which is used + * This section describes the FreeType~2 cache sub-system, which is used * to limit the number of concurrently opened @FT_Face and @FT_Size * objects, as well as caching information like character maps and glyph * images while limiting their maximum memory usage. @@ -165,7 +165,7 @@ FT_BEGIN_HEADER * Failure to do so will result in incorrect behaviour or even * memory leaks and crashes. */ - typedef struct FTC_FaceIDRec_* FTC_FaceID; + typedef FT_Pointer FTC_FaceID; /************************************************************************ @@ -193,7 +193,7 @@ FT_BEGIN_HEADER * A new @FT_Face handle. * * <Return> - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * <Note> * The third parameter `req_data' is the same as the one passed by the @@ -260,7 +260,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* An opaque handle to a cache node object. Each cache node is */ - /* reference-counted. A node with a count of 0 might be flushed */ + /* reference-counted. A node with a count of~0 might be flushed */ /* out of a full cache whenever a lookup request is performed. */ /* */ /* If you lookup nodes, you have the ability to `acquire' them, i.e., */ @@ -279,19 +279,19 @@ FT_BEGIN_HEADER /* FTC_Manager_New */ /* */ /* <Description> */ - /* Creates a new cache manager. */ + /* Create a new cache manager. */ /* */ /* <Input> */ /* library :: The parent FreeType library handle to use. */ /* */ /* max_faces :: Maximum number of opened @FT_Face objects managed by */ - /* this cache instance. Use 0 for defaults. */ + /* this cache instance. Use~0 for defaults. */ /* */ /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ - /* this cache instance. Use 0 for defaults. */ + /* this cache instance. Use~0 for defaults. */ /* */ /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ - /* Use 0 for defaults. Note that this value does not */ + /* Use~0 for defaults. Note that this value does not */ /* account for managed @FT_Face and @FT_Size objects. */ /* */ /* requester :: An application-provided callback used to translate */ @@ -301,11 +301,11 @@ FT_BEGIN_HEADER /* each time it is called (see @FTC_Face_Requester). */ /* */ /* <Output> */ - /* amanager :: A handle to a new manager object. 0 in case of */ + /* amanager :: A handle to a new manager object. 0~in case of */ /* failure. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_Manager_New( FT_Library library, @@ -323,7 +323,7 @@ FT_BEGIN_HEADER /* FTC_Manager_Reset */ /* */ /* <Description> */ - /* Empties a given cache manager. This simply gets rid of all the */ + /* Empty a given cache manager. This simply gets rid of all the */ /* currently cached @FT_Face and @FT_Size objects within the manager. */ /* */ /* <InOut> */ @@ -339,7 +339,7 @@ FT_BEGIN_HEADER /* FTC_Manager_Done */ /* */ /* <Description> */ - /* Destroys a given manager after emptying it. */ + /* Destroy a given manager after emptying it. */ /* */ /* <Input> */ /* manager :: A handle to the target cache manager object. */ @@ -354,7 +354,7 @@ FT_BEGIN_HEADER /* FTC_Manager_LookupFace */ /* */ /* <Description> */ - /* Retrieves the @FT_Face object that corresponds to a given face ID */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ /* through a cache manager. */ /* */ /* <Input> */ @@ -366,7 +366,7 @@ FT_BEGIN_HEADER /* aface :: A handle to the face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Face object is always owned by the manager. You */ @@ -415,10 +415,10 @@ FT_BEGIN_HEADER /* interpreted as integer pixel character sizes. */ /* Otherwise, they are expressed as 1/64th of points. */ /* */ - /* x_res :: Only used when `pixel' is value 0 to indicate the */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ /* horizontal resolution in dpi. */ /* */ - /* y_res :: Only used when `pixel' is value 0 to indicate the */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ /* vertical resolution in dpi. */ /* */ /* <Note> */ @@ -434,7 +434,18 @@ FT_BEGIN_HEADER FT_UInt x_res; FT_UInt y_res; - } FTC_ScalerRec, *FTC_Scaler; + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; /*************************************************************************/ @@ -455,7 +466,7 @@ FT_BEGIN_HEADER /* asize :: A handle to the size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Size object is always owned by the manager. You */ @@ -569,7 +580,7 @@ FT_BEGIN_HEADER * A new cache handle. NULL in case of error. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * Like all other caches, this one will be destroyed with the cache @@ -598,13 +609,14 @@ FT_BEGIN_HEADER * The source face ID. * * cmap_index :: - * The index of the charmap in the source face. + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. * * char_code :: * The character code (in the corresponding charmap). * * @return: - * Glyph index. 0 means `no glyph'. + * Glyph index. 0~means `no glyph'. * */ FT_EXPORT( FT_UInt ) @@ -710,7 +722,7 @@ FT_BEGIN_HEADER /* FTC_ImageCache_New */ /* */ /* <Description> */ - /* Creates a new glyph image cache. */ + /* Create a new glyph image cache. */ /* */ /* <Input> */ /* manager :: The parent manager for the image cache. */ @@ -719,7 +731,7 @@ FT_BEGIN_HEADER /* acache :: A handle to the new glyph image cache object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_New( FTC_Manager manager, @@ -732,7 +744,7 @@ FT_BEGIN_HEADER /* FTC_ImageCache_Lookup */ /* */ /* <Description> */ - /* Retrieves a given glyph image from a glyph image cache. */ + /* Retrieve a given glyph image from a glyph image cache. */ /* */ /* <Input> */ /* cache :: A handle to the source glyph image cache. */ @@ -742,7 +754,7 @@ FT_BEGIN_HEADER /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of of the corresponding cache */ @@ -750,7 +762,7 @@ FT_BEGIN_HEADER /* below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ @@ -795,7 +807,7 @@ FT_BEGIN_HEADER /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of of the corresponding */ @@ -803,7 +815,7 @@ FT_BEGIN_HEADER /* (see note below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ @@ -821,6 +833,9 @@ FT_BEGIN_HEADER /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_LookupScaler( FTC_ImageCache cache, FTC_Scaler scaler, @@ -862,11 +877,11 @@ FT_BEGIN_HEADER /* top :: The vertical distance from the pen position (on the */ /* baseline) to the upper bitmap border (a.k.a. `top */ /* side bearing'). The distance is positive for upwards */ - /* Y coordinates. */ + /* y~coordinates. */ /* */ /* format :: The format of the glyph bitmap (monochrome or gray). */ /* */ - /* max_grays :: Maximum gray level value (in the range 1 to 255). */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ /* */ /* pitch :: The number of bytes per bitmap line. May be positive */ /* or negative. */ @@ -915,7 +930,7 @@ FT_BEGIN_HEADER /* FTC_SBitCache_New */ /* */ /* <Description> */ - /* Creates a new cache to store small glyph bitmaps. */ + /* Create a new cache to store small glyph bitmaps. */ /* */ /* <Input> */ /* manager :: A handle to the source cache manager. */ @@ -924,7 +939,7 @@ FT_BEGIN_HEADER /* acache :: A handle to the new sbit cache. NULL in case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_SBitCache_New( FTC_Manager manager, @@ -937,7 +952,7 @@ FT_BEGIN_HEADER /* FTC_SBitCache_Lookup */ /* */ /* <Description> */ - /* Looks up a given small glyph bitmap in a given sbit cache and */ + /* Look up a given small glyph bitmap in a given sbit cache and */ /* `lock' it to prevent its flushing from the cache until needed. */ /* */ /* <Input> */ @@ -955,7 +970,7 @@ FT_BEGIN_HEADER /* below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ @@ -963,7 +978,7 @@ FT_BEGIN_HEADER /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ @@ -1010,7 +1025,7 @@ FT_BEGIN_HEADER /* (see note below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ @@ -1018,7 +1033,7 @@ FT_BEGIN_HEADER /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftchapters.h b/reactos/lib/3rdparty/freetype/include/freetype/ftchapters.h index bd812c8e65e..7775a6bb00a 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftchapters.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftchapters.h @@ -32,6 +32,7 @@ /* version */ /* basic_types */ /* base_interface */ +/* glyph_variants */ /* glyph_management */ /* mac_specific */ /* sizes_management */ @@ -54,6 +55,7 @@ /* type1_tables */ /* sfnt_names */ /* bdf_fonts */ +/* cid_fonts */ /* pfr_fonts */ /* winfnt_fonts */ /* font_formats */ @@ -88,6 +90,7 @@ /* computations */ /* list_processing */ /* outline_processing */ +/* quick_advance */ /* bitmap_handling */ /* raster */ /* glyph_stroker */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftcid.h b/reactos/lib/3rdparty/freetype/include/freetype/ftcid.h new file mode 100644 index 00000000000..203a30caf85 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftcid.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SNFT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftgasp.h b/reactos/lib/3rdparty/freetype/include/freetype/ftgasp.h index 97cd3301457..91a769e520f 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftgasp.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ -/* Copyright 2007 by */ +/* Copyright 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,13 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + /*************************************************************************** * * @section: @@ -31,11 +38,11 @@ * Gasp Table * * @abstract: - * Retrieving TrueType `gasp' table entries + * Retrieving TrueType `gasp' table entries. * * @description: * The function @FT_Get_Gasp can be used to query a TrueType or OpenType - * font for specific entries in their `gasp' table, if any. This is + * font for specific entries in its `gasp' table, if any. This is * mainly useful when implementing native TrueType hinting with the * bytecode interpreter to duplicate the Windows text rendering results. */ @@ -95,7 +102,7 @@ * ppem :: The vertical character pixel size. * * @return: - * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE is there is no + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no * `gasp' table in the face. * * @since: diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h b/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h index 08058dadd13..cacccf025e4 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -145,7 +145,7 @@ FT_BEGIN_HEADER /* */ /* top :: The top-side bearing, i.e., the vertical distance from */ /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards-y! */ + /* bitmap. This distance is positive for upwards~y! */ /* */ /* bitmap :: A descriptor for the bitmap. */ /* */ @@ -194,7 +194,7 @@ FT_BEGIN_HEADER /* outline :: A descriptor for the outline. */ /* */ /* <Note> */ - /* You can typecast a @FT_Glyph to @FT_OutlineGlyph if you have */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ /* the outline's content easily. */ /* */ @@ -219,7 +219,8 @@ FT_BEGIN_HEADER /* FT_Get_Glyph */ /* */ /* <Description> */ - /* A function used to extract a glyph image from a slot. */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ /* */ /* <Input> */ /* slot :: A handle to the source glyph slot. */ @@ -228,7 +229,7 @@ FT_BEGIN_HEADER /* aglyph :: A handle to the glyph object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, @@ -248,11 +249,11 @@ FT_BEGIN_HEADER /* source :: A handle to the source glyph object. */ /* */ /* <Output> */ - /* target :: A handle to the target glyph object. 0 in case of */ + /* target :: A handle to the target glyph object. 0~in case of */ /* error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_Copy( FT_Glyph source, @@ -265,7 +266,7 @@ FT_BEGIN_HEADER /* FT_Glyph_Transform */ /* */ /* <Description> */ - /* Transforms a glyph image if its format is scalable. */ + /* Transform a glyph image if its format is scalable. */ /* */ /* <InOut> */ /* glyph :: A handle to the target glyph object. */ @@ -375,7 +376,7 @@ FT_BEGIN_HEADER /* expressed in 1/64th of pixels if it is grid-fitted. */ /* */ /* <Note> */ - /* Coordinates are relative to the glyph origin, using the Y-upwards */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ /* convention. */ /* */ /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ @@ -421,17 +422,17 @@ FT_BEGIN_HEADER /* FT_Glyph_To_Bitmap */ /* */ /* <Description> */ - /* Converts a given glyph object to a bitmap glyph object. */ + /* Convert a given glyph object to a bitmap glyph object. */ /* */ /* <InOut> */ /* the_glyph :: A pointer to a handle to the target glyph. */ /* */ /* <Input> */ - /* render_mode :: An enumeration that describe how the data is */ + /* render_mode :: An enumeration that describes how the data is */ /* rendered. */ /* */ /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be 0 (if no */ + /* image before rendering. Can be~0 (if no */ /* translation). The origin is expressed in */ /* 26.6 pixels. */ /* */ @@ -440,15 +441,17 @@ FT_BEGIN_HEADER /* never destroyed in case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ /* The glyph image is translated with the `origin' vector before */ /* rendering. */ /* */ /* The first parameter is a pointer to an @FT_Glyph handle, that will */ - /* be replaced by this function. Typically, you would use (omitting */ - /* error handling): */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ /* */ /* */ /* { */ @@ -462,12 +465,12 @@ FT_BEGIN_HEADER /* // extract glyph image */ /* error = FT_Get_Glyph( face->glyph, &glyph ); */ /* */ - /* // convert to a bitmap (default render mode + destroy old) */ + /* // convert to a bitmap (default render mode + destroying old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ /* 0, 1 ); */ - /* if ( error ) // glyph unchanged */ + /* if ( error ) // `glyph' unchanged */ /* ... */ /* } */ /* */ @@ -482,7 +485,42 @@ FT_BEGIN_HEADER /* } */ /* */ /* */ - /* This function does nothing if the glyph format isn't scalable. */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, @@ -497,7 +535,7 @@ FT_BEGIN_HEADER /* FT_Done_Glyph */ /* */ /* <Description> */ - /* Destroys a given glyph. */ + /* Destroy a given glyph. */ /* */ /* <Input> */ /* glyph :: A handle to the target glyph object. */ @@ -524,7 +562,7 @@ FT_BEGIN_HEADER /* FT_Matrix_Multiply */ /* */ /* <Description> */ - /* Performs the matrix operation `b = a*b'. */ + /* Perform the matrix operation `b = a*b'. */ /* */ /* <Input> */ /* a :: A pointer to matrix `a'. */ @@ -537,7 +575,7 @@ FT_BEGIN_HEADER /* */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix* b ); + FT_Matrix* b ); /*************************************************************************/ @@ -546,14 +584,14 @@ FT_BEGIN_HEADER /* FT_Matrix_Invert */ /* */ /* <Description> */ - /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ /* */ /* <InOut> */ /* matrix :: A pointer to the target matrix. Remains untouched in */ /* case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftgxval.h b/reactos/lib/3rdparty/freetype/include/freetype/ftgxval.h index c7ea861a0da..497015c1011 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftgxval.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftgxval.h @@ -202,7 +202,7 @@ FT_BEGIN_HEADER * The array itself must be allocated by a client. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with TrueTypeGX fonts, returning an error @@ -285,14 +285,14 @@ FT_BEGIN_HEADER * FT_ClassicKern_Validate * * @description: - * Validate classic (16bit format) kern table to assure that the offsets + * Validate classic (16-bit format) kern table to assure that the offsets * and indices are valid. The idea is that a higher-level library which * actually does the text layout can access those tables without error * checking (which can be quite time consuming). * * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both - * the new 32bit format and the classic 16bit format, while - * FT_ClassicKern_Validate only supports the classic 16bit format. + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. * * @input: * face :: @@ -307,7 +307,7 @@ FT_BEGIN_HEADER * A pointer to the kern table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * After use, the application should deallocate the buffers pointed to by diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftgzip.h b/reactos/lib/3rdparty/freetype/include/freetype/ftgzip.h index 9893437bfa7..acbc4f0327b 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftgzip.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftgzip.h @@ -66,7 +66,7 @@ FT_BEGIN_HEADER * The source stream. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h b/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h index 1c428f117db..2fcc113ad5d 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,7 +28,7 @@ #define __FTIMAGE_H__ -/* _STANDALONE_ is from ftgrays.c */ + /* _STANDALONE_ is from ftgrays.c */ #ifndef _STANDALONE_ #include <ft2build.h> #endif @@ -53,7 +53,7 @@ FT_BEGIN_HEADER /* <Description> */ /* The type FT_Pos is a 32-bit integer used to store vectorial */ /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 16,16, or 26.6 fixed float */ + /* distances in integer font units, or 16.16, or 26.6 fixed float */ /* pixel coordinates. */ /* */ typedef signed long FT_Pos; @@ -119,39 +119,40 @@ FT_BEGIN_HEADER /* */ /* <Values> */ /* FT_PIXEL_MODE_NONE :: */ - /* Value 0 is reserved. */ + /* Value~0 is reserved. */ /* */ /* FT_PIXEL_MODE_MONO :: */ - /* A monochrome bitmap, using 1 bit per pixel. Note that pixels */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ /* are stored in most-significant order (MSB), which means that */ /* the left-most pixel in a byte has value 128. */ /* */ /* FT_PIXEL_MODE_GRAY :: */ /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ /* images. Each pixel is stored in one byte. Note that the number */ - /* of value `gray' levels is stored in the `num_bytes' field of */ - /* the @FT_Bitmap structure (it generally is 256). */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ /* */ /* FT_PIXEL_MODE_GRAY2 :: */ - /* A 2-bit/pixel bitmap, used to represent embedded anti-aliased */ - /* bitmaps in font files according to the OpenType specification. */ - /* We haven't found a single font using this format, however. */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ /* */ /* FT_PIXEL_MODE_GRAY4 :: */ - /* A 4-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ /* bitmaps in font files according to the OpenType specification. */ /* We haven't found a single font using this format, however. */ /* */ /* FT_PIXEL_MODE_LCD :: */ - /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ - /* images used for display on LCD displays; the bitmap is three */ - /* times wider than the original glyph image. See also */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD. */ /* */ /* FT_PIXEL_MODE_LCD_V :: */ - /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ - /* images used for display on rotated LCD displays; the bitmap */ - /* is three times taller than the original glyph image. See also */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD_V. */ /* */ typedef enum FT_Pixel_Mode_ @@ -206,11 +207,11 @@ FT_BEGIN_HEADER /* An enumeration type to describe the format of a bitmap palette, */ /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ /* */ - /* <Fields> */ - /* ft_palette_mode_rgb :: The palette is an array of 3-bytes RGB */ + /* <Values> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ /* records. */ /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-bytes RGBA */ + /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ /* records. */ /* */ /* <Note> */ @@ -222,7 +223,7 @@ FT_BEGIN_HEADER ft_palette_mode_rgb = 0, ft_palette_mode_rgba, - ft_palettte_mode_max /* do not remove */ + ft_palette_mode_max /* do not remove */ } FT_Palette_Mode; @@ -317,14 +318,23 @@ FT_BEGIN_HEADER /* elements, giving the outline's point coordinates. */ /* */ /* tags :: A pointer to an array of `n_points' chars, giving */ - /* each outline point's type. If bit 0 is unset, the */ - /* point is `off' the curve, i.e., a Bézier control */ - /* point, while it is `on' when set. */ + /* each outline point's type. */ /* */ - /* Bit 1 is meaningful for `off' points only. If set, */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ /* it indicates a third-order Bézier arc control point; */ /* and a second-order control point if unset. */ /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ /* contours :: An array of `n_contours' shorts, giving the end */ /* point of each contour within the outline. For */ /* example, the first contour is defined by the points */ @@ -335,6 +345,12 @@ FT_BEGIN_HEADER /* and give hints to the scan-converter and hinter on */ /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ typedef struct FT_Outline_ { short n_contours; /* number of contours in glyph */ @@ -348,71 +364,91 @@ FT_BEGIN_HEADER } FT_Outline; + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + /*************************************************************************/ /* */ /* <Enum> */ - /* FT_OUTLINE_FLAGS */ + /* FT_OUTLINE_FLAGS */ /* */ /* <Description> */ /* A list of bit-field constants use for the flags in an outline's */ /* `flags' field. */ /* */ /* <Values> */ - /* FT_OUTLINE_NONE :: Value 0 is reserved. */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ /* */ - /* FT_OUTLINE_OWNER :: If set, this flag indicates that the */ - /* outline's field arrays (i.e., */ - /* `points', `flags' & `contours') are */ - /* `owned' by the outline object, and */ - /* should thus be freed when it is */ - /* destroyed. */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ /* */ - /* FT_OUTLINE_EVEN_ODD_FILL :: By default, outlines are filled using */ - /* the non-zero winding rule. If set to */ - /* 1, the outline will be filled using */ - /* the even-odd fill rule (only works */ - /* with the smooth raster). */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ /* */ - /* FT_OUTLINE_REVERSE_FILL :: By default, outside contours of an */ - /* outline are oriented in clock-wise */ - /* direction, as defined in the TrueType */ - /* specification. This flag is set if */ - /* the outline uses the opposite */ - /* direction (typically for Type 1 */ - /* fonts). This flag is ignored by the */ - /* scan-converter. */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ /* */ - /* FT_OUTLINE_IGNORE_DROPOUTS :: By default, the scan converter will */ - /* try to detect drop-outs in an outline */ - /* and correct the glyph bitmap to */ - /* ensure consistent shape continuity. */ - /* If set, this flag hints the scan-line */ - /* converter to ignore such cases. */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ /* */ - /* FT_OUTLINE_HIGH_PRECISION :: This flag indicates that the */ - /* scan-line converter should try to */ - /* convert this outline to bitmaps with */ - /* the highest possible quality. It is */ - /* typically set for small character */ - /* sizes. Note that this is only a */ - /* hint, that might be completely */ - /* ignored by a given scan-converter. */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ /* */ - /* FT_OUTLINE_SINGLE_PASS :: This flag is set to force a given */ - /* scan-converter to only use a single */ - /* pass over the outline to render a */ - /* bitmap glyph image. Normally, it is */ - /* set for very large character sizes. */ - /* It is only a hint, that might be */ - /* completely ignored by a given */ - /* scan-converter. */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ /* */ #define FT_OUTLINE_NONE 0x0 #define FT_OUTLINE_OWNER 0x1 #define FT_OUTLINE_EVEN_ODD_FILL 0x2 #define FT_OUTLINE_REVERSE_FILL 0x4 #define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 #define FT_OUTLINE_HIGH_PRECISION 0x100 #define FT_OUTLINE_SINGLE_PASS 0x200 @@ -448,21 +484,24 @@ FT_BEGIN_HEADER #define FT_CURVE_TAG( flag ) ( flag & 3 ) -#define FT_CURVE_TAG_ON 1 -#define FT_CURVE_TAG_CONIC 0 -#define FT_CURVE_TAG_CUBIC 2 +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 -#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_HAS_SCANMODE 4 -#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ - FT_CURVE_TAG_TOUCH_Y ) +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y -#define FT_Curve_Tag_On FT_CURVE_TAG_ON -#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC -#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC -#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X -#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y /*************************************************************************/ /* */ @@ -482,7 +521,7 @@ FT_BEGIN_HEADER /* decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_MoveToFunc)( const FT_Vector* to, @@ -490,6 +529,7 @@ FT_BEGIN_HEADER #define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + /*************************************************************************/ /* */ /* <FuncType> */ @@ -508,13 +548,14 @@ FT_BEGIN_HEADER /* decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_LineToFunc)( const FT_Vector* to, void* user ); -#define FT_Outline_LineTo_Func FT_Outline_LineToFunc +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + /*************************************************************************/ /* */ @@ -538,14 +579,15 @@ FT_BEGIN_HEADER /* the decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_ConicToFunc)( const FT_Vector* control, const FT_Vector* to, void* user ); -#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + /*************************************************************************/ /* */ @@ -569,7 +611,7 @@ FT_BEGIN_HEADER /* the decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_CubicToFunc)( const FT_Vector* control1, @@ -577,7 +619,7 @@ FT_BEGIN_HEADER const FT_Vector* to, void* user ); -#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc /*************************************************************************/ @@ -615,7 +657,7 @@ FT_BEGIN_HEADER /* y' = (x << shift) - delta */ /* } */ /* */ - /* Set the value of `shift' and `delta' to 0 to get the original */ + /* Set the value of `shift' and `delta' to~0 to get the original */ /* point coordinates. */ /* */ typedef struct FT_Outline_Funcs_ @@ -648,7 +690,7 @@ FT_BEGIN_HEADER /* This macro converts four-letter tags to an unsigned long type. */ /* */ /* <Note> */ - /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ @@ -680,7 +722,7 @@ FT_BEGIN_HEADER /* */ /* <Values> */ /* FT_GLYPH_FORMAT_NONE :: */ - /* The value 0 is reserved. */ + /* The value~0 is reserved. */ /* */ /* FT_GLYPH_FORMAT_COMPOSITE :: */ /* The glyph image is a composite of several other images. This */ @@ -700,7 +742,7 @@ FT_BEGIN_HEADER /* */ /* FT_GLYPH_FORMAT_PLOTTER :: */ /* The glyph image is a vectorial path with no inside and outside */ - /* contours. Some Type 1 fonts, like those in the Hershey family, */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ /* contain glyphs in this format. These are described as */ /* @FT_Outline, but FreeType isn't currently capable of rendering */ /* them correctly. */ @@ -812,10 +854,11 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc which takes the y-coordinate of the span as a */ + /* @FT_SpanFunc which takes the y~coordinate of the span as a */ /* a parameter. */ /* */ - /* The coverage value is always between 0 and 255. */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ /* */ typedef struct FT_Span_ { @@ -837,7 +880,7 @@ FT_BEGIN_HEADER /* spans on each scan line. */ /* */ /* <Input> */ - /* y :: The scanline's y-coordinate. */ + /* y :: The scanline's y~coordinate. */ /* */ /* count :: The number of spans to draw on this scanline. */ /* */ @@ -854,8 +897,8 @@ FT_BEGIN_HEADER /* */ /* Note that the `count' field cannot be greater than a fixed value */ /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to 32, which means */ - /* that if there are more than 32 spans on a given scanline, the */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ /* callback is called several times with the same `y' parameter in */ /* order to draw all callbacks. */ /* */ @@ -868,7 +911,7 @@ FT_BEGIN_HEADER const FT_Span* spans, void* user ); -#define FT_Raster_Span_Func FT_SpanFunc +#define FT_Raster_Span_Func FT_SpanFunc /*************************************************************************/ @@ -885,14 +928,14 @@ FT_BEGIN_HEADER /* per-se the TrueType spec. */ /* */ /* <Input> */ - /* y :: The pixel's y-coordinate. */ + /* y :: The pixel's y~coordinate. */ /* */ - /* x :: The pixel's x-coordinate. */ + /* x :: The pixel's x~coordinate. */ /* */ /* user :: User-supplied data that is passed to the callback. */ /* */ /* <Return> */ - /* 1 if the pixel is `set', 0 otherwise. */ + /* 1~if the pixel is `set', 0~otherwise. */ /* */ typedef int (*FT_Raster_BitTest_Func)( int y, @@ -913,14 +956,14 @@ FT_BEGIN_HEADER /* drop-out control according to the TrueType specification. */ /* */ /* <Input> */ - /* y :: The pixel's y-coordinate. */ + /* y :: The pixel's y~coordinate. */ /* */ - /* x :: The pixel's x-coordinate. */ + /* x :: The pixel's x~coordinate. */ /* */ /* user :: User-supplied data that is passed to the callback. */ /* */ /* <Return> */ - /* 1 if the pixel is `set', 0 otherwise. */ + /* 1~if the pixel is `set', 0~otherwise. */ /* */ typedef void (*FT_Raster_BitSet_Func)( int y, @@ -999,7 +1042,7 @@ FT_BEGIN_HEADER /* */ /* gray_spans :: The gray span drawing callback. */ /* */ - /* black_spans :: The black span drawing callback. */ + /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ /* */ /* bit_test :: The bit test callback. UNIMPLEMENTED! */ /* */ @@ -1036,7 +1079,7 @@ FT_BEGIN_HEADER const void* source; int flags; FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; + FT_SpanFunc black_spans; /* doesn't work! */ FT_Raster_BitTest_Func bit_test; /* doesn't work! */ FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; @@ -1060,7 +1103,7 @@ FT_BEGIN_HEADER /* raster :: A handle to the new raster object. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ /* <Note> */ /* The `memory' parameter is a typeless pointer in order to avoid */ @@ -1073,7 +1116,8 @@ FT_BEGIN_HEADER (*FT_Raster_NewFunc)( void* memory, FT_Raster* raster ); -#define FT_Raster_New_Func FT_Raster_NewFunc +#define FT_Raster_New_Func FT_Raster_NewFunc + /*************************************************************************/ /* */ @@ -1089,7 +1133,8 @@ FT_BEGIN_HEADER typedef void (*FT_Raster_DoneFunc)( FT_Raster raster ); -#define FT_Raster_Done_Func FT_Raster_DoneFunc +#define FT_Raster_Done_Func FT_Raster_DoneFunc + /*************************************************************************/ /* */ @@ -1123,7 +1168,8 @@ FT_BEGIN_HEADER unsigned char* pool_base, unsigned long pool_size ); -#define FT_Raster_Reset_Func FT_Raster_ResetFunc +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + /*************************************************************************/ /* */ @@ -1148,7 +1194,8 @@ FT_BEGIN_HEADER unsigned long mode, void* args ); -#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + /*************************************************************************/ /* */ @@ -1156,8 +1203,8 @@ FT_BEGIN_HEADER /* FT_Raster_RenderFunc */ /* */ /* <Description> */ - /* Invokes a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ /* */ /* <Input> */ /* raster :: A handle to the raster object. */ @@ -1166,7 +1213,7 @@ FT_BEGIN_HEADER /* store the rendering parameters. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ /* <Note> */ /* The exact format of the source image depends on the raster's glyph */ @@ -1188,7 +1235,8 @@ FT_BEGIN_HEADER (*FT_Raster_RenderFunc)( FT_Raster raster, const FT_Raster_Params* params ); -#define FT_Raster_Render_Func FT_Raster_RenderFunc +#define FT_Raster_Render_Func FT_Raster_RenderFunc + /*************************************************************************/ /* */ @@ -1211,12 +1259,12 @@ FT_BEGIN_HEADER /* */ typedef struct FT_Raster_Funcs_ { - FT_Glyph_Format glyph_format; - FT_Raster_NewFunc raster_new; - FT_Raster_ResetFunc raster_reset; - FT_Raster_SetModeFunc raster_set_mode; - FT_Raster_RenderFunc raster_render; - FT_Raster_DoneFunc raster_done; + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; } FT_Raster_Funcs; diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h b/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h index 46bc8bdd37c..96abedea7b6 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007 by */ +/* Copyright 2002, 2003, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,192 +31,208 @@ FT_BEGIN_HEADER - /*************************************************************************** - * - * @section: - * incremental - * - * @title: - * Incremental Loading - * - * @abstract: - * Custom Glyph Loading. - * - * @description: - * This section contains various functions used to perform so-called - * `incremental' glyph loading. This is a mode where all glyphs loaded - * from a given @FT_Face are provided by the client application, - * - * Apart from that, all other tables are loaded normally from the font - * file. This mode is useful when FreeType is used within another - * engine, e.g., a Postscript Imaging Processor. - * - * To enable this mode, you must use @FT_Open_Face, passing an - * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an - * @FT_Incremental_Interface value. See the comments for - * @FT_Incremental_InterfaceRec for an example. - * - */ + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application, + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ - /*************************************************************************** - * - * @type: - * FT_Incremental - * - * @description: - * An opaque type describing a user-provided object used to implement - * `incremental' glyph loading within FreeType. This is used to support - * embedded fonts in certain environments (e.g., Postscript interpreters), - * where the glyph data isn't in the font file, or must be overridden by - * different values. - * - * @note: - * It is up to client applications to create and implement @FT_Incremental - * objects, as long as they provide implementations for the methods - * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc - * and @FT_Incremental_GetGlyphMetricsFunc. - * - * See the description of @FT_Incremental_InterfaceRec to understand how - * to use incremental objects with FreeType. - */ + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ typedef struct FT_IncrementalRec_* FT_Incremental; - /*************************************************************************** - * - * @struct: - * FT_Incremental_Metrics - * - * @description: - * A small structure used to contain the basic glyph metrics returned - * by the @FT_Incremental_GetGlyphMetricsFunc method. - * - * @fields: - * bearing_x :: - * Left bearing, in font units. - * - * bearing_y :: - * Top bearing, in font units. - * - * advance :: - * Glyph advance, in font units. - * - * @note: - * These correspond to horizontal or vertical metrics depending on the - * value of the `vertical' argument to the function - * @FT_Incremental_GetGlyphMetricsFunc. - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ typedef struct FT_Incremental_MetricsRec_ { FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; - } FT_Incremental_MetricsRec, *FT_Incremental_Metrics; + } FT_Incremental_MetricsRec; - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphDataFunc - * - * @description: - * A function called by FreeType to access a given glyph's data bytes - * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is - * enabled. - * - * Note that the format of the glyph's data bytes depends on the font - * file format. For TrueType, it must correspond to the raw bytes within - * the `glyf' table. For Postscript formats, it must correspond to the - * *unencrypted* charstring bytes, without any `lenIV' header. It is - * undefined for any other format. - * - * @input: - * incremental :: - * Handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * @output: - * adata :: - * A structure describing the returned glyph data bytes (which will be - * accessed as a read-only byte block). - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * If this function returns successfully the method - * @FT_Incremental_FreeGlyphDataFunc will be called later to release - * the data bytes. - * - * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for - * compound glyphs. - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ typedef FT_Error (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, FT_UInt glyph_index, FT_Data* adata ); - /*************************************************************************** - * - * @type: - * FT_Incremental_FreeGlyphDataFunc - * - * @description: - * A function used to release the glyph data bytes returned by a - * successful call to @FT_Incremental_GetGlyphDataFunc. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * data :: - * A structure describing the glyph data bytes (which will be accessed - * as a read-only byte block). - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ typedef void (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, FT_Data* data ); - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphMetricsFunc - * - * @description: - * A function used to retrieve the basic metrics of a given glyph index - * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place from - * the glyph images proper. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * vertical :: - * If true, return vertical metrics. - * - * ametrics :: - * This parameter is used for both input and output. - * The original glyph metrics, if any, in font units. If metrics are - * not available all the values must be set to zero. - * - * @output: - * ametrics :: - * The replacement glyph metrics in font units. - * - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ typedef FT_Error (*FT_Incremental_GetGlyphMetricsFunc) ( FT_Incremental incremental, @@ -244,6 +260,7 @@ FT_BEGIN_HEADER * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does * not provide overriding glyph metrics. + * */ typedef struct FT_Incremental_FuncsRec_ { @@ -254,41 +271,42 @@ FT_BEGIN_HEADER } FT_Incremental_FuncsRec; - /*************************************************************************** - * - * @struct: - * FT_Incremental_InterfaceRec - * - * @description: - * A structure to be used with @FT_Open_Face to indicate that the user - * wants to support incremental glyph loading. You should use it with - * @FT_PARAM_TAG_INCREMENTAL as in the following example: - * - * { - * FT_Incremental_InterfaceRec inc_int; - * FT_Parameter parameter; - * FT_Open_Args open_args; - * - * - * // set up incremental descriptor - * inc_int.funcs = my_funcs; - * inc_int.object = my_object; - * - * // set up optional parameter - * parameter.tag = FT_PARAM_TAG_INCREMENTAL; - * parameter.data = &inc_int; - * - * // set up FT_Open_Args structure - * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; - * open_args.pathname = my_font_pathname; - * open_args.num_params = 1; - * open_args.params = ¶meter; // we use one optional argument - * - * // open the font - * error = FT_Open_Face( library, &open_args, index, &face ); - * ... - * } - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ typedef struct FT_Incremental_InterfaceRec_ { const FT_Incremental_FuncsRec* funcs; @@ -297,31 +315,31 @@ FT_BEGIN_HEADER } FT_Incremental_InterfaceRec; - /*************************************************************************** - * - * @type: - * FT_Incremental_Interface - * - * @description: - * A pointer to an @FT_Incremental_InterfaceRec structure. - * - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_INCREMENTAL - * - * @description: - * A constant used as the tag of @FT_Parameter structures to indicate - * an incremental loading object to be used by FreeType. - * - */ + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ #define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) - /* */ + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftlcdfil.h b/reactos/lib/3rdparty/freetype/include/freetype/ftlcdfil.h index 9a61377a394..c6201b38e99 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftlcdfil.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -85,7 +91,7 @@ FT_BEGIN_HEADER * @since: * 2.3.0 */ - typedef enum + typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, @@ -119,7 +125,7 @@ FT_BEGIN_HEADER * well on most LCD screens. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This feature is always disabled by default. Clients must make an @@ -141,8 +147,8 @@ FT_BEGIN_HEADER * If this feature is activated, the dimensions of LCD glyph bitmaps are * either larger or taller than the dimensions of the corresponding * outline with regards to the pixel grid. For example, for - * @FT_RENDER_MODE_LCD, the filter adds up to 3 pixels to the left, and - * up to 3 pixels to the right. + * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and + * up to 3~pixels to the right. * * The bitmap offset values are adjusted correctly, so clients shouldn't * need to modify their layout and glyph positioning code when enabling diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftlist.h b/reactos/lib/3rdparty/freetype/include/freetype/ftlist.h index f3223ee8fdb..93b05fc0d62 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftlist.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftlist.h @@ -81,7 +81,7 @@ FT_BEGIN_HEADER /* FT_List_Find */ /* */ /* <Description> */ - /* Finds the list node for a given listed object. */ + /* Find the list node for a given listed object. */ /* */ /* <Input> */ /* list :: A pointer to the parent list. */ @@ -101,7 +101,7 @@ FT_BEGIN_HEADER /* FT_List_Add */ /* */ /* <Description> */ - /* Appends an element to the end of a list. */ + /* Append an element to the end of a list. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ @@ -118,7 +118,7 @@ FT_BEGIN_HEADER /* FT_List_Insert */ /* */ /* <Description> */ - /* Inserts an element at the head of a list. */ + /* Insert an element at the head of a list. */ /* */ /* <InOut> */ /* list :: A pointer to parent list. */ @@ -135,7 +135,7 @@ FT_BEGIN_HEADER /* FT_List_Remove */ /* */ /* <Description> */ - /* Removes a node from a list. This function doesn't check whether */ + /* Remove a node from a list. This function doesn't check whether */ /* the node is in the list! */ /* */ /* <Input> */ @@ -155,7 +155,7 @@ FT_BEGIN_HEADER /* FT_List_Up */ /* */ /* <Description> */ - /* Moves a node to the head/top of a list. Used to maintain LRU */ + /* Move a node to the head/top of a list. Used to maintain LRU */ /* lists. */ /* */ /* <InOut> */ @@ -193,7 +193,7 @@ FT_BEGIN_HEADER /* FT_List_Iterate */ /* */ /* <Description> */ - /* Parses a list and calls a given iterator function on each element. */ + /* Parse a list and calls a given iterator function on each element. */ /* Note that parsing is stopped as soon as one of the iterator calls */ /* returns a non-zero value. */ /* */ @@ -242,7 +242,7 @@ FT_BEGIN_HEADER /* FT_List_Finalize */ /* */ /* <Description> */ - /* Destroys all elements in the list as well as the list itself. */ + /* Destroy all elements in the list as well as the list itself. */ /* */ /* <Input> */ /* list :: A handle to the list. */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftlzw.h b/reactos/lib/3rdparty/freetype/include/freetype/ftlzw.h index d950653ebf8..00d40169a75 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftlzw.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftlzw.h @@ -63,7 +63,7 @@ FT_BEGIN_HEADER * source :: The source stream. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftmac.h b/reactos/lib/3rdparty/freetype/include/freetype/ftmac.h index 3c6fafe5500..ab5bab5170c 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftmac.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftmac.h @@ -18,9 +18,9 @@ /***************************************************************************/ /* */ -/* NOTE: Include this file after <freetype/freetype.h> and after the */ -/* Mac-specific <Types.h> header (or any other Mac header that */ -/* includes <Types.h>); we use Handle type. */ +/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ /* */ /***************************************************************************/ @@ -85,7 +85,7 @@ FT_BEGIN_HEADER /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Notes> */ /* This function can be used to create @FT_Face objects from fonts */ @@ -100,7 +100,8 @@ FT_BEGIN_HEADER FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, - FT_Face *aface ); + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ @@ -123,7 +124,7 @@ FT_BEGIN_HEADER /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, @@ -151,7 +152,7 @@ FT_BEGIN_HEADER /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, @@ -182,13 +183,14 @@ FT_BEGIN_HEADER /* face_index :: Index of the face. For passing to @FT_New_Face. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, UInt8* path, UInt32 maxPathSize, - FT_Long* face_index ); + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ @@ -207,12 +209,12 @@ FT_BEGIN_HEADER /* spec :: FSSpec to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ + /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ @@ -242,12 +244,12 @@ FT_BEGIN_HEADER /* spec :: FSRef to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ + /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftmm.h b/reactos/lib/3rdparty/freetype/include/freetype/ftmm.h index a9ccfe71380..3aefb9e4f25 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftmm.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -44,7 +44,7 @@ FT_BEGIN_HEADER /* setting design axis coordinates. */ /* */ /* George Williams has extended this interface to make it work with */ - /* both Type 1 Multiple Masters fonts and GX distortable (var) */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ /* fonts. Some of these routines only work with MM fonts, others */ /* will work with both types. They are similar enough that a */ /* consistent interface makes sense. */ @@ -91,12 +91,12 @@ FT_BEGIN_HEADER /* This structure can't be used for GX var fonts. */ /* */ /* <Fields> */ - /* num_axis :: Number of axes. Cannot exceed 4. */ + /* num_axis :: Number of axes. Cannot exceed~4. */ /* */ /* num_designs :: Number of designs; should be normally 2^num_axis */ - /* even though the Type 1 specification strangely */ + /* even though the Type~1 specification strangely */ /* allows for intermediate designs to be present. This */ - /* number cannot exceed 16. */ + /* number cannot exceed~16. */ /* */ /* axis :: A table of axis descriptors. */ /* */ @@ -187,7 +187,7 @@ FT_BEGIN_HEADER /* Some fields are specific to one format and not to the other. */ /* */ /* <Fields> */ - /* num_axis :: The number of axes. The maximum value is 4 for */ + /* num_axis :: The number of axes. The maximum value is~4 for */ /* MM; no limit in GX. */ /* */ /* num_designs :: The number of designs; should be normally */ @@ -227,7 +227,7 @@ FT_BEGIN_HEADER /* FT_Get_Multi_Master */ /* */ /* <Description> */ - /* Retrieves the Multiple Master descriptor of a given font. */ + /* Retrieve the Multiple Master descriptor of a given font. */ /* */ /* This function can't be used with GX fonts. */ /* */ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER /* amaster :: The Multiple Masters descriptor. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Multi_Master( FT_Face face, @@ -251,18 +251,18 @@ FT_BEGIN_HEADER /* FT_Get_MM_Var */ /* */ /* <Description> */ - /* Retrieves the Multiple Master/GX var descriptor of a given font. */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ - /* amaster :: The Multiple Masters descriptor. */ + /* amaster :: The Multiple Masters/GX var descriptor. */ /* Allocates a data structure, which the user must free */ /* (a single call to FT_FREE will do it). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_MM_Var( FT_Face face, @@ -290,7 +290,7 @@ FT_BEGIN_HEADER /* coords :: An array of design coordinates. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, @@ -317,7 +317,7 @@ FT_BEGIN_HEADER /* coords :: An array of design coordinates. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, @@ -345,7 +345,7 @@ FT_BEGIN_HEADER /* between 0 and 1.0). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftmodapi.h b/reactos/lib/3rdparty/freetype/include/freetype/ftmodapi.h index 9cc32aff4e1..3c9b876dfee 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftmodapi.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -78,12 +78,50 @@ FT_BEGIN_HEADER typedef FT_Pointer FT_Module_Interface; + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ typedef void (*FT_Module_Destructor)( FT_Module module ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); @@ -112,14 +150,11 @@ FT_BEGIN_HEADER /* as a 16.16 fixed number (major.minor). Starts */ /* at version 2.0, i.e., 0x20000. */ /* */ - /* module_init :: A function used to initialize (not create) a */ - /* new module object. */ + /* module_init :: The initializing function. */ /* */ - /* module_done :: A function used to finalize (not destroy) a */ - /* given module object */ + /* module_done :: The finalizing function. */ /* */ - /* get_interface :: Queries a given module for a specific */ - /* interface by name. */ + /* get_interface :: The interface requesting function. */ /* */ typedef struct FT_Module_Class_ { @@ -144,7 +179,7 @@ FT_BEGIN_HEADER /* FT_Add_Module */ /* */ /* <Description> */ - /* Adds a new module to a given library instance. */ + /* Add a new module to a given library instance. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ @@ -153,7 +188,7 @@ FT_BEGIN_HEADER /* clazz :: A pointer to class descriptor for the module. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ @@ -170,7 +205,7 @@ FT_BEGIN_HEADER /* FT_Get_Module */ /* */ /* <Description> */ - /* Finds a module by its name. */ + /* Find a module by its name. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ @@ -178,7 +213,7 @@ FT_BEGIN_HEADER /* module_name :: The module's name (as an ASCII string). */ /* */ /* <Return> */ - /* A module handle. 0 if none was found. */ + /* A module handle. 0~if none was found. */ /* */ /* <Note> */ /* FreeType's internal modules aren't documented very well, and you */ @@ -195,7 +230,7 @@ FT_BEGIN_HEADER /* FT_Remove_Module */ /* */ /* <Description> */ - /* Removes a given module from a library instance. */ + /* Remove a given module from a library instance. */ /* */ /* <InOut> */ /* library :: A handle to a library object. */ @@ -204,7 +239,7 @@ FT_BEGIN_HEADER /* module :: A handle to a module object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The module object is destroyed by the function in case of success. */ @@ -224,6 +259,10 @@ FT_BEGIN_HEADER /* from a given memory object. It is thus possible to use libraries */ /* with distinct memory allocators within the same program. */ /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ /* <Input> */ /* memory :: A handle to the original memory object. */ /* */ @@ -231,7 +270,7 @@ FT_BEGIN_HEADER /* alibrary :: A pointer to handle of a new library object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_New_Library( FT_Memory memory, @@ -244,14 +283,14 @@ FT_BEGIN_HEADER /* FT_Done_Library */ /* */ /* <Description> */ - /* Discards a given library object. This closes all drivers and */ + /* Discard a given library object. This closes all drivers and */ /* discards all resource objects. */ /* */ /* <Input> */ /* library :: A handle to the target library. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); @@ -268,7 +307,7 @@ FT_BEGIN_HEADER /* FT_Set_Debug_Hook */ /* */ /* <Description> */ - /* Sets a debug hook function for debugging the interpreter of a font */ + /* Set a debug hook function for debugging the interpreter of a font */ /* format. */ /* */ /* <InOut> */ @@ -283,7 +322,7 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ + /* the TrueType and the Type~1 interpreter) are defined. */ /* */ /* Since the internal headers of FreeType are no longer installed, */ /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ @@ -301,7 +340,7 @@ FT_BEGIN_HEADER /* FT_Add_Default_Modules */ /* */ /* <Description> */ - /* Adds the set of default drivers to a given library object. */ + /* Add the set of default drivers to a given library object. */ /* This is only useful when you create a library object with */ /* @FT_New_Library (usually to plug a custom memory manager). */ /* */ @@ -362,7 +401,7 @@ FT_BEGIN_HEADER * 2.2 * */ - typedef enum + typedef enum FT_TrueTypeEngineType_ { FT_TRUETYPE_ENGINE_TYPE_NONE = 0, FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, @@ -377,7 +416,7 @@ FT_BEGIN_HEADER * FT_Get_TrueType_Engine_Type * * @description: - * Return a @FT_TrueTypeEngineType value to indicate which level of + * Return an @FT_TrueTypeEngineType value to indicate which level of * the TrueType virtual machine a given library instance supports. * * @input: diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftotval.h b/reactos/lib/3rdparty/freetype/include/freetype/ftotval.h index 7c488fdf465..027f2e88657 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftotval.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* This section contains the declaration of functions to validate */ - /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ /* */ /*************************************************************************/ @@ -86,8 +86,11 @@ FT_BEGIN_HEADER * FT_VALIDATE_JSTF :: * Validate JSTF table. * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * * FT_VALIDATE_OT :: - * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). * */ #define FT_VALIDATE_BASE 0x0100 @@ -95,12 +98,14 @@ FT_BEGIN_HEADER #define FT_VALIDATE_GPOS 0x0400 #define FT_VALIDATE_GSUB 0x0800 #define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 #define FT_VALIDATE_OT FT_VALIDATE_BASE | \ FT_VALIDATE_GDEF | \ FT_VALIDATE_GPOS | \ FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH /* */ @@ -140,7 +145,7 @@ FT_BEGIN_HEADER * A pointer to the JSTF table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with OpenType fonts, returning an error diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h b/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h index 786ae13ed8f..d7d01e82706 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,7 +84,7 @@ FT_BEGIN_HEADER /* FT_Outline_Decompose */ /* */ /* <Description> */ - /* Walks over an outline's structure to decompose it into individual */ + /* Walk over an outline's structure to decompose it into individual */ /* segments and Bézier arcs. This function is also able to emit */ /* `move to' and `close to' operations to indicate the start and end */ /* of new contours in the outline. */ @@ -92,7 +92,7 @@ FT_BEGIN_HEADER /* <Input> */ /* outline :: A pointer to the source target. */ /* */ - /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* func_interface :: A table of `emitters', i.e., function pointers */ /* called during decomposition to indicate path */ /* operations. */ /* */ @@ -103,7 +103,7 @@ FT_BEGIN_HEADER /* decomposition. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, @@ -117,7 +117,7 @@ FT_BEGIN_HEADER /* FT_Outline_New */ /* */ /* <Description> */ - /* Creates a new outline of a given size. */ + /* Create a new outline of a given size. */ /* */ /* <Input> */ /* library :: A handle to the library object from where the */ @@ -130,11 +130,10 @@ FT_BEGIN_HEADER /* numContours :: The maximal number of contours within the outline. */ /* */ /* <Output> */ - /* anoutline :: A handle to the new outline. NULL in case of */ - /* error. */ + /* anoutline :: A handle to the new outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The reason why this function takes a `library' parameter is simply */ @@ -160,7 +159,7 @@ FT_BEGIN_HEADER /* FT_Outline_Done */ /* */ /* <Description> */ - /* Destroys an outline created with @FT_Outline_New. */ + /* Destroy an outline created with @FT_Outline_New. */ /* */ /* <Input> */ /* library :: A handle of the library object used to allocate the */ @@ -169,7 +168,7 @@ FT_BEGIN_HEADER /* outline :: A pointer to the outline object to be discarded. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If the outline's `owner' field is not set, only the outline */ @@ -200,7 +199,7 @@ FT_BEGIN_HEADER /* outline :: A handle to a source outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); @@ -212,7 +211,7 @@ FT_BEGIN_HEADER /* FT_Outline_Get_CBox */ /* */ /* <Description> */ - /* Returns an outline's `control box'. The control box encloses all */ + /* Return an outline's `control box'. The control box encloses all */ /* the outline's points, including Bézier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ @@ -240,7 +239,7 @@ FT_BEGIN_HEADER /* FT_Outline_Translate */ /* */ /* <Description> */ - /* Applies a simple translation to the points of an outline. */ + /* Apply a simple translation to the points of an outline. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ @@ -262,7 +261,7 @@ FT_BEGIN_HEADER /* FT_Outline_Copy */ /* */ /* <Description> */ - /* Copies an outline into another one. Both objects must have the */ + /* Copy an outline into another one. Both objects must have the */ /* same sizes (number of points & number of contours) when this */ /* function is called. */ /* */ @@ -273,7 +272,7 @@ FT_BEGIN_HEADER /* target :: A handle to the target outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Copy( const FT_Outline* source, @@ -286,7 +285,7 @@ FT_BEGIN_HEADER /* FT_Outline_Transform */ /* */ /* <Description> */ - /* Applies a simple 2x2 matrix to all of an outline's points. Useful */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ /* for applying rotations, slanting, flipping, etc. */ /* */ /* <InOut> */ @@ -310,7 +309,7 @@ FT_BEGIN_HEADER /* FT_Outline_Embolden */ /* */ /* <Description> */ - /* Emboldens an outline. The new outline will be at most 4 times */ + /* Embolden an outline. The new outline will be at most 4~times */ /* `strength' pixels wider and higher. You may think of the left and */ /* bottom borders as unchanged. */ /* */ @@ -325,7 +324,7 @@ FT_BEGIN_HEADER /* 26.6 pixel format. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The used algorithm to increase or decrease the thickness of the */ @@ -333,6 +332,9 @@ FT_BEGIN_HEADER /* situations like acute angles or intersections are sometimes */ /* handled incorrectly. */ /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox. */ + /* */ /* Example call: */ /* */ /* { */ @@ -352,14 +354,14 @@ FT_BEGIN_HEADER /* FT_Outline_Reverse */ /* */ /* <Description> */ - /* Reverses the drawing direction of an outline. This is used to */ + /* Reverse the drawing direction of an outline. This is used to */ /* ensure consistent fill conventions for mirrored glyphs. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ /* */ /* <Note> */ - /* This functions toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ /* the outline's `flags' field. */ /* */ /* It shouldn't be used by a normal client application, unless it */ @@ -375,7 +377,7 @@ FT_BEGIN_HEADER /* FT_Outline_Get_Bitmap */ /* */ /* <Description> */ - /* Renders an outline within a bitmap. The outline's image is simply */ + /* Render an outline within a bitmap. The outline's image is simply */ /* OR-ed to the target bitmap. */ /* */ /* <Input> */ @@ -387,14 +389,19 @@ FT_BEGIN_HEADER /* abitmap :: A pointer to the target bitmap descriptor. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ /* */ /* It will use the raster corresponding to the default glyph format. */ /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, FT_Outline* outline, @@ -407,8 +414,8 @@ FT_BEGIN_HEADER /* FT_Outline_Render */ /* */ /* <Description> */ - /* Renders an outline within a bitmap using the current scan-convert. */ - /* This functions uses an @FT_Raster_Params structure as an argument, */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ /* allowing advanced features like direct composition, translucency, */ /* etc. */ /* */ @@ -422,7 +429,7 @@ FT_BEGIN_HEADER /* describe the rendering operation. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You should know what you are doing and how @FT_Raster_Params works */ @@ -432,6 +439,11 @@ FT_BEGIN_HEADER /* converter is called, which means that the value you give to it is */ /* actually ignored. */ /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Render( FT_Library library, FT_Outline* outline, @@ -446,7 +458,7 @@ FT_BEGIN_HEADER * @description: * A list of values used to describe an outline's contour orientation. * - * The TrueType and Postscript specifications use different conventions + * The TrueType and PostScript specifications use different conventions * to determine whether outline contours should be filled or unfilled. * * @values: @@ -455,7 +467,7 @@ FT_BEGIN_HEADER * be filled, and counter-clockwise ones must be unfilled. * * FT_ORIENTATION_POSTSCRIPT :: - * According to the Postscript specification, counter-clockwise contours + * According to the PostScript specification, counter-clockwise contours * must be filled, and clockwise ones must be unfilled. * * FT_ORIENTATION_FILL_RIGHT :: @@ -465,7 +477,7 @@ FT_BEGIN_HEADER * * FT_ORIENTATION_FILL_LEFT :: * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to - * remember that in Postscript, everything that is to the left of + * remember that in PostScript, everything that is to the left of * the drawing direction of a contour must be filled. * * FT_ORIENTATION_NONE :: @@ -473,7 +485,7 @@ FT_BEGIN_HEADER * the glyph have different orientation. * */ - typedef enum + typedef enum FT_Orientation_ { FT_ORIENTATION_TRUETYPE = 0, FT_ORIENTATION_POSTSCRIPT = 1, diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftpfr.h b/reactos/lib/3rdparty/freetype/include/freetype/ftpfr.h index e2801fd0f98..0b7b7d427c9 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftpfr.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,8 +62,8 @@ FT_BEGIN_HEADER * * @output: * aoutline_resolution :: - * Outline resolution. This is equivalent to `face->units_per_EM'. - * Optional (parameter can be NULL). + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_resolution :: * Metrics resolution. This is equivalent to `outline_resolution' @@ -73,14 +73,14 @@ FT_BEGIN_HEADER * A 16.16 fixed-point number used to scale distance expressed * in metrics units to device sub-pixels. This is equivalent to * `face->size->x_scale', but for metrics only. Optional (parameter - * can be NULL) + * can be NULL). * * ametrics_y_scale :: * Same as `ametrics_x_scale' but for the vertical direction. - * optional (parameter can be NULL) + * optional (parameter can be NULL). * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * If the input face is not a PFR, this function will return an error. @@ -115,7 +115,7 @@ FT_BEGIN_HEADER * avector :: A kerning vector. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function always return distances in original PFR metrics @@ -150,7 +150,7 @@ FT_BEGIN_HEADER * aadvance :: The glyph advance in metrics units. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftrender.h b/reactos/lib/3rdparty/freetype/include/freetype/ftrender.h index 5b07f08c2de..41c31eac48c 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftrender.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftrender.h @@ -124,27 +124,32 @@ FT_BEGIN_HEADER /* The renderer module class descriptor. */ /* */ /* <Fields> */ - /* root :: The root @FT_Module_Class fields. */ + /* root :: The root @FT_Module_Class fields. */ /* */ - /* glyph_format :: The glyph image format this renderer handles. */ + /* glyph_format :: The glyph image format this renderer handles. */ /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ /* */ - /* set_mode :: A method used to pass additional parameters. */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ /* */ - /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. This */ - /* is a pointer to its raster's class. */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ /* */ - /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. This */ - /* is a pointer to the corresponding raster object, */ - /* if any. */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to the corresponding raster */ + /* object, if any. */ /* */ typedef struct FT_Renderer_Class_ { - FT_Module_Class root; + FT_Module_Class root; - FT_Glyph_Format glyph_format; + FT_Glyph_Format glyph_format; FT_Renderer_RenderFunc render_glyph; FT_Renderer_TransformFunc transform_glyph; @@ -162,7 +167,7 @@ FT_BEGIN_HEADER /* FT_Get_Renderer */ /* */ /* <Description> */ - /* Retrieves the current renderer for a given glyph format. */ + /* Retrieve the current renderer for a given glyph format. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ @@ -170,7 +175,7 @@ FT_BEGIN_HEADER /* format :: The glyph format. */ /* */ /* <Return> */ - /* A renderer handle. 0 if none found. */ + /* A renderer handle. 0~if none found. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ @@ -190,7 +195,7 @@ FT_BEGIN_HEADER /* FT_Set_Renderer */ /* */ /* <Description> */ - /* Sets the current renderer to use, and set additional mode. */ + /* Set the current renderer to use, and set additional mode. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ @@ -203,7 +208,7 @@ FT_BEGIN_HEADER /* parameters :: Additional parameters. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* In case of success, the renderer will be used to convert glyph */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftsizes.h b/reactos/lib/3rdparty/freetype/include/freetype/ftsizes.h index 622df162d2c..3e548cc39f3 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftsizes.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -89,7 +89,7 @@ FT_BEGIN_HEADER /* asize :: A handle to a new size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You need to call @FT_Activate_Size in order to select the new size */ @@ -115,7 +115,7 @@ FT_BEGIN_HEADER /* size :: A handle to a target size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Size( FT_Size size ); @@ -129,8 +129,8 @@ FT_BEGIN_HEADER /* <Description> */ /* Even though it is possible to create several size objects for a */ /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the last-created one to */ - /* determine the `current character pixel size'. */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* activated last to determine the `current character pixel size'. */ /* */ /* This function can be used to `activate' a previously created size */ /* object. */ @@ -139,7 +139,7 @@ FT_BEGIN_HEADER /* size :: A handle to a target size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If `face' is the size's parent face object, this function changes */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h b/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h index 003cbcd129c..f20b4099dae 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,7 +48,7 @@ FT_BEGIN_HEADER /* Access the names embedded in TrueType and OpenType files. */ /* */ /* <Description> */ - /* The TrueType and OpenType specification allow the inclusion of */ + /* The TrueType and OpenType specifications allow the inclusion of */ /* a special `names table' in font files. This table contains */ /* textual (and internationalized) information regarding the font, */ /* like family name, copyright, version, etc. */ @@ -114,7 +114,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Name_Count */ /* */ /* <Description> */ - /* Retrieves the number of name strings in the SFNT `name' table. */ + /* Retrieve the number of name strings in the SFNT `name' table. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -132,7 +132,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Name */ /* */ /* <Description> */ - /* Retrieves a string of the SFNT `name' table for a given index. */ + /* Retrieve a string of the SFNT `name' table for a given index. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -143,11 +143,12 @@ FT_BEGIN_HEADER /* aname :: The indexed @FT_SfntName structure. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftstroke.h b/reactos/lib/3rdparty/freetype/include/freetype/ftstroke.h index 738b43c1acc..3afb87df887 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftstroke.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,7 +84,7 @@ FT_BEGIN_HEADER * is too closed (this is useful to avoid unpleasant spikes * in beveled rendering). */ - typedef enum + typedef enum FT_Stroker_LineJoin_ { FT_STROKER_LINEJOIN_ROUND = 0, FT_STROKER_LINEJOIN_BEVEL, @@ -115,7 +115,7 @@ FT_BEGIN_HEADER * The end of lines is rendered as a square around the * last point. */ - typedef enum + typedef enum FT_Stroker_LineCap_ { FT_STROKER_LINECAP_BUTT = 0, FT_STROKER_LINECAP_ROUND, @@ -149,7 +149,7 @@ FT_BEGIN_HEADER * You can however use @FT_Outline_GetInsideBorder and * @FT_Outline_GetOutsideBorder to get these. */ - typedef enum + typedef enum FT_StrokerBorder_ { FT_STROKER_BORDER_LEFT = 0, FT_STROKER_BORDER_RIGHT @@ -171,7 +171,7 @@ FT_BEGIN_HEADER * The source outline handle. * * @return: - * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) @@ -216,7 +216,7 @@ FT_BEGIN_HEADER * A new stroker object handle. NULL in case of error. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_New( FT_Library library, @@ -249,7 +249,7 @@ FT_BEGIN_HEADER * expressed as 16.16 fixed point value. * * @note: - * The radius is expressed in the same units that the outline + * The radius is expressed in the same units as the outline * coordinates. */ FT_EXPORT( void ) @@ -297,18 +297,18 @@ FT_BEGIN_HEADER * The source outline. * * opened :: - * A boolean. If 1, the outline is treated as an open path instead + * A boolean. If~1, the outline is treated as an open path instead * of a closed one. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: - * If `opened' is 0 (the default), the outline is treated as a closed - * path, and the stroker will generate two distinct `border' outlines. + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. * - * If `opened' is 1, the outline is processed as an open path, and the - * stroker will generate a single `stroke' outline. + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. * * This function calls @FT_Stroker_Rewind automatically. */ @@ -334,10 +334,10 @@ FT_BEGIN_HEADER * A pointer to the start vector. * * open :: - * A boolean. If 1, the sub-path is treated as an open one. + * A boolean. If~1, the sub-path is treated as an open one. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function is useful when you need to stroke a path that is @@ -362,11 +362,11 @@ FT_BEGIN_HEADER * The target stroker handle. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function after @FT_Stroker_BeginSubPath. - * If the subpath was not `opened', this function will `draw' a + * If the subpath was not `opened', this function `draws' a * single line segment to the start position when needed. */ FT_EXPORT( FT_Error ) @@ -390,7 +390,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -421,7 +421,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -456,7 +456,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -476,7 +476,7 @@ FT_BEGIN_HEADER * * @description: * Call this function once you have finished parsing your paths - * with the stroker. It will return the number of points and + * with the stroker. It returns the number of points and * contours necessary to export one of the `border' or `stroke' * outlines generated by the stroker. * @@ -495,7 +495,7 @@ FT_BEGIN_HEADER * The number of contours. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * When an outline, or a sub-path, is `closed', the stroker generates @@ -525,8 +525,8 @@ FT_BEGIN_HEADER * export the corresponding border to your own @FT_Outline * structure. * - * Note that this function will append the border points and - * contours to your outline, but will not try to resize its + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its * arrays. * * @input: @@ -583,7 +583,7 @@ FT_BEGIN_HEADER * The number of contours. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_GetCounts( FT_Stroker stroker, @@ -598,10 +598,10 @@ FT_BEGIN_HEADER * * @description: * Call this function after @FT_Stroker_GetBorderCounts to - * export the all borders to your own @FT_Outline structure. + * export all borders to your own @FT_Outline structure. * - * Note that this function will append the border points and - * contours to your outline, but will not try to resize its + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its * arrays. * * @input: @@ -649,11 +649,11 @@ FT_BEGIN_HEADER * A stroker handle. * * destroy :: - * A Boolean. If 1, the source glyph object is destroyed + * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. @@ -682,15 +682,15 @@ FT_BEGIN_HEADER * A stroker handle. * * inside :: - * A Boolean. If 1, return the inside border, otherwise + * A Boolean. If~1, return the inside border, otherwise * the outside border. * * destroy :: - * A Boolean. If 1, the source glyph object is destroyed + * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftsynth.h b/reactos/lib/3rdparty/freetype/include/freetype/ftsynth.h index 36984bf1a7b..a068b7928d6 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftsynth.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2006 by */ +/* Copyright 2000-2001, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,7 @@ /*************************************************************************/ /*************************************************************************/ /********* *********/ - /********* WARNING, THIS IS ALPHA CODE, THIS API *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ /********* FREETYPE DEVELOPMENT TEAM *********/ /********* *********/ @@ -34,6 +34,13 @@ /*************************************************************************/ + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource which should be copied into the application and */ + /* adapted to the particular needs. */ + + #ifndef __FTSYNTH_H__ #define __FTSYNTH_H__ @@ -50,20 +57,20 @@ FT_BEGIN_HEADER - /* Make sure slot owns slot->bitmap. */ - FT_EXPORT( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); - - /* Do not use this function directly! Copy the code to */ - /* your application and modify it to suit your need. */ + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the metrics are estimates only; if you need */ + /* precise values you should call @FT_Outline_Get_CBox. */ FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); - + /* Slant an outline glyph to the right by about 12 degrees. */ FT_EXPORT( void ) FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); - /* */ + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftsystem.h b/reactos/lib/3rdparty/freetype/include/freetype/ftsystem.h index 59cd0198221..a95b2c76b61 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftsystem.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftsystem.h @@ -82,7 +82,7 @@ FT_BEGIN_HEADER * The size in bytes to allocate. * * @return: - * Address of new memory block. 0 in case of failure. + * Address of new memory block. 0~in case of failure. * */ typedef void* @@ -133,7 +133,7 @@ FT_BEGIN_HEADER * The block's current address. * * @return: - * New block address. 0 in case of memory shortage. + * New block address. 0~in case of memory shortage. * * @note: * In case of error, the old block must still be available. @@ -152,7 +152,7 @@ FT_BEGIN_HEADER * FT_MemoryRec * * @description: - * A structure used to describe a given memory manager to FreeType 2. + * A structure used to describe a given memory manager to FreeType~2. * * @fields: * user :: @@ -240,7 +240,7 @@ FT_BEGIN_HEADER * * @note: * This function might be called to perform a seek or skip operation - * with a `count' of 0. + * with a `count' of~0. * */ typedef unsigned long diff --git a/reactos/lib/3rdparty/freetype/include/freetype/fttypes.h b/reactos/lib/3rdparty/freetype/include/freetype/fttypes.h index 2340bacd310..a57ffa69bd8 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/fttypes.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,7 @@ FT_BEGIN_HEADER /* The basic data types defined by the library. */ /* */ /* <Description> */ - /* This section contains the basic data types defined by FreeType 2, */ + /* This section contains the basic data types defined by FreeType~2, */ /* ranging from simple scalar types to bitmap descriptors. More */ /* font-specific structures are defined in a different section. */ /* */ @@ -53,6 +53,10 @@ FT_BEGIN_HEADER /* FT_Char */ /* FT_Int */ /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ /* FT_Short */ /* FT_UShort */ /* FT_Long */ @@ -95,7 +99,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A typedef of unsigned char, used for simple booleans. As usual, */ - /* values 1 and 0 represent true and false, respectively. */ + /* values 1 and~0 represent true and false, respectively. */ /* */ typedef unsigned char FT_Bool; @@ -163,7 +167,7 @@ FT_BEGIN_HEADER /* FT_Tag */ /* */ /* <Description> */ - /* A typedef for 32bit tags (as used in the SFNT format). */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ /* */ typedef FT_UInt32 FT_Tag; @@ -286,7 +290,7 @@ FT_BEGIN_HEADER /* FT_Error */ /* */ /* <Description> */ - /* The FreeType error code type. A value of 0 is always interpreted */ + /* The FreeType error code type. A value of~0 is always interpreted */ /* as a successful operation. */ /* */ typedef int FT_Error; @@ -309,7 +313,7 @@ FT_BEGIN_HEADER /* FT_Offset */ /* */ /* <Description> */ - /* This is equivalent to the ANSI C `size_t' type, i.e., the largest */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ /* _unsigned_ integer type used to express a file size or position, */ /* or a memory block size. */ /* */ @@ -322,7 +326,7 @@ FT_BEGIN_HEADER /* FT_PtrDist */ /* */ /* <Description> */ - /* This is equivalent to the ANSI C `ptrdiff_t' type, i.e., the */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ /* largest _signed_ integer type used to express the distance */ /* between two pointers. */ /* */ @@ -409,7 +413,7 @@ FT_BEGIN_HEADER /* FT_Generic_Finalizer */ /* */ /* <Description> */ - /* Describes a function used to destroy the `client' data of any */ + /* Describe a function used to destroy the `client' data of any */ /* FreeType object. See the description of the @FT_Generic type for */ /* details of usage. */ /* */ @@ -466,10 +470,11 @@ FT_BEGIN_HEADER /* TrueType tables into an unsigned long to be used within FreeType. */ /* */ /* <Note> */ - /* The produced values *must* be 32bit integers. Don't redefine this */ - /* macro. */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ /* */ #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ ( ( (FT_ULong)_x1 << 24 ) | \ ( (FT_ULong)_x2 << 16 ) | \ ( (FT_ULong)_x3 << 8 ) | \ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftwinfnt.h b/reactos/lib/3rdparty/freetype/include/freetype/ftwinfnt.h index a0063cc7356..ea33353536e 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftwinfnt.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,11 +111,11 @@ FT_BEGIN_HEADER * ordering and minor deviations). * * FT_WinFNT_ID_CP949 :: - * A superset of Korean Hangul KS C 5601-1987 (with different + * A superset of Korean Hangul KS~C 5601-1987 (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP950 :: - * A superset of traditional Chinese Big 5 ETen (with different + * A superset of traditional Chinese Big~5 ETen (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP1250 :: @@ -219,36 +219,47 @@ FT_BEGIN_HEADER FT_UShort color_table_offset; FT_ULong reserved1[4]; - } FT_WinFNT_HeaderRec, *FT_WinFNT_Header; + } FT_WinFNT_HeaderRec; - /********************************************************************** - * - * @function: - * FT_Get_WinFNT_Header - * - * @description: - * Retrieve a Windows FNT font info header. - * - * @input: - * face :: A handle to the input face. - * - * @output: - * aheader :: The WinFNT header. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * This function only works with Windows FNT faces, returning an error - * otherwise. - */ + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ FT_EXPORT( FT_Error ) FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *aheader ); - /* */ + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftxf86.h b/reactos/lib/3rdparty/freetype/include/freetype/ftxf86.h index ea82abb0842..8c68afdcc58 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftxf86.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftxf86.h @@ -49,6 +49,9 @@ FT_BEGIN_HEADER /* however, there are special cases (like in PDF devices) where it is */ /* important to differentiate, in spite of FreeType's uniform API. */ /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ /*************************************************************************/ @@ -60,8 +63,8 @@ FT_BEGIN_HEADER /* <Description> */ /* Return a string describing the format of a given face, using values */ /* which can be used as an X11 FONT_PROPERTY. Possible values are */ - /* `TrueType', `Type 1', `BDF', `PCF', `Type 42', `CID Type 1', `CFF', */ - /* `PFR', and `Windows FNT'. */ + /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ + /* `PFR', and `Windows~FNT'. */ /* */ /* <Input> */ /* face :: */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/autohint.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/autohint.h index ee004022f9d..7e3a08a0511 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/autohint.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/autohint.h @@ -196,6 +196,32 @@ FT_BEGIN_HEADER } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_AutoHinter_ServiceRec class_ = \ + { \ + reset_face_, get_global_hints_, done_global_hints_, load_glyph_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_AutoHinter_ServiceRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->reset_face = reset_face_; \ + clazz->get_global_hints = get_global_hints_; \ + clazz->done_global_hints = done_global_hints_; \ + clazz->load_glyph = load_glyph_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h index c7e9901ebaf..f8b4324777e 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,6 +111,31 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + /* * Return -1, 0, or +1, depending on the orientation of a given corner. * We use the Cartesian coordinate system, with positive vertical values @@ -140,6 +165,7 @@ FT_BEGIN_HEADER #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) #define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h index 15627147b8e..7baae3531d5 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,7 +54,7 @@ FT_BEGIN_HEADER #define FT_TRACE_DEF( x ) trace_ ## x , /* defining the enumeration */ - typedef enum + typedef enum FT_Trace_ { #include FT_INTERNAL_TRACE_H trace_count @@ -92,7 +92,7 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_TRACE */ -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ +#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_TRACE */ @@ -146,10 +146,12 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* You need two opening resp. closing parentheses! */ + /* You need two opening and closing parentheses! */ /* */ /* Example: FT_TRACE0(( "Value is %i", foo )) */ /* */ + /* Output of the FT_TRACEX macros is sent to stderr. */ + /* */ /*************************************************************************/ #define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) @@ -164,7 +166,9 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Define the FT_ERROR macro */ + /* Define the FT_ERROR macro. */ + /* */ + /* Output of this macro is sent to stderr. */ /* */ /*************************************************************************/ @@ -174,14 +178,14 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_ERROR */ -#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ - /* Define the FT_ASSERT macro */ + /* Define the FT_ASSERT macro. */ /* */ /*************************************************************************/ @@ -197,28 +201,30 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_ERROR */ -#define FT_ASSERT( condition ) do ; while ( 0 ) +#define FT_ASSERT( condition ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ - /* Define `FT_Message' and `FT_Panic' when needed */ + /* Define `FT_Message' and `FT_Panic' when needed. */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_ERROR -#include "stdio.h" /* for vprintf() */ +#include "stdio.h" /* for vfprintf() */ /* print a message */ FT_BASE( void ) - FT_Message( const char* fmt, ... ); + FT_Message( const char* fmt, + ... ); /* print a message and exit */ FT_BASE( void ) - FT_Panic( const char* fmt, ... ); + FT_Panic( const char* fmt, + ... ); #endif /* FT_DEBUG_LEVEL_ERROR */ @@ -229,8 +235,8 @@ FT_BEGIN_HEADER #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - /* we disable the warning `conditional expression is constant' here */ - /* in order to compile cleanly with the maximum level of warnings */ + /* We disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings. */ #pragma warning( disable : 4127 ) #endif /* _MSC_VER */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h index 97f3fd04d90..1d06997bd18 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,6 +91,7 @@ FT_BEGIN_HEADER (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, FT_Long charcode ); + typedef FT_Error (*FT_Face_GetKerningFunc)( FT_Face face, FT_UInt left_glyph, @@ -104,11 +105,11 @@ FT_BEGIN_HEADER typedef FT_Error - (*FT_Face_GetAdvancesFunc)( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Bool vertical, - FT_UShort* advances ); + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); /*************************************************************************/ @@ -145,10 +146,6 @@ FT_BEGIN_HEADER /* load_glyph :: A function handle to load a glyph to a slot. */ /* This field is mandatory! */ /* */ - /* get_char_index :: A function handle to return the glyph index of */ - /* a given character for a given charmap. This */ - /* field is mandatory! */ - /* */ /* get_kerning :: A function handle to return the unscaled */ /* kerning for a given pair of glyphs. Can be */ /* set to 0 if the format doesn't support */ @@ -180,8 +177,8 @@ FT_BEGIN_HEADER /* to 0 if the scaling done in the base layer */ /* suffices. */ /* <Note> */ - /* Most function pointers, with the exception of `load_glyph' and */ - /* `get_char_index' can be set to 0 to indicate a default behaviour. */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ /* */ typedef struct FT_Driver_ClassRec_ { @@ -243,6 +240,179 @@ FT_BEGIN_HEADER #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Driver_ClassRec stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + a_, b_, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + clazz->set_char_sizes = a_; \ + clazz->set_pixel_sizes = b_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + class_##_pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h index 9f47c0b8c87..ce4dc6c9cc6 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h @@ -67,11 +67,11 @@ FT_BEGIN_HEADER typedef struct FT_GlyphLoadRec_ { - FT_Outline outline; /* outline */ - FT_Vector* extra_points; /* extra points table */ + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ FT_Vector* extra_points2; /* second extra points table */ - FT_UInt num_subglyphs; /* number of subglyphs */ - FT_SubGlyph subglyphs; /* subglyphs */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ } FT_GlyphLoadRec, *FT_GlyphLoad; @@ -121,15 +121,15 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (_count)) <= (int)(_loader)->max_points ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (_count)) <= (int)(_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) #define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h index c6ddc42ea9b..2010ca90d7e 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h @@ -333,8 +333,8 @@ FT_BEGIN_HEADER FT_ULong size, FT_Error *p_error ); -#define FT_MEM_STRDUP( dst, str ) \ - (dst) = ft_mem_strdup( memory, (const char*)(str), &error ) +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) #define FT_STRDUP( dst, str ) \ FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h index 15b68d63f15..574cf582967 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,6 +35,7 @@ #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -160,6 +161,31 @@ FT_BEGIN_HEADER (*FT_CMap_CharNextFunc)( FT_CMap cmap, FT_UInt32 *achar_code ); + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + typedef struct FT_CMap_ClassRec_ { @@ -169,8 +195,56 @@ FT_BEGIN_HEADER FT_CMap_CharIndexFunc char_index; FT_CMap_CharNextFunc char_next; + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + } FT_CMap_ClassRec; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_CMAP_CLASS(class_) \ + FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_CMap_ClassRec class_ = \ + { \ + size_, init_, done_, char_index_, char_next_, char_var_index_, \ + char_var_default_, variant_list_, charvariant_list_, variantchar_list_ \ + }; +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_CMAP_CLASS(class_) \ + void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec* clazz); + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_CMap_ClassRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->size = size_; \ + clazz->init = init_; \ + clazz->done = done_; \ + clazz->char_index = char_index_; \ + clazz->char_next = char_next_; \ + clazz->char_var_index = char_var_index_; \ + clazz->char_var_default = char_var_default_; \ + clazz->variant_list = variant_list_; \ + clazz->charvariant_list = charvariant_list_; \ + clazz->variantchar_list = variantchar_list_; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* create a new charmap and add it to charmap->face */ FT_BASE( FT_Error ) @@ -306,7 +380,28 @@ FT_BEGIN_HEADER } FT_GlyphSlot_InternalRec; +#if 0 + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -710,6 +805,10 @@ FT_BEGIN_HEADER /* */ /* debug_hooks :: XXX */ /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globallly. */ + /* */ + typedef struct FT_LibraryRec_ { FT_Memory memory; /* library's memory manager */ @@ -740,6 +839,10 @@ FT_BEGIN_HEADER FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + } FT_LibraryRec; @@ -811,6 +914,484 @@ FT_BEGIN_HEADER FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; #endif + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftimage.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Outline_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static FT_Error \ + Init_Class_##class_( FT_Outline_Funcs* clazz ) \ + { \ + clazz->move_to = move_to_; \ + clazz->line_to = line_to_; \ + clazz->conic_to = conic_to_; \ + clazz->cubic_to = cubic_to_; \ + clazz->shift = shift_; \ + clazz->delta = delta_; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Raster_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, raster_done_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, raster_render_, raster_done_) \ + void \ + FT_Init_Class_##class_( FT_Raster_Funcs* clazz ) \ + { \ + clazz->glyph_format = glyph_format_; \ + clazz->raster_new = raster_new_; \ + clazz->raster_reset = raster_reset_; \ + clazz->raster_set_mode = raster_set_mode_; \ + clazz->raster_render = raster_render_; \ + clazz->raster_done = raster_done_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftrender.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_GLYPH */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Glyph_Class struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Glyph_Class class_ = \ + { \ + size_, format_, init_, done_, copy_, transform_, bbox_, prepare_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + void \ + FT_Init_Class_##class_( FT_Glyph_Class* clazz ) \ + { \ + clazz->glyph_size = size_; \ + clazz->glyph_format = format_; \ + clazz->glyph_init = init_; \ + clazz->glyph_done = done_; \ + clazz->glyph_copy = copy_; \ + clazz->glyph_transform = transform_; \ + clazz->glyph_bbox = bbox_; \ + clazz->glyph_prepare = prepare_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_RENDERER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_RENDERER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Renderer_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_RENDERER(class_) \ + FT_EXPORT_VAR( const FT_Renderer_Class ) class_; + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Renderer_Class class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + glyph_format_, \ + \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + \ + raster_class_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_RENDERER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( rclazz ) \ + FT_FREE( rclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Renderer_Class* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + \ + clazz->glyph_format = glyph_format_; \ + \ + clazz->render_glyph = render_glyph_; \ + clazz->transform_glyph = transform_glyph_; \ + clazz->get_glyph_cbox = get_glyph_cbox_; \ + clazz->set_mode = set_mode_; \ + \ + clazz->raster_class = raster_class_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftmodapi.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Creator */ + /* */ + /* <Description> */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destroyer */ + /* */ + /* <Description> */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_MODULE */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ + /* <Macro> */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct inside */ + /* another stract that contains it or in a function that initializes */ + /* that containing stract */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_MODULE(class_) \ + FT_CALLBACK_TABLE \ + const FT_Module_Class class_; \ + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }, + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Module_Class class_ = \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_MODULE(class_) \ + FT_Error FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ); \ + void FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ); + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + clazz->root.module_flags = flags_; \ + clazz->root.module_size = size_; \ + clazz->root.module_name = name_; \ + clazz->root.module_version = version_; \ + clazz->root.module_requires = requires_; \ + \ + clazz->root.module_interface = interface_; \ + \ + clazz->root.module_init = init_; \ + clazz->root.module_done = done_; \ + clazz->root.get_interface = get_interface_; + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Module_Class* clazz; \ + FT_Error error; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + clazz->module_flags = flags_; \ + clazz->module_size = size_; \ + clazz->module_name = name_; \ + clazz->module_version = version_; \ + clazz->module_requires = requires_; \ + \ + clazz->module_interface = interface_; \ + \ + clazz->module_init = init_; \ + clazz->module_done = done_; \ + clazz->get_interface = get_interface_; \ + \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftpic.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftpic.h new file mode 100644 index 00000000000..1b31957d702 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftpic.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTPIC_H__ +#define __FTPIC_H__ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + /* pic containers for modules */ + void* autofit; + void* cff; + void* pshinter; + void* psnames; + void* raster; + void* sfnt; + void* smooth; + void* truetype; + } FT_PIC_Container; + + /* Initialize the various function tables, structs, etc. stored in the container. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h index 94402bcfa73..aa573c87054 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004, 2006, 2007 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,7 +34,19 @@ FT_BEGIN_HEADER /* Number of guessing rules supported in `FT_Raccess_Guess'. */ /* Don't forget to increment the number if you add a new guessing rule. */ -#define FT_RACCESS_N_RULES 8 +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_ULong offset; + + } FT_RFork_Ref; /*************************************************************************/ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftserv.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftserv.h index 45d2fa91834..569b9f7e0e8 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/ftserv.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/ftserv.h @@ -163,6 +163,298 @@ FT_BEGIN_HEADER typedef const FT_ServiceDescRec* FT_ServiceDesc; + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */ + /* */ + /* <Description> */ + /* Used to initialize an array of FT_ServiceDescRec structs. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated array is returned. */ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* */ + /* These functions should be manyally called from the pic_init and */ + /* pic_free functions of your module (see FT_DEFINE_MODULE) */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {serv_id_6, serv_data_6}, \ + {NULL, NULL} \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = NULL; \ + clazz[2].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = NULL; \ + clazz[3].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = NULL; \ + clazz[4].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4, \ + serv_data_4, serv_id_5, serv_data_5) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = NULL; \ + clazz[5].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = NULL; \ + clazz[6].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* * Parse a list of FT_ServiceDescRec descriptors and look for @@ -301,6 +593,7 @@ FT_BEGIN_HEADER */ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/fttrace.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/fttrace.h index 81916fc6aea..e9b383a5881 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/fttrace.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,16 +31,19 @@ FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ @@ -48,6 +51,7 @@ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ /* TrueType driver components */ FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ @@ -58,6 +62,7 @@ FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) FT_TRACE_DEF( t1driver ) FT_TRACE_DEF( t1gload ) FT_TRACE_DEF( t1hint ) @@ -114,6 +119,7 @@ FT_TRACE_DEF( otvgdef ) FT_TRACE_DEF( otvgpos ) FT_TRACE_DEF( otvgsub ) FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) /* TrueTypeGX/AAT validation components */ FT_TRACE_DEF( gxvmodule ) diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/internal.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/internal.h index 27d5dc585d3..f500a651c27 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/internal.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/internal.h @@ -25,6 +25,7 @@ #define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> #define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/psaux.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/psaux.h index 4baf7a094a8..a96e0dfa865 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/psaux.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -197,6 +197,7 @@ FT_BEGIN_HEADER { T1_FIELD_LOCATION_CID_INFO, T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_EXTRA, T1_FIELD_LOCATION_FONT_INFO, T1_FIELD_LOCATION_PRIVATE, T1_FIELD_LOCATION_BBOX, @@ -227,7 +228,11 @@ FT_BEGIN_HEADER FT_UInt array_max; /* maximal number of elements for */ /* array */ FT_UInt count_offset; /* offset of element count for */ - /* arrays */ + /* arrays; must not be zero if in */ + /* use -- in other words, a */ + /* `num_FOO' element must not */ + /* start the used structure if we */ + /* parse a `FOO' array */ FT_UInt dict; /* where we expect it */ } T1_FieldRec; @@ -355,7 +360,7 @@ FT_BEGIN_HEADER FT_Error (*to_bytes)( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); @@ -528,13 +533,6 @@ FT_BEGIN_HEADER /* */ /* max_contours :: Maximal number of contours in builder outline. */ /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scaling value (FUnits to */ - /* sub-pixels). */ - /* */ - /* scale_y :: The vertical scaling value (FUnits to sub-pixels). */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -567,11 +565,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - FT_Pos pos_x; FT_Pos pos_y; @@ -582,7 +575,6 @@ FT_BEGIN_HEADER T1_ParseState parse_state; FT_Bool load_points; FT_Bool no_recurse; - FT_Bool shift; FT_Bool metrics_only; @@ -697,9 +689,11 @@ FT_BEGIN_HEADER T1_Decoder_Callback parse_callback; T1_Decoder_FuncsRec funcs; - FT_Int* buildchar; + FT_Long* buildchar; FT_UInt len_buildchar; + FT_Bool seac; + } T1_DecoderRec; @@ -761,7 +755,7 @@ FT_BEGIN_HEADER FT_Int (*get_index)( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ); void* user_data; diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/pshints.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/pshints.h index 48452c0cf3e..0c357651be4 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/pshints.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -157,7 +157,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). * * coords :: - * Array of 2 integers, used as (position,length) stem descriptor. + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -175,9 +176,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStemFunc)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -197,8 +198,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems, 1 for vertical ones. * * coords :: - * An array of 6 integers, holding 3 (position,length) pairs for the - * counter-controlled stems. + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -209,9 +210,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStem3Func)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -446,7 +447,7 @@ FT_BEGIN_HEADER * The number of stems. * * coords :: - * An array of `count' (position,length) pairs. + * An array of `count' (position,length) pairs in 16.16 format. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -678,6 +679,30 @@ FT_BEGIN_HEADER typedef PSHinter_Interface* PSHinter_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + static const PSHinter_Interface class_ = \ + { \ + get_globals_funcs_, get_t1_funcs_, get_t2_funcs_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + PSHinter_Interface* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_globals_funcs = get_globals_funcs_; \ + clazz->get_t1_funcs = get_t1_funcs_; \ + clazz->get_t2_funcs = get_t2_funcs_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h index 0f7fc6115d6..9264239146b 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h @@ -45,6 +45,26 @@ FT_BEGIN_HEADER FT_BDF_GetPropertyFunc get_property; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + void \ + FT_Init_Class_##class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h new file mode 100644 index 00000000000..9b874b5e725 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVCID_H__ +#define __SVCID_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid ); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_CIDRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVCID_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h index e5e56b253c1..d66a41d5ae3 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h @@ -51,6 +51,28 @@ FT_BEGIN_HEADER FT_GlyphDict_NameIndexFunc name_index; /* optional */ }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h index 8a99ec4b1a7..66e1da22f1a 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h @@ -68,6 +68,31 @@ FT_BEGIN_HEADER FT_Set_Var_Design_Func set_var_design; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + void \ + FT_Init_Class_##class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h index 282da68d13e..106c54f8530 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h @@ -46,6 +46,27 @@ FT_BEGIN_HEADER FT_PsName_GetFunc get_ps_font_name; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h index c4e25ed635f..961030cc391 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -98,7 +98,7 @@ FT_BEGIN_HEADER (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, FT_UInt32 unicode ); - typedef FT_ULong + typedef FT_UInt32 (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, FT_UInt32 *unicode ); @@ -117,6 +117,41 @@ FT_BEGIN_HEADER const unsigned short* adobe_expert_encoding; }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h index 63f5db9c19a..91ba91e5dc0 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003, 2004, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,6 +33,10 @@ FT_BEGIN_HEADER (*PS_GetFontInfoFunc)( FT_Face face, PS_FontInfoRec* afont_info ); + typedef FT_Error + (*PS_GetFontExtraFunc)( FT_Face face, + PS_FontExtraRec* afont_extra ); + typedef FT_Int (*PS_HasGlyphNamesFunc)( FT_Face face ); @@ -44,10 +48,38 @@ FT_BEGIN_HEADER FT_DEFINE_SERVICE( PsInfo ) { PS_GetFontInfoFunc ps_get_font_info; + PS_GetFontExtraFunc ps_get_font_extra; PS_HasGlyphNamesFunc ps_has_glyph_names; PS_GetFontPrivateFunc ps_get_font_private; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h index b4a85d97ec7..30bb1620fe1 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h @@ -58,6 +58,7 @@ FT_BEGIN_HEADER (*FT_SFNT_TableInfoFunc)( FT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ); @@ -68,6 +69,27 @@ FT_BEGIN_HEADER FT_SFNT_TableInfoFunc table_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + void \ + FT_Init_Class_##class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h index 1e02d15506d..8af00351d9d 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h @@ -1,13 +1,13 @@ /***************************************************************************/ /* */ -/* svsttcmap.h */ +/* svttcmap.h */ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ /* Copyright 2003 by */ /* Masatake YAMATO, Redhat K.K. */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,6 +49,13 @@ FT_BEGIN_HEADER /* The language ID used in Mac fonts. Definitions of values are in */ /* freetype/ttnameid.h. */ /* */ + /* format :: */ + /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* encoding table), 2~(high-byte mapping through table), 4~(segment */ + /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ + /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ + /* coverage), and 14 (Unicode Variation Sequences). */ + /* */ typedef struct TT_CMapInfo_ { FT_ULong language; @@ -67,6 +74,27 @@ FT_BEGIN_HEADER TT_CMap_Info_GetFunc get_cmap_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h index e57d484b7e2..ab2dc9a9fe9 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h @@ -37,6 +37,25 @@ FT_BEGIN_HEADER TT_Glyf_GetLocationFunc get_location; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + void \ + FT_Init_Class_##class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/sfnt.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/sfnt.h index 7e8f6847c98..6326debd00c 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/sfnt.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/sfnt.h @@ -753,6 +753,141 @@ FT_BEGIN_HEADER /* transitional */ typedef SFNT_Interface* SFNT_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \ + a, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) +#endif +#define FT_INTERNAL(a) \ + a, + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + static const SFNT_Interface class_ = \ + { \ + FT_INTERNAL(goto_table_) \ + FT_INTERNAL(init_face_) \ + FT_INTERNAL(load_face_) \ + FT_INTERNAL(done_face_) \ + FT_INTERNAL(get_interface_) \ + FT_INTERNAL(load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \ + FT_INTERNAL(load_head_) \ + FT_INTERNAL(load_hhea_) \ + FT_INTERNAL(load_cmap_) \ + FT_INTERNAL(load_maxp_) \ + FT_INTERNAL(load_os2_) \ + FT_INTERNAL(load_post_) \ + FT_INTERNAL(load_name_) \ + FT_INTERNAL(free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \ + FT_INTERNAL(load_kern_) \ + FT_INTERNAL(load_gasp_) \ + FT_INTERNAL(load_pclt_) \ + FT_INTERNAL(load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \ + FT_INTERNAL(get_psname_) \ + FT_INTERNAL(free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \ + FT_INTERNAL(get_kerning_) \ + FT_INTERNAL(load_font_dir_) \ + FT_INTERNAL(load_hmtx_) \ + FT_INTERNAL(load_eblc_) \ + FT_INTERNAL(free_eblc_) \ + FT_INTERNAL(set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics_) \ + FT_INTERNAL(get_metrics_) \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \ + clazz->a = a_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) +#endif +#define FT_INTERNAL(a, a_) \ + clazz->a = a_; + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, SFNT_Interface* clazz ) \ + { \ + FT_UNUSED(library); \ + FT_INTERNAL(goto_table,goto_table_) \ + FT_INTERNAL(init_face,init_face_) \ + FT_INTERNAL(load_face,load_face_) \ + FT_INTERNAL(done_face,done_face_) \ + FT_INTERNAL(get_interface,get_interface_) \ + FT_INTERNAL(load_any,load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \ + FT_INTERNAL(load_head,load_head_) \ + FT_INTERNAL(load_hhea,load_hhea_) \ + FT_INTERNAL(load_cmap,load_cmap_) \ + FT_INTERNAL(load_maxp,load_maxp_) \ + FT_INTERNAL(load_os2,load_os2_) \ + FT_INTERNAL(load_post,load_post_) \ + FT_INTERNAL(load_name,load_name_) \ + FT_INTERNAL(free_name,free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \ + FT_INTERNAL(load_kern,load_kern_) \ + FT_INTERNAL(load_gasp,load_gasp_) \ + FT_INTERNAL(load_pclt,load_pclt_) \ + FT_INTERNAL(load_bhed,load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image,load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \ + FT_INTERNAL(get_psname,get_psname_) \ + FT_INTERNAL(free_psnames,free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \ + FT_INTERNAL(get_kerning,get_kerning_) \ + FT_INTERNAL(load_font_dir,load_font_dir_) \ + FT_INTERNAL(load_hmtx,load_hmtx_) \ + FT_INTERNAL(load_eblc,load_eblc_) \ + FT_INTERNAL(free_eblc,free_eblc_) \ + FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \ + FT_INTERNAL(get_metrics,get_metrics_) \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/t1types.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/t1types.h index 047c6d59df0..5f730637b5b 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/t1types.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,9 @@ FT_BEGIN_HEADER /* */ /* code_first :: The lowest valid character code in the encoding. */ /* */ - /* code_last :: The highest valid character code in the encoding. */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ /* */ /* char_index :: An array of corresponding glyph indices. */ /* */ @@ -87,11 +89,24 @@ FT_BEGIN_HEADER } T1_EncodingType; + /* used to hold extra data of PS_FontInfoRec that + * cannot be stored in the publicly defined structure. + * + * Note these can't be blended with multiple-masters. + */ + typedef struct PS_FontExtraRec_ + { + FT_UShort fs_type; + + } PS_FontExtraRec; + + typedef struct T1_FontRec_ { - PS_FontInfoRec font_info; /* font info dictionary */ - PS_PrivateRec private_dict; /* private dictionary */ - FT_String* font_name; /* top-level dictionary */ + PS_FontInfoRec font_info; /* font info dictionary */ + PS_FontExtraRec font_extra; /* font info extra fields */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ T1_EncodingType encoding_type; T1_EncodingRec encoding; @@ -217,7 +232,7 @@ FT_BEGIN_HEADER /* undocumented, optional: has the same meaning as len_buildchar */ /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ FT_UInt len_buildchar; - FT_Int* buildchar; + FT_Long* buildchar; /* since version 2.1 - interface to PostScript hinter */ const void* pshinter; @@ -231,7 +246,10 @@ FT_BEGIN_HEADER void* psnames; void* psaux; CID_FaceInfoRec cid; + PS_FontExtraRec font_extra; +#if 0 void* afm_data; +#endif CID_Subrs subrs; /* since version 2.1 - interface to PostScript hinter */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/internal/tttypes.h b/reactos/lib/3rdparty/freetype/include/freetype/internal/tttypes.h index dfbb6a1ea0b..acbb863b0f1 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/internal/tttypes.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -586,7 +586,7 @@ FT_BEGIN_HEADER /* table_offset :: The offset of the index table in the `EBLC' */ /* table. Only used during strike loading. */ /* */ - typedef struct TT_SBit_RangeRec + typedef struct TT_SBit_RangeRec_ { FT_UShort first_glyph; FT_UShort last_glyph; @@ -902,7 +902,7 @@ FT_BEGIN_HEADER FT_Byte* table; FT_Byte* table_end; FT_Byte* strings; - FT_UInt32 strings_size; + FT_ULong strings_size; FT_UInt num_strikes; FT_Bool loaded; @@ -1401,7 +1401,7 @@ FT_BEGIN_HEADER FT_Byte* vert_metrics; FT_ULong vert_metrics_size; - FT_UInt num_locations; + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ FT_Byte* glyph_locations; FT_Byte* hdmx_table; diff --git a/reactos/lib/3rdparty/freetype/include/freetype/t1tables.h b/reactos/lib/3rdparty/freetype/include/freetype/t1tables.h index 250629d2522..5e2a3934cee 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/t1tables.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,7 @@ FT_BEGIN_HEADER /* Type 1 Tables */ /* */ /* <Abstract> */ - /* Type 1 (PostScript) specific font tables. */ + /* Type~1 (PostScript) specific font tables. */ /* */ /* <Description> */ /* This section contains the definition of Type 1-specific tables, */ @@ -62,11 +62,11 @@ FT_BEGIN_HEADER /* PS_FontInfoRec */ /* */ /* <Description> */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ /* FontInfo dictionary. */ /* */ - typedef struct PS_FontInfoRec + typedef struct PS_FontInfoRec_ { FT_String* version; FT_String* notice; @@ -78,7 +78,18 @@ FT_BEGIN_HEADER FT_Short underline_position; FT_UShort underline_thickness; - } PS_FontInfoRec, *PS_FontInfo; + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; /*************************************************************************/ @@ -100,9 +111,9 @@ FT_BEGIN_HEADER /* PS_PrivateRec */ /* */ /* <Description> */ - /* A structure used to model a Type1/Type2 private dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own Private */ - /* dictionary. */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ /* */ typedef struct PS_PrivateRec_ { @@ -142,7 +153,18 @@ FT_BEGIN_HEADER FT_Short min_feature[2]; - } PS_PrivateRec, *PS_Private; + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; /*************************************************************************/ @@ -168,7 +190,7 @@ FT_BEGIN_HEADER /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ - typedef enum + typedef enum T1_Blend_Flags_ { /*# required fields in a FontInfo blend dictionary */ T1_BLEND_UNDERLINE_POSITION = 0, @@ -272,6 +294,14 @@ FT_BEGIN_HEADER typedef PS_BlendRec T1_Blend; + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ typedef struct CID_FaceDictRec_ { PS_PrivateRec private_dict; @@ -290,7 +320,20 @@ FT_BEGIN_HEADER FT_ULong subrmap_offset; FT_Int sd_bytes; - } CID_FaceDictRec, *CID_FaceDict; + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + /* */ /* backwards-compatible definition */ @@ -332,7 +375,18 @@ FT_BEGIN_HEADER FT_ULong data_offset; - } CID_FaceInfoRec, *CID_FaceInfo; + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; /*************************************************************************/ @@ -347,99 +401,99 @@ FT_BEGIN_HEADER /* */ typedef CID_FaceInfoRec CID_Info; - /* */ - - /************************************************************************ - * - * @function: - * FT_Has_PS_Glyph_Names - * - * @description: - * Return true if a given face provides reliable Postscript glyph - * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, - * except that certain fonts (mostly TrueType) contain incorrect - * glyph name tables. - * - * When this function returns true, the caller is sure that the glyph - * names returned by @FT_Get_Glyph_Name are reliable. - * - * @input: - * face :: - * face handle - * - * @return: - * Boolean. True if glyph names are reliable. - */ + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ FT_EXPORT( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ); - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Info - * - * @description: - * Retrieve the @PS_FontInfoRec structure corresponding to a given - * Postscript font. - * - * @input: - * face :: - * Postscript face handle. - * - * @output: - * afont_info :: - * Output font info structure pointer. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not Postscript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. - */ + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Info( FT_Face face, - PS_FontInfoRec *afont_info ); + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Private - * - * @description: - * Retrieve the @PS_PrivateRec structure corresponding to a given - * Postscript font. - * - * @input: - * face :: - * Postscript face handle. - * - * @output: - * afont_private :: - * Output private dictionary structure pointer. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not Postscript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. - */ + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Private( FT_Face face, - PS_PrivateRec *afont_private ); - - /* */ + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ttnameid.h b/reactos/lib/3rdparty/freetype/include/freetype/ttnameid.h index b9acbdad119..cbeac78db1e 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ttnameid.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,13 @@ FT_BEGIN_HEADER + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + /*************************************************************************/ /* */ /* Possible values for the `platform' identifier code in the name */ @@ -108,13 +115,18 @@ FT_BEGIN_HEADER * * TT_APPLE_ID_UNICODE_32 :: * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. */ -#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ -#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ /*********************************************************************** @@ -290,6 +302,8 @@ FT_BEGIN_HEADER * Adobe expert encoding. * TT_ADOBE_ID_CUSTOM :: * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. */ #define TT_ADOBE_ID_STANDARD 0 @@ -821,16 +835,18 @@ FT_BEGIN_HEADER /* This is new in OpenType 1.3 */ #define TT_NAME_ID_CID_FINDFONT_NAME 20 + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + /*************************************************************************/ /* */ /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ /* */ - /* Updated 02-Jul-2000. */ + /* Updated 08-Nov-2008. */ /* */ - /* General Scripts Area */ - /* Bit 0 Basic Latin */ #define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ /* Bit 1 C1 Controls and Latin-1 Supplement */ @@ -839,27 +855,44 @@ FT_BEGIN_HEADER #define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ /* Bit 3 Latin Extended-B */ #define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ - /* Bit 4 IPA Extensions */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ #define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ #define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ - /* Bit 6 Combining Diacritical Marks */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ #define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ /* Bit 7 Greek and Coptic */ #define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ - /* Bit 8 is reserved (was: Greek Symbols and Coptic) */ - /* Bit 9 Cyrillic + */ - /* Cyrillic Supplementary */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ #define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ /* Bit 10 Armenian */ #define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ /* Bit 11 Hebrew */ #define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ - /* Bit 12 is reserved (was: Hebrew Extended) */ - /* Bit 13 Arabic */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ #define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ - /* Bit 14 is reserved (was: Arabic Extended) */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ /* Bit 15 Devanagari */ #define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ /* Bit 16 Bengali */ @@ -882,20 +915,26 @@ FT_BEGIN_HEADER #define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ /* Bit 25 Lao */ #define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ - /* Bit 26 Georgian */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ #define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ - /* Bit 27 is reserved (was Georgian Extended) */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ /* Bit 28 Hangul Jamo */ #define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ #define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ /* Bit 30 Greek Extended */ #define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ - - /* Symbols Area */ - - /* Bit 31 General Punctuation */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ #define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ /* Bit 32 Superscripts And Subscripts */ #define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ /* Bit 33 Currency Symbols */ @@ -906,16 +945,18 @@ FT_BEGIN_HEADER #define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ /* Bit 36 Number Forms */ #define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ - /* Bit 37 Arrows + */ - /* Supplemental Arrows-A + */ - /* Supplemental Arrows-B */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ #define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ /* U+27F0-U+27FF */ /* U+2900-U+297F */ - /* Bit 38 Mathematical Operators + */ - /* Supplemental Mathematical Operators + */ - /* Miscellaneous Mathematical Symbols-A + */ - /* Miscellaneous Mathematical Symbols-B */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ #define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ /* U+2A00-U+2AFF */ /* U+27C0-U+27EF */ @@ -938,60 +979,53 @@ FT_BEGIN_HEADER #define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ /* Bit 47 Dingbats */ #define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ - - /* CJK Phonetics and Symbols Area */ - /* Bit 48 CJK Symbols and Punctuation */ #define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ /* Bit 49 Hiragana */ #define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ - /* Bit 50 Katakana + */ - /* Katakana Phonetic Extensions */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ #define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ /* U+31F0-U+31FF */ - /* Bit 51 Bopomofo + */ - /* Bopomofo Extended */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ #define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ /* U+31A0-U+31BF */ /* Bit 52 Hangul Compatibility Jamo */ #define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ - /* Bit 53 Kanbun */ -#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ -#define TT_UCR_KANBUN TT_UCR_CJK_MISC + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA /* Bit 54 Enclosed CJK Letters and Months */ #define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ /* Bit 55 CJK Compatibility */ #define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ - - /* Hangul Syllables Area */ - - /* Bit 56 Hangul */ + /* Bit 56 Hangul Syllables */ #define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ - - /* Surrogates Area */ - - /* Bit 57 High Surrogates + */ - /* High Private Use Surrogates + */ - /* Low Surrogates */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ #define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ - /* According to OpenType specs v.1.3+, setting bit 57 implies that there */ - /* is at least one codepoint beyond the Basic Multilingual Plane that is */ - /* supported by this font. So it really means: >= U+10000 */ - - /* Bit 58 is reserved for Unicode SubRanges */ - - /* CJK Ideographs Area */ - - /* Bit 59 CJK Unified Ideographs + */ - /* CJK Radicals Supplement + */ - /* Kangxi Radicals + */ - /* Ideographic Description Characters + */ - /* CJK Unified Ideographs Extension A */ - /* CJK Unified Ideographs Extension A + */ - /* CJK Unified Ideographs Extension B + */ - /* Kanbun */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ #define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ /* U+2E80-U+2EFF */ /* U+2F00-U+2FDF */ @@ -999,17 +1033,13 @@ FT_BEGIN_HEADER /* U+3400-U+4DB5 */ /*U+20000-U+2A6DF*/ /* U+3190-U+319F */ - - /* Private Use Area */ - /* Bit 60 Private Use */ #define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ - - /* Compatibility Area and Specials */ - - /* Bit 61 CJK Compatibility Ideographs + */ - /* CJK Compatibility Ideographs Supplement */ -#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ /*U+2F800-U+2FA1F*/ /* Bit 62 Alphabetic Presentation Forms */ #define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ @@ -1017,8 +1047,10 @@ FT_BEGIN_HEADER #define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ /* Bit 64 Combining Half Marks */ #define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ - /* Bit 65 CJK Compatibility Forms */ -#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE30-U+FE4F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ /* Bit 66 Small Form Variants */ #define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ /* Bit 67 Arabic Presentation Forms-B */ @@ -1037,8 +1069,12 @@ FT_BEGIN_HEADER #define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ /* Bit 74 Myanmar */ #define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ - /* Bit 75 Ethiopic */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ #define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ /* Bit 76 Cherokee */ #define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ /* Bit 77 Unified Canadian Aboriginal Syllabics */ @@ -1047,20 +1083,22 @@ FT_BEGIN_HEADER #define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ /* Bit 79 Runic */ #define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ - /* Bit 80 Khmer */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ #define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ /* Bit 81 Mongolian */ #define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ /* Bit 82 Braille Patterns */ #define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ - /* Bit 83 Yi Syllables + */ - /* Yi Radicals */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ #define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ /* U+A490-U+A4CF */ - /* Bit 84 Tagalog + */ - /* Hanunoo + */ - /* Buhid + */ - /* Tagbanwa */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ #define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ /* U+1720-U+173F */ /* U+1740-U+175F */ @@ -1071,20 +1109,97 @@ FT_BEGIN_HEADER #define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ /* Bit 87 Deseret */ #define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ - /* Bit 88 Byzantine Musical Symbols + */ - /* Musical Symbols */ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ #define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ /* Bit 89 Mathematical Alphanumeric Symbols */ #define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ - /* Bit 90 Private Use (plane 15) + */ - /* Private Use (plane 16) */ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ #define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ /*U+100000-U+10FFFD*/ - /* Bit 91 Variation Selectors */ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ #define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ /* Bit 92 Tags */ #define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ /*************************************************************************/ @@ -1103,7 +1218,7 @@ FT_BEGIN_HEADER /* */ /* Here some alias #defines in order to be clearer. */ /* */ - /* These are not always #defined to stay within the 31 character limit */ + /* These are not always #defined to stay within the 31~character limit */ /* which some compilers have. */ /* */ /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/tttables.h b/reactos/lib/3rdparty/freetype/include/freetype/tttables.h index 43eca2e2580..c12b1726896 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/tttables.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -156,9 +156,9 @@ FT_BEGIN_HEADER /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ - /* Reserved :: 10 reserved bytes. */ + /* Reserved :: 8~reserved bytes. */ /* */ - /* metric_Data_Format :: Always 0. */ + /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ /* table -- this value can be smaller than */ @@ -281,9 +281,9 @@ FT_BEGIN_HEADER /* This value is `reserved' in vmtx */ /* version 1.0. */ /* */ - /* Reserved :: 8 reserved bytes. */ + /* Reserved :: 8~reserved bytes. */ /* */ - /* metric_Data_Format :: Always 0. */ + /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_HMetrics :: Number of VMetrics entries in the */ /* `vmtx' table -- this value can be */ @@ -406,9 +406,9 @@ FT_BEGIN_HEADER /* TT_Postscript */ /* */ /* <Description> */ - /* A structure used to model a TrueType Postscript table. All fields */ + /* A structure used to model a TrueType PostScript table. All fields */ /* comply to the TrueType specification. This structure does not */ - /* reference the Postscript glyph names, which can be nevertheless */ + /* reference the PostScript glyph names, which can be nevertheless */ /* accessed with the `ttpost' module. */ /* */ typedef struct TT_Postscript_ @@ -555,7 +555,7 @@ FT_BEGIN_HEADER /* An enumeration used to specify the index of an SFNT table. */ /* Used in the @FT_Get_Sfnt_Table API function. */ /* */ - typedef enum + typedef enum FT_Sfnt_Tag_ { ft_sfnt_head = 0, ft_sfnt_maxp = 1, @@ -578,7 +578,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Table */ /* */ /* <Description> */ - /* Returns a pointer to a given SFNT table within a face. */ + /* Return a pointer to a given SFNT table within a face. */ /* */ /* <Input> */ /* face :: A handle to the source. */ @@ -586,7 +586,7 @@ FT_BEGIN_HEADER /* tag :: The index of the SFNT table. */ /* */ /* <Return> */ - /* A type-less pointer to the table. This will be 0 in case of */ + /* A type-less pointer to the table. This will be~0 in case of */ /* error, or if the corresponding table was not found *OR* loaded */ /* from the file. */ /* */ @@ -608,14 +608,14 @@ FT_BEGIN_HEADER * FT_Load_Sfnt_Table * * @description: - * Loads any font table into client memory. + * Load any font table into client memory. * * @input: * face :: * A handle to the source face. * * tag :: - * The four-byte tag of the table to load. Use the value 0 if you want + * The four-byte tag of the table to load. Use the value~0 if you want * to access the whole font file. Otherwise, you can use one of the * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new * one with @FT_MAKE_TAG. @@ -633,18 +633,18 @@ FT_BEGIN_HEADER * If the `length' parameter is NULL, then try to load the whole table. * Return an error code if it fails. * - * Else, if `*length' is 0, exit immediately while returning the + * Else, if `*length' is~0, exit immediately while returning the * table's (or file) full size in it. * * Else the number of bytes to read from the table or file, from the * starting offset. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * If you need to determine the table's length you should first call this - * function with `*length' set to 0, as in the following example: + * function with `*length' set to~0, as in the following example: * * { * FT_ULong length = 0; @@ -674,7 +674,7 @@ FT_BEGIN_HEADER * FT_Sfnt_Table_Info * * @description: - * Returns information on an SFNT table. + * Return information on an SFNT table. * * @input: * face :: @@ -692,10 +692,10 @@ FT_BEGIN_HEADER * The length of the SFNT table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: - * SFNT tables with length zero are treated as missing by Windows. + * SFNT tables with length zero are treated as missing. * */ FT_EXPORT( FT_Error ) @@ -720,7 +720,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* The language ID of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, just return 0 as the default value. */ + /* TrueType/sfnt face, just return~0 as the default value. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_CMap_Language_ID( FT_CharMap charmap ); diff --git a/reactos/lib/3rdparty/freetype/include/freetype/tttags.h b/reactos/lib/3rdparty/freetype/include/freetype/tttags.h index e10244ca7c9..307ce4b6374 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/tttags.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2001, 2004, 2005 by */ +/* Copyright 1996-2001, 2004, 2005, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,6 +41,7 @@ FT_BEGIN_HEADER #define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) #define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) #define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) @@ -49,6 +50,7 @@ FT_BEGIN_HEADER #define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) #define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) #define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) #define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) #define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) #define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) @@ -67,6 +69,8 @@ FT_BEGIN_HEADER #define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) #define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) #define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) #define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) #define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) #define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) @@ -78,14 +82,18 @@ FT_BEGIN_HEADER #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) #define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) #define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) #define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) #define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) #define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) diff --git a/reactos/lib/3rdparty/freetype/modules.cfg b/reactos/lib/3rdparty/freetype/modules.cfg index 6d8a95eaca6..4047d7f09cf 100644 --- a/reactos/lib/3rdparty/freetype/modules.cfg +++ b/reactos/lib/3rdparty/freetype/modules.cfg @@ -1,6 +1,6 @@ # modules.cfg # -# Copyright 2005, 2006, 2007 by +# Copyright 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -106,7 +106,7 @@ RASTER_MODULES += smooth # FreeType's cache sub-system (quite stable but still in beta -- this means # that its public API is subject to change if necessary). See -# include/freetype/ftcache.h. +# include/freetype/ftcache.h. Needs ftglyph.c. AUX_MODULES += cache # TrueType GX/AAT table validation. Needs ftgxval.c below. @@ -158,37 +158,62 @@ BASE_EXTENSIONS += ftbdf.c # See include/freetype/ftbitmap.h for the API. BASE_EXTENSIONS += ftbitmap.c -# Convenience functions to handle glyphs. +# Access CID font information. +# +# See include/freetype/ftcid.h for the API. +BASE_EXTENSIONS += ftcid.c + +# Access FSType information. Needs fttype1.c. +# +# See include/freetype/freetype.h for the API. +BASE_EXTENSIONS += ftfstype.c + +# Support for GASP table queries. +# +# See include/freetype/ftgasp.h for the API. +BASE_EXTENSIONS += ftgasp.c + +# Convenience functions to handle glyphs. Needs ftbitmap.c. # # See include/freetype/ftglyph.h for the API. BASE_EXTENSIONS += ftglyph.c -# Interface for gxvalid module (which is required). +# Interface for gxvalid module. # # See include/freetype/ftgxval.h for the API. BASE_EXTENSIONS += ftgxval.c +# Support for LCD color filtering of subpixel bitmaps. +# +# See include/freetype/ftlcdfil.h for the API. +BASE_EXTENSIONS += ftlcdfil.c + # Multiple Master font interface. # # See include/freetype/ftmm.h for the API. BASE_EXTENSIONS += ftmm.c -# Interface for otvalid module (which is required). +# Interface for otvalid module. # # See include/freetype/ftotval.h for the API. BASE_EXTENSIONS += ftotval.c +# Support for FT_Face_CheckTrueTypePatents. +# +# See include/freetype/freetype.h for the API. +BASE_EXTENSIONS += ftpatent.c + # Interface for accessing PFR-specific data. Needs PFR font driver. # # See include/freetype/ftpfr.h for the API. BASE_EXTENSIONS += ftpfr.c -# Path stroker. +# Path stroker. Needs ftglyph.c. # # See include/freetype/ftstroke.h for the API. BASE_EXTENSIONS += ftstroke.c -# Support for synthetic embolding and slanting of fonts. +# Support for synthetic embolding and slanting of fonts. Needs ftbitmap.c. # # See include/freetype/ftsynth.h for the API. BASE_EXTENSIONS += ftsynth.c @@ -210,21 +235,6 @@ BASE_EXTENSIONS += ftwinfnt.c # See include/freetype/ftxf86.h for the API. BASE_EXTENSIONS += ftxf86.c -# Support for LCD color filtering of subpixel bitmaps. -# -# See include/freetype/ftlcdfil.h for the API. -BASE_EXTENSIONS += ftlcdfil.c - -# Support for GASP table queries. -# -# See include/freetype/ftgasp.h for the API. -BASE_EXTENSIONS += ftgasp.c - -# Support for FT_Face_CheckTrueTypePatents. -# -# See include/freetype.h for the API. -BASE_EXTENSIONS += ftpatent.c - #### #### The components `ftsystem.c' (for memory allocation and stream I/O #### management) and `ftdebug.c' (for emitting debug messages to the user) diff --git a/reactos/lib/3rdparty/freetype/src/autofit/Jamfile b/reactos/lib/3rdparty/freetype/src/autofit/Jamfile index acee8bf2cbf..2714765b5b5 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/autofit/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/autofit Jamfile # -# Copyright 2003, 2004, 2005, 2006, 2007 by +# Copyright 2003, 2004, 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -14,14 +14,14 @@ SubDir FT2_TOP src autofit ; { local _sources ; - # define FT2_AUTOFIT2 do enable to experimental latin hinter replacement + # define FT2_AUTOFIT2 to enable experimental latin hinter replacement if $(FT2_AUTOFIT2) { DEFINES += FT_OPTION_AUTOFIT2 ; } if $(FT2_MULTI) { - _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp ; + _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; if $(FT2_AUTOFIT2) { diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afcjk.c b/reactos/lib/3rdparty/freetype/src/autofit/afcjk.c index c7ca266da8a..bab0c42bade 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afcjk.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afcjk.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK script (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /*************************************************************************/ /*************************************************************************/ - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_LatinMetrics metrics, FT_Face face ) { @@ -58,9 +58,12 @@ if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) face->charmap = NULL; - - /* latin's version would suffice */ - af_latin_metrics_init_widths( metrics, face, 0x7530 ); + else + { + /* latin's version would suffice */ + af_latin_metrics_init_widths( metrics, face, 0x7530 ); + af_latin_metrics_check_digits( metrics, face ); + } FT_Set_Charmap( face, oldmap ); @@ -91,7 +94,7 @@ } - static void + FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_LatinMetrics metrics, AF_Scaler scaler ) { @@ -427,7 +430,9 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; @@ -596,7 +601,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1015,7 +1020,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Pos delta = 0; @@ -1251,10 +1256,15 @@ else if ( after >= edge_limit ) af_cjk_align_serif_edge( hints, before, edge ); else - edge->pos = before->pos + - FT_MulDiv( edge->fpos - before->fpos, - after->pos - before->pos, - after->fpos - before->fpos ); + { + if ( after->fpos == before->fpos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->fpos - before->fpos, + after->pos - before->pos, + after->fpos - before->fpos ); + } } } } @@ -1350,7 +1360,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_apply( AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) @@ -1434,35 +1444,33 @@ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { #if 0 - { 0x0100, 0xFFFF }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */ - { 0x2F00, 0x2FDF }, /* Kangxi Radicals */ - { 0x3000, 0x303F }, /* CJK Symbols and Punctuation */ - { 0x3040, 0x309F }, /* Hiragana */ - { 0x30A0, 0x30FF }, /* Katakana */ - { 0x3100, 0x312F }, /* Bopomofo */ - { 0x3130, 0x318F }, /* Hangul Compatibility Jamo */ - { 0x31A0, 0x31BF }, /* Bopomofo Extended */ - { 0x31C0, 0x31EF }, /* CJK Strokes */ - { 0x31F0, 0x31FF }, /* Katakana Phonetic Extensions */ - { 0x3200, 0x32FF }, /* Enclosed CJK Letters and Months */ - { 0x3300, 0x33FF }, /* CJK Compatibility */ - { 0x3400, 0x4DBF }, /* CJK Unified Ideographs Extension A */ - { 0x4DC0, 0x4DFF }, /* Yijing Hexagram Symbols */ - { 0x4E00, 0x9FFF }, /* CJK Unified Ideographs */ - { 0xF900, 0xFAFF }, /* CJK Compatibility Ideographs */ - { 0xFE30, 0xFE4F }, /* CJK Compatibility Forms */ - { 0xFF00, 0xFFEF }, /* Halfwidth and Fullwidth Forms */ - { 0x20000, 0x2A6DF }, /* CJK Unified Ideographs Extension B */ - { 0x2F800, 0x2FA1F }, /* CJK Compatibility Ideographs Supplement */ - { 0, 0 } + AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ + AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1474,19 +1482,17 @@ (AF_Script_InitHintsFunc) af_cjk_hints_init, (AF_Script_ApplyHintsFunc) af_cjk_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_CJK */ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { - { 0, 0 } + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1498,7 +1504,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afcjk.h b/reactos/lib/3rdparty/freetype/src/autofit/afcjk.h index 0de4a5ab728..0b20d4ae356 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afcjk.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afcjk.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK script (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,10 +27,26 @@ FT_BEGIN_HEADER /* the CJK-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_cjk_script_class; + AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class) + FT_LOCAL( FT_Error ) + af_cjk_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ); + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afdummy.c b/reactos/lib/3rdparty/freetype/src/autofit/afdummy.c index ed96e96410d..42b2fcb216d 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afdummy.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afdummy.c @@ -42,9 +42,7 @@ } - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_dummy_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class, AF_SCRIPT_NONE, NULL, @@ -56,7 +54,7 @@ (AF_Script_InitHintsFunc) af_dummy_hints_init, (AF_Script_ApplyHintsFunc) af_dummy_hints_apply - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afdummy.h b/reactos/lib/3rdparty/freetype/src/autofit/afdummy.h index 2a5faf8f851..b69ef437fe9 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afdummy.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afdummy.h @@ -29,8 +29,7 @@ FT_BEGIN_HEADER * be performed. This is the default for non-latin glyphs! */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_dummy_script_class; + AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class) /* */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afglobal.c b/reactos/lib/3rdparty/freetype/src/autofit/afglobal.c index 1875f52befc..ac293619d3d 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afglobal.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include "aflatin.h" #include "afcjk.h" #include "afindic.h" +#include "afpic.h" #include "aferrors.h" @@ -28,6 +29,11 @@ #include "aflatin2.h" #endif +#ifndef FT_CONFIG_OPTION_PIC + +/* when updating this table, don't forget to update + AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ + /* populate this list when you add new scripts */ static AF_ScriptClass const af_script_classes[] = { @@ -37,14 +43,18 @@ #endif &af_latin_script_class, &af_cjk_script_class, - &af_indic_script_class, + &af_indic_script_class, NULL /* do not remove */ }; +#endif /* FT_CONFIG_OPTION_PIC */ + /* index of default script in `af_script_classes' */ #define AF_SCRIPT_LIST_DEFAULT 2 - /* indicates an uncovered glyph */ -#define AF_SCRIPT_LIST_NONE 255 + /* a bit mask indicating an uncovered glyph */ +#define AF_SCRIPT_LIST_NONE 0x7F + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x80 /* @@ -55,7 +65,7 @@ typedef struct AF_FaceGlobalsRec_ { FT_Face face; - FT_UInt glyph_count; /* same as face->num_glyphs */ + FT_Long glyph_count; /* same as face->num_glyphs */ FT_Byte* glyph_scripts; AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; @@ -72,7 +82,7 @@ FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; - FT_UInt ss; + FT_UInt ss, i; /* the value 255 means `uncovered glyph' */ @@ -84,17 +94,17 @@ if ( error ) { /* - * Ignore this error; we simply use Latin as the standard - * script. XXX: Shouldn't we rather disable hinting? + * Ignore this error; we simply use the default script. + * XXX: Shouldn't we rather disable hinting? */ error = AF_Err_Ok; goto Exit; } /* scan each script in a Unicode charmap */ - for ( ss = 0; af_script_classes[ss]; ss++ ) + for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) { - AF_ScriptClass clazz = af_script_classes[ss]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; AF_Script_UniRange range; @@ -114,7 +124,7 @@ gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && - gindex < globals->glyph_count && + gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -127,7 +137,7 @@ if ( gindex == 0 || charcode > range->last ) break; - if ( gindex < globals->glyph_count && + if ( gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -136,13 +146,23 @@ } } + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gscripts[gindex] |= AF_DIGIT; + } + Exit: /* * By default, all uncovered glyphs are set to the latin script. * XXX: Shouldn't we disable hinting or do something similar? */ { - FT_UInt nn; + FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) @@ -201,7 +221,7 @@ { if ( globals->metrics[nn] ) { - AF_ScriptClass clazz = af_script_classes[nn]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; FT_ASSERT( globals->metrics[nn]->clazz == clazz ); @@ -232,12 +252,12 @@ FT_UInt gidx; AF_ScriptClass clazz; FT_UInt script = options & 15; - const FT_UInt script_max = sizeof ( af_script_classes ) / - sizeof ( af_script_classes[0] ); + const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / + sizeof ( AF_SCRIPT_CLASSES_GET[0] ); FT_Error error = AF_Err_Ok; - if ( gindex >= globals->glyph_count ) + if ( gindex >= (FT_ULong)globals->glyph_count ) { error = AF_Err_Invalid_Argument; goto Exit; @@ -245,9 +265,9 @@ gidx = script; if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex]; + gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE; - clazz = af_script_classes[gidx]; + clazz = AF_SCRIPT_CLASSES_GET[gidx]; if ( script == 0 ) script = clazz->script; @@ -286,4 +306,15 @@ } + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afglobal.h b/reactos/lib/3rdparty/freetype/src/autofit/afglobal.h index cf52c087560..2a68e19607a 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afglobal.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2007 by */ +/* Copyright 2003, 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,11 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_face_globals_free( AF_FaceGlobals globals ); - /* */ + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + + /* */ FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afhints.c b/reactos/lib/3rdparty/freetype/src/autofit/afhints.c index 482870686d5..fe38fba9954 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afhints.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,7 +34,7 @@ { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *segment ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); if ( old_max >= big_max ) @@ -77,7 +77,7 @@ { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *edge ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); if ( old_max >= big_max ) @@ -127,7 +127,7 @@ #ifdef AF_DEBUG -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H static const char* af_dir_str( AF_Direction dir ) @@ -203,14 +203,14 @@ if ( flags & AF_EDGE_ROUND ) { - memcpy( temp + pos, "round", 5 ); + ft_memcpy( temp + pos, "round", 5 ); pos += 5; } if ( flags & AF_EDGE_SERIF ) { if ( pos > 0 ) temp[pos++] = ' '; - memcpy( temp + pos, "serif", 5 ); + ft_memcpy( temp + pos, "serif", 5 ); pos += 5; } if ( pos == 0 ) @@ -645,6 +645,7 @@ FT_Int contour_index = 0; + FT_UNUSED( first ); for ( point = points; point < point_limit; point++, vec++, tag++ ) { point->fx = (FT_Short)vec->x; @@ -940,8 +941,8 @@ } { - FT_UInt min, max, mid; - FT_Pos fpos; + FT_PtrDist min, max, mid; + FT_Pos fpos; /* find enclosing edges */ @@ -952,7 +953,7 @@ /* for small edge counts, a linear search is better */ if ( max <= 8 ) { - FT_UInt nn; + FT_PtrDist nn; for ( nn = 0; nn < max; nn++ ) if ( edges[nn].fpos >= u ) diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afhints.h b/reactos/lib/3rdparty/freetype/src/autofit/afhints.h index 49e88d1b621..675826835ae 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afhints.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,7 +30,7 @@ FT_BEGIN_HEADER * script analysis routines (until now). */ - typedef enum + typedef enum AF_Dimension_ { AF_DIMENSION_HORZ = 0, /* x coordinates, */ /* i.e., vertical segments & edges */ @@ -44,7 +44,7 @@ FT_BEGIN_HEADER /* hint directions -- the values are computed so that two vectors are */ /* in opposite directions iff `dir1 + dir2 == 0' */ - typedef enum + typedef enum AF_Direction_ { AF_DIR_NONE = 4, AF_DIR_RIGHT = 1, @@ -56,7 +56,7 @@ FT_BEGIN_HEADER /* point hint flags */ - typedef enum + typedef enum AF_Flags_ { AF_FLAG_NONE = 0, @@ -87,7 +87,7 @@ FT_BEGIN_HEADER /* edge hint flags */ - typedef enum + typedef enum AF_Edge_Flags_ { AF_EDGE_NORMAL = 0, AF_EDGE_ROUND = 1 << 0, @@ -214,7 +214,7 @@ FT_BEGIN_HEADER FT_Pos xmin_delta; /* used for warping */ FT_Pos xmax_delta; - + } AF_GlyphHintsRec; diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afindic.c b/reactos/lib/3rdparty/freetype/src/autofit/afindic.c index c6e7522e15b..1d9e9eafbad 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afindic.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afindic.c @@ -43,7 +43,7 @@ static void af_indic_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) + AF_Scaler scaler ) { /* use CJK routines */ af_cjk_metrics_scale( metrics, scaler ); @@ -52,7 +52,7 @@ static FT_Error af_indic_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) + AF_LatinMetrics metrics ) { /* use CJK routines */ return af_cjk_hints_init( hints, metrics ); @@ -61,8 +61,8 @@ static FT_Error af_indic_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics) + FT_Outline* outline, + AF_LatinMetrics metrics) { /* use CJK routines */ return af_cjk_hints_apply( hints, outline, metrics ); @@ -81,16 +81,14 @@ static const AF_Script_UniRangeRec af_indic_uniranges[] = { #if 0 - { 0x0100, 0xFFFF }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x0900, 0x0DFF}, /* Indic Range */ - { 0, 0 } + AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ + AF_UNIRANGE_REC( 0UL, 0UL) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -102,7 +100,7 @@ (AF_Script_InitHintsFunc) af_indic_hints_init, (AF_Script_ApplyHintsFunc) af_indic_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_INDIC */ @@ -112,9 +110,7 @@ }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -126,7 +122,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_INDIC */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afindic.h b/reactos/lib/3rdparty/freetype/src/autofit/afindic.h index b242b261443..662a982200e 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afindic.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afindic.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the Indic-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_indic_script_class; + AF_DECLARE_SCRIPT_CLASS(af_indic_script_class) /* */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c index 52e952d9885..394fb9789ba 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,9 @@ /***************************************************************************/ +#include <ft2build.h> +#include FT_ADVANCES_H + #include "aflatin.h" #include "aferrors.h" @@ -146,7 +149,8 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS + 1] = { "THEZOCQS", "HEZLOCUS", @@ -195,7 +199,8 @@ for ( ; p < limit && *p; p++ ) { FT_UInt glyph_index; - FT_Int best_point, best_y, best_first, best_last; + FT_Pos best_y; /* same as points.y */ + FT_Int best_point, best_first, best_last; FT_Vector* points; FT_Bool round = 0; @@ -328,7 +333,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -379,7 +384,7 @@ blue->flags |= AF_LATIN_BLUE_TOP; /* - * The following flags is used later to adjust the y and x scales + * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ @@ -393,6 +398,52 @@ } + FT_LOCAL_DEF( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + FT_Fixed advance, old_advance = 0; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -426,6 +477,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin_metrics_init_widths( metrics, face, 'o' ); af_latin_metrics_init_blues( metrics, face ); + af_latin_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -1004,12 +1056,14 @@ if ( !found ) { - AF_Edge edge; + AF_Edge edge; /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; @@ -1565,7 +1619,7 @@ /* not hinted, appear a lot bolder or thinner than the */ /* vertical stems. */ - FT_Int delta; + FT_Pos delta; dist = ( dist + 22 ) & ~63; @@ -1649,7 +1703,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2006,7 +2060,10 @@ if ( before >= edges && before < edge && after < edge_limit && after > edge ) { - edge->pos = before->pos + + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + FT_MulDiv( edge->opos - before->opos, after->pos - before->pos, after->opos - before->opos ); @@ -2122,33 +2179,37 @@ static const AF_Script_UniRangeRec af_latin_uniranges[] = { - { 0x0020, 0x007F }, /* Basic Latin (no control characters) */ - { 0x00A0, 0x00FF }, /* Latin-1 Supplement (no control characters) */ - { 0x0100, 0x017F }, /* Latin Extended-A */ - { 0x0180, 0x024F }, /* Latin Extended-B */ - { 0x0250, 0x02AF }, /* IPA Extensions */ - { 0x02B0, 0x02FF }, /* Spacing Modifier Letters */ - { 0x0300, 0x036F }, /* Combining Diacritical Marks */ - { 0x0370, 0x03FF }, /* Greek and Coptic */ - { 0x0400, 0x04FF }, /* Cyrillic */ - { 0x0500, 0x052F }, /* Cyrillic Supplement */ - { 0x1D00, 0x1D7F }, /* Phonetic Extensions */ - { 0x1D80, 0x1DBF }, /* Phonetic Extensions Supplement */ - { 0x1DC0, 0x1DFF }, /* Combining Diacritical Marks Supplement */ - { 0x1E00, 0x1EFF }, /* Latin Extended Additional */ - { 0x1F00, 0x1FFF }, /* Greek Extended */ - { 0x2000, 0x206F }, /* General Punctuation */ - { 0x2070, 0x209F }, /* Superscripts and Subscripts */ - { 0x20A0, 0x20CF }, /* Currency Symbols */ - { 0x2150, 0x218F }, /* Number Forms */ - { 0x2460, 0x24FF }, /* Enclosed Alphanumerics */ - { 0 , 0 } + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ + AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin_script_class, AF_SCRIPT_LATIN, af_latin_uniranges, @@ -2160,7 +2221,7 @@ (AF_Script_InitHintsFunc) af_latin_hints_init, (AF_Script_ApplyHintsFunc) af_latin_hints_apply - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.h b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.h index 3251d3783f3..660b10c83f7 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_latin_script_class; + AF_DECLARE_SCRIPT_CLASS(af_latin_script_class) /* constants are given with units_per_em == 2048 in mind */ @@ -138,6 +137,10 @@ FT_BEGIN_HEADER FT_Face face, FT_ULong charcode ); + FT_LOCAL( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ); + /*************************************************************************/ /*************************************************************************/ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c index 0b4177414c1..5e2ad48c406 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,8 @@ /***************************************************************************/ +#include FT_ADVANCES_H + #include "aflatin.h" #include "aflatin2.h" #include "aferrors.h" @@ -154,7 +156,7 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin2_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] = { "THEZOCQS", "HEZLOCUS", @@ -336,7 +338,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -401,6 +403,52 @@ } + FT_LOCAL_DEF( void ) + af_latin2_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + FT_Fixed advance, old_advance; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin2_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -434,6 +482,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin2_metrics_init_widths( metrics, face, 'o' ); af_latin2_metrics_init_blues( metrics, face ); + af_latin2_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -944,6 +993,9 @@ } } } +#if 0 + } +#endif /* now, compute the `serif' segments */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) @@ -1736,7 +1788,6 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2047,54 +2098,60 @@ /* We don't handle horizontal edges since we can't easily assure that */ /* the third (lowest) stem aligns with the base line; it might end up */ /* one pixel higher or lower. */ + #if 0 - n_edges = edge_limit - edges; - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span, delta; + FT_Int n_edges = edge_limit - edges; - if ( n_edges == 6 ) + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) + if ( n_edges == 6 ) { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; } - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } } } #endif + if ( has_serifs || !anchor ) { /* @@ -2150,7 +2207,10 @@ if ( before >= edges && before < edge && after < edge_limit && after > edge ) { - edge->pos = before->pos + + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + FT_MulDiv( edge->opos - before->opos, after->pos - before->pos, after->opos - before->opos ); @@ -2260,15 +2320,13 @@ static const AF_Script_UniRangeRec af_latin2_uniranges[] = { - { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */ - { 160, 255 }, - { 0, 0 } + AF_UNIRANGE_REC( 32UL, 127UL ), /* XXX: TODO: Add new Unicode ranges here! */ + AF_UNIRANGE_REC( 160UL, 255UL ), + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin2_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class, AF_SCRIPT_LATIN2, af_latin2_uniranges, @@ -2280,7 +2338,7 @@ (AF_Script_InitHintsFunc) af_latin2_hints_init, (AF_Script_ApplyHintsFunc) af_latin2_hints_apply - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.h b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.h index 34eda058229..925c6214db3 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_latin2_script_class; + AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class) /* */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afloader.c b/reactos/lib/3rdparty/freetype/src/autofit/afloader.c index 4e4373a4924..6dd9f2a314a 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afloader.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,7 +19,6 @@ #include "afloader.h" #include "afhints.h" #include "afglobal.h" -#include "aflatin.h" #include "aferrors.h" @@ -165,9 +164,10 @@ /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); + if ( metrics->clazz->script_hints_apply ) + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); /* we now need to hint the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ @@ -183,9 +183,9 @@ if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) { - old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; + old_rsb = loader->pp2.x - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; /* remember unhinted values to later account */ /* for rounding errors */ @@ -216,8 +216,9 @@ } else { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x ); loader->pp2.x = FT_PIX_ROUND( pp2x ); @@ -228,8 +229,9 @@ } else { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); @@ -412,7 +414,8 @@ slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); /* for mono-width fonts (like Andale, Courier, etc.) we need */ - /* to keep the original rounded advance width */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ #if 0 if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; @@ -420,13 +423,9 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - { - /* non-spacing glyphs must stay as-is */ - if ( slot->metrics.horiAdvance ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - } - else + if ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) { slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, metrics->scaler.x_scale ); @@ -436,6 +435,12 @@ slot->lsb_delta = 0; slot->rsb_delta = 0; } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } #endif slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, @@ -515,9 +520,13 @@ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; - error = metrics->clazz->script_hints_init( &loader->hints, metrics ); - if ( error ) - goto Exit; + if ( metrics->clazz->script_hints_init ) + { + error = metrics->clazz->script_hints_init( &loader->hints, + metrics ); + if ( error ) + goto Exit; + } error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); } diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afmodule.c b/reactos/lib/3rdparty/freetype/src/autofit/afmodule.c index cd5e1cc218b..ec2d707c9f9 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afmodule.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afmodule.c @@ -18,6 +18,7 @@ #include "afmodule.h" #include "afloader.h" +#include "afpic.h" #ifdef AF_DEBUG int _af_debug; @@ -66,19 +67,15 @@ } - FT_CALLBACK_TABLE_DEF - const FT_AutoHinter_ServiceRec af_autofitter_service = - { + FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service, NULL, NULL, NULL, (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph - }; + ) + FT_DEFINE_MODULE(autofit_module_class, - FT_CALLBACK_TABLE_DEF - const FT_Module_Class autofit_module_class = - { FT_MODULE_HINTER, sizeof ( FT_AutofitterRec ), @@ -86,12 +83,12 @@ 0x10000L, /* version 1.0 of the autofitter */ 0x20000L, /* requires FreeType 2.0 or above */ - (const void*)&af_autofitter_service, + (const void*)&AF_AF_AUTOFITTER_SERVICE_GET, (FT_Module_Constructor)af_autofitter_init, (FT_Module_Destructor) af_autofitter_done, (FT_Module_Requester) NULL - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afmodule.h b/reactos/lib/3rdparty/freetype/src/autofit/afmodule.h index 36268a0890a..d9792399b63 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afmodule.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/afmodule.h @@ -20,13 +20,13 @@ #define __AFMODULE_H__ #include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Module_Class autofit_module_class; +FT_DECLARE_MODULE(autofit_module_class) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afpic.c b/reactos/lib/3rdparty/freetype/src/autofit/afpic.c new file mode 100644 index 00000000000..76822c301a8 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/autofit/afpic.c @@ -0,0 +1,92 @@ +/***************************************************************************/ +/* */ +/* afpic.c */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "afpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from afmodule.c */ + void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*); + + /* forward declaration of PIC init functions from script classes */ +#include "aflatin.h" +#include "aflatin2.h" +#include "afcjk.h" +#include "afdummy.h" +#include "afindic.h" + + void + autofit_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->autofit ) + { + FT_FREE( pic_container->autofit ); + pic_container->autofit = NULL; + } + } + + FT_Error + autofit_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_UInt ss; + FT_Error error = FT_Err_Ok; + AFModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->autofit = container; + + /* initialize pointer table - this is how the module usually expects this data */ + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) + { + container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; + } + container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL; + + /* add call to initialization function when you add new scripts */ + ss = 0; + FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]); +#ifdef FT_OPTION_AUTOFIT2 + FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]); +#endif + FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]); + + FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service); + +/*Exit:*/ + if(error) + autofit_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afpic.h b/reactos/lib/3rdparty/freetype/src/autofit/afpic.h new file mode 100644 index 00000000000..80e62d39a99 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/autofit/afpic.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afpic.h */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFPIC_H__ +#define __AFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_AF_AUTOFITTER_SERVICE_GET af_autofitter_service + +#else /* FT_CONFIG_OPTION_PIC */ + +#include "aftypes.h" + +/* increase these when you add new scripts, and update autofit_module_class_pic_init */ +#ifdef FT_OPTION_AUTOFIT2 + #define AF_SCRIPT_CLASSES_COUNT 6 +#else + #define AF_SCRIPT_CLASSES_COUNT 5 +#endif +#define AF_SCRIPT_CLASSES_REC_COUNT (AF_SCRIPT_CLASSES_COUNT-1) + + typedef struct AFModulePIC_ + { + AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; + AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + FT_AutoHinter_ServiceRec af_autofitter_service; + } AFModulePIC; + +#define GET_PIC(lib) ((AFModulePIC*)((lib)->pic_container.autofit)) +#define AF_SCRIPT_CLASSES_GET (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes) +#define AF_AF_AUTOFITTER_SERVICE_GET (GET_PIC(library)->af_autofitter_service) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __AFPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aftypes.h b/reactos/lib/3rdparty/freetype/src/autofit/aftypes.h index 9c27df2d9f0..5574f0c302b 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aftypes.h +++ b/reactos/lib/3rdparty/freetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,8 @@ FT_BEGIN_HEADER #ifdef AF_DEBUG -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H + #define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 ) extern int _af_debug; @@ -69,7 +70,7 @@ extern void* _af_debug_hints; #else /* !AF_DEBUG */ -#define AF_LOG( x ) do ; while ( 0 ) /* nothing */ +#define AF_LOG( x ) do { } while ( 0 ) /* nothing */ #endif /* !AF_DEBUG */ @@ -202,7 +203,7 @@ extern void* _af_debug_hints; * auto-hinted glyph image. */ - typedef enum + typedef enum AF_ScalerFlags_ { AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ @@ -260,12 +261,12 @@ extern void* _af_debug_hints; * used by more than one script. */ - typedef enum + typedef enum AF_Script_ { AF_SCRIPT_NONE = 0, AF_SCRIPT_LATIN = 1, AF_SCRIPT_CJK = 2, - AF_SCRIPT_INDIC = 3, + AF_SCRIPT_INDIC = 3, #ifdef FT_OPTION_AUTOFIT2 AF_SCRIPT_LATIN2, #endif @@ -284,6 +285,7 @@ extern void* _af_debug_hints; { AF_ScriptClass clazz; AF_ScalerRec scaler; + FT_Bool digits_have_same_width; } AF_ScriptMetricsRec, *AF_ScriptMetrics; @@ -320,6 +322,8 @@ extern void* _af_debug_hints; } AF_Script_UniRangeRec; +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + typedef const AF_Script_UniRangeRec *AF_Script_UniRange; @@ -328,7 +332,7 @@ extern void* _af_debug_hints; AF_Script script; AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt script_metrics_size; + FT_Offset script_metrics_size; AF_Script_InitMetricsFunc script_metrics_init; AF_Script_ScaleMetricsFunc script_metrics_scale; AF_Script_DoneMetricsFunc script_metrics_done; @@ -338,6 +342,56 @@ extern void* _af_debug_hints; } AF_ScriptClassRec; +/* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \ + script_class = \ + { \ + script_, \ + ranges, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + \ + h_init, \ + h_apply \ + }; + +#else + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_LOCAL(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac); + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_LOCAL_DEF(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + \ + ac->script_metrics_size = m_size; \ + \ + ac->script_metrics_init = m_init; \ + ac->script_metrics_scale = m_scale; \ + ac->script_metrics_done = m_done; \ + \ + ac->script_hints_init = h_init; \ + ac->script_hints_apply = h_apply; \ + } +#endif + /* */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/afwarp.c b/reactos/lib/3rdparty/freetype/src/autofit/afwarp.c index 6c31cffc4e1..f5bb9b18ad9 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/afwarp.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/afwarp.c @@ -317,7 +317,7 @@ { FT_Fixed best_scale = warper->best_scale; FT_Pos best_delta = warper->best_delta; - + hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) + best_delta; diff --git a/reactos/lib/3rdparty/freetype/src/autofit/autofit.c b/reactos/lib/3rdparty/freetype/src/autofit/autofit.c index 2fe66a990ec..83b613e79b3 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/autofit.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/autofit.c @@ -18,6 +18,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "afpic.c" #include "afangles.c" #include "afglobal.c" #include "afhints.c" diff --git a/reactos/lib/3rdparty/freetype/src/autofit/module.mk b/reactos/lib/3rdparty/freetype/src/autofit/module.mk index 4a386ce66cc..6ec60912ab7 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/module.mk +++ b/reactos/lib/3rdparty/freetype/src/autofit/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += AUTOFIT_MODULE define AUTOFIT_MODULE -$(OPEN_DRIVER)autofit_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, autofit_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)autofit $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/base/Jamfile b/reactos/lib/3rdparty/freetype/src/base/Jamfile index aeffe388e58..832e8b84249 100644 --- a/reactos/lib/3rdparty/freetype/src/base/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/base/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/base Jamfile # -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,8 +17,11 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; if $(FT2_MULTI) { - _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln - ftobjs ftnames ftrfork ; + _sources = ftadvanc ftcalc ftdbgmem ftgloadr + ftobjs ftoutln ftrfork ftsnames + ftstream fttrigon ftutil + basepic ftpic + ; } else { @@ -31,11 +34,11 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; # Add the optional/replaceable files. # { - local _sources = system init glyph mm bdf - bbox debug xf86 type1 pfr - stroke winfnt otval bitmap synth - gxval lcdfil gasp patent - ; + local _sources = bbox bdf bitmap debug gasp + glyph gxval init lcdfil mm + otval pfr stroke synth system + type1 winfnt xf86 patent + ; Library $(FT2_LIB) : ft$(_sources).c ; } @@ -46,5 +49,12 @@ if $(MAC) { Library $(FT2_LIB) : ftmac.c ; } +else if $(OS) = MACOSX +{ + if $(FT2_MULTI) + { + Library $(FT2_LIB) : ftmac.c ; + } +} # end of src/base Jamfile diff --git a/reactos/lib/3rdparty/freetype/src/base/basepic.c b/reactos/lib/3rdparty/freetype/src/base/basepic.c new file mode 100644 index 00000000000..c0bccb6959b --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/basepic.c @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* basepic.c */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftglyph.c */ + void FT_Init_Class_ft_outline_glyph_class(FT_Glyph_Class*); + void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*); + + /* forward declaration of PIC init functions from ftinit.c */ + FT_Error ft_create_default_module_classes(FT_Library); + void ft_destroy_default_module_classes(FT_Library); + + void + ft_base_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->base ) + { + /* Destroy default module classes (in case FT_Add_Default_Modules was used) */ + ft_destroy_default_module_classes( library ); + + FT_FREE( pic_container->base ); + pic_container->base = NULL; + } + } + + + FT_Error + ft_base_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + BasePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->base = container; + + /* initialize default modules list and pointers */ + error = ft_create_default_module_classes( library ); + if ( error ) + goto Exit; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_outline_glyph_class(&container->ft_outline_glyph_class); + FT_Init_Class_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class); + +Exit: + if(error) + ft_base_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/basepic.h b/reactos/lib/3rdparty/freetype/src/base/basepic.h new file mode 100644 index 00000000000..bb17745769e --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/basepic.h @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* basepic.h */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __BASEPIC_H__ +#define __BASEPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class +#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class +#define FT_DEFAULT_MODULES_GET ft_default_modules + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_GLYPH_H + + typedef struct BasePIC_ + { + FT_Module_Class** default_module_classes; + FT_Glyph_Class ft_outline_glyph_class; + FT_Glyph_Class ft_bitmap_glyph_class; + } BasePIC; + +#define GET_PIC(lib) ((BasePIC*)((lib)->pic_container.base)) +#define FT_OUTLINE_GLYPH_CLASS_GET (&GET_PIC(library)->ft_outline_glyph_class) +#define FT_BITMAP_GLYPH_CLASS_GET (&GET_PIC(library)->ft_bitmap_glyph_class) +#define FT_DEFAULT_MODULES_GET (GET_PIC(library)->default_module_classes) + + void + ft_base_pic_free( FT_Library library ); + + FT_Error + ft_base_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ + +FT_END_HEADER + +#endif /* __BASEPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftadvanc.c b/reactos/lib/3rdparty/freetype/src/base/ftadvanc.c new file mode 100644 index 00000000000..8ab7fcb9271 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftadvanc.c @@ -0,0 +1,163 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.c */ +/* */ +/* Quick computation of advance widths (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_ADVANCES_H +#include FT_INTERNAL_OBJECTS_H + + + static FT_Error + _ft_face_scale_advances( FT_Face face, + FT_Fixed* advances, + FT_UInt count, + FT_Int32 flags ) + { + FT_Fixed scale; + FT_UInt nn; + + + if ( flags & FT_LOAD_NO_SCALE ) + return FT_Err_Ok; + + if ( face->size == NULL ) + return FT_Err_Invalid_Size_Handle; + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + scale = face->size->metrics.y_scale; + else + scale = face->size->metrics.x_scale; + + /* this must be the same scaling as to get linear{Hori,Vert}Advance */ + /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ + + for ( nn = 0; nn < count; nn++ ) + advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); + + return FT_Err_Ok; + } + + + /* at the moment, we can perform fast advance retrieval only in */ + /* the following cases: */ + /* */ + /* - unscaled load */ + /* - unhinted load */ + /* - light-hinted load */ + +#define LOAD_ADVANCE_FAST_CHECK( flags ) \ + ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 flags, + FT_Fixed *padvance ) + { + FT_Face_GetAdvancesFunc func; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( gindex >= (FT_UInt)face->num_glyphs ) + return FT_Err_Invalid_Glyph_Index; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + FT_Error error; + + + error = func( face, gindex, 1, flags, padvance ); + if ( !error ) + return _ft_face_scale_advances( face, padvance, 1, flags ); + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + return FT_Get_Advances( face, gindex, 1, flags, padvance ); + } + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *padvances ) + { + FT_Face_GetAdvancesFunc func; + FT_UInt num, end, nn; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + num = (FT_UInt)face->num_glyphs; + end = start + count; + if ( start >= num || end < start || end > num ) + return FT_Err_Invalid_Glyph_Index; + + if ( count == 0 ) + return FT_Err_Ok; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + error = func( face, start, count, flags, padvances ); + if ( !error ) + goto Exit; + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + error = FT_Err_Ok; + + if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) + return FT_Err_Unimplemented_Feature; + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + for ( nn = 0; nn < count; nn++ ) + { + error = FT_Load_Glyph( face, start + nn, flags ); + if ( error ) + break; + + padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? face->glyph->advance.y + : face->glyph->advance.x; + } + + if ( error ) + return error; + + Exit: + return _ft_face_scale_advances( face, padvances, count, flags ); + } + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbase.c b/reactos/lib/3rdparty/freetype/src/base/ftbase.c index d176b8150c3..6a27ea95a62 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftbase.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,19 +20,22 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT +#include "ftpic.c" +#include "basepic.c" +#include "ftadvanc.c" #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" -#include "ftnames.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" +#include "ftsnames.c" #include "ftstream.c" #include "fttrigon.c" #include "ftutil.c" -#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include <ftmac.c> +#if defined( FT_MACINTOSH ) && !defined ( DARWIN_NO_CARBON ) +#include "ftmac.c" #endif /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbase.h b/reactos/lib/3rdparty/freetype/src/base/ftbase.h new file mode 100644 index 00000000000..9cae85da9ef --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftbase.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* ftbase.h */ +/* */ +/* The FreeType private functions used in base module (specification). */ +/* */ +/* Copyright 2008 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBASE_H__ +#define __FTBASE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ + /* font, and try to load a face specified by the face_index. */ + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ); + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* From ftmac.c. */ + FT_LOCAL_DEF( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ); + + +FT_END_HEADER + +#endif /* __FTBASE_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbbox.c b/reactos/lib/3rdparty/freetype/src/base/ftbbox.c index 532ab135791..8136ccc1e9f 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftbbox.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftbbox.c @@ -29,6 +29,7 @@ #include FT_IMAGE_H #include FT_OUTLINE_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H typedef struct TBBox_Rec_ @@ -559,6 +560,13 @@ return 0; } +FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + ) /* documentation is in ftbbox.h */ @@ -628,18 +636,13 @@ /* the two boxes are different, now walk over the outline to */ /* get the Bezier arc extrema. */ - static const FT_Outline_Funcs bbox_interface = - { - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 - }; - FT_Error error; TBBox_Rec user; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs bbox_interface; + Init_Class_bbox_interface(&bbox_interface); +#endif user.bbox = bbox; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbitmap.c b/reactos/lib/3rdparty/freetype/src/base/ftbitmap.c index c847eb00d24..82b5baf2a64 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftbitmap.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftbitmap.c @@ -2,10 +2,9 @@ /* */ /* ftbitmap.c */ /* */ -/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (body). */ +/* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +18,7 @@ #include <ft2build.h> #include FT_BITMAP_H +#include FT_IMAGE_H #include FT_INTERNAL_OBJECTS_H @@ -228,8 +228,12 @@ if ( !bitmap || !bitmap->buffer ) return FT_Err_Invalid_Argument; - xstr = FT_PIX_ROUND( xStrength ) >> 6; - ystr = FT_PIX_ROUND( yStrength ) >> 6; + if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || + ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) + return FT_Err_Invalid_Argument; + + xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; + ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; if ( xstr == 0 && ystr == 0 ) return FT_Err_Ok; @@ -388,6 +392,8 @@ case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_GRAY2: case FT_PIXEL_MODE_GRAY4: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: { FT_Int pad; FT_Long old_size; @@ -482,6 +488,8 @@ case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: { FT_Int width = source->width; FT_Byte* s = source->buffer; @@ -603,6 +611,31 @@ } + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) + { + if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && + !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Bitmap bitmap; + FT_Error error; + + + FT_Bitmap_New( &bitmap ); + error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); + if ( error ) + return error; + + slot->bitmap = bitmap; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + + return FT_Err_Ok; + } + + /* documentation is in ftbitmap.h */ FT_EXPORT_DEF( FT_Error ) diff --git a/reactos/lib/3rdparty/freetype/src/base/ftcalc.c b/reactos/lib/3rdparty/freetype/src/base/ftcalc.c index 63aed95b75e..3892fabfe93 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftcalc.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,10 +33,14 @@ #include <ft2build.h> +#include FT_GLYPH_H #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H +#ifdef FT_MULFIX_INLINED +#undef FT_MulFix +#endif /* we need to define a 64-bits data type here */ @@ -106,12 +110,12 @@ FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ) { - FT_ULong val, root, newroot, mask; + FT_UInt32 val, root, newroot, mask; root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; + mask = (FT_UInt32)0x40000000UL; + val = (FT_UInt32)x; do { @@ -192,15 +196,33 @@ FT_MulFix( FT_Long a, FT_Long b ) { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#else + FT_Int s = 1; FT_Long c; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } + if ( a < 0 ) + { + a = -a; + s = -1; + } + + if ( b < 0 ) + { + b = -b; + s = -s; + } c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - return ( s > 0 ) ? c : -c ; + + return ( s > 0 ) ? c : -c; + +#endif /* FT_MULFIX_ASSEMBLER */ } @@ -340,6 +362,7 @@ long s; + /* XXX: this function does not allow 64-bit arguments */ if ( a == 0 || b == c ) return a; @@ -355,12 +378,12 @@ FT_Int64 temp, temp2; - ft_multo64( a, b, &temp ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); temp2.hi = 0; temp2.lo = (FT_UInt32)(c >> 1); FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -394,8 +417,8 @@ FT_Int64 temp; - ft_multo64( a, b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -412,31 +435,18 @@ FT_MulFix( FT_Long a, FT_Long b ) { - /* use inline assembly to speed up things a bit */ +#ifdef FT_MULFIX_ASSEMBLER -#if defined( __GNUC__ ) && defined( i386 ) + return FT_MULFIX_ASSEMBLER( a, b ); - FT_Long result; +#elif 0 - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - "mov %%eax, %0\n" - : "=r"(result) - : "a"(a), "d"(b) - : "%ecx" - ); - return result; - -#elif 1 + /* + * This code is nonportable. See comment below. + * + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. + */ FT_Long sa, sb; FT_ULong ua, ub; @@ -445,6 +455,24 @@ if ( a == 0 || b == 0x10000L ) return a; + /* + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). + * + * Unfortunately, it doesn't work (at least not portably). + * + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. + */ sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); a = ( a ^ sa ) - sa; sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); @@ -512,13 +540,14 @@ FT_UInt32 q; - s = a; a = FT_ABS(a); - s ^= b; b = FT_ABS(b); + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); if ( b == 0 ) { /* check for division by 0 */ - q = 0x7FFFFFFFL; + q = (FT_UInt32)0x7FFFFFFFL; } else if ( ( a >> 16 ) == 0 ) { @@ -535,7 +564,7 @@ temp2.hi = 0; temp2.lo = (FT_UInt32)( b >> 1 ); FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, b ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); } return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); @@ -666,6 +695,110 @@ #endif /* FT_LONG64 */ + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix *b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_Err_Invalid_Argument; + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_Err_Invalid_Argument; /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + /* documentation is in ftcalc.h */ FT_BASE_DEF( FT_Int32 ) @@ -709,7 +842,7 @@ FT_Pos out_x, FT_Pos out_y ) { - FT_Int result; + FT_Long result; /* avoid overflow on 16-bit system */ /* deal with the trivial cases quickly */ @@ -758,8 +891,9 @@ FT_Int64 z1, z2; - ft_multo64( in_x, out_y, &z1 ); - ft_multo64( in_y, out_x, &z2 ); + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; @@ -775,7 +909,8 @@ #endif } - return result; + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return (FT_Int)result; } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftcid.c b/reactos/lib/3rdparty/freetype/src/base/ftcid.c new file mode 100644 index 00000000000..733aae14751 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftcid.c @@ -0,0 +1,117 @@ +/***************************************************************************/ +/* */ +/* ftcid.c */ +/* */ +/* FreeType API for accessing CID font information. */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CID_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_CID_H + + + /* documentation is in ftcid.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement) + { + FT_Error error; + const char* r = NULL; + const char* o = NULL; + FT_Int s = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_ros ) + error = service->get_ros( face, &r, &o, &s ); + } + + if ( registry ) + *registry = r; + + if ( ordering ) + *ordering = o; + + if ( supplement ) + *supplement = s; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Bool ic = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_is_cid ) + error = service->get_is_cid( face, &ic); + } + + if ( is_cid ) + *is_cid = ic; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_UInt c = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_cid_from_glyph_index ) + error = service->get_cid_from_glyph_index( face, glyph_index, &c); + } + + if ( cid ) + *cid = c; + + return error; + } + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c b/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c index 52a5c2057f8..677f242080c 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,8 +33,7 @@ * memory, however. */ -#include <stdio.h> -#include <stdlib.h> +#include FT_CONFIG_STANDARD_LIBRARY_H FT_BASE_DEF( const char* ) _ft_debug_file = 0; FT_BASE_DEF( long ) _ft_debug_lineno = 0; @@ -422,7 +421,7 @@ "FreeType: %ld bytes of memory leaked in %ld blocks\n", leaks, leak_count ); - printf( "FreeType: No memory leaks detected!\n" ); + printf( "FreeType: no memory leaks detected\n" ); } } @@ -990,7 +989,7 @@ #else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ - const FT_Byte _debug_mem_dummy = 0; + static const FT_Byte _debug_mem_dummy = 0; #endif /* !FT_DEBUG_MEMORY */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftdebug.c b/reactos/lib/3rdparty/freetype/src/base/ftdebug.c index c55d3c8114e..2adbeabeb23 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftdebug.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2001, 2002, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,7 +46,7 @@ #include FT_INTERNAL_DEBUG_H -#if defined( FT_DEBUG_LEVEL_ERROR ) +#ifdef FT_DEBUG_LEVEL_ERROR /* documentation is in ftdebug.h */ @@ -57,7 +57,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); } @@ -71,7 +71,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); exit( EXIT_FAILURE ); diff --git a/reactos/lib/3rdparty/freetype/src/base/ftfstype.c b/reactos/lib/3rdparty/freetype/src/base/ftfstype.c new file mode 100644 index 00000000000..d0ef7b7c1b0 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftfstype.c @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* ftfstype.c */ +/* */ +/* FreeType utility file to access FSType data (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ) + { + TT_OS2* os2; + + + /* first, try to get the fs_type directly from the font */ + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_extra ) + { + PS_FontExtraRec extra; + + + if ( !service->ps_get_font_extra( face, &extra ) && + extra.fs_type != 0 ) + return extra.fs_type; + } + } + + /* look at FSType before fsType for Type42 */ + + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + os2->version != 0xFFFFU ) + return os2->fsType; + + return 0; + } + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftgloadr.c b/reactos/lib/3rdparty/freetype/src/base/ftgloadr.c index ab52621ea67..ac0010ddd88 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftgloadr.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftgloadr.c @@ -218,6 +218,9 @@ { new_max = FT_PAD_CEIL( new_max, 8 ); + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) goto Exit; @@ -246,6 +249,10 @@ if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftglyph.c b/reactos/lib/3rdparty/freetype/src/base/ftglyph.c index 969c5dbb05a..ef61d45df2b 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftglyph.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,6 +34,7 @@ #include FT_BITMAP_H #include FT_INTERNAL_OBJECTS_H +#include "basepic.h" /*************************************************************************/ /* */ @@ -45,68 +46,6 @@ #define FT_COMPONENT trace_glyph - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** Convenience functions ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix *b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_Err_Invalid_Argument; - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_Err_Invalid_Argument; /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -191,9 +130,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_bitmap_glyph_class = - { + FT_DEFINE_GLYPH(ft_bitmap_glyph_class, sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, @@ -203,7 +140,7 @@ 0, /* FT_Glyph_TransformFunc */ ft_bitmap_glyph_bbox, 0 /* FT_Glyph_PrepareFunc */ - }; + ) /*************************************************************************/ @@ -317,9 +254,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_outline_glyph_class = - { + FT_DEFINE_GLYPH( ft_outline_glyph_class, sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, @@ -329,7 +264,7 @@ ft_outline_glyph_transform, ft_outline_glyph_bbox, ft_outline_glyph_prepare - }; + ) /*************************************************************************/ @@ -376,10 +311,16 @@ const FT_Glyph_Class* clazz; + /* check arguments */ + if ( !target ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + *target = 0; - /* check arguments */ - if ( !target || !source || !source->clazz ) + if ( !source || !source->clazz ) { error = FT_Err_Invalid_Argument; goto Exit; @@ -429,11 +370,11 @@ /* if it is a bitmap, that's easy :-) */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = &ft_bitmap_glyph_class; + clazz = FT_BITMAP_GLYPH_CLASS_GET; /* it it is an outline too */ else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = &ft_outline_glyph_class; + clazz = FT_OUTLINE_GLYPH_CLASS_GET; else { @@ -589,7 +530,7 @@ clazz = glyph->clazz; /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == &ft_bitmap_glyph_class ) + if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) goto Exit; if ( !clazz || !clazz->glyph_prepare ) @@ -602,7 +543,7 @@ dummy.format = clazz->glyph_format; /* create result bitmap glyph */ - error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, + error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET, (FT_Glyph*)(void*)&bitmap ); if ( error ) goto Exit; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftinit.c b/reactos/lib/3rdparty/freetype/src/base/ftinit.c index 7af19c3d80f..ef13503869f 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftinit.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_MODULE_H +#include "basepic.h" /*************************************************************************/ @@ -53,11 +54,13 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_init +#ifndef FT_CONFIG_OPTION_PIC + #undef FT_USE_MODULE #ifdef __cplusplus -#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class x; +#define FT_USE_MODULE( type, x ) extern "C" const type x; #else -#define FT_USE_MODULE( x ) extern const FT_Module_Class x; +#define FT_USE_MODULE( type, x ) extern const type x; #endif @@ -65,7 +68,7 @@ #undef FT_USE_MODULE -#define FT_USE_MODULE( x ) (const FT_Module_Class*)&(x), +#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), static const FT_Module_Class* const ft_default_modules[] = @@ -74,6 +77,99 @@ 0 }; +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef __cplusplus +#define FT_EXTERNC extern "C" +#else +#define FT_EXTERNC extern +#endif + + /* declare the module's class creation/destruction functions */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \ + FT_EXTERNC void FT_Destroy_Class_##x( FT_Library library, FT_Module_Class* clazz ); + +#include FT_CONFIG_MODULES_H + + + /* count all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) MODULE_CLASS_##x, + + enum { +#include FT_CONFIG_MODULES_H + FT_NUM_MODULE_CLASSES + }; + + /* destroy all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \ + i++; \ + + FT_BASE_DEF( void ) + ft_destroy_default_module_classes( FT_Library library ) + { + FT_Module_Class** classes; + FT_Memory memory; + FT_UInt i; + BasePIC* pic_container = library->pic_container.base; + + if ( !pic_container->default_module_classes ) + return; + + memory = library->memory; + classes = pic_container->default_module_classes; + i = 0; + +#include FT_CONFIG_MODULES_H + + FT_FREE( classes ); + pic_container->default_module_classes = 0; + } + + /* initialize all module classes and the pointer table */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + error = FT_Create_Class_##x(library, &clazz); \ + if (error) goto Exit; \ + classes[i++] = clazz; + + FT_BASE_DEF( FT_Error ) + ft_create_default_module_classes( FT_Library library ) + { + FT_Error error; + FT_Memory memory; + FT_Module_Class** classes; + FT_Module_Class* clazz; + FT_UInt i; + BasePIC* pic_container = library->pic_container.base; + + memory = library->memory; + pic_container->default_module_classes = 0; + + if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) ) + return error; + /* initialize all pointers to 0, especially the last one */ + for (i = 0; i < FT_NUM_MODULE_CLASSES; i++) + classes[i] = 0; + classes[FT_NUM_MODULE_CLASSES] = 0; + + i = 0; + +#include FT_CONFIG_MODULES_H + +Exit: + if (error) ft_destroy_default_module_classes( library ); + else pic_container->default_module_classes = classes; + + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ /* documentation is in ftmodapi.h */ @@ -86,16 +182,15 @@ /* test for valid `library' delayed to FT_Add_Module() */ - cur = ft_default_modules; + cur = FT_DEFAULT_MODULES_GET; while ( *cur ) { error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) - { - FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n", - (*cur)->module_name, error )); - } + FT_TRACE0(( "FT_Add_Default_Module:" + " Cannot install `%s', error = 0x%x\n", + (*cur)->module_name, error )); cur++; } } @@ -127,13 +222,7 @@ if ( error ) FT_Done_Memory( memory ); else - { - (*alibrary)->version_major = FREETYPE_MAJOR; - (*alibrary)->version_minor = FREETYPE_MINOR; - (*alibrary)->version_patch = FREETYPE_PATCH; - FT_Add_Default_Modules( *alibrary ); - } return error; } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftlcdfil.c b/reactos/lib/3rdparty/freetype/src/base/ftlcdfil.c index f40bbeae5fb..80640111c4f 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftlcdfil.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -161,7 +161,7 @@ #ifdef USE_LEGACY - /* FIR filter used by the default and light filters */ + /* intra-pixel filter used by the legacy filter */ static void _ft_lcd_filter_legacy( FT_Bitmap* bitmap, FT_Render_Mode mode, @@ -181,7 +181,7 @@ FT_UNUSED( library ); - /* horizontal in-place FIR filter */ + /* horizontal in-place intra-pixel filter */ if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) { FT_Byte* line = bitmap->buffer; @@ -266,7 +266,7 @@ #endif /* USE_LEGACY */ - FT_EXPORT( FT_Error ) + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { @@ -296,13 +296,13 @@ #elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - memcpy( library->lcd_weights, light_filter, 5 ); + ft_memcpy( library->lcd_weights, light_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; #else - memcpy( library->lcd_weights, default_filter, 5 ); + ft_memcpy( library->lcd_weights, default_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; @@ -311,7 +311,7 @@ break; case FT_LCD_FILTER_LIGHT: - memcpy( library->lcd_weights, light_filter, 5 ); + ft_memcpy( library->lcd_weights, light_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; break; @@ -335,7 +335,7 @@ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - FT_EXPORT( FT_Error ) + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { diff --git a/reactos/lib/3rdparty/freetype/src/base/ftmac.c b/reactos/lib/3rdparty/freetype/src/base/ftmac.c index fd6201adb5a..63f927d57d8 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftmac.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftmac.c @@ -8,7 +8,8 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, */ +/* 2009 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +68,9 @@ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_STREAM_H +#include "ftbase.h" /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ @@ -76,20 +79,36 @@ #undef OS_INLINE #define OS_INLINE static __inline__ #endif -#include <Carbon/Carbon.h> -#ifndef HFS_MAXPATHLEN -#define HFS_MAXPATHLEN 1024 + /* `configure' checks the availability of `ResourceIndex' strictly */ + /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ + /* not set (e.g., a build without `configure'), the availability */ + /* is guessed from the SDK version. */ +#ifndef HAVE_TYPE_RESOURCE_INDEX +#if !defined( MAC_OS_X_VERSION_10_5 ) || \ + ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) +#define HAVE_TYPE_RESOURCE_INDEX 0 +#else +#define HAVE_TYPE_RESOURCE_INDEX 1 +#endif +#endif /* !HAVE_TYPE_RESOURCE_INDEX */ + +#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) + typedef short ResourceIndex; #endif +#include <CoreServices/CoreServices.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/syslimits.h> /* PATH_MAX */ + + /* Don't want warnings about our own use of deprecated functions. */ #define FT_DEPRECATED_ATTRIBUTE #include FT_MAC_H - /* undefine blocking-macros in ftmac.h */ -#undef FT_GetFile_From_Mac_Name( a, b, c ) -#undef FT_GetFile_From_Mac_ATS_Name( a, b, c ) -#undef FT_New_Face_From_FSSpec( a, b, c, d ) +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over @@ -100,6 +119,7 @@ #endif + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -115,19 +135,28 @@ /* Private function. */ /* The FSSpec type has been discouraged for a long time, */ - /* but for some reason, there is no FSRef version of */ - /* ATSFontGetFileSpecification(), so we made our own. */ - /* Apple will provide one eventually. */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ static OSStatus FT_ATSFontGetFileReference( ATSFontRef ats_font_id, FSRef* ats_font_ref ) { -#if __LP64__ +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ FT_UNUSED( ats_font_id ); FT_UNUSED( ats_font_ref ); + return fnfErr; -#else +#else /* 32bit Carbon API on legacy platforms */ OSStatus err; FSSpec spec; @@ -214,7 +243,8 @@ FSSpec* pathSpec, FT_Long* face_index ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( fontName ); FT_UNUSED( pathSpec ); FT_UNUSED( face_index ); @@ -239,8 +269,8 @@ static OSErr - FT_FSPathMakeRes( const UInt8* pathname, - short* res ) + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) { OSErr err; FSRef ref; @@ -357,7 +387,7 @@ static void parse_fond( char* fond_data, short* have_sfnt, - short* sfnt_id, + ResID* sfnt_id, Str255 lwfn_file_name, short face_index ) { @@ -374,6 +404,10 @@ assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + /* Let's do a little range checking before we get too excited here */ if ( face_index < count_faces_sfnt( fond_data ) ) { @@ -425,9 +459,10 @@ ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } - if ( style->indexes[0] > 1 ) + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) { - unsigned char* suffixes = names[style->indexes[0] - 1]; + unsigned char* suffixes = names[style->indexes[face_index] - 1]; for ( i = 1; i <= suffixes[0]; i++ ) @@ -463,8 +498,8 @@ UInt8* path_lwfn, size_t path_size ) { - FSRef ref, par_ref; - int dirname_len; + FSRef ref, par_ref; + size_t dirname_len; /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ @@ -504,10 +539,10 @@ count_faces( Handle fond, const UInt8* pathname ) { - short sfnt_id; + ResID sfnt_id; short have_sfnt, have_lwfn; Str255 lwfn_file_name; - UInt8 buff[HFS_MAXPATHLEN]; + UInt8 buff[PATH_MAX]; FT_Error err; short num_faces; @@ -539,13 +574,13 @@ chunks are often not organized that way, so we glue chunks of the same type together. */ static FT_Error - read_lwfn( FT_Memory memory, - short res, - FT_Byte** pfb_data, - FT_ULong* size ) + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_id; + ResID res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong old_total_size = 0; @@ -563,7 +598,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -602,7 +637,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -654,120 +689,17 @@ } - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - static void - memory_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Create a new memory stream from a buffer and a size. */ - static FT_Error - new_memory_stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream_CloseFunc close, - FT_Stream* astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !base ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - if ( FT_NEW( stream ) ) - goto Exit; - - FT_Stream_OpenMemory( stream, base, size ); - - stream->close = close; - - *astream = stream; - - Exit: - return error; - } - - - /* Create a new FT_Face given a buffer and a driver name. */ - static FT_Error - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - char* driver_name, - FT_Face* aface ) - { - FT_Open_Args args; - FT_Error error; - FT_Stream stream; - FT_Memory memory = library->memory; - - - error = new_memory_stream( library, - base, - size, - memory_stream_close, - &stream ); - if ( error ) - { - FT_FREE( base ); - return error; - } - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - if ( driver_name ) - { - args.flags = args.flags | FT_OPEN_DRIVER; - args.driver = FT_Get_Module( library, driver_name ); - } - - /* At this point, face_index has served its purpose; */ - /* whoever calls this function has already used it to */ - /* locate the correct font data. We should not propagate */ - /* this index to FT_Open_Face() (unless it is negative). */ - - if ( face_index > 0 ) - face_index = 0; - - error = FT_Open_Face( library, &args, face_index, aface ); - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else - FT_Stream_Free( stream, 0 ); - - return error; - } - - - /* Create a new FT_Face from a file spec to an LWFN file. */ + /* Create a new FT_Face from a file path to an LWFN file. */ static FT_Error FT_New_Face_From_LWFN( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Byte* pfb_data; - FT_ULong pfb_size; - FT_Error error; - short res; + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) @@ -792,7 +724,7 @@ /* Create a new FT_Face from an SFNT resource, specified by res ID. */ static FT_Error FT_New_Face_From_SFNT( FT_Library library, - short sfnt_id, + ResID sfnt_id, FT_Long face_index, FT_Face* aface ) { @@ -801,11 +733,11 @@ size_t sfnt_size; FT_Error error = FT_Err_Ok; FT_Memory memory = library->memory; - int is_cff; + int is_cff, is_sfnt_ps; - sfnt = GetResource( 'sfnt', sfnt_id ); - if ( ResError() ) + sfnt = GetResource( TTAG_sfnt, sfnt_id ); + if ( sfnt == NULL ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -818,31 +750,56 @@ ft_memcpy( sfnt_data, *sfnt, sfnt_size ); ReleaseResource( sfnt ); - is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); - return open_face_from_buffer( library, - sfnt_data, - sfnt_size, - face_index, - is_cff ? "cff" : "truetype", - aface ); + if ( is_sfnt_ps ) + { + FT_Stream stream; + + + if ( FT_NEW( stream ) ) + goto Try_OpenType; + + FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); + if ( !open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ) ) + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + FT_FREE( sfnt_data ); + goto Exit; + } + + FT_FREE( stream ); + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; } - /* Create a new FT_Face from a file spec to a suitcase file. */ + /* Create a new FT_Face from a file path to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Error error = FT_Err_Cannot_Open_Resource; - short res_ref, res_index; - Handle fond; - short num_faces_in_res, num_faces_in_fond; + FT_Error error = FT_Err_Cannot_Open_Resource; + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res, num_faces_in_fond; if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) @@ -855,7 +812,7 @@ num_faces_in_res = 0; for ( res_index = 1; ; ++res_index ) { - fond = Get1IndResource( 'FOND', res_index ); + fond = Get1IndResource( TTAG_FOND, res_index ); if ( ResError() ) break; @@ -869,7 +826,7 @@ } CloseResFile( res_ref ); - if ( FT_Err_Ok == error && NULL != aface ) + if ( FT_Err_Ok == error && NULL != aface && NULL != *aface ) (*aface)->num_faces = num_faces_in_res; return error; } @@ -883,25 +840,25 @@ FT_Long face_index, FT_Face* aface ) { - short sfnt_id, have_sfnt, have_lwfn = 0; - short fond_id; + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; OSType fond_type; Str255 fond_name; Str255 lwfn_file_name; - UInt8 path_lwfn[HFS_MAXPATHLEN]; + UInt8 path_lwfn[PATH_MAX]; OSErr err; FT_Error error = FT_Err_Ok; GetResInfo( fond, &fond_id, &fond_type, fond_name ); - if ( ResError() != noErr || fond_type != 'FOND' ) + if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_Err_Invalid_File_Format; parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); if ( lwfn_file_name[0] ) { - short res; + ResFileRefNum res; res = HomeResFile( fond ); @@ -909,7 +866,7 @@ goto found_no_lwfn_file; { - UInt8 path_fond[HFS_MAXPATHLEN]; + UInt8 path_fond[PATH_MAX]; FSRef ref; @@ -961,7 +918,7 @@ /* LWFN is a (very) specific file format, check for it explicitly */ file_type = get_file_type_from_path( pathname ); - if ( file_type == 'LWFN' ) + if ( file_type == TTAG_LWFN ) return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); /* Otherwise the file type doesn't matter (there are more than */ @@ -1029,6 +986,8 @@ /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ /* accepts an FSRef instead of a path. */ /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1038,7 +997,7 @@ FT_Error error; FT_Open_Args args; OSErr err; - UInt8 pathname[HFS_MAXPATHLEN]; + UInt8 pathname[PATH_MAX]; if ( !ref ) @@ -1068,13 +1027,15 @@ /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ /* accepts an FSSpec instead of a path. */ /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec* spec, FT_Long face_index, FT_Face* aface ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( library ); FT_UNUSED( spec ); FT_UNUSED( face_index ); diff --git a/reactos/lib/3rdparty/freetype/src/base/ftmm.c b/reactos/lib/3rdparty/freetype/src/base/ftmm.c index 586d5e84db1..0307729811f 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftmm.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001, 2003, 2004 by */ +/* Copyright 1996-2001, 2003, 2004, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ *aservice, MULTI_MASTERS ); - if ( aservice ) + if ( *aservice ) error = FT_Err_Ok; } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftobjs.c b/reactos/lib/3rdparty/freetype/src/base/ftobjs.c index fa080940045..421540c8dc2 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftobjs.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ #include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_IDS_H #include FT_OUTLINE_H @@ -36,8 +37,11 @@ #include FT_SERVICE_KERNING_H #include FT_SERVICE_TRUETYPE_ENGINE_H +#include "ftbase.h" + #define GRID_FIT_METRICS + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -128,13 +132,14 @@ FT_Stream stream; + *astream = 0; + if ( !library ) return FT_Err_Invalid_Library_Handle; if ( !args ) return FT_Err_Invalid_Argument; - *astream = 0; memory = library->memory; if ( FT_NEW( stream ) ) @@ -196,6 +201,12 @@ } + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ #undef FT_COMPONENT #define FT_COMPONENT trace_objs @@ -244,7 +255,7 @@ FT_BASE_DEF( void ) ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) { - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); @@ -337,14 +348,18 @@ /* free bitmap buffer if needed */ ft_glyphslot_free_bitmap( slot ); - /* free glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) + /* slot->internal might be NULL in out-of-memory situations */ + if ( slot->internal ) { - FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; - } + /* free glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + FT_GlyphLoader_Done( slot->internal->loader ); + slot->internal->loader = 0; + } - FT_FREE( slot->internal ); + FT_FREE( slot->internal ); + } } @@ -542,7 +557,7 @@ FT_Driver driver; FT_GlyphSlot slot; FT_Library library; - FT_Bool autohint = 0; + FT_Bool autohint = FALSE; FT_Module hinter; @@ -577,31 +592,33 @@ * Determine whether we need to auto-hint or not. * The general rules are: * - * - Do only auto-hinting if we have a hinter module, - * a scalable font format dealing with outlines, - * and no transforms except simple slants. + * - Do only auto-hinting if we have a hinter module, a scalable font + * format dealing with outlines, and no transforms except simple + * slants and/or rotations by integer multiples of 90 degrees. * - * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set - * or if we don't have a native font hinter. + * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't + * have a native font hinter. * * - Otherwise, auto-hint for LIGHT hinting mode. * - * - Exception: The font requires the unpatented - * bytecode interpreter to load properly. + * - Exception: The font is `tricky' and requires the native hinter to + * load properly. */ - autohint = 0; - if ( hinter && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 && - ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && - face->internal->transform_matrix.yy > 0 && - face->internal->transform_matrix.yx == 0 ) + if ( hinter && + !( load_flags & FT_LOAD_NO_HINTING ) && + !( load_flags & FT_LOAD_NO_AUTOHINT ) && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + !FT_IS_TRICKY( face ) && + ( ( face->internal->transform_matrix.yx == 0 && + face->internal->transform_matrix.xx != 0 ) || + ( face->internal->transform_matrix.xx == 0 && + face->internal->transform_matrix.yx != 0 ) ) ) { - if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 || - !FT_DRIVER_HAS_HINTER( driver ) ) - autohint = 1; + if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || + !FT_DRIVER_HAS_HINTER( driver ) ) + autohint = TRUE; else { FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); @@ -609,7 +626,7 @@ if ( mode == FT_RENDER_MODE_LIGHT || face->internal->ignore_unpatented_hinter ) - autohint = 1; + autohint = TRUE; } } @@ -634,12 +651,24 @@ goto Load_Ok; } - /* load auto-hinted outline */ - hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + { + FT_Face_Internal internal = face->internal; + FT_Int transform_flags = internal->transform_flags; - error = hinting->load_glyph( (FT_AutoHinter)hinter, - slot, face->size, - glyph_index, load_flags ); + + /* since the auto-hinter calls FT_Load_Glyph by itself, */ + /* make sure that glyphs aren't transformed */ + internal->transform_flags = 0; + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); + + internal->transform_flags = transform_flags; + } } else { @@ -680,7 +709,7 @@ /* compute the linear advance in 16.16 pixels */ if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + ( FT_IS_SCALABLE( face ) ) ) { FT_Size_Metrics* metrics = &face->size->metrics; @@ -883,14 +912,13 @@ /* are limited to the BMP (said UCS-2 encoding.) */ /* */ /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE). */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ /* */ static FT_Error find_unicode_charmap( FT_Face face ) { FT_CharMap* first; FT_CharMap* cur; - FT_CharMap* unicmap = NULL; /* some UCS-2 map, if we found it */ /* caller should have already checked that `face' is valid */ @@ -935,36 +963,75 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { - unicmap = cur; /* record we found a Unicode charmap */ - - /* XXX If some new encodings to represent UCS-4 are added, */ - /* they should be added here. */ + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - - /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } } - /* We do not have any UCS-4 charmap. Sigh. */ - /* Let's see if we have some other kind of Unicode charmap, though. */ - if ( unicmap != NULL ) + /* We do not have any UCS-4 charmap. */ + /* Do the loop again and search for UCS-2 charmaps. */ + cur = first + face->num_charmaps; + + for ( ; --cur >= first; ) { - face->charmap = unicmap[0]; - return 0; + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + face->charmap = cur[0]; + return FT_Err_Ok; + } } - /* Chou blanc! */ return FT_Err_Invalid_CharMap_Handle; } + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_variant_selector_charmap */ + /* */ + /* <Description> */ + /* This function finds the variant selector charmap, if there is one. */ + /* There can only be one (platform=0, specific=5, format=14). */ + /* */ + static FT_CharMap + find_variant_selector_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* end; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return NULL; + + end = first + face->num_charmaps; /* points after the last one */ + + for ( cur = first; cur < end; ++cur ) + { + if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && + FT_Get_CMap_Format( cur[0] ) == 14 ) + return cur[0]; + } + + return NULL; + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -1013,15 +1080,17 @@ for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) - face->internal->incremental_interface = params[i].data; + face->internal->incremental_interface = + (FT_Incremental_Interface)params[i].data; } #endif - error = clazz->init_face( stream, - face, - (FT_Int)face_index, - num_params, - params ); + if ( clazz->init_face ) + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); if ( error ) goto Fail; @@ -1044,7 +1113,8 @@ if ( error ) { destroy_charmaps( face, memory ); - clazz->done_face( face ); + if ( clazz->done_face ) + clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); *aface = 0; @@ -1057,7 +1127,7 @@ /* there's a Mac-specific extended implementation of FT_New_Face() */ /* in src/base/ftmac.c */ -#ifndef FT_MACINTOSH +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) /* documentation is in freetype.h */ @@ -1076,11 +1146,12 @@ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; + args.stream = NULL; return FT_Open_Face( library, &args, face_index, aface ); } -#endif /* !FT_MACINTOSH */ +#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */ /* documentation is in freetype.h */ @@ -1102,12 +1173,13 @@ args.flags = FT_OPEN_MEMORY; args.memory_base = file_base; args.memory_size = file_size; + args.stream = NULL; return FT_Open_Face( library, &args, face_index, aface ); } -#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) +#ifdef FT_CONFIG_OPTION_MAC_FONTS /* The behavior here is very similar to that in base/ftmac.c, but it */ /* is designed to work on non-mac systems, so no mac specific calls. */ @@ -1136,9 +1208,9 @@ /* we don't really have access to it. */ - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - /* from ftmac.c */ + /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ + /* It frees the memory it uses. */ + /* From ftmac.c. */ static void memory_stream_close( FT_Stream stream ) { @@ -1154,7 +1226,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* from ftmac.c */ + /* From ftmac.c. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1191,7 +1263,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ /* from ftmac.c */ - static FT_Error + FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, FT_ULong size, @@ -1224,20 +1296,172 @@ args.driver = FT_Get_Module( library, driver_name ); } +#ifdef FT_MACINTOSH + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; +#endif + error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else +#ifdef FT_MACINTOSH + FT_Stream_Free( stream, 0 ); +#else { FT_Stream_Close( stream ); FT_FREE( stream ); } +#endif return error; } + /* Look up `TYP1' or `CID ' table from sfnt table directory. */ + /* `offset' and `length' must exclude the binary header in tables. */ + + /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ + /* format too. Here, since we can't expect that the TrueType font */ + /* driver is loaded unconditially, we must parse the font by */ + /* ourselves. We are only interested in the name of the table and */ + /* the offset. */ + + static FT_Error + ft_lookup_PS_in_sfnt_stream( FT_Stream stream, + FT_Long face_index, + FT_ULong* offset, + FT_ULong* length, + FT_Bool* is_sfnt_cid ) + { + FT_Error error; + FT_UShort numTables; + FT_Long pstable_index; + FT_ULong tag; + int i; + + + *offset = 0; + *length = 0; + *is_sfnt_cid = FALSE; + + /* TODO: support for sfnt-wrapped PS/CID in TTC format */ + + /* version check for 'typ1' (should be ignored?) */ + if ( FT_READ_ULONG( tag ) ) + return error; + if ( tag != TTAG_typ1 ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_USHORT( numTables ) ) + return error; + if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ + return error; + + pstable_index = -1; + *is_sfnt_cid = FALSE; + + for ( i = 0; i < numTables; i++ ) + { + if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || + FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) + return error; + + if ( tag == TTAG_CID ) + { + pstable_index++; + *offset += 22; + *length -= 22; + *is_sfnt_cid = TRUE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + else if ( tag == TTAG_TYP1 ) + { + pstable_index++; + *offset += 24; + *length -= 24; + *is_sfnt_cid = FALSE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + if ( face_index >= 0 && pstable_index == face_index ) + return FT_Err_Ok; + } + return FT_Err_Table_Missing; + } + + + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ) + { + FT_Error error; + FT_Memory memory = library->memory; + FT_ULong offset, length; + FT_Long pos; + FT_Bool is_sfnt_cid; + FT_Byte* sfnt_ps; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + pos = FT_Stream_Pos( stream ); + + error = ft_lookup_PS_in_sfnt_stream( stream, + face_index, + &offset, + &length, + &is_sfnt_cid ); + if ( error ) + goto Exit; + + if ( FT_Stream_Seek( stream, pos + offset ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); + if ( error ) + goto Exit; + + error = open_face_from_buffer( library, + sfnt_ps, + length, + face_index < 0 ? face_index : 0, + is_sfnt_cid ? "cid" : "type1", + aface ); + Exit: + { + FT_Error error1; + + + if ( error == FT_Err_Unknown_File_Format ) + { + error1 = FT_Stream_Seek( stream, pos ); + if ( error1 ) + return error1; + } + + return error; + } + } + + +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) + /* The resource header says we've got resource_cnt `POST' (type1) */ /* resources in this file. They all need to be coalesced into */ /* one lump which gets passed on to the type1 driver. */ @@ -1392,17 +1616,25 @@ if ( rlen == -1 ) return FT_Err_Cannot_Open_Resource; + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ); + if ( !error ) + goto Exit; + + /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ + if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + goto Exit; + if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) return error; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); if ( error ) goto Exit; - is_cff = rlen > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; - + is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); error = open_face_from_buffer( library, sfnt_data, rlen, @@ -1441,7 +1673,7 @@ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + TTAG_POST, &data_offsets, &count ); if ( !error ) { @@ -1456,7 +1688,7 @@ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - FT_MAKE_TAG( 's', 'f', 'n', 't' ), + TTAG_sfnt, &data_offsets, &count ); if ( !error ) { @@ -1488,6 +1720,9 @@ FT_Long dlen, offset; + if ( NULL == stream ) + return FT_Err_Invalid_Stream_Operation; + error = FT_Stream_Seek( stream, 0 ); if ( error ) goto Exit; @@ -1544,7 +1779,7 @@ FT_Error errors[FT_RACCESS_N_RULES]; FT_Open_Args args2; - FT_Stream stream2; + FT_Stream stream2 = 0; FT_Raccess_Guess( library, stream, @@ -1599,7 +1834,7 @@ } - /* Check for some macintosh formats. */ + /* Check for some macintosh formats without Carbon framework. */ /* Is this a macbinary file? If so look at the resource fork. */ /* Is this a mac dfont file? */ /* Is this an old style resource fork? (in data) */ @@ -1642,6 +1877,7 @@ face_index, aface, args ); return error; } +#endif #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ @@ -1657,10 +1893,12 @@ FT_Error error; FT_Driver driver; FT_Memory memory; - FT_Stream stream; + FT_Stream stream = 0; FT_Face face = 0; FT_ListNode node = 0; FT_Bool external_stream; + FT_Module* cur; + FT_Module* limit; /* test for valid `library' delayed to */ @@ -1675,7 +1913,7 @@ /* create input stream */ error = FT_Stream_New( library, args, &stream ); if ( error ) - goto Exit; + goto Fail3; memory = library->memory; @@ -1712,8 +1950,8 @@ else { /* check each font driver for an appropriate format */ - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; + cur = library->modules; + limit = cur + library->num_modules; for ( ; cur < limit; cur++ ) @@ -1738,6 +1976,28 @@ if ( !error ) goto Success; +#ifdef FT_CONFIG_OPTION_MAC_FONTS + if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + FT_ERROR_BASE( error ) == FT_Err_Table_Missing ) + { + /* TrueType but essential tables are missing */ + if ( FT_Stream_Seek( stream, 0 ) ) + break; + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + num_params, + params, + aface ); + if ( !error ) + { + FT_Stream_Free( stream, external_stream ); + return error; + } + } +#endif + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) goto Fail3; } @@ -1747,7 +2007,8 @@ /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */ /* it may be because we have an empty data fork, so we need to check */ /* the resource fork. */ - if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && + if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream && + FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) goto Fail2; @@ -2143,12 +2404,24 @@ ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, FT_Pos advance ) { + FT_Pos height = metrics->height; + + + /* compensate for glyph with bbox above/below the baseline */ + if ( metrics->horiBearingY < 0 ) + { + if ( height < metrics->horiBearingY ) + height = metrics->horiBearingY; + } + else if ( metrics->horiBearingY > 0 ) + height -= metrics->horiBearingY; + /* the factor 1.2 is a heuristical value */ if ( !advance ) - advance = metrics->height * 12 / 10; + advance = height * 12 / 10; - metrics->vertBearingX = -( metrics->width / 2 ); - metrics->vertBearingY = ( advance - metrics->height ) / 2; + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = ( advance - height ) / 2; metrics->vertAdvance = advance; } @@ -2212,8 +2485,8 @@ } else { - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; metrics->ascender = bsize->y_ppem; metrics->descender = 0; metrics->height = bsize->height << 6; @@ -2324,8 +2597,8 @@ else { FT_ZERO( metrics ); - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; } } @@ -2631,6 +2904,8 @@ cur = face->charmaps; if ( !cur ) return FT_Err_Invalid_CharMap_Handle; + if ( FT_Get_CMap_Format( charmap ) == 14 ) + return FT_Err_Invalid_Argument; limit = cur + face->num_charmaps; @@ -2791,7 +3066,12 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - result = cmap->clazz->char_index( cmap, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); } return result; } @@ -2849,6 +3129,186 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_UInt result = 0; + + + if ( face && face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + FT_CMap ucmap = FT_CMAP( face->charmap ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Int result = -1; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variant_list( vcmap, memory ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); + } + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->variantchar_list( vcmap, memory, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) @@ -2891,7 +3351,7 @@ ((FT_Byte*)buffer)[0] = 0; if ( face && - glyph_index <= (FT_UInt)face->num_glyphs && + (FT_Long)glyph_index <= face->num_glyphs && FT_HAS_GLYPH_NAMES( face ) ) { FT_Service_GlyphDict service; @@ -2991,6 +3451,7 @@ FT_ULong *length ) { FT_Service_SFNT_Table service; + FT_ULong offset; if ( !face || !FT_IS_SFNT( face ) ) @@ -3000,7 +3461,7 @@ if ( service == NULL ) return FT_Err_Unimplemented_Feature; - return service->table_info( face, table_index, tag, length ); + return service->table_info( face, table_index, tag, &offset, length ); } @@ -3061,11 +3522,11 @@ if ( size == NULL ) - return FT_Err_Bad_Argument; + return FT_Err_Invalid_Argument; face = size->face; if ( face == NULL || face->driver == NULL ) - return FT_Err_Bad_Argument; + return FT_Err_Invalid_Argument; /* we don't need anything more complex than that; all size objects */ /* are already listed by the face */ @@ -3325,7 +3786,7 @@ while ( renderer ) { error = renderer->render( renderer, slot, render_mode, NULL ); - if ( !error || + if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) break; @@ -3723,11 +4184,23 @@ library->memory = memory; +#ifdef FT_CONFIG_OPTION_PIC + /* initialize position independent code containers */ + error = ft_pic_container_init( library ); + if ( error ) + goto Fail; +#endif + /* allocate the render pool */ library->raster_pool_size = FT_RENDER_POOL_SIZE; - if ( FT_RENDER_POOL_SIZE > 0 ) - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; +#if FT_RENDER_POOL_SIZE > 0 + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; +#endif + + library->version_major = FREETYPE_MAJOR; + library->version_minor = FREETYPE_MINOR; + library->version_patch = FREETYPE_PATCH; /* That's ok now */ *alibrary = library; @@ -3735,6 +4208,9 @@ return FT_Err_Ok; Fail: +#ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +#endif FT_FREE( library ); return error; } @@ -3812,7 +4288,11 @@ faces = &FT_DRIVER(module)->faces_list; while ( faces->head ) + { FT_Done_Face( FT_FACE( faces->head->data ) ); + if ( faces->head ) + FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); + } } } @@ -3847,6 +4327,11 @@ FT_FREE( library->raster_pool ); library->raster_pool_size = 0; +#ifdef FT_CONFIG_OPTION_PIC + /* Destroy pic container contents */ + ft_pic_container_destroy( library ); +#endif + FT_FREE( library ); return FT_Err_Ok; } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftotval.c b/reactos/lib/3rdparty/freetype/src/base/ftotval.c index b6de6db85d1..20ed686eee6 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftotval.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +18,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_OPENTYPE_VALIDATE_H +#include FT_OPENTYPE_VALIDATE_H /* documentation is in ftotval.h */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftoutln.c b/reactos/lib/3rdparty/freetype/src/base/ftoutln.c index 6926f3a09a7..49ef82e27d8 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftoutln.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include <ft2build.h> #include FT_OUTLINE_H #include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H #include FT_TRIGONOMETRY_H @@ -83,21 +84,25 @@ FT_Int last; /* index of last point in contour */ + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + last = outline->contours[n]; if ( last < 0 ) goto Invalid_Outline; limit = outline->points + last; - v_start = outline->points[first]; - v_last = outline->points[last]; + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -128,6 +133,8 @@ tags--; } + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->move_to( &v_start, user ); if ( error ) goto Exit; @@ -148,6 +155,8 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); error = func_interface->line_to( &vec, user ); if ( error ) goto Exit; @@ -174,6 +183,10 @@ if ( tag == FT_CURVE_TAG_ON ) { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &vec, user ); if ( error ) goto Exit; @@ -186,6 +199,10 @@ v_middle.x = ( v_control.x + vec.x ) / 2; v_middle.y = ( v_control.y + vec.y ) / 2; + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &v_middle, user ); if ( error ) goto Exit; @@ -194,6 +211,10 @@ goto Do_Conic; } + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &v_start, user ); goto Close; @@ -209,8 +230,11 @@ point += 2; tags += 2; - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); if ( point <= limit ) { @@ -220,12 +244,22 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); if ( error ) goto Exit; continue; } + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); goto Close; } @@ -233,6 +267,8 @@ } /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->line_to( &v_start, user ); Close: @@ -242,9 +278,11 @@ first = last + 1; } - return 0; + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return FT_Err_Ok; Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); return error; Invalid_Outline: @@ -474,12 +512,14 @@ FT_Pos yOffset ) { FT_UShort n; - FT_Vector* vec = outline->points; + FT_Vector* vec; if ( !outline ) return; + vec = outline->points; + for ( n = 0; n < outline->n_points; n++ ) { vec->x += xOffset; @@ -556,7 +596,7 @@ FT_Raster_Params* params ) { FT_Error error; - FT_Bool update = 0; + FT_Bool update = FALSE; FT_Renderer renderer; FT_ListNode node; @@ -587,7 +627,7 @@ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); - update = 1; + update = TRUE; } /* if we changed the current renderer for the glyph image format */ @@ -626,13 +666,13 @@ } - /* documentation is in ftoutln.h */ + /* documentation is in freetype.h */ FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vector, const FT_Matrix* matrix ) { - FT_Pos xz, yz; + FT_Pos xz, yz; if ( !vector || !matrix ) @@ -1005,7 +1045,7 @@ } } - if ( xmin == 32768 ) + if ( xmin == 32768L ) return FT_ORIENTATION_TRUETYPE; ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftpatent.c b/reactos/lib/3rdparty/freetype/src/base/ftpatent.c index d63f191c3ea..236d9a674c4 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftpatent.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftpatent.c @@ -5,7 +5,7 @@ /* FreeType API for checking patented TrueType bytecode instructions */ /* (body). */ /* */ -/* Copyright 2007 by David Turner. */ +/* Copyright 2007, 2008 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -103,6 +103,7 @@ } Exit: + FT_UNUSED( error ); FT_FRAME_EXIT(); return result; } @@ -113,7 +114,7 @@ FT_ULong tag ) { FT_Stream stream = face->stream; - FT_Error error; + FT_Error error = FT_Err_Ok; FT_Service_SFNT_Table service; FT_Bool result = FALSE; @@ -122,15 +123,18 @@ if ( service ) { - FT_ULong offset, size; + FT_UInt i = 0; + FT_ULong tag_i = 0, offset_i, length_i; + for ( i = 0; !error && tag_i != tag ; i++ ) + error = service->table_info( face, i, + &tag_i, &offset_i, &length_i ); - error = service->table_info( face, tag, &offset, &size ); if ( error || - FT_STREAM_SEEK( offset ) ) + FT_STREAM_SEEK( offset_i ) ) goto Exit; - result = _tt_check_patents_in_range( stream, size ); + result = _tt_check_patents_in_range( stream, length_i ); } Exit: @@ -260,7 +264,7 @@ FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ) { - FT_Bool result = 0; + FT_Bool result = FALSE; #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftpfr.c b/reactos/lib/3rdparty/freetype/src/base/ftpfr.c index 9e930ddf7e3..f9592bb1bba 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftpfr.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002, 2003, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,6 +46,9 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_Err_Invalid_Argument; + service = ft_pfr_check( face ); if ( service ) { @@ -55,14 +58,17 @@ ametrics_x_scale, ametrics_y_scale ); } - else if ( face ) + else { FT_Fixed x_scale, y_scale; /* this is not a PFR font */ - *aoutline_resolution = face->units_per_EM; - *ametrics_resolution = face->units_per_EM; + if ( aoutline_resolution ) + *aoutline_resolution = face->units_per_EM; + + if ( ametrics_resolution ) + *ametrics_resolution = face->units_per_EM; x_scale = y_scale = 0x10000L; if ( face->size ) @@ -70,11 +76,15 @@ x_scale = face->size->metrics.x_scale; y_scale = face->size->metrics.y_scale; } - *ametrics_x_scale = x_scale; - *ametrics_y_scale = y_scale; + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + error = FT_Err_Unknown_File_Format; } - else - error = FT_Err_Invalid_Argument; return error; } @@ -92,14 +102,15 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_Err_Invalid_Argument; + service = ft_pfr_check( face ); if ( service ) error = service->get_kerning( face, left, right, avector ); - else if ( face ) + else error = FT_Get_Kerning( face, left, right, FT_KERNING_UNSCALED, avector ); - else - error = FT_Err_Invalid_Argument; return error; } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftpic.c b/reactos/lib/3rdparty/freetype/src/base/ftpic.c new file mode 100644 index 00000000000..d5271a9726a --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftpic.c @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* ftpic.c */ +/* */ +/* The FreeType position independent code services (body). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* documentation is in ftpic.h */ + + FT_BASE_DEF( FT_Error ) + ft_pic_container_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + + FT_MEM_SET( pic_container, 0, sizeof(*pic_container) ); + + error = ft_base_pic_init( library ); + if(error) + return error; + + return FT_Err_Ok; + } + + + /* Destroy the contents of the container. */ + FT_BASE_DEF( void ) + ft_pic_container_destroy( FT_Library library ) + { + ft_base_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftrfork.c b/reactos/lib/3rdparty/freetype/src/base/ftrfork.c index a4f726d9303..133c2de0575 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftrfork.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -132,6 +132,19 @@ } + static int + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, + FT_RFork_Ref* b ) + { + if ( a->res_id < b->res_id ) + return -1; + else if ( a->res_id > b->res_id ) + return 1; + else + return 0; + } + + FT_BASE_DEF( FT_Error ) FT_Raccess_Get_DataOffsets( FT_Library library, FT_Stream stream, @@ -141,12 +154,13 @@ FT_Long **offsets, FT_Long *count ) { - FT_Error error; - int i, j, cnt, subcnt; - FT_Long tag_internal, rpos; - FT_Memory memory = library->memory; - FT_Long temp; - FT_Long *offsets_internal; + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + FT_RFork_Ref *ref; error = FT_Stream_Seek( stream, map_offset ); @@ -179,28 +193,43 @@ if ( error ) return error; - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + if ( FT_NEW_ARRAY( ref, *count ) ) return error; for ( j = 0; j < *count; ++j ) { - (void)FT_STREAM_SKIP( 2 ); /* resource id */ - (void)FT_STREAM_SKIP( 2 ); /* rsource name */ - + if ( FT_READ_USHORT( ref[j].res_id ) ) + goto Exit; + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + goto Exit; if ( FT_READ_LONG( temp ) ) - { - FT_FREE( offsets_internal ); - return error; - } + goto Exit; + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; - offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); - - (void)FT_STREAM_SKIP( 4 ); /* mbz */ + ref[j].offset = temp & 0xFFFFFFL; } - *offsets = offsets_internal; + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); - return FT_Err_Ok; + if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + goto Exit; + + /* XXX: duplicated reference ID, + * gap between reference IDs are acceptable? + * further investigation on Apple implementation is needed. + */ + for ( j = 0; j < *count; ++j ) + offsets_internal[j] = rdata_pos + ref[j].offset; + + *offsets = offsets_internal; + error = FT_Err_Ok; + + Exit: + FT_FREE( ref ); + return error; } } @@ -227,7 +256,7 @@ typedef FT_Error (*raccess_guess_func)( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -235,56 +264,63 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -298,7 +334,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ); @@ -329,6 +365,7 @@ raccess_guess_apple_double, raccess_guess_apple_single, raccess_guess_darwin_ufs_export, + raccess_guess_darwin_newvfs, raccess_guess_darwin_hfsplus, raccess_guess_vfat, raccess_guess_linux_cap, @@ -339,7 +376,11 @@ for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) { new_names[i] = NULL; - errors[i] = FT_Stream_Seek( stream, 0 ); + if ( NULL != stream ) + errors[i] = FT_Stream_Seek( stream, 0 ); + else + errors[i] = FT_Err_Ok; + if ( errors[i] ) continue ; @@ -354,14 +395,20 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { - FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 ); + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x07; *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -370,14 +417,20 @@ static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { - FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00); + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x00; *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -386,7 +439,7 @@ static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -416,7 +469,7 @@ static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -433,7 +486,7 @@ memory = library->memory; - if ( base_file_len > FT_INT_MAX ) + if ( base_file_len + 6 > FT_INT_MAX ) return FT_Err_Array_Too_Large; if ( FT_ALLOC( newpath, base_file_len + 6 ) ) @@ -449,10 +502,46 @@ } + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with Mac OS X (> 10.1). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + FT_Long base_file_len = ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 18 > FT_INT_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -479,7 +568,7 @@ static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -505,7 +594,7 @@ static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -536,7 +625,7 @@ static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -568,7 +657,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ) { @@ -620,8 +709,12 @@ return FT_Err_Ok; } else - FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + { + error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + if ( error ) + return error; } + } return FT_Err_Unknown_File_Format; } @@ -629,7 +722,7 @@ static FT_Error raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, + char *file_name, FT_Long *result_offset ) { FT_Open_Args args2; @@ -659,9 +752,9 @@ const char *insertion ) { char* new_name; - char* tmp; + const char* tmp; const char* slash; - unsigned new_length; + size_t new_length; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); @@ -701,7 +794,7 @@ FT_BASE_DEF( void ) FT_Raccess_Guess( FT_Library library, FT_Stream stream, - char* base_name, + char *base_name, char **new_names, FT_Long *offsets, FT_Error *errors ) diff --git a/reactos/lib/3rdparty/freetype/src/base/ftsnames.c b/reactos/lib/3rdparty/freetype/src/base/ftsnames.c new file mode 100644 index 00000000000..3447888ca23 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/base/ftsnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftsnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftstream.c b/reactos/lib/3rdparty/freetype/src/base/ftstream.c index a067a1fde7d..b638599dbcf 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftstream.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,13 +60,12 @@ FT_Error error = FT_Err_Ok; - stream->pos = pos; - if ( stream->read ) { if ( stream->read( stream, pos, 0, 0 ) ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -75,12 +74,16 @@ /* note that seeking to the first position after the file is valid */ else if ( pos > stream->size ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; } + if ( !error ) + stream->pos = pos; + return error; } @@ -89,6 +92,9 @@ FT_Stream_Skip( FT_Stream stream, FT_Long distance ) { + if ( distance < 0 ) + return FT_Err_Invalid_Stream_Operation; + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); } @@ -121,7 +127,8 @@ if ( pos >= stream->size ) { - FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); return FT_Err_Invalid_Stream_Operation; @@ -142,8 +149,8 @@ if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_ReadAt:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); error = FT_Err_Invalid_Stream_Operation; @@ -208,7 +215,7 @@ FT_Stream_ReleaseFrame( FT_Stream stream, FT_Byte** pbytes ) { - if ( stream->read ) + if ( stream && stream->read ) { FT_Memory memory = stream->memory; @@ -253,8 +260,8 @@ stream->base, count ); if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); FT_FREE( stream->base ); @@ -270,8 +277,8 @@ if ( stream->pos >= stream->size || stream->pos + count > stream->size ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", stream->pos, count, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -456,7 +463,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadChar:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -502,8 +510,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShort:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShort:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -549,8 +557,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShortLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShortLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -596,8 +604,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadOffset:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadOffset:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -642,9 +650,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLong:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } @@ -688,10 +697,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLongLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLongLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } @@ -704,12 +713,13 @@ { FT_Error error; FT_Bool frame_accessed = 0; - FT_Byte* cursor = stream->cursor; - + FT_Byte* cursor; if ( !fields || !stream ) return FT_Err_Invalid_Argument; + cursor = stream->cursor; + error = FT_Err_Ok; do { diff --git a/reactos/lib/3rdparty/freetype/src/base/ftstroke.c b/reactos/lib/3rdparty/freetype/src/base/ftstroke.c index 8f7e0459da4..0978b0ed947 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftstroke.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -230,7 +230,7 @@ /***************************************************************************/ /***************************************************************************/ - typedef enum + typedef enum FT_StrokeTags_ { FT_STROKE_TAG_ON = 1, /* on-curve point */ FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ @@ -261,7 +261,7 @@ { FT_UInt old_max = border->max_points; FT_UInt new_max = border->num_points + new_points; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; if ( new_max > old_max ) @@ -279,6 +279,7 @@ border->max_points = cur_max; } + Exit: return error; } @@ -346,7 +347,7 @@ } border->start = -1; - border->movable = 0; + border->movable = FALSE; } @@ -355,7 +356,7 @@ FT_Vector* to, FT_Bool movable ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_ASSERT( border->start >= 0 ); @@ -410,7 +411,7 @@ border->num_points += 2; } - border->movable = 0; + border->movable = FALSE; return error; } @@ -443,7 +444,7 @@ border->num_points += 3; } - border->movable = 0; + border->movable = FALSE; return error; } @@ -461,7 +462,7 @@ FT_Angle total, angle, step, rotate, next, theta; FT_Vector a, b, a2, b2; FT_Fixed length; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; /* compute start point */ @@ -527,12 +528,12 @@ { /* close current open path if any ? */ if ( border->start >= 0 ) - ft_stroke_border_close( border, 0 ); + ft_stroke_border_close( border, FALSE ); border->start = border->num_points; - border->movable = 0; + border->movable = FALSE; - return ft_stroke_border_lineto( border, to, 0 ); + return ft_stroke_border_lineto( border, to, FALSE ); } @@ -547,7 +548,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -556,7 +557,7 @@ { border->num_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -572,7 +573,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -581,7 +582,7 @@ FT_UInt *anum_points, FT_UInt *anum_contours ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_UInt num_points = 0; FT_UInt num_contours = 0; @@ -605,9 +606,6 @@ if ( tags[0] & FT_STROKE_TAG_END ) { - if ( in_contour == 0 ) - goto Fail; - in_contour = 0; num_contours++; } @@ -616,7 +614,7 @@ if ( in_contour != 0 ) goto Fail; - border->valid = 1; + border->valid = TRUE; Exit: *anum_points = num_points; @@ -708,7 +706,7 @@ FT_Bool valid; FT_StrokeBorderRec borders[2]; - FT_Memory memory; + FT_Library library; } FT_StrokerRec; @@ -731,7 +729,7 @@ if ( !FT_NEW( stroker ) ) { - stroker->memory = memory; + stroker->library = library; ft_stroke_border_init( &stroker->borders[0], memory ); ft_stroke_border_init( &stroker->borders[1], memory ); @@ -779,13 +777,13 @@ { if ( stroker ) { - FT_Memory memory = stroker->memory; + FT_Memory memory = stroker->library->memory; ft_stroke_border_done( &stroker->borders[0] ); ft_stroke_border_done( &stroker->borders[1] ); - stroker->memory = NULL; + stroker->library = NULL; FT_FREE( stroker ); } } @@ -798,7 +796,7 @@ { FT_Angle total, rotate; FT_Fixed radius = stroker->radius; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_StrokeBorder border = stroker->borders + side; @@ -813,7 +811,7 @@ radius, stroker->angle_in + rotate, total ); - border->movable = 0; + border->movable = FALSE; return error; } @@ -824,7 +822,7 @@ FT_Angle angle, FT_Int side ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) @@ -849,7 +847,7 @@ delta.x += stroker->center.x + delta2.x; delta.y += stroker->center.y + delta2.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -859,7 +857,32 @@ delta.x += delta2.x + stroker->center.x; delta.y += delta2.y + stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) + { + /* add a butt ending */ + FT_Vector delta; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta, radius, angle + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta, radius, angle - rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); } Exit: @@ -876,7 +899,7 @@ FT_Angle phi, theta, rotate; FT_Fixed length, thcos, sigma; FT_Vector delta; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; rotate = FT_SIDE_TO_ROTATE( side ); @@ -900,7 +923,7 @@ stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; - border->movable = 0; + border->movable = FALSE; } else { @@ -911,7 +934,7 @@ delta.y += stroker->center.y; } - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); return error; } @@ -928,9 +951,7 @@ if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) - { error = ft_stroker_arcto( stroker, side ); - } else { /* this is a mitered or beveled corner */ @@ -943,7 +964,7 @@ rotate = FT_SIDE_TO_ROTATE( side ); miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); if ( theta == FT_ANGLE_PI ) { theta = rotate; @@ -959,7 +980,7 @@ sigma = FT_MulFix( stroker->miter_limit, thcos ); if ( sigma >= 0x10000L ) - miter = 0; + miter = FALSE; if ( miter ) /* this is a miter (broken angle) */ { @@ -983,7 +1004,7 @@ delta.x += middle.x; delta.y += middle.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -992,7 +1013,7 @@ delta.x += middle.x; delta.y += middle.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -1001,7 +1022,7 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 1 ); + error = ft_stroke_border_lineto( border, &delta, TRUE ); } else /* this is a bevel (intersection) */ @@ -1016,8 +1037,9 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; /* now add end point */ FT_Vector_From_Polar( &delta, stroker->radius, @@ -1025,7 +1047,7 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 1 ); + error = ft_stroke_border_lineto( border, &delta, TRUE ); } } @@ -1037,7 +1059,7 @@ static FT_Error ft_stroker_process_corner( FT_Stroker stroker ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Angle turn; FT_Int inside_side; @@ -1069,7 +1091,7 @@ /* add two points to the left and right borders corresponding to the */ - /* start of the subpath.. */ + /* start of the subpath */ static FT_Error ft_stroker_subpath_start( FT_Stroker stroker, FT_Angle start_angle ) @@ -1099,7 +1121,7 @@ /* save angle for last cap */ stroker->subpath_angle = start_angle; - stroker->first_point = 0; + stroker->first_point = FALSE; Exit: return error; @@ -1112,7 +1134,7 @@ FT_Stroker_LineTo( FT_Stroker stroker, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_StrokeBorder border; FT_Vector delta; FT_Angle angle; @@ -1143,7 +1165,7 @@ goto Exit; } - /* now add a line segment to both the "inside" and "outside" paths */ + /* now add a line segment to both the `inside' and `outside' paths */ for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) { @@ -1153,7 +1175,7 @@ point.x = to->x + delta.x; point.y = to->y + delta.y; - error = ft_stroke_border_lineto( border, &point, 1 ); + error = ft_stroke_border_lineto( border, &point, TRUE ); if ( error ) goto Exit; @@ -1176,12 +1198,12 @@ FT_Vector* control, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Vector bez_stack[34]; FT_Vector* arc; FT_Vector* limit = bez_stack + 30; FT_Angle start_angle; - FT_Bool first_arc = 1; + FT_Bool first_arc = TRUE; arc = bez_stack; @@ -1206,7 +1228,7 @@ if ( first_arc ) { - first_arc = 0; + first_arc = FALSE; start_angle = angle_in; @@ -1275,12 +1297,12 @@ FT_Vector* control2, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Vector bez_stack[37]; FT_Vector* arc; FT_Vector* limit = bez_stack + 32; FT_Angle start_angle; - FT_Bool first_arc = 1; + FT_Bool first_arc = TRUE; arc = bez_stack; @@ -1308,7 +1330,7 @@ if ( first_arc ) { - first_arc = 0; + first_arc = FALSE; /* process corner if necessary */ start_angle = angle_in; @@ -1386,15 +1408,16 @@ { /* We cannot process the first point, because there is not enough */ /* information regarding its corner/cap. The latter will be processed */ - /* in the "end_subpath" routine. */ + /* in the `FT_Stroker_EndSubPath' routine. */ /* */ - stroker->first_point = 1; - stroker->center = *to; - stroker->subpath_open = open; + stroker->first_point = TRUE; + stroker->center = *to; + stroker->subpath_open = open; - /* record the subpath start point index for each border */ + /* record the subpath start point for each border */ stroker->subpath_start = *to; - return 0; + + return FT_Err_Ok; } @@ -1402,10 +1425,10 @@ ft_stroker_add_reverse_left( FT_Stroker stroker, FT_Bool open ) { - FT_StrokeBorder right = stroker->borders + 0; - FT_StrokeBorder left = stroker->borders + 1; + FT_StrokeBorder right = stroker->borders + 0; + FT_StrokeBorder left = stroker->borders + 1; FT_Int new_points; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_ASSERT( left->start >= 0 ); @@ -1452,8 +1475,8 @@ left->num_points = left->start; right->num_points += new_points; - right->movable = 0; - left->movable = 0; + right->movable = FALSE; + left->movable = FALSE; } Exit: @@ -1467,7 +1490,8 @@ FT_EXPORT_DEF( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; + if ( stroker->subpath_open ) { @@ -1480,8 +1504,8 @@ if ( error ) goto Exit; - /* add reversed points from "left" to "right" */ - error = ft_stroker_add_reverse_left( stroker, 1 ); + /* add reversed points from `left' to `right' */ + error = ft_stroker_add_reverse_left( stroker, TRUE ); if ( error ) goto Exit; @@ -1494,7 +1518,7 @@ /* Now end the right subpath accordingly. The left one is */ /* rewind and doesn't need further processing. */ - ft_stroke_border_close( right, 0 ); + ft_stroke_border_close( right, FALSE ); } else { @@ -1536,8 +1560,8 @@ } /* then end our two subpaths */ - ft_stroke_border_close( stroker->borders + 0, 1 ); - ft_stroke_border_close( stroker->borders + 1, 0 ); + ft_stroke_border_close( stroker->borders + 0, TRUE ); + ft_stroke_border_close( stroker->borders + 1, FALSE ); } Exit: @@ -1692,7 +1716,7 @@ v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -1836,7 +1860,7 @@ first = last + 1; } - return 0; + return FT_Err_Ok; Exit: return error; @@ -1845,8 +1869,13 @@ return FT_Err_Invalid_Outline; } - +/* declare an extern to access ft_outline_glyph_class global allocated + in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access + it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC extern const FT_Glyph_Class ft_outline_glyph_class; +#endif +#include "basepic.h" /* documentation is in ftstroke.h */ @@ -1858,13 +1887,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -1884,7 +1914,7 @@ FT_UInt num_points, num_contours; - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); if ( error ) goto Fail; @@ -1931,13 +1961,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -1967,7 +1998,7 @@ border = FT_STROKER_BORDER_LEFT; } - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); if ( error ) goto Fail; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftsynth.c b/reactos/lib/3rdparty/freetype/src/base/ftsynth.c index ff88ce96c5b..326d8e73e47 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftsynth.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftsynth.c @@ -18,11 +18,21 @@ #include <ft2build.h> #include FT_SYNTHESIS_H +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include FT_BITMAP_H + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_synth + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -68,36 +78,13 @@ /*************************************************************************/ - FT_EXPORT_DEF( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) - { - if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && - !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - { - FT_Bitmap bitmap; - FT_Error error; - - - FT_Bitmap_New( &bitmap ); - error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); - if ( error ) - return error; - - slot->bitmap = bitmap; - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - } - - return FT_Err_Ok; - } - - /* documentation is in ftsynth.h */ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { FT_Library library = slot->library; - FT_Face face = FT_SLOT_FACE( slot ); + FT_Face face = slot->face; FT_Error error; FT_Pos xstr, ystr; @@ -123,11 +110,24 @@ } else if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) { - xstr = FT_PIX_FLOOR( xstr ); + /* round to full pixels */ + xstr &= ~63; if ( xstr == 0 ) xstr = 1 << 6; - ystr = FT_PIX_FLOOR( ystr ); + ystr &= ~63; + /* + * XXX: overflow check for 16-bit system, for compatibility + * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * unfortunately, this function return no informations + * about the cause of error. + */ + if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) + { + FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); + FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + return; + } error = FT_GlyphSlot_Own_Bitmap( slot ); if ( error ) return; @@ -151,8 +151,9 @@ slot->metrics.vertBearingY += ystr; slot->metrics.vertAdvance += ystr; + /* XXX: 16-bit overflow case must be excluded before here */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - slot->bitmap_top += ystr >> 6; + slot->bitmap_top += (FT_Int)( ystr >> 6 ); } diff --git a/reactos/lib/3rdparty/freetype/src/base/ftsystem.c b/reactos/lib/3rdparty/freetype/src/base/ftsystem.c index f61a3edfb6b..4d06d6db5cc 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftsystem.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2001, 2002, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -205,7 +205,8 @@ file = STREAM_FILE( stream ); - ft_fseek( file, offset, SEEK_SET ); + if ( stream->pos != offset ) + ft_fseek( file, offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -226,8 +227,8 @@ file = ft_fopen( filepathname, "rb" ); if ( !file ) { - FT_ERROR(( "FT_Stream_Open:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); + FT_ERROR(( "FT_Stream_Open:" + " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } @@ -294,7 +295,7 @@ #ifdef FT_DEBUG_MEMORY ft_mem_debug_done( memory ); #endif - memory->free( memory, memory ); + ft_sfree( memory ); } diff --git a/reactos/lib/3rdparty/freetype/src/base/fttrigon.c b/reactos/lib/3rdparty/freetype/src/base/fttrigon.c index 9f513946b83..fdf433ab866 100644 --- a/reactos/lib/3rdparty/freetype/src/base/fttrigon.c +++ b/reactos/lib/3rdparty/freetype/src/base/fttrigon.c @@ -72,10 +72,10 @@ val = ( val >= 0 ) ? val : -val; v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFFL; + v2 = (FT_UInt32)(val & 0xFFFFL); - k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = FT_TRIG_SCALE & 0xFFFFL; /* constant */ + k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ + k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */ hi = k1 * v1; lo1 = k1 * v2 + k2 * v1; /* can't overflow */ @@ -86,7 +86,7 @@ hi += lo1 >> 16; if ( lo1 < lo3 ) - hi += 0x10000UL; + hi += (FT_UInt32)0x10000UL; val = (FT_Fixed)hi; @@ -433,7 +433,7 @@ if ( shift > 0 ) { - FT_Int32 half = 1L << ( shift - 1 ); + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; diff --git a/reactos/lib/3rdparty/freetype/src/base/rules.mk b/reactos/lib/3rdparty/freetype/src/base/rules.mk index d6e441254b7..10f578abc8c 100644 --- a/reactos/lib/3rdparty/freetype/src/base/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,8 +21,6 @@ # BASE_EXT_OBJ: A list of base layer extensions, i.e., components found # in `freetype/src/base' which are not compiled within the # base layer proper. -# -# BASE_H is defined in freetype.mk to simplify the dependency rules. BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) @@ -35,17 +33,25 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # All files listed here should be included in `ftbase.c' (for a `single' # build). # -BASE_SRC := $(BASE_DIR)/ftcalc.c \ +BASE_SRC := $(BASE_DIR)/ftadvanc.c \ + $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ - $(BASE_DIR)/ftnames.c \ $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ $(BASE_DIR)/ftrfork.c \ + $(BASE_DIR)/ftsnames.c \ $(BASE_DIR)/ftstream.c \ $(BASE_DIR)/fttrigon.c \ $(BASE_DIR)/ftutil.c + +ifneq ($(ftmac_c),) + BASE_SRC += $(BASE_DIR)/$(ftmac_c) +endif + +BASE_H := $(BASE_DIR)/ftbase.h + # Base layer `extensions' sources # # An extension is added to the library file as a separate object. It is @@ -77,13 +83,13 @@ BASE_SRC_S := $(BASE_DIR)/ftbase.c # Base layer - single object build # -$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) +$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) $(BASE_H) $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) # Multiple objects build + extensions # -$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) +$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) $(BASE_H) $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) diff --git a/reactos/lib/3rdparty/freetype/src/bdf/bdf.h b/reactos/lib/3rdparty/freetype/src/bdf/bdf.h index 1b64426aad6..561b4158a51 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/bdf.h +++ b/reactos/lib/3rdparty/freetype/src/bdf/bdf.h @@ -114,8 +114,8 @@ FT_BEGIN_HEADER union { char* atom; - long int32; - unsigned long card32; + long l; + unsigned long ul; } value; /* Value of the property. */ @@ -160,7 +160,7 @@ FT_BEGIN_HEADER typedef struct _hashnode_ { const char* key; - void* data; + size_t data; } _hashnode, *hashnode; diff --git a/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.c b/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.c index 74cc2f1b8bf..631ec460e7c 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.c +++ b/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 by + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -53,7 +53,7 @@ THE SOFTWARE. typedef struct BDF_CMapRec_ { FT_CMapRec cmap; - FT_UInt num_encodings; + FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ BDF_encoding_el* encodings; } BDF_CMapRec, *BDF_CMap; @@ -92,8 +92,8 @@ THE SOFTWARE. { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_UInt result = 0; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ min = 0; @@ -101,7 +101,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -131,9 +131,9 @@ THE SOFTWARE. { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_UInt32 charcode = *acharcode + 1; - FT_UInt result = 0; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + FT_ULong charcode = *acharcode + 1; min = 0; @@ -141,7 +141,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; /* same as BDF_encoding_el.enc */ mid = ( min + max ) >> 1; @@ -169,7 +169,14 @@ THE SOFTWARE. } Exit: - *acharcode = charcode; + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; return result; } @@ -181,7 +188,9 @@ THE SOFTWARE. bdf_cmap_init, bdf_cmap_done, bdf_cmap_char_index, - bdf_cmap_char_next + bdf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -194,9 +203,8 @@ THE SOFTWARE. bdf_font_t* font = bdf->bdffont; bdf_property_t* prop; - int nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - int lengths[4]; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t nn, len, lengths[4]; face->style_flags = 0; @@ -282,7 +290,7 @@ THE SOFTWARE. /* add_style_name and setwidth_name */ if ( nn == 0 || nn == 3 ) { - int mm; + size_t mm; for ( mm = 0; mm < len; mm++ ) @@ -302,10 +310,15 @@ THE SOFTWARE. FT_CALLBACK_DEF( void ) BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ { - BDF_Face face = (BDF_Face)bdfface; - FT_Memory memory = FT_FACE_MEMORY( face ); + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory; + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + bdf_free_font( face->bdffont ); FT_FREE( face->en_table ); @@ -419,7 +432,7 @@ THE SOFTWARE. prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); @@ -427,21 +440,21 @@ THE SOFTWARE. if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = - (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); else bsize->size = bsize->width << 6; prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.int32 << 6; + bsize->y_ppem = (FT_Short)prop->value.l << 6; prop = bdf_get_font_property( font, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.int32; + resolution_x = (FT_Short)prop->value.l; prop = bdf_get_font_property( font, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.int32; + resolution_y = (FT_Short)prop->value.l; if ( bsize->y_ppem == 0 ) { @@ -472,7 +485,12 @@ THE SOFTWARE. (face->en_table[n]).glyph = (FT_Short)n; if ( cur[n].encoding == font->default_char ) - face->default_glyph = n; + { + if ( n < FT_UINT_MAX ) + face->default_glyph = (FT_UInt)n; + else + FT_TRACE1(( "idx %d is too large for this system\n", n )); + } } } @@ -608,7 +626,7 @@ THE SOFTWARE. switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = BDF_Err_Ok; break; @@ -664,7 +682,10 @@ THE SOFTWARE. bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; - bitmap->pitch = glyph.bpr; + if ( glyph.bpr > INT_MAX ) + FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", + glyph.bpr )); + bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ /* note: we don't allocate a new array to hold the bitmap; */ /* we can simply point to it */ @@ -736,13 +757,23 @@ THE SOFTWARE. break; case BDF_INTEGER: + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = prop->value.int32; + aproperty->u.integer = (FT_Int32)prop->value.l; break; case BDF_CARDINAL: + if ( prop->value.ul > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large cardinal 0x%x is truncated\n" )); + } aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; - aproperty->u.cardinal = prop->value.card32; + aproperty->u.cardinal = (FT_UInt32)prop->value.ul; break; default: diff --git a/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.h b/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.h index 86f40ee4af5..db7093bb45f 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.h +++ b/reactos/lib/3rdparty/freetype/src/bdf/bdfdrivr.h @@ -36,6 +36,10 @@ THE SOFTWARE. FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + typedef struct BDF_encoding_el_ { diff --git a/reactos/lib/3rdparty/freetype/src/bdf/bdflib.c b/reactos/lib/3rdparty/freetype/src/bdf/bdflib.c index 512cd62c3ec..5fa5868c715 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/bdflib.c +++ b/reactos/lib/3rdparty/freetype/src/bdf/bdflib.c @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 * Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a @@ -281,7 +281,7 @@ static FT_Error hash_insert( char* key, - void* data, + size_t data, hashtable* ht, FT_Memory memory ) { @@ -415,18 +415,18 @@ static FT_Error - _bdf_list_ensure( _bdf_list_t* list, - int num_items ) + _bdf_list_ensure( _bdf_list_t* list, + unsigned long num_items ) /* same as _bdf_list_t.used */ { FT_Error error = BDF_Err_Ok; - if ( num_items > (int)list->size ) + if ( num_items > list->size ) { - int oldsize = list->size; - int newsize = oldsize + ( oldsize >> 1 ) + 4; - int bigsize = FT_INT_MAX / sizeof ( char* ); - FT_Memory memory = list->memory; + unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ + unsigned long newsize = oldsize + ( oldsize >> 1 ) + 4; + unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); + FT_Memory memory = list->memory; if ( oldsize == bigsize ) @@ -614,8 +614,8 @@ { _bdf_line_func_t cb; unsigned long lineno, buf_size; - int refill, bytes, hold, to_skip; - int start, end, cursor, avail; + int refill, hold, to_skip; + ptrdiff_t bytes, start, end, cursor, avail; char* buf = 0; FT_Memory memory = stream->memory; FT_Error error = BDF_Err_Ok; @@ -648,8 +648,8 @@ { if ( refill ) { - bytes = (int)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, - (FT_ULong)(buf_size - cursor) ); + bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, + (FT_ULong)(buf_size - cursor) ); avail = cursor + bytes; cursor = 0; refill = 0; @@ -971,7 +971,7 @@ int format, bdf_font_t* font ) { - unsigned long n; + size_t n; bdf_property_t* p; FT_Memory memory = font->memory; FT_Error error = BDF_Err_Ok; @@ -991,7 +991,9 @@ p = font->user_props + font->nuser_props; FT_ZERO( p ); - n = (unsigned long)( ft_strlen( name ) + 1 ); + n = ft_strlen( name ) + 1; + if ( n > FT_ULONG_MAX ) + return BDF_Err_Invalid_Argument; if ( FT_NEW_ARRAY( p->name, n ) ) goto Exit; @@ -1003,7 +1005,7 @@ n = _num_bdf_properties + font->nuser_props; - error = hash_insert( p->name, (void *)n, &(font->proptbl), memory ); + error = hash_insert( p->name, n, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -1018,8 +1020,8 @@ bdf_get_property( char* name, bdf_font_t* font ) { - hashnode hn; - unsigned long propid; + hashnode hn; + size_t propid; if ( name == 0 || *name == 0 ) @@ -1028,7 +1030,7 @@ if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) return 0; - propid = (unsigned long)hn->data; + propid = hn->data; if ( propid >= _num_bdf_properties ) return font->user_props + ( propid - _num_bdf_properties ); @@ -1131,11 +1133,11 @@ _bdf_set_default_spacing( bdf_font_t* font, bdf_options_t* opts ) { - unsigned long len; - char name[256]; - _bdf_list_t list; - FT_Memory memory; - FT_Error error = BDF_Err_Ok; + size_t len; + char name[256]; + _bdf_list_t list; + FT_Memory memory; + FT_Error error = BDF_Err_Ok; if ( font == 0 || font->name == 0 || font->name[0] == 0 ) @@ -1150,7 +1152,7 @@ font->spacing = opts->font_spacing; - len = (unsigned long)( ft_strlen( font->name ) + 1 ); + len = ft_strlen( font->name ) + 1; /* Limit ourselves to 256 characters in the font name. */ if ( len >= 256 ) { @@ -1261,7 +1263,7 @@ char* name, char* value ) { - unsigned long propid; + size_t propid; hashnode hn; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; @@ -1273,7 +1275,7 @@ { /* The property already exists in the font, so simply replace */ /* the value of the property with the current value. */ - fp = font->props + (unsigned long)hn->data; + fp = font->props + hn->data; switch ( fp->format ) { @@ -1289,11 +1291,11 @@ break; case BDF_INTEGER: - fp->value.int32 = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value, 0, 10 ); break; case BDF_CARDINAL: - fp->value.card32 = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value, 0, 10 ); break; default: @@ -1335,7 +1337,7 @@ font->props_size++; } - propid = (unsigned long)hn->data; + propid = hn->data; if ( propid >= _num_bdf_properties ) prop = font->user_props + ( propid - _num_bdf_properties ); else @@ -1359,11 +1361,11 @@ break; case BDF_INTEGER: - fp->value.int32 = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value, 0, 10 ); break; case BDF_CARDINAL: - fp->value.card32 = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value, 0, 10 ); break; } @@ -1372,7 +1374,7 @@ if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) { /* Add the property to the font property table. */ error = hash_insert( fp->name, - (void *)font->props_used, + font->props_used, (hashtable *)font->internal, memory ); if ( error ) @@ -1387,13 +1389,19 @@ /* present, and the SPACING property should override the default */ /* spacing. */ if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) - font->default_char = fp->value.int32; + font->default_char = fp->value.l; else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) - font->font_ascent = fp->value.int32; + font->font_ascent = fp->value.l; else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) - font->font_descent = fp->value.int32; + font->font_descent = fp->value.l; else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) { + if ( !fp->value.atom ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) font->spacing = BDF_PROPORTIONAL; else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) @@ -2038,7 +2046,7 @@ p->memory = 0; { /* setup */ - unsigned long i; + size_t i; bdf_property_t* prop; @@ -2048,7 +2056,7 @@ for ( i = 0, prop = (bdf_property_t*)_bdf_properties; i < _num_bdf_properties; i++, prop++ ) { - error = hash_insert( prop->name, (void *)i, + error = hash_insert( prop->name, i, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -2072,6 +2080,7 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + /* at this point, `p->font' can't be NULL */ p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) @@ -2465,7 +2474,7 @@ hn = hash_lookup( name, (hashtable *)font->internal ); - return hn ? ( font->props + (unsigned long)hn->data ) : 0; + return hn ? ( font->props + hn->data ) : 0; } diff --git a/reactos/lib/3rdparty/freetype/src/bdf/module.mk b/reactos/lib/3rdparty/freetype/src/bdf/module.mk index dfaa2744ebe..fe06ae8e064 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/module.mk +++ b/reactos/lib/3rdparty/freetype/src/bdf/module.mk @@ -27,7 +27,7 @@ FTMODULE_H_COMMANDS += BDF_DRIVER define BDF_DRIVER -$(OPEN_DRIVER)bdf_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, bdf_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/bdf/rules.mk b/reactos/lib/3rdparty/freetype/src/bdf/rules.mk index 25d98e55b07..6ff1614ddec 100644 --- a/reactos/lib/3rdparty/freetype/src/bdf/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/bdf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2001, 2002, 2003 by +# Copyright (C) 2001, 2002, 2003, 2008 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,7 +29,7 @@ # bdf driver directory # -BDF_DIR := $(SRC_DIR)/bdf +BDF_DIR := $(SRC_DIR)/bdf BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) @@ -44,7 +44,8 @@ BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ # bdf driver headers # BDF_DRV_H := $(BDF_DIR)/bdf.h \ - $(BDF_DIR)/bdfdrivr.h + $(BDF_DIR)/bdfdrivr.h \ + $(BDF_DIR)/bdferror.h # bdf driver object(s) # diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcbasic.c b/reactos/lib/3rdparty/freetype/src/cache/ftcbasic.c index f2e62297d5c..ebc8871ccc0 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcbasic.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,15 +17,17 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_CACHE_H #include "ftcglyph.h" #include "ftcimage.h" #include "ftcsbits.h" -#include FT_INTERNAL_MEMORY_H #include "ftccback.h" #include "ftcerror.h" +#define FT_COMPONENT trace_cache + #ifdef FT_CONFIG_OPTION_OLD_INTERNALS @@ -140,8 +142,18 @@ error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, &face ); + + if ( error || !face ) + return result; + + if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) + { + FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); + FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); + } + if ( !error ) - result = face->num_glyphs; + result = (FT_UInt)face->num_glyphs; return result; } @@ -304,7 +316,7 @@ FTC_Node *anode ) { FTC_BasicQueryRec query; - FTC_INode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_Error error; FT_UInt32 hash; @@ -320,13 +332,13 @@ if ( anode ) *anode = NULL; -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) /* * This one is a major hack used to detect whether we are passed a * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. */ - if ( type->width >= 0x10000 ) + if ( (FT_ULong)type->width >= 0x10000L ) { FTC_OldImageDesc desc = (FTC_OldImageDesc)type; @@ -341,10 +353,16 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = type->flags; + query.attrs.load_flags = (FT_UInt)type->flags; } query.attrs.scaler.pixel = 1; @@ -365,7 +383,7 @@ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, FTC_GQUERY( &query ), - (FTC_Node*) &node ); + &node ); #endif if ( !error ) { @@ -373,8 +391,8 @@ if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } } @@ -394,7 +412,7 @@ FTC_Node *anode ) { FTC_BasicQueryRec query; - FTC_INode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_Error error; FT_UInt32 hash; @@ -410,8 +428,15 @@ if ( anode ) *anode = NULL; + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler = scaler[0]; - query.attrs.load_flags = load_flags; + query.attrs.load_flags = (FT_UInt)load_flags; hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; @@ -428,8 +453,8 @@ if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } } @@ -438,7 +463,7 @@ } - + #ifdef FT_CONFIG_OPTION_OLD_INTERNALS /* yet another backwards-legacy structure */ @@ -630,7 +655,7 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_SNode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_UInt32 hash; @@ -643,12 +668,12 @@ *ansbit = NULL; -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) /* This one is a major hack used to detect whether we are passed a * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. */ - if ( type->width >= 0x10000 ) + if ( (FT_ULong)type->width >= 0x10000L ) { FTC_OldImageDesc desc = (FTC_OldImageDesc)type; @@ -663,10 +688,16 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = type->flags; + query.attrs.load_flags = (FT_UInt)type->flags; } query.attrs.scaler.pixel = 1; @@ -690,17 +721,18 @@ hash, gindex, FTC_GQUERY( &query ), - (FTC_Node*)&node ); + &node ); #endif if ( error ) goto Exit; - *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } Exit: @@ -720,7 +752,7 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_SNode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_UInt32 hash; @@ -733,8 +765,15 @@ *ansbit = NULL; + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler = scaler[0]; - query.attrs.load_flags = load_flags; + query.attrs.load_flags = (FT_UInt)load_flags; /* beware, the hash must be the same for all glyph ranges! */ hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + @@ -750,12 +789,13 @@ if ( error ) goto Exit; - *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } Exit: diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftccache.c b/reactos/lib/3rdparty/freetype/src/cache/ftccache.c index f3e699c3850..463addd99be 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftccache.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,9 @@ #include "ftccback.h" #include "ftcerror.h" +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + #define FTC_HASH_MAX_LOAD 2 #define FTC_HASH_MIN_LOAD 1 @@ -93,9 +96,9 @@ for (;;) { FTC_Node node, *pnode; - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FT_UInt count = mask + p + 1; /* number of buckets */ + FT_UFast p = cache->p; + FT_UFast mask = cache->mask; + FT_UFast count = mask + p + 1; /* number of buckets */ /* do we need to shrink the buckets array? */ @@ -153,7 +156,7 @@ /* do we need to expand the buckets array? */ else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) { - FT_UInt old_index = p + mask; + FT_UFast old_index = p + mask; FTC_Node* pold; @@ -216,7 +219,7 @@ if ( node == NULL ) { - FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); + FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); return; } @@ -273,7 +276,7 @@ /* find node's cache */ if ( node->cache_index >= manager->num_caches ) { - FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif @@ -283,7 +286,7 @@ #ifdef FT_DEBUG_ERROR if ( cache == NULL ) { - FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif @@ -302,7 +305,7 @@ #if 0 /* check, just in case of general corruption :-) */ if ( manager->num_nodes == 0 ) - FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n", + FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n", manager->num_nodes )); #endif } @@ -347,7 +350,7 @@ { FTC_Manager manager = cache->manager; FT_UFast i; - FT_UInt count; + FT_UFast count; count = cache->p + cache->mask + 1; diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftccache.h b/reactos/lib/3rdparty/freetype/src/cache/ftccache.h index 8c0a7c94fe6..2082bc4f4f0 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftccache.h +++ b/reactos/lib/3rdparty/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,7 +91,7 @@ FT_BEGIN_HEADER FT_Pointer query, FTC_Cache cache ); - typedef FT_ULong + typedef FT_Offset (*FTC_Node_WeightFunc)( FTC_Node node, FTC_Cache cache ); @@ -121,7 +121,7 @@ FT_BEGIN_HEADER FTC_Node_CompareFunc node_remove_faceid; FTC_Node_FreeFunc node_free; - FT_UInt cache_size; + FT_Offset cache_size; FTC_Cache_InitFunc cache_init; FTC_Cache_DoneFunc cache_done; @@ -202,7 +202,7 @@ FT_BEGIN_HEADER FTC_Cache _cache = FTC_CACHE(cache); \ FT_UInt32 _hash = (FT_UInt32)(hash); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ - FT_UInt _idx; \ + FT_UFast _idx; \ \ \ error = 0; \ @@ -246,8 +246,7 @@ FT_BEGIN_HEADER error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ _Ok: \ - _pnode = (FTC_Node*)(void*)&(node); \ - *_pnode = _node; \ + node = _node; \ FT_END_STMNT #else /* !FTC_INLINE */ diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftccback.h b/reactos/lib/3rdparty/freetype/src/cache/ftccback.h index 86e72a7514f..4d0818db277 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftccback.h +++ b/reactos/lib/3rdparty/freetype/src/cache/ftccback.h @@ -36,7 +36,7 @@ FT_Pointer gquery, FTC_Cache cache ); - FT_LOCAL( FT_ULong ) + FT_LOCAL( FT_Offset ) ftc_inode_weight( FTC_Node inode, FTC_Cache cache ); @@ -50,7 +50,7 @@ FT_Pointer gquery, FTC_Cache cache ); - FT_LOCAL( FT_ULong ) + FT_LOCAL( FT_Offset ) ftc_snode_weight( FTC_Node snode, FTC_Cache cache ); diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftccmap.c b/reactos/lib/3rdparty/freetype/src/cache/ftccmap.c index aa59307f489..a802b0557c7 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftccmap.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include "ftcmanag.h" #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H -#include FT_TRUETYPE_IDS_H #include "ftccback.h" #include "ftcerror.h" @@ -86,9 +85,9 @@ #define FTC_CMAP_INDICES_MAX 128 /* compute a query/node hash */ -#define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ - ( (char_code) / FTC_CMAP_INDICES_MAX ) ) +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( (charcode) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ typedef struct FTC_CMapQueryRec_ @@ -175,7 +174,7 @@ /* compute the weight of a given cmap node */ - FT_CALLBACK_DEF( FT_ULong ) + FT_CALLBACK_DEF( FT_Offset ) ftc_cmap_node_weight( FTC_Node cnode, FTC_Cache cache ) { @@ -284,15 +283,27 @@ { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; - FTC_CMapNode node; + FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_UInt32 hash; + FT_Int no_cmap_change = 0; + if ( cmap_index < 0 ) + { + /* Treat a negative cmap index as a special value, meaning that you */ + /* don't want to change the FT_Face's character map through this */ + /* call. This can be useful if the face requester callback already */ + /* sets the face's charmap to the appropriate value. */ + + no_cmap_change = 1; + cmap_index = 0; + } + if ( !cache ) { - FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); + FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } @@ -311,7 +322,7 @@ * Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf', * which contains more than 5 charmaps. */ - if ( cmap_index >= 16 ) + if ( cmap_index >= 16 && !no_cmap_change ) { FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; @@ -362,18 +373,21 @@ FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else - error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); + error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; - FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); + FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < + FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ - if ( (FT_UInt)( char_code - node->first >= FTC_CMAP_INDICES_MAX ) ) + if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= + FTC_CMAP_INDICES_MAX ) ) return 0; - gindex = node->indices[char_code - node->first]; + gindex = FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; @@ -381,7 +395,9 @@ gindex = 0; - error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); + error = FTC_Manager_LookupFace( cache->manager, + FTC_CMAP_NODE( node )->face_id, + &face ); if ( error ) goto Exit; @@ -393,16 +409,18 @@ old = face->charmap; cmap = face->charmaps[cmap_index]; - if ( old != cmap ) + if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); - if ( old != cmap ) + if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } - node->indices[char_code - node->first] = (FT_UShort)gindex; + FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first] + = (FT_UShort)gindex; } Exit: diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c index 5c03abe0552..2f462a2f645 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006 by */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,8 +20,6 @@ #include FT_CACHE_H #include "ftcglyph.h" #include FT_ERRORS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H #include "ftccback.h" #include "ftcerror.h" diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.h b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.h index 87a4199bfd8..c18f9c3af31 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.h +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.h @@ -277,12 +277,14 @@ FT_BEGIN_HEADER FTC_GCache _gcache = FTC_GCACHE( cache ); \ FTC_GQuery _gquery = (FTC_GQuery)( query ); \ FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ + FTC_MruNode _mrunode; \ \ \ _gquery->gindex = (gindex); \ \ FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ - _gquery->family, error ); \ + _mrunode, error ); \ + _gquery->family = FTC_FAMILY( _mrunode ); \ if ( !error ) \ { \ FTC_Family _gqfamily = _gquery->family; \ @@ -303,11 +305,10 @@ FT_BEGIN_HEADER #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ gindex, query, node, error ) \ FT_BEGIN_STMNT \ - void* _n = &(node); \ - \ \ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ - FTC_GQUERY( query ), (FTC_Node*)_n ); \ + FTC_GQUERY( query ), node ); \ + \ FT_END_STMNT #endif /* !FTC_INLINE */ diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcimage.c b/reactos/lib/3rdparty/freetype/src/cache/ftcimage.c index 15d4e80c8c3..417daf2aaea 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcimage.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcimage.c @@ -103,12 +103,12 @@ } - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) ftc_inode_weight( FTC_Node ftcinode, FTC_Cache ftccache ) { FTC_INode inode = (FTC_INode)ftcinode; - FT_ULong size = 0; + FT_Offset size = 0; FT_Glyph glyph = inode->glyph; FT_UNUSED( ftccache ); @@ -151,7 +151,7 @@ #if 0 - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) FTC_INode_Weight( FTC_INode inode ) { return ftc_inode_weight( FTC_NODE( inode ), NULL ); diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcmanag.c b/reactos/lib/3rdparty/freetype/src/cache/ftcmanag.c index 9d7347c3dfd..f2a298e7d90 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcmanag.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,10 @@ #include "ftccback.h" #include "ftcerror.h" +#ifdef FT_CONFIG_OPTION_PIC +#error "cache system does not support PIC yet" +#endif + #undef FT_COMPONENT #define FT_COMPONENT trace_cache @@ -78,6 +82,8 @@ } FTC_SizeNodeRec, *FTC_SizeNode; +#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) ) + FT_CALLBACK_DEF( void ) ftc_size_node_done( FTC_MruNode ftcnode, @@ -176,12 +182,12 @@ FTC_Scaler scaler, FT_Size *asize ) { - FT_Error error; - FTC_SizeNode node; + FT_Error error; + FTC_MruNode mrunode; if ( asize == NULL ) - return FTC_Err_Bad_Argument; + return FTC_Err_Invalid_Argument; *asize = NULL; @@ -191,14 +197,14 @@ #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, - node, error ); + mrunode, error ); #else - error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node ); + error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode ); #endif if ( !error ) - *asize = node->size; + *asize = FTC_SIZE_NODE( mrunode )->size; return error; } @@ -220,6 +226,8 @@ } FTC_FaceNodeRec, *FTC_FaceNode; +#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) ) + FT_CALLBACK_DEF( FT_Error ) ftc_face_node_init( FTC_MruNode ftcnode, @@ -301,12 +309,12 @@ FTC_FaceID face_id, FT_Face *aface ) { - FT_Error error; - FTC_FaceNode node; + FT_Error error; + FTC_MruNode mrunode; if ( aface == NULL ) - return FTC_Err_Bad_Argument; + return FTC_Err_Invalid_Argument; *aface = NULL; @@ -317,14 +325,14 @@ #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, - node, error ); + mrunode, error ); #else - error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node ); + error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode ); #endif if ( !error ) - *aface = node->face; + *aface = FTC_FACE_NODE( mrunode )->face; return error; } @@ -476,8 +484,8 @@ if ( (FT_UInt)node->cache_index >= manager->num_caches ) - FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", - node->cache_index )); + FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); else weight += cache->clazz.node_weight( node, cache ); @@ -486,8 +494,8 @@ } while ( node != first ); if ( weight != manager->cur_weight ) - FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", - manager->cur_weight, weight )); + FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", + manager->cur_weight, weight )); } /* check circular list */ @@ -505,9 +513,9 @@ } while ( node != first ); if ( count != manager->num_nodes ) - FT_ERROR(( - "FTC_Manager_Check: invalid cache node count %d instead of %d\n", - manager->num_nodes, count )); + FT_TRACE0(( "FTC_Manager_Check:" + " invalid cache node count %d instead of %d\n", + manager->num_nodes, count )); } } @@ -534,9 +542,9 @@ #ifdef FT_DEBUG_ERROR FTC_Manager_Check( manager ); - FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n", - manager->cur_weight, manager->max_weight, - manager->num_nodes )); + FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", + manager->cur_weight, manager->max_weight, + manager->num_nodes )); #endif if ( manager->cur_weight < manager->max_weight || first == NULL ) @@ -579,8 +587,8 @@ if ( manager->num_caches >= FTC_MAX_CACHES ) { error = FTC_Err_Too_Many_Caches; - FT_ERROR(( "%s: too many registered caches\n", - "FTC_Manager_Register_Cache" )); + FT_ERROR(( "FTC_Manager_RegisterCache:" + " too many registered caches\n" )); goto Exit; } @@ -608,7 +616,8 @@ } Exit: - *acache = cache; + if ( acache ) + *acache = cache; return error; } @@ -660,7 +669,9 @@ /* this will remove all FTC_SizeNode that correspond to * the face_id as well */ - FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id ); + FTC_MruList_RemoveSelection( &manager->faces, + (FTC_MruNode_CompareFunc)NULL, + face_id ); for ( nn = 0; nn < manager->num_caches; nn++ ) FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcmru.c b/reactos/lib/3rdparty/freetype/src/cache/ftcmru.c index 3a6c625afa5..9944b58980d 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcmru.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ /* */ /* FreeType MRU support (body). */ /* */ -/* Copyright 2003, 2004, 2006 by */ +/* Copyright 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,7 +46,7 @@ { if ( cnode == node ) { - fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" ); exit( 2 ); } cnode = cnode->next; @@ -94,7 +94,7 @@ } while ( cnode != first ); - fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Up: invalid action\n" ); exit( 2 ); Ok: } @@ -141,7 +141,7 @@ } while ( cnode != first ); - fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" ); exit( 2 ); Ok: } diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcmru.h b/reactos/lib/3rdparty/freetype/src/cache/ftcmru.h index c8f0c6ef6e3..5739439f450 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcmru.h +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcmru.h @@ -107,7 +107,7 @@ FT_BEGIN_HEADER typedef struct FTC_MruListClassRec_ { - FT_UInt node_size; + FT_Offset node_size; FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; @@ -163,7 +163,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ FTC_MruNode* _pfirst = &(list)->nodes; \ FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ - FTC_MruNode _first, _node, *_pnode; \ + FTC_MruNode _first, _node; \ \ \ error = 0; \ @@ -180,8 +180,7 @@ FT_BEGIN_HEADER if ( _node != _first ) \ FTC_MruNode_Up( _pfirst, _node ); \ \ - _pnode = (FTC_MruNode*)(void*)&(node); \ - *_pnode = _node; \ + node = _node; \ goto _MruOk; \ } \ _node = _node->next; \ diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcsbits.c b/reactos/lib/3rdparty/freetype/src/cache/ftcsbits.c index 72f139d565b..60d46aa7a06 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcsbits.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,9 @@ #include "ftccback.h" #include "ftcerror.h" +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + /*************************************************************************/ /*************************************************************************/ @@ -129,13 +132,13 @@ FT_Int temp; FT_GlyphSlot slot = face->glyph; FT_Bitmap* bitmap = &slot->bitmap; - FT_Int xadvance, yadvance; + FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) { - FT_ERROR(( "%s: glyph loaded didn't return a bitmap!\n", - "ftc_snode_load" )); + FT_TRACE0(( "ftc_snode_load:" + " glyph loaded didn't return a bitmap\n" )); goto BadGlyph; } @@ -263,7 +266,7 @@ } - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) ftc_snode_weight( FTC_Node ftcsnode, FTC_Cache cache ) { @@ -271,7 +274,7 @@ FT_UInt count = snode->count; FTC_SBit sbit = snode->sbits; FT_Int pitch; - FT_ULong size; + FT_Offset size; FT_UNUSED( cache ); @@ -300,7 +303,7 @@ #if 0 - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) FTC_SNode_Weight( FTC_SNode snode ) { return ftc_snode_weight( FTC_NODE( snode ), NULL ); diff --git a/reactos/lib/3rdparty/freetype/src/cache/rules.mk b/reactos/lib/3rdparty/freetype/src/cache/rules.mk index 457dec848df..ed75a6a91fd 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001, 2003, 2004, 2006 by +# Copyright 2000, 2001, 2003, 2004, 2006, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -26,7 +26,7 @@ CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) # CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ $(CACHE_DIR)/ftccache.c \ - $(CACHE_DIR)/ftccmap.c \ + $(CACHE_DIR)/ftccmap.c \ $(CACHE_DIR)/ftcglyph.c \ $(CACHE_DIR)/ftcimage.c \ $(CACHE_DIR)/ftcmanag.c \ @@ -35,12 +35,14 @@ CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ # Cache driver headers # -CACHE_DRV_H := $(CACHE_DIR)/ftccback.h \ +CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ + $(CACHE_DIR)/ftccback.h \ $(CACHE_DIR)/ftcerror.h \ $(CACHE_DIR)/ftcglyph.h \ $(CACHE_DIR)/ftcimage.h \ $(CACHE_DIR)/ftcmanag.h \ - $(CACHE_DIR)/ftcmru.h + $(CACHE_DIR)/ftcmru.h \ + $(CACHE_DIR)/ftcsbits.h # Cache driver object(s) diff --git a/reactos/lib/3rdparty/freetype/src/cff/Jamfile b/reactos/lib/3rdparty/freetype/src/cff/Jamfile index 6d0bb1b8679..6705d3cfdb7 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/cff/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ; if $(FT2_MULTI) { - _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap ; + _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/cff/cff.c b/reactos/lib/3rdparty/freetype/src/cff/cff.c index e6d8954c9ab..fccfd442f5d 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cff.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cff.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "cffpic.c" #include "cffdrivr.c" #include "cffparse.c" #include "cffload.c" diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffcmap.c b/reactos/lib/3rdparty/freetype/src/cff/cffcmap.c index fffc5fc550d..46d603e3a89 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffcmap.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,7 +65,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_encoding_char_next( CFF_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -99,16 +99,16 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_encoding_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, sizeof ( CFF_CMapStdRec ), (FT_CMap_InitFunc) cff_cmap_encoding_init, (FT_CMap_DoneFunc) cff_cmap_encoding_done, (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next - }; + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + + NULL, NULL, NULL, NULL, NULL + ) /*************************************************************************/ @@ -192,7 +192,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -205,16 +205,15 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_unicode_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, sizeof ( PS_UnicodesRec ), (FT_CMap_InitFunc) cff_cmap_unicode_init, (FT_CMap_DoneFunc) cff_cmap_unicode_done, (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next - }; + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + NULL, NULL, NULL, NULL, NULL + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffcmap.h b/reactos/lib/3rdparty/freetype/src/cff/cffcmap.h index 3809b85611f..3f7f67bbe05 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffcmap.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffcmap.h @@ -43,8 +43,7 @@ FT_BEGIN_HEADER } CFF_CMapStdRec; - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_encoding_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) /*************************************************************************/ @@ -57,8 +56,7 @@ FT_BEGIN_HEADER /* unicode (synthetic) cmaps */ - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_unicode_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c index 952e88e39f2..217adf2f129 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,21 +21,25 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H +#include FT_SERVICE_CID_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" #include "cffcmap.h" +#include "cffparse.h" #include "cfferrs.h" +#include "cffpic.h" #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_H + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -151,7 +155,7 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { - FT_Error error; + FT_Error error; CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; CFF_Size size = (CFF_Size)cffsize; @@ -163,10 +167,10 @@ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + /* reset the size object if necessary */ if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; - /* reset the size object if necessary */ if ( size ) { /* these two objects must have the same parent */ @@ -184,10 +188,39 @@ } - /* - * GLYPH DICT SERVICE - * - */ + FT_CALLBACK_DEF( FT_Error ) + cff_get_advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ) + { + FT_UInt nn; + FT_Error error = CFF_Err_Ok; + FT_GlyphSlot slot = face->glyph; + + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + + for ( nn = 0; nn < count; nn++ ) + { + error = Load_Glyph( slot, face->size, start + nn, flags ); + if ( error ) + break; + + advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? slot->linearVertAdvance + : slot->linearHoriAdvance; + } + + return error; + } + + + /* + * GLYPH DICT SERVICE + * + */ static FT_Error cff_get_glyph_name( CFF_Face face, @@ -206,10 +239,10 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "cff_get_glyph_name:" )); - FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -226,8 +259,8 @@ FT_FREE( gname ); error = CFF_Err_Ok; - Exit: - return error; + Exit: + return error; } @@ -277,17 +310,16 @@ } - static const FT_Service_GlyphDictRec cff_service_glyph_dict = - { + FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict, (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index, - }; + (FT_GlyphDict_NameIndexFunc)cff_get_name_index + ) - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Int cff_ps_has_glyph_names( FT_Face face ) @@ -306,9 +338,10 @@ if ( cff && cff->font_info == NULL ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; - PS_FontInfoRec *font_info; - FT_Memory memory = face->root.memory; + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontInfoRec *font_info; + FT_Memory memory = face->root.memory; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -316,19 +349,19 @@ font_info->version = cff_index_get_sid_string( &cff->string_index, dict->version, - cff->psnames ); + psnames ); font_info->notice = cff_index_get_sid_string( &cff->string_index, dict->notice, - cff->psnames ); + psnames ); font_info->full_name = cff_index_get_sid_string( &cff->string_index, dict->full_name, - cff->psnames ); + psnames ); font_info->family_name = cff_index_get_sid_string( &cff->string_index, dict->family_name, - cff->psnames ); + psnames ); font_info->weight = cff_index_get_sid_string( &cff->string_index, dict->weight, - cff->psnames ); + psnames ); font_info->italic_angle = dict->italic_angle; font_info->is_fixed_pitch = dict->is_fixed_pitch; font_info->underline_position = (FT_Short)dict->underline_position; @@ -337,19 +370,40 @@ cff->font_info = font_info; } - *afont_info = *cff->font_info; + if ( cff ) + *afont_info = *cff->font_info; Fail: return error; } - static const FT_Service_PsInfoRec cff_service_ps_info = - { + FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info, (PS_GetFontInfoFunc) cff_ps_get_font_info, + (PS_GetFontExtraFunc) NULL, (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ - }; + ) + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cff_get_ps_name( CFF_Face face ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + return (const char*)cff->font_name; + } + + + FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name, + (FT_PsName_GetFunc)cff_get_ps_name + ) /* @@ -368,15 +422,16 @@ { FT_CMap cmap = FT_CMAP( charmap ); FT_Error error = CFF_Err_Ok; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); cmap_info->language = 0; + cmap_info->format = 0; - if ( cmap->clazz != &cff_cmap_encoding_class_rec && - cmap->clazz != &cff_cmap_unicode_class_rec ) + if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET && + cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET ) { - FT_Face face = FT_CMAP_FACE( cmap ); - FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, @@ -391,10 +446,143 @@ } - static const FT_Service_TTCMapsRec cff_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info, (TT_CMap_Info_GetFunc)cff_get_cmap_info - }; + ) + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cff_get_ros( CFF_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( registry ) + { + if ( cff->registry == NULL ) + cff->registry = cff_index_get_sid_string( &cff->string_index, + dict->cid_registry, + psnames ); + *registry = cff->registry; + } + + if ( ordering ) + { + if ( cff->ordering == NULL ) + cff->ordering = cff_index_get_sid_string( &cff->string_index, + dict->cid_ordering, + psnames ); + *ordering = cff->ordering; + } + + /* + * XXX: According to Adobe TechNote #5176, the supplement in CFF + * can be a real number. We truncate it to fit public API + * since freetype-2.3.6. + */ + if ( supplement ) + { + if ( dict->cid_supplement < FT_INT_MIN || + dict->cid_supplement > FT_INT_MAX ) + FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", + dict->cid_supplement )); + *supplement = (FT_Int)dict->cid_supplement; + } + } + + Fail: + return error; + } + + + static FT_Error + cff_get_is_cid( CFF_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + *is_cid = 0; + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry != 0xFFFFU ) + *is_cid = 1; + } + + return error; + } + + + static FT_Error + cff_get_cid_from_glyph_index( CFF_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff; + + + cff = (CFF_Font)face->extra.data; + + if ( cff ) + { + FT_UInt c; + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( glyph_index > cff->num_glyphs ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + c = cff->charset.sids[glyph_index]; + + if ( cid ) + *cid = c; + } + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info, + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + ) /*************************************************************************/ @@ -408,18 +596,24 @@ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ - - static const FT_ServiceDescRec cff_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, + FT_DEFINE_SERVICEDESCREC6(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC5(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) #endif - { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) cff_get_interface( FT_Module driver, /* CFF_Driver */ @@ -427,9 +621,11 @@ { FT_Module sfnt; FT_Module_Interface result; + FT_Library library = driver->library; + FT_UNUSED(library); - result = ft_service_list_lookup( cff_services, module_interface ); + result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); if ( result != NULL ) return result; @@ -442,11 +638,13 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec cff_driver_class = - { - /* begin with the FT_Module_Class fields */ - { +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define CFF_SIZE_SELECT cff_size_select +#else +#define CFF_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(cff_driver_class, FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, @@ -461,7 +659,6 @@ cff_driver_init, cff_driver_done, cff_get_interface, - }, /* now the specific driver fields */ sizeof( TT_FaceRec ), @@ -475,25 +672,19 @@ cff_slot_init, cff_slot_done, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ Load_Glyph, cff_get_kerning, 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + cff_get_advances, /* FT_Face_GetAdvancesFunc */ cff_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - cff_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + CFF_SIZE_SELECT + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.h b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.h index 553848c0a9c..50e8138701e 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Driver_ClassRec cff_driver_class; + FT_DECLARE_DRIVER( cff_driver_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffgload.c b/reactos/lib/3rdparty/freetype/src/cff/cffgload.c index d354227e250..40fa20b426f 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffgload.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,11 +18,9 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_OUTLINE_H -#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "cffobjs.h" @@ -110,6 +108,12 @@ cff_op_callgsubr, cff_op_return, + /* Type 1 opcodes: invalid but seen in real life */ + cff_op_hsbw, + cff_op_closepath, + cff_op_callothersubr, + cff_op_pop, + /* do not remove */ cff_op_max @@ -120,6 +124,11 @@ #define CFF_COUNT_EXACT 0x40 #define CFF_COUNT_CLEAR_STACK 0x20 + /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ + /* used for checking the width and requested numbers of arguments */ + /* only; they are set to zero afterwards */ + + /* the other two flags are informative only and unused currently */ static const FT_Byte cff_argument_counts[] = { @@ -187,6 +196,11 @@ 1, /* callsubr */ 1, + 0, + + 2, /* hsbw */ + 0, + 0, 0 }; @@ -222,6 +236,8 @@ /* */ /* glyph :: The current glyph object. */ /* */ + /* hinting :: Whether hinting is active. */ + /* */ static void cff_builder_init( CFF_Builder* builder, TT_Face face, @@ -251,17 +267,14 @@ if ( hinting && size ) { - builder->hints_globals = size->root.internal; + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + builder->hints_globals = (void *)internal->topfont; builder->hints_funcs = glyph->root.internal->glyph_hints; } } - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -339,11 +352,15 @@ /* decoder :: A pointer to the glyph builder to initialize. */ /* */ /* <Input> */ - /* face :: The current face object. */ + /* face :: The current face object. */ /* */ - /* size :: The current size object. */ + /* size :: The current size object. */ /* */ - /* slot :: The current glyph object. */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + /* hint_mode :: The hinting mode. */ /* */ FT_LOCAL_DEF( void ) cff_decoder_init( CFF_Decoder* decoder, @@ -371,18 +388,21 @@ } - /* this function is used to select the locals subrs array */ + /* this function is used to select the subfont */ + /* and the locals subrs array */ FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ) { - CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data; - CFF_SubFont sub = &cff->top_font; - FT_Error error = CFF_Err_Ok; + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = CFF_Err_Ok; /* manage CID fonts */ - if ( cff->num_subfonts >= 1 ) + if ( cff->num_subfonts ) { FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); @@ -394,8 +414,23 @@ goto Exit; } + FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } } +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "glyph index %d:\n", glyph_index )); +#endif decoder->num_locals = sub->num_local_subrs; decoder->locals = sub->local_subrs; @@ -437,8 +472,6 @@ point->x = x >> 16; point->y = y >> 16; *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; @@ -517,27 +550,24 @@ cff_builder_close_contour( CFF_Builder* builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and if it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -546,8 +576,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } @@ -667,6 +707,12 @@ FT_ULong charstring_len; + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return CFF_Err_Syntax_Error; + } + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ /* They use the character code, not the glyph index, in this case. */ @@ -687,8 +733,8 @@ if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "cff_operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); return CFF_Err_Syntax_Error; } @@ -737,8 +783,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -763,8 +812,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -826,9 +878,10 @@ decoder->read_width = 1; /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)(char*)&seed ^ - (FT_Fixed)(char*)&decoder ^ - (FT_Fixed)(char*)&charstring_base; + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -883,18 +936,18 @@ ip += 2; } else if ( v < 247 ) - val = (FT_Long)v - 139; + val = (FT_Int32)v - 139; else if ( v < 251 ) { if ( ip >= limit ) goto Syntax_Error; - val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; } else if ( v < 255 ) { if ( ip >= limit ) goto Syntax_Error; - val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; } else { @@ -923,6 +976,11 @@ } else { + /* The specification says that normally arguments are to be taken */ + /* from the bottom of the stack. However, this seems not to be */ + /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ + /* arguments similar to a PS interpreter. */ + FT_Fixed* args = decoder->top; FT_Int num_args = (FT_Int)( args - decoder->stack ); FT_Int req_args; @@ -954,6 +1012,9 @@ case 8: op = cff_op_rrcurveto; break; + case 9: + op = cff_op_closepath; + break; case 10: op = cff_op_callsubr; break; @@ -1004,6 +1065,12 @@ case 15: op = cff_op_eq; break; + case 16: + op = cff_op_callothersubr; + break; + case 17: + op = cff_op_pop; + break; case 18: op = cff_op_drop; break; @@ -1055,6 +1122,9 @@ } } break; + case 13: + op = cff_op_hsbw; + break; case 14: op = cff_op_endchar; break; @@ -1103,6 +1173,7 @@ default: ; } + if ( op == cff_op_unknown ) goto Syntax_Error; @@ -1110,8 +1181,6 @@ req_args = cff_argument_counts[op]; if ( req_args & CFF_COUNT_CHECK_WIDTH ) { - args = stack; - if ( num_args > 0 && decoder->read_width ) { /* If `nominal_width' is non-zero, the number is really a */ @@ -1145,7 +1214,7 @@ case cff_op_endchar: /* If there is a width specified for endchar, we either have */ /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) ); + set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); break; default: @@ -1158,9 +1227,14 @@ decoder->glyph_width = decoder->nominal_width + ( stack[0] >> 16 ); + if ( decoder->width_only ) + { + /* we only want the advance width; stop here */ + break; + } + /* Consumed an argument. */ num_args--; - args++; } } @@ -1168,12 +1242,20 @@ req_args = 0; } - req_args &= 15; + req_args &= 0x000F; if ( num_args < req_args ) goto Stack_Underflow; args -= req_args; num_args -= req_args; + /* At this point, `args' points to the first argument of the */ + /* operand in case `req_args' isn't zero. Otherwise, we have */ + /* to adjust `args' manually. */ + + /* Note that we only pop arguments from the stack which we */ + /* really need and can digest so that we can continue in case */ + /* of superfluous stack elements. */ + switch ( op ) { case cff_op_hstem: @@ -1181,15 +1263,16 @@ case cff_op_hstemhm: case cff_op_vstemhm: /* the number of arguments is always even here */ - FT_TRACE4(( op == cff_op_hstem ? " hstem" : - ( op == cff_op_vstem ? " vstem" : - ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); + FT_TRACE4(( + op == cff_op_hstem ? " hstem\n" : + ( op == cff_op_vstem ? " vstem\n" : + ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); if ( hinter ) hinter->stems( hinter->hints, ( op == cff_op_hstem || op == cff_op_hstemhm ), num_args / 2, - args ); + args - ( num_args & ~1 ) ); decoder->num_hints += num_args / 2; args = stack; @@ -1209,7 +1292,7 @@ hinter->stems( hinter->hints, 0, num_args / 2, - args ); + args - ( num_args & ~1 ) ); decoder->num_hints += num_args / 2; } @@ -1232,12 +1315,14 @@ FT_UInt maskbyte; - FT_TRACE4(( " " )); + FT_TRACE4(( " (maskbytes: " )); for ( maskbyte = 0; maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); maskbyte++, ip++ ) FT_TRACE4(( "0x%02X", *ip )); + + FT_TRACE4(( ")\n" )); } #else ip += ( decoder->num_hints + 7 ) >> 3; @@ -1248,44 +1333,44 @@ break; case cff_op_rmoveto: - FT_TRACE4(( " rmoveto" )); + FT_TRACE4(( " rmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[0]; - y += args[1]; + x += args[-2]; + y += args[-1]; args = stack; break; case cff_op_vmoveto: - FT_TRACE4(( " vmoveto" )); + FT_TRACE4(( " vmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - y += args[0]; + y += args[-1]; args = stack; break; case cff_op_hmoveto: - FT_TRACE4(( " hmoveto" )); + FT_TRACE4(( " hmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[0]; + x += args[-1]; args = stack; break; case cff_op_rlineto: - FT_TRACE4(( " rlineto" )); + FT_TRACE4(( " rlineto\n" )); if ( cff_builder_start_point ( builder, x, y ) || check_points( builder, num_args / 2 ) ) goto Fail; - if ( num_args < 2 || num_args & 1 ) + if ( num_args < 2 ) goto Stack_Underflow; - args = stack; + args -= num_args & ~1; while ( args < decoder->top ) { x += args[0]; @@ -1302,8 +1387,11 @@ FT_Int phase = ( op == cff_op_hlineto ); - FT_TRACE4(( op == cff_op_hlineto ? " hlineto" - : " vlineto" )); + FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" + : " vlineto\n" )); + + if ( num_args < 1 ) + goto Stack_Underflow; if ( cff_builder_start_point ( builder, x, y ) || check_points( builder, num_args ) ) @@ -1328,125 +1416,164 @@ break; case cff_op_rrcurveto: - FT_TRACE4(( " rrcurveto" )); - - /* check number of arguments; must be a multiple of 6 */ - if ( num_args % 6 != 0 ) - goto Stack_Underflow; - - if ( cff_builder_start_point ( builder, x, y ) || - check_points( builder, num_args / 2 ) ) - goto Fail; - - args = stack; - while ( args < decoder->top ) { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; + FT_Int nargs; + + + FT_TRACE4(( " rrcurveto\n" )); + + if ( num_args < 6 ) + goto Stack_Underflow; + + nargs = num_args - num_args % 6; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, nargs / 2 ) ) + goto Fail; + + args -= nargs; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + } + args = stack; } - args = stack; break; case cff_op_vvcurveto: - FT_TRACE4(( " vvcurveto" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args = stack; - if ( num_args & 1 ) { - x += args[0]; - args++; - num_args--; + FT_Int nargs; + + + FT_TRACE4(( " vvcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + + if ( nargs & 1 ) + { + x += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; break; case cff_op_hhcurveto: - FT_TRACE4(( " hhcurveto" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args = stack; - if ( num_args & 1 ) { - y += args[0]; - args++; - num_args--; + FT_Int nargs; + + + FT_TRACE4(( " hhcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + if ( nargs & 1 ) + { + y += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; break; case cff_op_vhcurveto: case cff_op_hvcurveto: { FT_Int phase; + FT_Int nargs; - FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto" - : " hvcurveto" )); + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" + : " hvcurveto\n" )); if ( cff_builder_start_point( builder, x, y ) ) goto Fail; - args = stack; - if ( num_args < 4 || ( num_args % 4 ) > 1 ) + if ( num_args < 4 ) goto Stack_Underflow; - if ( check_points( builder, ( num_args / 4 ) * 3 ) ) + /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ + /* we reduce it to the largest one which fits */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + args -= nargs; + if ( check_points( builder, ( nargs / 4 ) * 3 ) ) goto Stack_Underflow; phase = ( op == cff_op_hvcurveto ); - while ( num_args >= 4 ) + while ( nargs >= 4 ) { - num_args -= 4; + nargs -= 4; if ( phase ) { x += args[0]; @@ -1455,7 +1582,7 @@ y += args[2]; cff_builder_add_point( builder, x, y, 0 ); y += args[3]; - if ( num_args == 1 ) + if ( nargs == 1 ) x += args[4]; cff_builder_add_point( builder, x, y, 1 ); } @@ -1467,7 +1594,7 @@ y += args[2]; cff_builder_add_point( builder, x, y, 0 ); x += args[3]; - if ( num_args == 1 ) + if ( nargs == 1 ) y += args[4]; cff_builder_add_point( builder, x, y, 1 ); } @@ -1480,19 +1607,23 @@ case cff_op_rlinecurve: { - FT_Int num_lines = ( num_args - 6 ) / 2; + FT_Int num_lines; + FT_Int nargs; - FT_TRACE4(( " rlinecurve" )); + FT_TRACE4(( " rlinecurve\n" )); - if ( num_args < 8 || ( num_args - 6 ) & 1 ) + if ( num_args < 8 ) goto Stack_Underflow; + nargs = num_args & ~1; + num_lines = ( nargs - 6 ) / 2; + if ( cff_builder_start_point( builder, x, y ) || check_points( builder, num_lines + 3 ) ) goto Fail; - args = stack; + args -= nargs; /* first, add the line segments */ while ( num_lines > 0 ) @@ -1520,19 +1651,24 @@ case cff_op_rcurveline: { - FT_Int num_curves = ( num_args - 2 ) / 6; + FT_Int num_curves; + FT_Int nargs; - FT_TRACE4(( " rcurveline" )); + FT_TRACE4(( " rcurveline\n" )); - if ( num_args < 8 || ( num_args - 2 ) % 6 ) + if ( num_args < 8 ) goto Stack_Underflow; + nargs = num_args - 2; + nargs = nargs - nargs % 6 + 2; + num_curves = ( nargs - 2 ) / 6; + if ( cff_builder_start_point ( builder, x, y ) || - check_points( builder, num_curves*3 + 2 ) ) + check_points( builder, num_curves * 3 + 2 ) ) goto Fail; - args = stack; + args -= nargs; /* first, add the curves */ while ( num_curves > 0 ) @@ -1563,18 +1699,16 @@ FT_Pos start_y; - FT_TRACE4(( " hflex1" )); + FT_TRACE4(( " hflex1\n" )); - args = stack; - - /* adding five more points; 4 control points, 1 on-curve point */ - /* make sure we have enough space for the start point if it */ + /* adding five more points: 4 control points, 1 on-curve point */ + /* -- make sure we have enough space for the start point if it */ /* needs to be added */ if ( cff_builder_start_point( builder, x, y ) || check_points( builder, 6 ) ) goto Fail; - /* Record the starting point's y position for later use */ + /* record the starting point's y position for later use */ start_y = y; /* first control point */ @@ -1616,9 +1750,7 @@ FT_Pos start_y; - FT_TRACE4(( " hflex" )); - - args = stack; + FT_TRACE4(( " hflex\n" )); /* adding six more points; 4 control points, 2 on-curve points */ if ( cff_builder_start_point( builder, x, y ) || @@ -1663,14 +1795,15 @@ case cff_op_flex1: { - FT_Pos start_x, start_y; /* record start x, y values for */ - /* alter use */ - FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + FT_Fixed* temp; - FT_TRACE4(( " flex1" )); + FT_TRACE4(( " flex1\n" )); /* adding six more points; 4 control points, 2 on-curve points */ if ( cff_builder_start_point( builder, x, y ) || @@ -1684,21 +1817,20 @@ /* XXX: figure out whether this is supposed to be a horizontal */ /* or vertical flex; the Type 2 specification is vague... */ - args = stack; + temp = args; /* grab up to the last argument */ for ( count = 5; count > 0; count-- ) { - dx += args[0]; - dy += args[1]; - args += 2; + dx += temp[0]; + dy += temp[1]; + temp += 2; } - /* rewind */ - args = stack; - - if ( dx < 0 ) dx = -dx; - if ( dy < 0 ) dy = -dy; + if ( dx < 0 ) + dx = -dx; + if ( dy < 0 ) + dy = -dy; /* strange test, but here it is... */ horizontal = ( dx > dy ); @@ -1707,7 +1839,8 @@ { x += args[0]; y += args[1]; - cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) ); + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 ) ); args += 2; } @@ -1734,13 +1867,12 @@ FT_UInt count; - FT_TRACE4(( " flex" )); + FT_TRACE4(( " flex\n" )); if ( cff_builder_start_point( builder, x, y ) || check_points( builder, 6 ) ) goto Fail; - args = stack; for ( count = 6; count > 0; count-- ) { x += args[0]; @@ -1755,21 +1887,20 @@ break; case cff_op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); /* We are going to emulate the seac operator. */ - if ( num_args == 4 ) + if ( num_args >= 4 ) { /* Save glyph width so that the subglyphs don't overwrite it. */ FT_Pos glyph_width = decoder->glyph_width; error = cff_operator_seac( decoder, - args[0], - args[1], - (FT_Int)( args[2] >> 16 ), - (FT_Int)( args[3] >> 16 ) ); - args += 4; + args[-4], + args[-3], + (FT_Int)( args[-2] >> 16 ), + (FT_Int)( args[-1] >> 16 ) ); decoder->glyph_width = glyph_width; } @@ -1799,11 +1930,11 @@ } /* return now! */ - FT_TRACE4(( "\n\n" )); + FT_TRACE4(( "\n" )); return error; case cff_op_abs: - FT_TRACE4(( " abs" )); + FT_TRACE4(( " abs\n" )); if ( args[0] < 0 ) args[0] = -args[0]; @@ -1811,28 +1942,28 @@ break; case cff_op_add: - FT_TRACE4(( " add" )); + FT_TRACE4(( " add\n" )); args[0] += args[1]; args++; break; case cff_op_sub: - FT_TRACE4(( " sub" )); + FT_TRACE4(( " sub\n" )); args[0] -= args[1]; args++; break; case cff_op_div: - FT_TRACE4(( " div" )); + FT_TRACE4(( " div\n" )); args[0] = FT_DivFix( args[0], args[1] ); args++; break; case cff_op_neg: - FT_TRACE4(( " neg" )); + FT_TRACE4(( " neg\n" )); args[0] = -args[0]; args++; @@ -1843,7 +1974,7 @@ FT_Fixed Rand; - FT_TRACE4(( " rand" )); + FT_TRACE4(( " rand\n" )); Rand = seed; if ( Rand >= 0x8000L ) @@ -1858,14 +1989,14 @@ break; case cff_op_mul: - FT_TRACE4(( " mul" )); + FT_TRACE4(( " mul\n" )); args[0] = FT_MulFix( args[0], args[1] ); args++; break; case cff_op_sqrt: - FT_TRACE4(( " sqrt" )); + FT_TRACE4(( " sqrt\n" )); if ( args[0] > 0 ) { @@ -1890,7 +2021,7 @@ case cff_op_drop: /* nothing */ - FT_TRACE4(( " drop" )); + FT_TRACE4(( " drop\n" )); break; @@ -1899,7 +2030,7 @@ FT_Fixed tmp; - FT_TRACE4(( " exch" )); + FT_TRACE4(( " exch\n" )); tmp = args[0]; args[0] = args[1]; @@ -1913,7 +2044,7 @@ FT_Int idx = (FT_Int)( args[0] >> 16 ); - FT_TRACE4(( " index" )); + FT_TRACE4(( " index\n" )); if ( idx < 0 ) idx = 0; @@ -1930,7 +2061,7 @@ FT_Int idx = (FT_Int)( args[1] >> 16 ); - FT_TRACE4(( " roll" )); + FT_TRACE4(( " roll\n" )); if ( count <= 0 ) count = 1; @@ -1972,7 +2103,7 @@ break; case cff_op_dup: - FT_TRACE4(( " dup" )); + FT_TRACE4(( " dup\n" )); args[1] = args[0]; args++; @@ -1984,7 +2115,7 @@ FT_Int idx = (FT_Int)( args[1] >> 16 ); - FT_TRACE4(( " put" )); + FT_TRACE4(( " put\n" )); if ( idx >= 0 && idx < decoder->len_buildchar ) decoder->buildchar[idx] = val; @@ -1997,7 +2128,7 @@ FT_Fixed val = 0; - FT_TRACE4(( " get" )); + FT_TRACE4(( " get\n" )); if ( idx >= 0 && idx < decoder->len_buildchar ) val = decoder->buildchar[idx]; @@ -2008,18 +2139,63 @@ break; case cff_op_store: - FT_TRACE4(( " store ")); + FT_TRACE4(( " store\n")); goto Unimplemented; case cff_op_load: - FT_TRACE4(( " load" )); + FT_TRACE4(( " load\n" )); goto Unimplemented; case cff_op_dotsection: /* this operator is deprecated and ignored by the parser */ - FT_TRACE4(( " dotsection" )); + FT_TRACE4(( " dotsection\n" )); + break; + + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)\n" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + + (args[1] >> 16); + x = args[0]; + y = 0; + args = stack; + break; + + case cff_op_callothersubr: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* don't modify stack; handle the subr as `unknown' so that */ + /* following `pop' operands use the arguments on stack */ + break; + + case cff_op_pop: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " pop (invalid op)\n" )); + + args++; break; case cff_op_and: @@ -2027,7 +2203,7 @@ FT_Fixed cond = args[0] && args[1]; - FT_TRACE4(( " and" )); + FT_TRACE4(( " and\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2039,7 +2215,7 @@ FT_Fixed cond = args[0] || args[1]; - FT_TRACE4(( " or" )); + FT_TRACE4(( " or\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2051,7 +2227,7 @@ FT_Fixed cond = !args[0]; - FT_TRACE4(( " eq" )); + FT_TRACE4(( " eq\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2063,7 +2239,7 @@ FT_Fixed cond = ( args[2] <= args[3] ); - FT_TRACE4(( " ifelse" )); + FT_TRACE4(( " ifelse\n" )); if ( !cond ) args[0] = args[1]; @@ -2077,12 +2253,12 @@ decoder->locals_bias ); - FT_TRACE4(( " callsubr(%d)", idx )); + FT_TRACE4(( " callsubr(%d)\n", idx )); if ( idx >= decoder->num_locals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid local subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); goto Syntax_Error; } @@ -2103,7 +2279,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2119,12 +2295,12 @@ decoder->globals_bias ); - FT_TRACE4(( " callgsubr(%d)", idx )); + FT_TRACE4(( " callgsubr(%d)\n", idx )); if ( idx >= decoder->num_globals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid global subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); goto Syntax_Error; } @@ -2145,7 +2321,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2156,7 +2332,7 @@ break; case cff_op_return: - FT_TRACE4(( " return" )); + FT_TRACE4(( " return\n" )); if ( decoder->zone <= decoder->zones ) { @@ -2194,15 +2370,15 @@ return error; Syntax_Error: - FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return CFF_Err_Invalid_File_Format; Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); return CFF_Err_Too_Few_Arguments; Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); return CFF_Err_Stack_Overflow; } @@ -2260,7 +2436,7 @@ &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, @@ -2290,23 +2466,30 @@ { FT_Error error; CFF_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font cff = (CFF_Font)face->extra.data; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting, force_scaling; + CFF_Font cff = (CFF_Font)face->extra.data; FT_Matrix font_matrix; FT_Vector font_offset; + force_scaling = FALSE; + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ /* it immediately to the real glyph_index -- if it isn't a */ /* subsetted font, glyph_indices and CIDs are identical, though */ if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && - cff->charset.cids ) + cff->charset.cids ) { - glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index ); - if ( glyph_index == 0 ) - return CFF_Err_Invalid_Argument; + /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ + if ( glyph_index != 0 ) + { + glyph_index = cff_charset_cid_to_gindex( &cff->charset, + glyph_index ); + if ( glyph_index == 0 ) + return CFF_Err_Invalid_Argument; + } } else if ( glyph_index >= cff->num_glyphs ) return CFF_Err_Invalid_Argument; @@ -2389,6 +2572,36 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return CFF_Err_Invalid_Argument; + /* if we have a CID subfont, use its matrix (which has already */ + /* been multiplied with the root matrix) */ + + /* this scaling is only relevant if the PS hinter isn't active */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); + + FT_ULong top_upm = cff->top_font.font_dict.units_per_em; + FT_ULong sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + + + font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; + font_offset = cff->subfonts[fd_index]->font_dict.font_offset; + + if ( top_upm != sub_upm ) + { + glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); + glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); + + force_scaling = TRUE; + } + } + else + { + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + } + glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -2405,15 +2618,18 @@ cff_decoder_init( &decoder, face, size, glyph, hinting, FT_LOAD_TARGET_MODE( load_flags ) ); + if ( load_flags & FT_LOAD_ADVANCE_ONLY ) + decoder.width_only = TRUE; + decoder.builder.no_recurse = - (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); /* now load the unscaled outline */ error = cff_get_glyph_data( face, glyph_index, &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) { error = cff_decoder_parse_charstrings( &decoder, @@ -2481,21 +2697,6 @@ if ( !error ) { - if ( cff->num_subfonts >= 1 ) - { - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); - - - font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; - font_offset = cff->subfonts[fd_index]->font_dict.font_offset; - } - else - { - font_matrix = cff->top_font.font_dict.font_matrix; - font_offset = cff->top_font.font_dict.font_offset; - } - /* Now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax. */ @@ -2526,9 +2727,14 @@ glyph->root.linearHoriAdvance = decoder.glyph_width; glyph->root.internal->glyph_transformed = 0; +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 && - face->vertical.long_metrics != 0 ); + face->vertical.long_metrics ); +#else + has_vertical_info = FT_BOOL( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ); +#endif /* get the vertical metrics from the vtmx table if we have one */ if ( has_vertical_info ) @@ -2565,7 +2771,6 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - /* apply the font matrix */ if ( !( font_matrix.xx == 0x10000L && font_matrix.yy == 0x10000L && font_matrix.xy == 0 && @@ -2587,7 +2792,7 @@ FT_Vector_Transform( &advance, &font_matrix ); metrics->vertAdvance = advance.y + font_offset.y; - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { /* scale the outline and the metrics */ FT_Int n; @@ -2620,7 +2825,8 @@ metrics->horiBearingY = cbox.yMax; if ( has_vertical_info ) - metrics->vertBearingX = -metrics->width / 2; + metrics->vertBearingX = metrics->horiBearingX - + metrics->horiAdvance / 2; else ft_synthesize_vertical_metrics( metrics, metrics->vertAdvance ); diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffgload.h b/reactos/lib/3rdparty/freetype/src/cff/cffgload.h index f67864a6925..956817a0806 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffgload.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,12 +53,6 @@ FT_BEGIN_HEADER /* */ /* current :: The current glyph outline. */ /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -92,11 +86,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - FT_Pos pos_x; FT_Pos pos_y; @@ -146,6 +135,7 @@ FT_BEGIN_HEADER FT_Pos nominal_width; FT_Bool read_width; + FT_Bool width_only; FT_Int num_hints; FT_Fixed* buildchar; FT_Int len_buildchar; @@ -164,6 +154,8 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode; + FT_Bool seac; + } CFF_Decoder; @@ -177,6 +169,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ); #if 0 /* unused until we support pure CFF fonts */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffload.c b/reactos/lib/3rdparty/freetype/src/cff/cffload.c index dd2f1133dca..64d13957235 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffload.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,7 @@ #if 1 + static const FT_UShort cff_isoadobe_charset[229] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -175,13 +176,15 @@ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; -#endif + +#endif /* 1 */ FT_LOCAL_DEF( FT_UShort ) cff_get_standard_encoding( FT_UInt charcode ) { - return (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0); + return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] + : 0 ); } @@ -316,7 +319,7 @@ static FT_Error cff_index_load_offsets( CFF_Index idx ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_Stream stream = idx->stream; FT_Memory memory = stream->memory; @@ -399,6 +402,7 @@ old_offset = 1; for ( n = 0; n <= idx->count; n++ ) { + /* at this point, `idx->offsets' can't be NULL */ offset = idx->offsets[n]; if ( !offset ) offset = old_offset; @@ -732,6 +736,7 @@ { FT_Error error = FT_Err_Ok; FT_UInt i; + FT_Long j; FT_UShort max_cid = 0; @@ -746,8 +751,11 @@ if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) goto Exit; - for ( i = 0; i < num_glyphs; i++ ) - charset->cids[charset->sids[i]] = (FT_UShort)i; + /* When multiple GIDs map to the same CID, we choose the lowest */ + /* GID. This is not described in any spec, but it matches the */ + /* behaviour of recent Acroread versions. */ + for ( j = num_glyphs - 1; j >= 0 ; j-- ) + charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; charset->num_glyphs = num_glyphs; @@ -838,7 +846,20 @@ goto Exit; for ( j = 1; j < num_glyphs; j++ ) - charset->sids[j] = FT_GET_USHORT(); + { + FT_UShort sid = FT_GET_USHORT(); + + + /* this constant is given in the CFF specification */ + if ( sid < 65000L ) + charset->sids[j] = sid; + else + { + FT_TRACE0(( "cff_charset_load:" + " invalid SID value %d set to zero\n", sid )); + charset->sids[j] = 0; + } + } FT_FRAME_EXIT(); } @@ -871,6 +892,20 @@ goto Exit; } + /* check whether the range contains at least one valid glyph; */ + /* the constant is given in the CFF specification */ + if ( glyph_sid >= 65000L ) { + FT_ERROR(( "cff_charset_load: invalid SID range\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* try to rescue some of the SIDs if `nleft' is too large */ + if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) { + FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" )); + nleft = ( FT_UInt )( 65000L - 1L - glyph_sid ); + } + /* Fill in the range of sids -- `nleft + 1' glyphs. */ for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) charset->sids[j] = glyph_sid; @@ -879,7 +914,7 @@ break; default: - FT_ERROR(( "cff_charset_load: invalid table format!\n" )); + FT_ERROR(( "cff_charset_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -902,7 +937,7 @@ if ( num_glyphs > 229 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)!\n" )); + "predefined charset (Adobe ISO-Latin)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -920,7 +955,7 @@ if ( num_glyphs > 166 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert)!\n" )); + "predefined charset (Adobe Expert)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -938,7 +973,7 @@ if ( num_glyphs > 87 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert Subset)!\n" )); + "predefined charset (Adobe Expert Subset)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1123,7 +1158,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1218,7 +1253,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1236,7 +1271,8 @@ CFF_Index idx, FT_UInt font_index, FT_Stream stream, - FT_ULong base_offset ) + FT_ULong base_offset, + FT_Library library ) { FT_Error error; CFF_ParserRec parser; @@ -1246,7 +1282,7 @@ CFF_Private priv = &font->private_dict; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict ); + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); @@ -1272,8 +1308,9 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || - cff_parser_run( &parser, dict, dict + dict_len ); + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + if ( !error ) + error = cff_parser_run( &parser, dict, dict + dict_len ); cff_index_forget_element( idx, &dict ); @@ -1296,7 +1333,7 @@ priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv ); + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || FT_FRAME_ENTER( font->font_dict.private_size ) ) @@ -1349,9 +1386,11 @@ FT_LOCAL_DEF( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, - CFF_Font font ) + CFF_Font font, + FT_Bool pure_cff ) { static const FT_Frame_Field cff_header_fields[] = { @@ -1388,7 +1427,7 @@ font->header_size < 4 || font->absolute_offsize > 4 ) { - FT_TRACE2(( "[not a CFF font header!]\n" )); + FT_TRACE2(( "[not a CFF font header]\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -1426,7 +1465,8 @@ &font->font_dict_index, face_index, stream, - base_offset ); + base_offset, + library ); if ( error ) goto Exit; @@ -1456,7 +1496,7 @@ if ( fd_index.count > CFF_MAX_CID_FONTS ) { - FT_ERROR(( "cff_font_load: FD array too large in CID font\n" )); + FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); goto Fail_CID; } @@ -1474,7 +1514,7 @@ { sub = font->subfonts[idx]; error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset ); + stream, base_offset, library ); if ( error ) goto Fail_CID; } @@ -1497,7 +1537,7 @@ /* read the charstrings index now */ if ( dict->charstrings_offset == 0 ) { - FT_ERROR(( "cff_font_load: no charstrings offset!\n" )); + FT_ERROR(( "cff_font_load: no charstrings offset\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -1515,7 +1555,7 @@ /* read the Charset and Encoding tables if available */ if ( font->num_glyphs > 0 ) { - FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU ); + FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); error = cff_charset_load( &font->charset, font->num_glyphs, stream, @@ -1535,9 +1575,6 @@ if ( error ) goto Exit; } - else - /* CID-keyed fonts only need CIDs */ - FT_FREE( font->charset.sids ); } /* get the font name (/CIDFontName for CID-keyed fonts, */ @@ -1590,6 +1627,9 @@ FT_FREE( font->font_info ); } + FT_FREE( font->registry ); + FT_FREE( font->ordering ); + FT_FREE( font->global_subrs ); FT_FREE( font->font_name ); } diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffload.h b/reactos/lib/3rdparty/freetype/src/cff/cffload.h index 068cbb58c23..2b313acf06e 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffload.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,9 +58,11 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, - CFF_Font font ); + CFF_Font font, + FT_Bool pure_cff ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c index c02cf33fc8b..e0966e0d38e 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,6 +30,7 @@ #include "cffload.h" #include "cffcmap.h" #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -56,7 +57,7 @@ cff_size_get_globals_funcs( CFF_Size size ) { CFF_Face face = (CFF_Face)size->root.face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; @@ -72,23 +73,84 @@ FT_LOCAL_DEF( void ) cff_size_done( FT_Size cffsize ) /* CFF_Size */ { - CFF_Size size = (CFF_Size)cffsize; + CFF_Size size = (CFF_Size)cffsize; + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)cffsize->internal; - if ( cffsize->internal ) + if ( internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)cffsize->internal ); + { + FT_UInt i; - cffsize->internal = 0; + + funcs->destroy( internal->topfont ); + + for ( i = font->num_subfonts; i > 0; i-- ) + funcs->destroy( internal->subfonts[i - 1] ); + } + + /* `internal' is freed by destroy_size (in ftobjs.c) */ } } + /* CFF and Type 1 private dictionaries have slightly different */ + /* structures; we need to synthesize a Type 1 dictionary on the fly */ + + static void + cff_make_private_dict( CFF_SubFont subfont, + PS_Private priv ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + count = priv->num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv->num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv->num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv->num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv->blue_scale = cpriv->blue_scale; + priv->blue_shift = (FT_Int)cpriv->blue_shift; + priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv->standard_width[0] = (FT_UShort)cpriv->standard_width; + priv->standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv->num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv->num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv->force_bold = cpriv->force_bold; + priv->language_group = cpriv->language_group; + priv->lenIV = cpriv->lenIV; + } + + FT_LOCAL_DEF( FT_Error ) cff_size_init( FT_Size cffsize ) /* CFF_Size */ { @@ -99,68 +161,43 @@ if ( funcs ) { - PSH_Globals globals; - CFF_Face face = (CFF_Face)cffsize->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; - CFF_SubFont subfont = &font->top_font; + CFF_Face face = (CFF_Face)cffsize->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal; - CFF_Private cpriv = &subfont->private_dict; PS_PrivateRec priv; + FT_Memory memory = cffsize->face->memory; + + FT_UInt i; - /* IMPORTANT: The CFF and Type1 private dictionaries have */ - /* slightly different structures; we need to */ - /* synthetize a type1 dictionary on the fly here. */ + if ( FT_NEW( internal ) ) + goto Exit; + cff_make_private_dict( &font->top_font, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->topfont ); + if ( error ) + goto Exit; + + for ( i = font->num_subfonts; i > 0; i-- ) { - FT_UInt n, count; + CFF_SubFont sub = font->subfonts[i - 1]; - FT_MEM_ZERO( &priv, sizeof ( priv ) ); - - count = priv.num_blue_values = cpriv->num_blue_values; - for ( n = 0; n < count; n++ ) - priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; - - count = priv.num_other_blues = cpriv->num_other_blues; - for ( n = 0; n < count; n++ ) - priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; - - count = priv.num_family_blues = cpriv->num_family_blues; - for ( n = 0; n < count; n++ ) - priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; - - count = priv.num_family_other_blues = cpriv->num_family_other_blues; - for ( n = 0; n < count; n++ ) - priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; - - priv.blue_scale = cpriv->blue_scale; - priv.blue_shift = (FT_Int)cpriv->blue_shift; - priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; - - priv.standard_width[0] = (FT_UShort)cpriv->standard_width; - priv.standard_height[0] = (FT_UShort)cpriv->standard_height; - - count = priv.num_snap_widths = cpriv->num_snap_widths; - for ( n = 0; n < count; n++ ) - priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; - - count = priv.num_snap_heights = cpriv->num_snap_heights; - for ( n = 0; n < count; n++ ) - priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; - - priv.force_bold = cpriv->force_bold; - priv.language_group = cpriv->language_group; - priv.lenIV = cpriv->lenIV; + cff_make_private_dict( sub, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->subfonts[i - 1] ); + if ( error ) + goto Exit; } - error = funcs->create( cffsize->face->memory, &priv, &globals ); - if ( !error ) - cffsize->internal = (FT_Size_Internal)(void*)globals; + cffsize->internal = (FT_Size_Internal)(void*)internal; } size->strike_index = 0xFFFFFFFFUL; + Exit: return error; } @@ -182,11 +219,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -223,11 +291,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face cffface = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)cffface->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -249,7 +348,7 @@ cff_slot_init( FT_GlyphSlot slot ) { CFF_Face face = (CFF_Face)slot->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; @@ -270,7 +369,7 @@ } } - return 0; + return CFF_Err_Ok; } @@ -288,7 +387,9 @@ FT_String* result; - result = ft_mem_strdup( memory, source, &error ); + (void)FT_STRDUP( result, source ); + + FT_UNUSED( error ); return result; } @@ -308,6 +409,7 @@ PSHinter_Service pshinter; FT_Bool pure_cff = 1; FT_Bool sfnt_format = 0; + FT_Library library = cffface->driver->root.library; #if 0 @@ -319,14 +421,14 @@ goto Bad_Format; #else sfnt = (SFNT_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "sfnt" ); + library, "sfnt" ); if ( !sfnt ) goto Bad_Format; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); pshinter = (PSHinter_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "pshinter" ); + library, "pshinter" ); #endif /* create input stream from resource */ @@ -337,7 +439,7 @@ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { - if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ + if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ { FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); goto Bad_Format; @@ -365,8 +467,7 @@ pure_cff = 0; /* load font directory */ - error = sfnt->load_face( stream, face, - face_index, num_params, params ); + error = sfnt->load_face( stream, face, 0, num_params, params ); if ( error ) goto Exit; } @@ -408,13 +509,15 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( stream, face_index, cff ); + error = cff_font_load( library, stream, face_index, cff, pure_cff ); if ( error ) goto Exit; cff->pshinter = pshinter; cff->psnames = (void*)psnames; + cffface->face_index = face_index; + /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ /* SFNT based fonts use the `name' table instead. */ @@ -427,13 +530,118 @@ /* which aren't CID-keyed */ if ( dict->cid_registry == 0xFFFFU && !psnames ) { - FT_ERROR(( "cff_face_init:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_face_init:" + " cannot open CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); goto Bad_Format; } + if ( !dict->units_per_em ) + dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; + + /* Normalize the font matrix so that `matrix->xx' is 1; the */ + /* scaling is done with `units_per_em' then (at this point, */ + /* it already contains the scaling factor, but without */ + /* normalization of the matrix). */ + /* */ + /* Note that the offsets must be expressed in integer font */ + /* units. */ + + { + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Fixed temp = FT_ABS( matrix->yy ); + + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + for ( i = cff->num_subfonts; i > 0; i-- ) + { + CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; + CFF_FontRecDict top = &cff->top_font.font_dict; + + FT_Matrix* matrix; + FT_Vector* offset; + FT_ULong* upm; + FT_Fixed temp; + + + if ( sub->units_per_em ) + { + FT_Long scaling; + + + if ( top->units_per_em > 1 && sub->units_per_em > 1 ) + scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + else + scaling = 1; + + FT_Matrix_Multiply_Scaled( &top->font_matrix, + &sub->font_matrix, + scaling ); + FT_Vector_Transform_Scaled( &sub->font_offset, + &top->font_matrix, + scaling ); + + sub->units_per_em = FT_MulDiv( sub->units_per_em, + top->units_per_em, + scaling ); + } + else + { + sub->font_matrix = top->font_matrix; + sub->font_offset = top->font_offset; + + sub->units_per_em = top->units_per_em; + } + + matrix = &sub->font_matrix; + offset = &sub->font_offset; + upm = &sub->units_per_em; + temp = FT_ABS( matrix->yy ); + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + /* if *upm is larger than 100*1000 we divide by 1000 -- */ + /* this can happen if e.g. there is no top-font FontMatrix */ + /* and the subfont FontMatrix already contains the complete */ + /* scaling for the subfont (see section 5.11 of the PLRM) */ + + /* 100 is a heuristic value */ + + if ( *upm > 100L * 1000L ) + *upm = ( *upm + 500 ) / 1000; + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + if ( pure_cff ) { char* style_name = NULL; @@ -444,7 +652,7 @@ /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = dict->cid_count; + cffface->num_glyphs = cff->charset.max_cid; else cffface->num_glyphs = cff->charstrings_index.count; @@ -454,10 +662,7 @@ cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; - if ( !dict->units_per_em ) - dict->units_per_em = 1000; - - cffface->units_per_EM = dict->units_per_em; + cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); cffface->ascender = (FT_Short)( cffface->bbox.yMax ); cffface->descender = (FT_Short)( cffface->bbox.yMin ); @@ -561,22 +766,22 @@ /* */ /* Compute face flags. */ /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ + flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER ); /* has native hinter */ if ( sfnt_format ) - flags |= FT_FACE_FLAG_SFNT; + flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; /* fixed width font? */ if ( dict->is_fixed_pitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; + flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ #if 0 /* kerning available? */ if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; + flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; #endif cffface->face_flags = flags; @@ -611,51 +816,25 @@ cffface->style_flags = flags; } - else - { - if ( !dict->units_per_em ) - dict->units_per_em = face->root.units_per_EM; - } - /* handle font matrix settings in subfonts (if any) */ - for ( i = cff->num_subfonts; i > 0; i-- ) - { - CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; - CFF_FontRecDict top = &cff->top_font.font_dict; - - - if ( sub->units_per_em ) - { - FT_Matrix scale; - - - scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em, - sub->units_per_em ); - scale.xy = scale.yx = 0; - - FT_Matrix_Multiply( &scale, &sub->font_matrix ); - FT_Vector_Transform( &sub->font_offset, &scale ); - } - else - { - sub->font_matrix = top->font_matrix; - sub->font_offset = top->font_offset; - } - } #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ - /* has unset this flag because of the 3.0 `post' table */ + /* has unset this flag because of the 3.0 `post' table. */ if ( dict->cid_registry == 0xFFFFU ) cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif + if ( dict->cid_registry != 0xFFFFU && pure_cff ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + /*******************************************************************/ /* */ /* Compute char maps. */ /* */ - /* Try to synthetize a Unicode charmap if there is none available */ + /* Try to synthesize a Unicode charmap if there is none available */ /* already. If an OpenType font contains a Unicode "cmap", we */ /* will use it, whatever be in the CFF part of the file. */ { @@ -683,7 +862,7 @@ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; - /* we didn't find a Unicode charmap -- synthetize one */ + /* we didn't find a Unicode charmap -- synthesize one */ cmaprec.face = cffface; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; @@ -691,7 +870,7 @@ nn = (FT_UInt)cffface->num_charmaps; - FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); + FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL ); /* if no Unicode charmap was previously selected, select this one */ if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) @@ -710,19 +889,19 @@ { cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } else if ( encoding->offset == 1 ) { cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } else { cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } FT_CMap_New( clazz, NULL, &cmaprec, NULL ); @@ -742,11 +921,17 @@ FT_LOCAL_DEF( void ) cff_face_done( FT_Face cffface ) /* CFF_Face */ { - CFF_Face face = (CFF_Face)cffface; - FT_Memory memory = cffface->memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + CFF_Face face = (CFF_Face)cffface; + FT_Memory memory; + SFNT_Service sfnt; + if ( !face ) + return; + + memory = cffface->memory; + sfnt = (SFNT_Service)face->sfnt; + if ( sfnt ) sfnt->done_face( face ); diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.h b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.h index f18b5d9322d..3c81cee0094 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "cfftypes.h" #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H FT_BEGIN_HEADER @@ -53,8 +54,8 @@ FT_BEGIN_HEADER /* */ typedef struct CFF_SizeRec_ { - FT_SizeRec root; - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ } CFF_SizeRec, *CFF_Size; @@ -80,6 +81,21 @@ FT_BEGIN_HEADER } CFF_GlyphSlotRec, *CFF_GlyphSlot; + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + /*************************************************************************/ /* */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffparse.c b/reactos/lib/3rdparty/freetype/src/cff/cffparse.c index 41af6a317f1..947ec9d343b 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffparse.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,10 @@ #include <ft2build.h> #include "cffparse.h" #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -33,47 +35,20 @@ #define FT_COMPONENT trace_cffparse - enum - { - cff_kind_none = 0, - cff_kind_num, - cff_kind_fixed, - cff_kind_fixed_thousand, - cff_kind_string, - cff_kind_bool, - cff_kind_delta, - cff_kind_callback, - - cff_kind_max /* do not remove */ - }; - - - /* now generate handlers for the most simple fields */ - typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); - - typedef struct CFF_Field_Handler_ - { - int kind; - int code; - FT_UInt offset; - FT_Byte size; - CFF_Field_Reader reader; - FT_UInt array_max; - FT_UInt count_offset; - - } CFF_Field_Handler; FT_LOCAL_DEF( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ) + void* object, + FT_Library library) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); parser->top = parser->stack; parser->object_code = code; parser->object = object; + parser->library = library; } @@ -136,24 +111,53 @@ } + static const FT_Long power_tens[] = + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L + }; + + /* read a real */ static FT_Fixed cff_parse_real( FT_Byte* start, FT_Byte* limit, - FT_Int power_ten ) + FT_Long power_ten, + FT_Long* scaling ) { - FT_Byte* p = start; - FT_Long num, divider, result, exponent; - FT_Int sign = 0, exponent_sign = 0; + FT_Byte* p = start; FT_UInt nib; FT_UInt phase; + FT_Long result, number, rest, exponent; + FT_Int sign = 0, exponent_sign = 0; + FT_Long exponent_add, integer_length, fraction_length; - result = 0; - num = 0; - divider = 1; - /* first of all, read the integer part */ + if ( scaling ) + *scaling = 0; + + result = 0; + + number = 0; + rest = 0; + exponent = 0; + + exponent_add = 0; + integer_length = 0; + fraction_length = 0; + + FT_UNUSED( rest ); + + /* First of all, read the integer part. */ phase = 4; for (;;) @@ -166,7 +170,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -178,10 +182,20 @@ else if ( nib > 9 ) break; else - result = result * 10 + nib; + { + /* Increase exponent if we can't add the digit. */ + if ( number >= 0xCCCCCCCL ) + exponent_add++; + /* Skip leading zeros. */ + else if ( nib || number ) + { + integer_length++; + number = number * 10 + nib; + } + } } - /* read decimal part, if any */ + /* Read fraction part, if any. */ if ( nib == 0xa ) for (;;) { @@ -193,7 +207,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -202,14 +216,18 @@ if ( nib >= 10 ) break; - if ( divider < 10000000L ) + /* Skip leading zeros if possible. */ + if ( !nib && !number ) + exponent_add--; + /* Only add digit if we don't overflow. */ + else if ( number < 0xCCCCCCCL && fraction_length < 9 ) { - num = num * 10 + nib; - divider *= 10; + fraction_length++; + number = number * 10 + nib; } } - /* read exponent, if any */ + /* Read exponent, if any. */ if ( nib == 12 ) { exponent_sign = 1; @@ -218,19 +236,17 @@ if ( nib == 11 ) { - exponent = 0; - for (;;) { - /* If we entered this iteration with phase == 4, we need */ - /* to read a new byte. */ + /* If we entered this iteration with phase == 4, */ + /* we need to read a new byte. */ if ( phase ) { p++; /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -240,47 +256,111 @@ break; exponent = exponent * 10 + nib; + + /* Arbitrarily limit exponent. */ + if ( exponent > 1000 ) + goto Exit; } if ( exponent_sign ) exponent = -exponent; - - power_ten += (FT_Int)exponent; } - /* raise to power of ten if needed */ - while ( power_ten > 0 ) + /* We don't check `power_ten' and `exponent_add'. */ + exponent += power_ten + exponent_add; + + if ( scaling ) { - result = result * 10; - num = num * 10; + /* Only use `fraction_length'. */ + fraction_length += integer_length; + exponent += integer_length; - power_ten--; + if ( fraction_length <= 5 ) + { + if ( number > 0x7FFFL ) + { + result = FT_DivFix( number, 10 ); + *scaling = exponent - fraction_length + 1; + } + else + { + if ( exponent > 0 ) + { + FT_Long new_fraction_length, shift; + + + /* Make `scaling' as small as possible. */ + new_fraction_length = FT_MIN( exponent, 5 ); + exponent -= new_fraction_length; + shift = new_fraction_length - fraction_length; + + number *= power_tens[shift]; + if ( number > 0x7FFFL ) + { + number /= 10; + exponent += 1; + } + } + else + exponent -= fraction_length; + + result = number << 16; + *scaling = exponent; + } + } + else + { + if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) + { + result = FT_DivFix( number, power_tens[fraction_length - 4] ); + *scaling = exponent - 4; + } + else + { + result = FT_DivFix( number, power_tens[fraction_length - 5] ); + *scaling = exponent - 5; + } + } } - - while ( power_ten < 0 ) + else { - result = result / 10; - divider = divider * 10; + integer_length += exponent; + fraction_length -= exponent; - power_ten++; + /* Check for overflow and underflow. */ + if ( FT_ABS( integer_length ) > 5 ) + goto Exit; + + /* Remove non-significant digits. */ + if ( integer_length < 0 ) { + number /= power_tens[-integer_length]; + fraction_length += integer_length; + } + + /* Convert into 16.16 format. */ + if ( fraction_length > 0 ) + { + if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) + goto Exit; + + result = FT_DivFix( number, power_tens[fraction_length] ); + } + else + { + number *= power_tens[-fraction_length]; + + if ( number > 0x7FFFL ) + goto Exit; + + result = number << 16; + } } - /* Move the integer part into the high 16 bits. */ - result <<= 16; - - /* Place the decimal part into the low 16 bits. */ - if ( num ) - result |= FT_DivFix( num, divider ); - if ( sign ) result = -result; Exit: return result; - - Bad: - result = 0; - goto Exit; } @@ -288,8 +368,8 @@ static FT_Long cff_parse_num( FT_Byte** d ) { - return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 ) - : cff_parse_integer( d[0], d[1] ) ); + return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) + : cff_parse_integer( d[0], d[1] ); } @@ -297,64 +377,120 @@ static FT_Fixed cff_parse_fixed( FT_Byte** d ) { - return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 ) - : cff_parse_integer( d[0], d[1] ) << 16 ); + return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL ) + : cff_parse_integer( d[0], d[1] ) << 16; } + /* read a floating point number, either integer or real, */ - /* but return 1000 times the number read in. */ + /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_thousand( FT_Byte** d ) + cff_parse_fixed_scaled( FT_Byte** d, + FT_Long scaling ) { - return **d == - 30 ? cff_parse_real ( d[0], d[1], 3 ) - : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 ); + return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL ) + : ( cff_parse_integer( d[0], d[1] ) * + power_tens[scaling] ) << 16; } + + /* read a floating point number, either integer or real, */ + /* and return it as precise as possible -- `scaling' returns */ + /* the scaling factor (as a power of 10) */ + static FT_Fixed + cff_parse_fixed_dynamic( FT_Byte** d, + FT_Long* scaling ) + { + FT_ASSERT( scaling ); + + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], 0, scaling ); + else + { + FT_Long number; + FT_Int integer_length; + + + number = cff_parse_integer( d[0], d[1] ); + + if ( number > 0x7FFFL ) + { + for ( integer_length = 5; integer_length < 10; integer_length++ ) + if ( number < power_tens[integer_length] ) + break; + + if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) + { + *scaling = integer_length - 4; + return FT_DivFix( number, power_tens[integer_length - 4] ); + } + else + { + *scaling = integer_length - 5; + return FT_DivFix( number, power_tens[integer_length - 5] ); + } + } + else + { + *scaling = 0; + return number << 16; + } + } + } + + static FT_Error cff_parse_font_matrix( CFF_Parser parser ) { CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; - FT_UShort* upm = &dict->units_per_em; + FT_ULong* upm = &dict->units_per_em; FT_Byte** data = parser->stack; - FT_Error error; - FT_Fixed temp; + FT_Error error = CFF_Err_Stack_Underflow; - error = CFF_Err_Stack_Underflow; - if ( parser->top >= parser->stack + 6 ) { - matrix->xx = cff_parse_fixed_thousand( data++ ); - matrix->yx = cff_parse_fixed_thousand( data++ ); - matrix->xy = cff_parse_fixed_thousand( data++ ); - matrix->yy = cff_parse_fixed_thousand( data++ ); - offset->x = cff_parse_fixed_thousand( data++ ); - offset->y = cff_parse_fixed_thousand( data ); + FT_Long scaling; - temp = FT_ABS( matrix->yy ); - - *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); - - if ( temp != 0x10000L ) - { - matrix->xx = FT_DivFix( matrix->xx, temp ); - matrix->yx = FT_DivFix( matrix->yx, temp ); - matrix->xy = FT_DivFix( matrix->xy, temp ); - matrix->yy = FT_DivFix( matrix->yy, temp ); - offset->x = FT_DivFix( offset->x, temp ); - offset->y = FT_DivFix( offset->y, temp ); - } - - /* note that the offsets must be expressed in integer font units */ - offset->x >>= 16; - offset->y >>= 16; error = CFF_Err_Ok; + + /* We expect a well-formed font matrix, this is, the matrix elements */ + /* `xx' and `yy' are of approximately the same magnitude. To avoid */ + /* loss of precision, we use the magnitude of element `xx' to scale */ + /* all other elements. The scaling factor is then contained in the */ + /* `units_per_em' value. */ + + matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + + scaling = -scaling; + + if ( scaling < 0 || scaling > 9 ) + { + /* Return default matrix in case of unlikely values. */ + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->yx = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + goto Exit; + } + + matrix->yx = cff_parse_fixed_scaled( data++, scaling ); + matrix->xy = cff_parse_fixed_scaled( data++, scaling ); + matrix->yy = cff_parse_fixed_scaled( data++, scaling ); + offset->x = cff_parse_fixed_scaled( data++, scaling ); + offset->y = cff_parse_fixed_scaled( data, scaling ); + + *upm = power_tens[scaling]; } + Exit: return error; } @@ -418,7 +554,12 @@ { dict->cid_registry = (FT_UInt)cff_parse_num ( data++ ); dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ ); - dict->cid_supplement = (FT_ULong)cff_parse_num( data ); + if ( **data == 30 ) + FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); + dict->cid_supplement = cff_parse_num( data ); + if ( dict->cid_supplement < 0 ) + FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", + dict->cid_supplement )); error = CFF_Err_Ok; } @@ -439,6 +580,11 @@ #define CFF_FIELD_DELTA( code, name, max ) \ CFF_FIELD( code, name, cff_kind_delta ) +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + +#ifndef FT_CONFIG_OPTION_PIC + #define CFF_FIELD_CALLBACK( code, name ) \ { \ cff_kind_callback, \ @@ -470,9 +616,6 @@ FT_FIELD_OFFSET( num_ ## name ) \ }, -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - static const CFF_Field_Handler cff_field_handlers[] = { @@ -482,13 +625,99 @@ }; +#else /* FT_CONFIG_OPTION_PIC */ + + void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class) + { + CFF_Field_Handler* clazz; + FT_Error error; + FT_Memory memory = library->memory; + int i=0; + +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code, name ) i++; +#define CFF_FIELD( code, name, kind ) i++; +#define CFF_FIELD_DELTA( code, name, max ) i++; + +#include "cfftoken.h" + i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/ + + if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) ) + return error; + + i=0; +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK + +#define CFF_FIELD_CALLBACK( code_, name_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + + *output_class = clazz; + return FT_Err_Ok; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + FT_LOCAL_DEF( FT_Error ) cff_parser_run( CFF_Parser parser, FT_Byte* start, FT_Byte* limit ) { - FT_Byte* p = start; - FT_Error error = CFF_Err_Ok; + FT_Byte* p = start; + FT_Error error = CFF_Err_Ok; + FT_Library library = parser->library; + FT_UNUSED(library); parser->top = parser->stack; @@ -558,7 +787,7 @@ } code = code | parser->object_code; - for ( field = cff_field_handlers; field->kind; field++ ) + for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ ) { if ( field->code == (FT_Int)code ) { @@ -585,7 +814,7 @@ goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_thousand( parser->stack ); + val = cff_parse_fixed_scaled( parser->stack, 3 ); Store_Number: switch ( field->size ) diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffparse.h b/reactos/lib/3rdparty/freetype/src/cff/cffparse.h index 8f3fa588592..7e2c00a0449 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffparse.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffparse.h @@ -36,6 +36,7 @@ FT_BEGIN_HEADER typedef struct CFF_ParserRec_ { + FT_Library library; FT_Byte* start; FT_Byte* limit; FT_Byte* cursor; @@ -52,7 +53,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ); + void* object, + FT_Library library); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -60,6 +62,37 @@ FT_BEGIN_HEADER FT_Byte* limit ); + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_fixed_thousand, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + + } CFF_Field_Handler; + + FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffpic.c b/reactos/lib/3rdparty/freetype/src/cff/cffpic.c new file mode 100644 index 00000000000..568956d6a93 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/cff/cffpic.c @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* cffpic.c */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "cffpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from cffdrivr.c */ + FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*); + void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*); + + /* forward declaration of PIC init functions from cffparse.c */ + FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**); + void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*); + + /* forward declaration of PIC init functions from cffcmap.c */ + void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*); + void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*); + + void + cff_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->cff ) + { + CffModulePIC* container = (CffModulePIC*)pic_container->cff; + if(container->cff_services) + FT_Destroy_Class_cff_services(library, container->cff_services); + container->cff_services = NULL; + if(container->cff_field_handlers) + FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers); + container->cff_field_handlers = NULL; + FT_FREE( container ); + pic_container->cff = NULL; + } + } + + FT_Error + cff_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + CffModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->cff = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_cff_services(library, &container->cff_services); + if(error) + goto Exit; + error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers); + if(error) + goto Exit; + FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info); + FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict); + FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name); + FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info); + FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info); + FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec); + FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec); +Exit: + if(error) + cff_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffpic.h b/reactos/lib/3rdparty/freetype/src/cff/cffpic.h new file mode 100644 index 00000000000..e29d068134b --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/cff/cffpic.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* cffpic.h */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFPIC_H__ +#define __CFFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_CFF_SERVICE_PS_INFO_GET cff_service_ps_info +#define FT_CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict +#define FT_CFF_SERVICE_PS_NAME_GET cff_service_ps_name +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info +#define FT_CFF_SERVICE_CID_INFO_GET cff_service_cid_info +#define FT_CFF_SERVICES_GET cff_services +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec +#define FT_CFF_FIELD_HANDLERS_GET cff_field_handlers + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_GLYPH_DICT_H +#include "cffparse.h" +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CID_H + + typedef struct CffModulePIC_ + { + FT_ServiceDescRec* cff_services; + CFF_Field_Handler* cff_field_handlers; + FT_Service_PsInfoRec cff_service_ps_info; + FT_Service_GlyphDictRec cff_service_glyph_dict; + FT_Service_PsFontNameRec cff_service_ps_name; + FT_Service_TTCMapsRec cff_service_get_cmap_info; + FT_Service_CIDRec cff_service_cid_info; + FT_CMap_ClassRec cff_cmap_encoding_class_rec; + FT_CMap_ClassRec cff_cmap_unicode_class_rec; + } CffModulePIC; + +#define GET_PIC(lib) ((CffModulePIC*)((lib)->pic_container.cff)) +#define FT_CFF_SERVICE_PS_INFO_GET (GET_PIC(library)->cff_service_ps_info) +#define FT_CFF_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->cff_service_glyph_dict) +#define FT_CFF_SERVICE_PS_NAME_GET (GET_PIC(library)->cff_service_ps_name) +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->cff_service_get_cmap_info) +#define FT_CFF_SERVICE_CID_INFO_GET (GET_PIC(library)->cff_service_cid_info) +#define FT_CFF_SERVICES_GET (GET_PIC(library)->cff_services) +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec) +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET (GET_PIC(library)->cff_cmap_unicode_class_rec) +#define FT_CFF_FIELD_HANDLERS_GET (GET_PIC(library)->cff_field_handlers) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __CFFPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/cff/cfftypes.h b/reactos/lib/3rdparty/freetype/src/cff/cfftypes.h index 306e5aab670..df92e9a1ac3 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cfftypes.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,7 +114,7 @@ FT_BEGIN_HEADER FT_Int paint_type; FT_Int charstring_type; FT_Matrix font_matrix; - FT_UShort units_per_em; + FT_ULong units_per_em; /* temporarily used as scaling value also */ FT_Vector font_offset; FT_ULong unique_id; FT_BBox font_bbox; @@ -130,7 +130,7 @@ FT_BEGIN_HEADER /* these should only be used for the top-level font dictionary */ FT_UInt cid_registry; FT_UInt cid_ordering; - FT_ULong cid_supplement; + FT_Long cid_supplement; FT_Long cid_font_version; FT_Long cid_font_revision; @@ -259,6 +259,10 @@ FT_BEGIN_HEADER /* since version 2.3.0 */ PS_FontInfoRec* font_info; /* font info dictionary */ + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + } CFF_FontRec, *CFF_Font; diff --git a/reactos/lib/3rdparty/freetype/src/cff/module.mk b/reactos/lib/3rdparty/freetype/src/cff/module.mk index 0474e37b69c..ef1391c279b 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/module.mk +++ b/reactos/lib/3rdparty/freetype/src/cff/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += CFF_DRIVER define CFF_DRIVER -$(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidgload.c b/reactos/lib/3rdparty/freetype/src/cid/cidgload.c index 8bec6e187b4..f59035ffa36 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidgload.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H #include "ciderrs.h" @@ -51,20 +52,23 @@ FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* For incremental fonts get the character data using */ /* the callback function. */ - if ( face->root.internal->incremental_interface ) + if ( inc ) { FT_Data glyph_data; - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, - &glyph_data ); + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, &glyph_data ); if ( error ) goto Exit; @@ -74,15 +78,13 @@ if ( glyph_data.length != 0 ) { glyph_length = glyph_data.length - cid->fd_bytes; - FT_ALLOC( charstring, glyph_length ); + (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); } - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); + inc->funcs->free_glyph_data( inc->object, &glyph_data ); if ( error ) goto Exit; @@ -163,22 +165,21 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - decoder->builder.left_bearing.x = metrics.bearing_x; - decoder->builder.left_bearing.y = metrics.bearing_y; - decoder->builder.advance.x = metrics.advance; + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); decoder->builder.advance.y = 0; } @@ -251,7 +252,7 @@ /* ignore the error if one occurred - skip to next glyph */ } - *max_advance = decoder.builder.advance.x; + *max_advance = FIXED_TO_INT( decoder.builder.advance.x ); psaux->t1_decoder_funcs->done( &decoder ); @@ -342,8 +343,10 @@ FT_Slot_Internal internal = cidglyph->internal; - cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x; - cidglyph->metrics.horiAdvance = decoder.builder.advance.x; + cidglyph->metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + cidglyph->metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); internal->glyph_matrix = font_matrix; internal->glyph_delta = font_offset; @@ -357,8 +360,10 @@ /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - cidglyph->linearHoriAdvance = decoder.builder.advance.x; + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + cidglyph->linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); cidglyph->internal->glyph_transformed = 0; /* make up vertical ones */ diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidload.c b/reactos/lib/3rdparty/freetype/src/cid/cidload.c index 9ed8cee46c7..3bb359446f9 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidload.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -97,6 +97,10 @@ object = (FT_Byte*)&cid->font_info; break; + case T1_FIELD_LOCATION_FONT_EXTRA: + object = (FT_Byte*)&face->font_extra; + break; + case T1_FIELD_LOCATION_BBOX: object = (FT_Byte*)&cid->font_bbox; break; @@ -108,7 +112,7 @@ if ( parser->num_dict < 0 ) { - FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", + FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", keyword->ident )); error = CID_Err_Syntax_Error; goto Exit; @@ -234,14 +238,38 @@ } + /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ + /* and CID_FaceDictRec (both are public header files and can't */ + /* changed); we simply copy the value */ + + FT_CALLBACK_DEF( FT_Error ) + parse_expansion_factor( CID_Face face, + CID_Parser* parser ) + { + CID_FaceDict dict; + + + if ( parser->num_dict >= 0 ) + { + dict = face->cid.font_dicts + parser->num_dict; + + dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); + dict->private_dict.expansion_factor = dict->expansion_factor; + } + + return CID_Err_Ok; + } + + static const T1_FieldRec cid_field_records[] = { #include "cidtoken.h" - T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) - T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c b/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c index 1b3bfbf749a..9647d870161 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -193,61 +193,61 @@ FT_LOCAL_DEF( void ) cid_face_done( FT_Face cidface ) /* CID_Face */ { - CID_Face face = (CID_Face)cidface; - FT_Memory memory; + CID_Face face = (CID_Face)cidface; + FT_Memory memory; + CID_FaceInfo cid; + PS_FontInfo info; - if ( face ) + if ( !face ) + return; + + cid = &face->cid; + info = &cid->font_info; + memory = cidface->memory; + + /* release subrs */ + if ( face->subrs ) { - CID_FaceInfo cid = &face->cid; - PS_FontInfo info = &cid->font_info; + FT_Int n; - memory = cidface->memory; - - /* release subrs */ - if ( face->subrs ) + for ( n = 0; n < cid->num_dicts; n++ ) { - FT_Int n; + CID_Subrs subr = face->subrs + n; - for ( n = 0; n < cid->num_dicts; n++ ) + if ( subr->code ) { - CID_Subrs subr = face->subrs + n; - - - if ( subr->code ) - { - FT_FREE( subr->code[0] ); - FT_FREE( subr->code ); - } + FT_FREE( subr->code[0] ); + FT_FREE( subr->code ); } - - FT_FREE( face->subrs ); } - /* release FontInfo strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - - /* release font dictionaries */ - FT_FREE( cid->font_dicts ); - cid->num_dicts = 0; - - /* release other strings */ - FT_FREE( cid->cid_font_name ); - FT_FREE( cid->registry ); - FT_FREE( cid->ordering ); - - cidface->family_name = 0; - cidface->style_name = 0; - - FT_FREE( face->binary_data ); - FT_FREE( face->cid_stream ); + FT_FREE( face->subrs ); } + + /* release FontInfo strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release font dictionaries */ + FT_FREE( cid->font_dicts ); + cid->num_dicts = 0; + + /* release other strings */ + FT_FREE( cid->cid_font_name ); + FT_FREE( cid->registry ); + FT_FREE( cid->ordering ); + + cidface->family_name = 0; + cidface->style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); } @@ -324,6 +324,7 @@ goto Exit; /* check the face index */ + /* XXX: handle CID fonts with more than a single face */ if ( face_index != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidparse.c b/reactos/lib/3rdparty/freetype/src/cid/cidparse.c index bb87afc5891..efed618f5af 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidparse.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,6 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H @@ -87,13 +86,13 @@ /* `StartData' or `/sfnts' */ { FT_Byte buffer[256 + 10]; - FT_Int read_len = 256 + 10; + FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ FT_Byte* p = buffer; - for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 ) + for ( offset = FT_STREAM_POS(); ; offset += 256 ) { - FT_Int stream_len; + FT_Long stream_len; /* same as signed FT_Stream->size */ stream_len = stream->size - FT_STREAM_POS(); diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidriver.c b/reactos/lib/3rdparty/freetype/src/cid/cidriver.c index 5c5a72957c0..3a2d22532a6 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidriver.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,13 +20,14 @@ #include "cidriver.h" #include "cidgload.h" #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H #include "ciderrs.h" #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_H + /*************************************************************************/ /* */ @@ -38,10 +39,10 @@ #define FT_COMPONENT trace_ciddriver - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* cid_get_postscript_name( CID_Face face ) @@ -62,38 +63,114 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error cid_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((CID_Face)face)->cid.font_info; - return 0; + + return CID_Err_Ok; } + static FT_Error + cid_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((CID_Face)face)->font_extra; + + return CID_Err_Ok; + } static const FT_Service_PsInfoRec cid_service_ps_info = { (PS_GetFontInfoFunc) cid_ps_get_font_info, + (PS_GetFontExtraFunc) cid_ps_get_font_extra, (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ (PS_GetFontPrivateFunc)NULL /* unsupported */ }; - /* - * SERVICE LIST - * - */ + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return CID_Err_Ok; + } + + + static FT_Error + cid_get_is_cid( CID_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( is_cid ) + *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + + return error; + } + + + static FT_Error + cid_get_cid_from_glyph_index( CID_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( cid ) + *cid = glyph_index; /* identity mapping */ + + return error; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + }; + + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, { NULL, NULL } }; diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidriver.h b/reactos/lib/3rdparty/freetype/src/cid/cidriver.h index d5a80f6f9fb..c7f424bb389 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidriver.h +++ b/reactos/lib/3rdparty/freetype/src/cid/cidriver.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_CALLBACK_TABLE const FT_Driver_ClassRec t1cid_driver_class; diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h b/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h index ad5bbb2eefd..94a3657b025 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h +++ b/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,6 +49,13 @@ T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + #undef FT_STRUCTURE #define FT_STRUCTURE CID_FaceDictRec @@ -62,7 +69,6 @@ T1_FIELD_NUM ( "SubrCount", num_subrs, 0 ) T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 ) T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 ) - T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 ) T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) @@ -92,6 +98,9 @@ T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 ) T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) + T1_FIELD_BOOL ( "ForceBold", force_bold, 0 ) + + #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox #undef T1CODE diff --git a/reactos/lib/3rdparty/freetype/src/cid/module.mk b/reactos/lib/3rdparty/freetype/src/cid/module.mk index 41e5a68e599..ce30bfd7ae4 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/module.mk +++ b/reactos/lib/3rdparty/freetype/src/cid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE1CID_DRIVER define TYPE1CID_DRIVER -$(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t1cid_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c index 6cca65831e0..3d100315636 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c @@ -71,10 +71,10 @@ static void gxv_bsln_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - FT_UShort v = value.u; + FT_UShort v = value_p->u; FT_UShort* ctlPoints; FT_UNUSED( glyph ); @@ -122,7 +122,7 @@ static GXV_LookupValueDesc gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -132,7 +132,7 @@ GXV_LookupValueDesc value; /* XXX: check range ? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + ( relative_gindex * sizeof ( FT_UShort ) ) ); p = valid->lookuptbl_head + offset; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c index 82fd6b3a6d3..de7ce6fdef1 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004, 2005, 2009 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,11 +51,11 @@ FT_UShort* b ) { if ( *a < *b ) - return ( -1 ); + return -1; else if ( *a > *b ) - return ( 1 ); + return 1; else - return ( 0 ); + return 0; } @@ -115,11 +116,11 @@ FT_ULong* b ) { if ( *a < *b ) - return ( -1 ); + return -1; else if ( *a > *b ) - return ( 1 ); + return 1; else - return ( 0 ); + return 0; } @@ -404,8 +405,8 @@ if ( UNITSIZE != CORRECTSIZE ) \ { \ FT_ERROR(( "unitSize=%d differs from" \ - "expected unitSize=%d" \ - "in LookupTable %s", \ + " expected unitSize=%d" \ + " in LookupTable %s\n", \ UNITSIZE, CORRECTSIZE, FORMAT )); \ if ( UNITSIZE != 0 && NUNITS != 0 ) \ { \ @@ -447,7 +448,7 @@ } value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( i, value, valid ); + valid->lookupval_func( i, &value, valid ); } valid->subtable_length = p - table; @@ -552,7 +553,7 @@ } for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - valid->lookupval_func( gid, value, valid ); + valid->lookupval_func( gid, &value, valid ); } gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); @@ -630,11 +631,11 @@ for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) { value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), - base_value, + &base_value, limit, valid ); - valid->lookupval_func( gid, value, valid ); + valid->lookupval_func( gid, &value, valid ); } } @@ -709,7 +710,7 @@ } prev_glyph = glyph; - valid->lookupval_func( glyph, value, valid ); + valid->lookupval_func( glyph, &value, valid ); } gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); @@ -749,7 +750,7 @@ { GXV_LIMIT_CHECK( 2 ); value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( (FT_UShort)( firstGlyph + i ), value, valid ); + valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); } valid->subtable_length = p - table; @@ -1180,7 +1181,7 @@ if ( NULL != valid->statetable.entry_validate_func ) valid->statetable.entry_validate_func( state, flags, - glyphOffset, + &glyphOffset, statetable_table, statetable_limit, valid ); @@ -1351,15 +1352,15 @@ static void gxv_XClassTable_lookupval_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u >= valid->xstatetable.nClasses ) + if ( value_p->u >= valid->xstatetable.nClasses ) FT_INVALID_DATA; - if ( value.u > valid->xstatetable.maxClassID ) - valid->xstatetable.maxClassID = value.u; + if ( value_p->u > valid->xstatetable.maxClassID ) + valid->xstatetable.maxClassID = value_p->u; } @@ -1391,7 +1392,7 @@ */ static GXV_LookupValueDesc gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -1401,7 +1402,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; @@ -1555,7 +1556,7 @@ if ( NULL != valid->xstatetable.entry_validate_func ) valid->xstatetable.entry_validate_func( state, flags, - glyphOffset, + &glyphOffset, xstatetable_table, xstatetable_limit, valid ); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h index 0128eca79e3..404c07ffad9 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h @@ -79,6 +79,8 @@ FT_BEGIN_HEADER } GXV_LookupValueDesc; + typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr; + typedef enum GXV_LookupValue_SignSpec_ { GXV_LOOKUPVALUE_UNSIGNED = 0, @@ -89,12 +91,12 @@ FT_BEGIN_HEADER typedef void (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ); typedef GXV_LookupValueDesc (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ); @@ -134,6 +136,7 @@ FT_BEGIN_HEADER } GXV_StateTable_GlyphOffsetDesc; + typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr; typedef void (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size, @@ -149,7 +152,7 @@ FT_BEGIN_HEADER (*GXV_StateTable_Entry_Validate_Func)( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes statetable_table, FT_Bytes statetable_limit, GXV_Validator valid ); @@ -175,6 +178,8 @@ FT_BEGIN_HEADER typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc; + typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr; + typedef void (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size, FT_ULong classTable, @@ -189,7 +194,7 @@ FT_BEGIN_HEADER (*GXV_XStateTable_Entry_Validate_Func)( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, GXV_Validator valid ); @@ -275,11 +280,11 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_TRACE */ -#define GXV_INIT do ; while ( 0 ) -#define GXV_NAME_ENTER( name ) do ; while ( 0 ) -#define GXV_EXIT do ; while ( 0 ) +#define GXV_INIT do { } while ( 0 ) +#define GXV_NAME_ENTER( name ) do { } while ( 0 ) +#define GXV_EXIT do { } while ( 0 ) -#define GXV_TRACE( s ) do ; while ( 0 ) +#define GXV_TRACE( s ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_TRACE */ diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c index d7c6ad166d5..002fec6d6b1 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004, 2005, 2008 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,7 +60,7 @@ #define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) - typedef enum + typedef enum GXV_FeatureFlagsMask_ { GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, @@ -198,7 +199,7 @@ FT_UShort feature; FT_UShort nSettings; - FT_UInt settingTable; + FT_ULong settingTable; FT_UShort featureFlags; FT_Bool exclusive; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvjust.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvjust.c index 29bf840b57a..e14f946f2da 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvjust.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvjust.c @@ -323,15 +323,15 @@ static void gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u > GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_max ) = value.u; - if ( value.u < GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_min ) = value.u; + if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_min ) = value_p->u; } @@ -384,7 +384,7 @@ gxv_just_classTable_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -395,7 +395,7 @@ FT_UShort currentClass; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); FT_UNUSED( valid ); @@ -449,15 +449,15 @@ static void gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u > GXV_JUST_DATA( wdc_offset_max ) ) - GXV_JUST_DATA( wdc_offset_max ) = value.u; - if ( value.u < GXV_JUST_DATA( wdc_offset_min ) ) - GXV_JUST_DATA( wdc_offset_min ) = value.u; + if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) ) + GXV_JUST_DATA( wdc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) ) + GXV_JUST_DATA( wdc_offset_min ) = value_p->u; } @@ -557,7 +557,7 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - FT_UInt table_size; + FT_Offset table_size; GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvkern.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvkern.c index bfb405f65ba..2137db842a4 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvkern.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvkern.c @@ -256,7 +256,7 @@ gxv_kern_subtable_fmt1_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -268,7 +268,7 @@ FT_UShort kernValue; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); push = (FT_UShort)( ( flags >> 15 ) & 1 ); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c index 48821ea8796..f14fa5b1313 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c @@ -83,10 +83,10 @@ static void gxv_lcar_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - FT_Bytes p = valid->root->base + value.u; + FT_Bytes p = valid->root->base + value_p->u; FT_Bytes limit = valid->root->limit; FT_UShort count; FT_Short partial; @@ -146,7 +146,7 @@ static GXV_LookupValueDesc gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -158,7 +158,7 @@ FT_UNUSED( lookuptbl_limit ); /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->root->base + offset; limit = valid->root->limit; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmod.h b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmod.h index 466584ef4fd..d912a8f8381 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmod.h +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmod.h @@ -34,6 +34,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) gxv_module_class; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.c index 6fb71b92be4..0aa066339df 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.c @@ -42,7 +42,7 @@ gxv_mort_feature_validate( GXV_mort_feature f, GXV_Validator valid ) { - if ( f->featureType > gxv_feat_registry_length ) + if ( f->featureType >= gxv_feat_registry_length ) { GXV_TRACE(( "featureType %d is out of registered range, " "setting %d is unchecked\n", @@ -85,17 +85,17 @@ /* - * nFeatureFlags is typed to FT_UInt to accept that in + * nFeatureFlags is typed to FT_ULong to accept that in * mort (typed FT_UShort) and morx (typed FT_ULong). */ FT_LOCAL_DEF( void ) gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, - FT_UInt nFeatureFlags, + FT_ULong nFeatureFlags, GXV_Validator valid ) { FT_Bytes p = table; - FT_UInt i; + FT_ULong i; GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.h b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.h index 1d64e69c475..1e5a1f5ab68 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.h +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort.h @@ -54,7 +54,7 @@ FT_LOCAL( void ) gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, - FT_UInt nFeatureFlags, + FT_ULong nFeatureFlags, GXV_Validator valid ); FT_LOCAL( void ) diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c index 0902056c628..0453062f636 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c @@ -64,7 +64,7 @@ gxv_mort_subtable_type0_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -80,7 +80,7 @@ FT_UNUSED( limit ); FT_UNUSED( GXV_Mort_IndicScript_Msg[verb] ); /* for the non-debugging */ - FT_UNUSED( glyphOffset ); /* case */ + FT_UNUSED( glyphOffset_p ); /* case */ markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); @@ -91,7 +91,7 @@ verb = (FT_UShort)( flags & 0x000F ); GXV_TRACE(( " IndicScript MorphRule for glyphOffset 0x%04x", - glyphOffset.u )); + glyphOffset_p->u )); GXV_TRACE(( " markFirst=%01d", markFirst )); GXV_TRACE(( " dontAdvance=%01d", dontAdvance )); GXV_TRACE(( " markLast=%01d", markLast )); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c index 0575b1260ac..696d85032d0 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c @@ -135,7 +135,7 @@ gxv_mort_subtable_type1_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -154,8 +154,8 @@ dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); reserved = (FT_Short)( flags & 0x3FFF ); - markOffset = (FT_Short)( glyphOffset.ul >> 16 ); - currentOffset = (FT_Short)( glyphOffset.ul ); + markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentOffset = (FT_Short)( glyphOffset_p->ul ); if ( 0 < reserved ) { @@ -202,7 +202,7 @@ if ( dst_gid > valid->face->num_glyphs ) { - GXV_TRACE(( "substTable include toolarge gid[%d]=%d >" + GXV_TRACE(( "substTable include too large gid[%d]=%d >" " max defined gid #%d\n", i, dst_gid, valid->face->num_glyphs )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c index f19d15dab5d..6f77cf39ce7 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c @@ -189,7 +189,7 @@ gxv_mort_subtable_type2_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -199,7 +199,7 @@ FT_UShort offset; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( limit ); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c index a04bc1efaf4..83470988c09 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c @@ -40,12 +40,12 @@ static void gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - gxv_glyphid_validate( value.u, valid ); + gxv_glyphid_validate( value_p->u, valid ); } /* @@ -78,7 +78,7 @@ static GXV_LookupValueDesc gxv_mort_subtable_type4_lookupfmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -88,7 +88,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c index a7cabc359fc..ec0bcb634d5 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c @@ -139,7 +139,7 @@ gxv_mort_subtable_type5_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -168,8 +168,8 @@ currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); markedInsertCount = (FT_Byte)( flags & 0x001F ); - currentInsertList = (FT_UShort)( glyphOffset.ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset.ul ); + currentInsertList = (FT_UShort)( glyphOffset->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset->ul ); if ( 0 != currentInsertList && 0 != currentInsertCount ) { diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c index 849d5e942a5..f8ba5b985d9 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT morx table validation (body). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005, 2008 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,8 +69,8 @@ FT_ULong length; FT_ULong coverage; FT_ULong subFeatureFlags; - FT_UInt type; - FT_UInt rest; + FT_ULong type; + FT_ULong rest; GXV_LIMIT_CHECK( 4 + 4 + 4 ); @@ -129,7 +130,7 @@ gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); p += valid->subtable_length; - if ( nSubtables >= 0x10000 ) + if ( nSubtables >= 0x10000L ) FT_INVALID_DATA; gxv_morx_subtables_validate( p, table + chainLength, diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c index ca92b6c3925..0159c5aef7a 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c @@ -42,7 +42,7 @@ gxv_morx_subtable_type0_entry_validate( FT_UShort state, FT_UShort flags, - GXV_XStateTable_GlyphOffsetDesc glyphOffset, + GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -54,7 +54,7 @@ FT_UShort verb; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c index 331d4ccdab3..e1c162fa0c6 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c @@ -103,7 +103,7 @@ gxv_morx_subtable_type1_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -127,8 +127,8 @@ reserved = (FT_UShort)( flags & 0x3FFF ); - markIndex = (FT_Short)( glyphOffset.ul >> 16 ); - currentIndex = (FT_Short)( glyphOffset.ul ); + markIndex = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentIndex = (FT_Short)( glyphOffset_p->ul ); GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n", setMark, dontAdvance )); @@ -155,14 +155,14 @@ static void gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); /* for the non-debugging case */ - GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value.u )); + GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); - if ( value.u > valid->face->num_glyphs ) + if ( value_p->u > valid->face->num_glyphs ) FT_INVALID_GLYPH_ID; } @@ -170,7 +170,7 @@ static GXV_LookupValueDesc gxv_morx_subtable_type1_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -180,7 +180,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c index 5cad5169c21..b4bb3353f69 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c @@ -186,7 +186,7 @@ gxv_morx_subtable_type2_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -206,7 +206,7 @@ performAction = (FT_UShort)( ( flags >> 13 ) & 1 ); reserved = (FT_UShort)( flags & 0x1FFF ); - ligActionIndex = glyphOffset.u; + ligActionIndex = glyphOffset_p->u; if ( reserved > 0 ) GXV_TRACE(( " reserved 14bit is non-zero\n" )); diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c index d9115618c09..5e3a16437e2 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c @@ -136,7 +136,7 @@ gxv_morx_subtable_type5_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -165,8 +165,8 @@ currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); markedInsertCount = (FT_Byte)( flags & 0x001F ); - currentInsertList = (FT_Byte) ( glyphOffset.ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset.ul ); + currentInsertList = (FT_Byte) ( glyphOffset_p->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset_p->ul ); if ( currentInsertList && 0 != currentInsertCount ) gxv_morx_subtable_type5_InsertList_validate( currentInsertList, diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c index 8d6fe669f30..e1250609460 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c @@ -67,18 +67,18 @@ static void gxv_opbd_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { /* offset in LookupTable is measured from the head of opbd table */ - FT_Bytes p = valid->root->base + value.u; + FT_Bytes p = valid->root->base + value_p->u; FT_Bytes limit = valid->root->limit; FT_Short delta_value; int i; - if ( value.u < GXV_OPBD_DATA( valueOffset_min ) ) - GXV_OPBD_DATA( valueOffset_min ) = value.u; + if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) + GXV_OPBD_DATA( valueOffset_min ) = value_p->u; for ( i = 0; i < 4; i++ ) { @@ -132,7 +132,7 @@ static GXV_LookupValueDesc gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -142,7 +142,7 @@ FT_UNUSED( valid ); /* XXX: check range? */ - value.u = (FT_UShort)( base_value.u + + value.u = (FT_UShort)( base_value_p->u + relative_gindex * 4 * sizeof ( FT_Short ) ); return value; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvprop.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvprop.c index 010eeda4266..66c3ab74042 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvprop.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvprop.c @@ -168,10 +168,10 @@ static void gxv_prop_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - gxv_prop_property_validate( value.u, glyph, valid ); + gxv_prop_property_validate( value_p->u, glyph, valid ); } @@ -204,7 +204,7 @@ static GXV_LookupValueDesc gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -214,7 +214,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof( FT_UShort ) ); p = valid->lookuptbl_head + offset; limit = lookuptbl_limit; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c index 432ee4e2719..df3fd15c0b6 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c @@ -198,7 +198,7 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - FT_UInt table_size; + FT_Offset table_size; GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; diff --git a/reactos/lib/3rdparty/freetype/src/gxvalid/module.mk b/reactos/lib/3rdparty/freetype/src/gxvalid/module.mk index 44ef94addfa..9fd098e2c5e 100644 --- a/reactos/lib/3rdparty/freetype/src/gxvalid/module.mk +++ b/reactos/lib/3rdparty/freetype/src/gxvalid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += GXVALID_MODULE define GXVALID_MODULE -$(OPEN_DRIVER)gxv_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, gxv_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)gxvalid $(ECHO_DRIVER_DESC)TrueTypeGX/AAT validation module$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/gzip/adler32.c b/reactos/lib/3rdparty/freetype/src/gzip/adler32.c index 36f6a432eaf..c53f9dd125d 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/adler32.c +++ b/reactos/lib/3rdparty/freetype/src/gzip/adler32.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: adler32.c,v 1.5 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #include "zlib.h" diff --git a/reactos/lib/3rdparty/freetype/src/gzip/ftgzip.c b/reactos/lib/3rdparty/freetype/src/gzip/ftgzip.c index af2022d7f5a..6f0c515723e 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/ftgzip.c +++ b/reactos/lib/3rdparty/freetype/src/gzip/ftgzip.c @@ -8,7 +8,7 @@ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,7 +25,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include FT_GZIP_H -#include <string.h> +#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_MODULE_ERRORS_H @@ -40,6 +40,10 @@ #ifdef FT_CONFIG_OPTION_USE_ZLIB +#ifdef FT_CONFIG_OPTION_PIC +#error "gzip code does not support PIC yet" +#endif + #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB #include <zlib.h> @@ -54,7 +58,9 @@ /* original ZLib. */ #define NO_DUMMY_DECL -#define MY_ZCALLOC +#ifndef USE_ZLIB_ZCALLOC +#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */ +#endif #include "zlib.h" @@ -117,7 +123,7 @@ } -#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB +#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC ) local voidpf zcalloc ( voidpf opaque, @@ -134,7 +140,7 @@ ft_gzip_free( (FT_Memory)opaque, ptr ); } -#endif /* !SYSTEM_ZLIB */ +#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */ /***************************************************************************/ @@ -569,7 +575,7 @@ if ( error ) result = 0; - FT_Stream_Seek( stream, old_pos ); + (void)FT_Stream_Seek( stream, old_pos ); } return result; diff --git a/reactos/lib/3rdparty/freetype/src/gzip/inftrees.c b/reactos/lib/3rdparty/freetype/src/gzip/inftrees.c index 3c39aca6e3a..ef536521686 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/inftrees.c +++ b/reactos/lib/3rdparty/freetype/src/gzip/inftrees.c @@ -366,6 +366,9 @@ z_streamp z /* for messages */ if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed distance tree"; else if (r == Z_BUF_ERROR) { +#if 0 + { +#endif #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } diff --git a/reactos/lib/3rdparty/freetype/src/gzip/zconf.h b/reactos/lib/3rdparty/freetype/src/gzip/zconf.h index 3ccc3a66ab6..3abf0ba03b0 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/zconf.h +++ b/reactos/lib/3rdparty/freetype/src/gzip/zconf.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.h,v 1.4 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #ifndef _ZCONF_H #define _ZCONF_H @@ -60,6 +60,12 @@ # define MSDOS #endif +/* WinCE doesn't have errno.h */ +#ifdef _WIN32_WCE +# define NO_ERRNO_H +#endif + + /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). diff --git a/reactos/lib/3rdparty/freetype/src/gzip/zutil.c b/reactos/lib/3rdparty/freetype/src/gzip/zutil.c index 5ed2da08713..7ad0c1f81bb 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/zutil.c +++ b/reactos/lib/3rdparty/freetype/src/gzip/zutil.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.3 2006/04/29 07:31:16 wl Exp $ */ +/* @(#) $Id$ */ #include "zutil.h" @@ -49,7 +49,7 @@ void zmemzero(dest, len) } #endif -#ifdef __TURBOC__ +#if defined( MSDOS ) && defined( __TURBOC__ ) && !defined( MY_ZCALLOC ) #if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) /* Small and medium model in Turbo C are for now limited to near allocation * with reduced MAX_WBITS and MAX_MEM_LEVEL @@ -126,10 +126,10 @@ void zcfree (voidpf opaque, voidpf ptr) Assert(0, "zcfree: ptr not found"); } #endif -#endif /* __TURBOC__ */ +#endif /* MSDOS && __TURBOC__ */ -#if defined(M_I86) && !defined(__32BIT__) +#if defined(M_I86) && !defined(__32BIT__) && !defined( MY_ZCALLOC ) /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC diff --git a/reactos/lib/3rdparty/freetype/src/gzip/zutil.h b/reactos/lib/3rdparty/freetype/src/gzip/zutil.h index 8e3c69a9f06..c9688cd9c04 100644 --- a/reactos/lib/3rdparty/freetype/src/gzip/zutil.h +++ b/reactos/lib/3rdparty/freetype/src/gzip/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.6 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H diff --git a/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c b/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c index 45fbf7b6ea1..4f601a16d28 100644 --- a/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c +++ b/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2009 by */ /* Albert Chin-A-Young. */ /* */ /* Based on code in src/gzip/ftgzip.c, Copyright 2004 by */ @@ -27,8 +27,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include FT_LZW_H -#include <string.h> -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_MODULE_ERRORS_H @@ -43,6 +42,10 @@ #ifdef FT_CONFIG_OPTION_USE_LZW +#ifdef FT_CONFIG_OPTION_PIC +#error "lzw code does not support PIC yet" +#endif + #include "ftzopen.h" diff --git a/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.c b/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.c index fc7831510d1..8bc65c8f57b 100644 --- a/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.c +++ b/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005, 2006, 2007 by David Turner. */ +/* Copyright 2005, 2006, 2007, 2009 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -113,8 +113,8 @@ { FT_Memory memory = state->memory; FT_Error error; - FT_UInt old_size = state->stack_size; - FT_UInt new_size = old_size; + FT_Offset old_size = state->stack_size; + FT_Offset new_size = old_size; new_size = new_size + ( new_size >> 1 ) + 4; @@ -332,6 +332,9 @@ while ( code >= 256U ) { + if ( !state->prefix ) + goto Eof; + FTLZW_STACK_PUSH( state->suffix[code - 256] ); code = state->prefix[code - 256]; } diff --git a/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.h b/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.h index 97881149c22..f7d2936be2f 100644 --- a/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.h +++ b/reactos/lib/3rdparty/freetype/src/lzw/ftzopen.h @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005, 2006, 2007 by David Turner. */ +/* Copyright 2005, 2006, 2007, 2008 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -46,7 +46,7 @@ #define LZW_MASK( n ) ( ( 1U << (n) ) - 1U ) - typedef enum + typedef enum FT_LzwPhase_ { FT_LZW_PHASE_START = 0, FT_LZW_PHASE_CODE, @@ -109,7 +109,7 @@ * `free_ent', `num_bits' cannot grow larger than `max_bits'. */ - typedef struct _FT_LzwStateRec + typedef struct FT_LzwStateRec_ { FT_LzwPhase phase; FT_Int in_eof; @@ -118,7 +118,7 @@ FT_Int buf_offset; FT_Int buf_size; FT_Bool buf_clear; - FT_Int buf_total; + FT_Offset buf_total; FT_UInt max_bits; /* max code bits, from file header */ FT_Int block_mode; /* block mode flag, from file header */ @@ -137,7 +137,7 @@ FT_Byte* stack; /* character stack */ FT_UInt stack_top; - FT_UInt stack_size; + FT_Offset stack_size; FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */ FT_Stream source; /* source stream */ diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/Jamfile b/reactos/lib/3rdparty/freetype/src/otvalid/Jamfile index 35a14c6ab94..b457143de4f 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/otvalid/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; if $(FT2_MULTI) { - _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod ; + _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/module.mk b/reactos/lib/3rdparty/freetype/src/otvalid/module.mk index aa4db047d55..9cadde55e46 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/module.mk +++ b/reactos/lib/3rdparty/freetype/src/otvalid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += OTVALID_MODULE define OTVALID_MODULE -$(OPEN_DRIVER)otv_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, otv_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.c index 2f85f601b66..d5c2b75abb6 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "otvgpos.c" #include "otvgsub.c" #include "otvjstf.c" +#include "otvmath.c" #include "otvmod.c" /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.h b/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.h index 38f030f3935..eb99b9cc48e 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.h +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,7 @@ FT_BEGIN_HEADER otv_GDEF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, + FT_UInt glyph_count, FT_Validator valid ); FT_LOCAL( void ) @@ -63,6 +64,11 @@ FT_BEGIN_HEADER FT_UInt glyph_count, FT_Validator valid ); + FT_LOCAL( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ); + FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvbase.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvbase.c index 8ad2238d6d6..d742d2dc95f 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvbase.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,7 +62,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -297,7 +297,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; table_size = 6; diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.c index d94e4f3cb62..a4f885b51f8 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,10 +39,12 @@ FT_LOCAL_DEF( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator valid, + FT_Int expected_count ) { FT_Bytes p = table; FT_UInt CoverageFormat; + FT_UInt total = 0; OTV_NAME_ENTER( "Coverage" ); @@ -57,6 +59,7 @@ case 1: /* CoverageFormat1 */ { FT_UInt GlyphCount; + FT_UInt i; GlyphCount = FT_NEXT_USHORT( p ); @@ -64,13 +67,25 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ + + for ( i = 0; i < GlyphCount; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + + total = GlyphCount; } break; case 2: /* CoverageFormat2 */ { FT_UInt n, RangeCount; - FT_UInt Start, End, StartCoverageIndex, total = 0, last = 0; + FT_UInt Start, End, StartCoverageIndex, last = 0; RangeCount = FT_NEXT_USHORT( p ); @@ -89,6 +104,9 @@ if ( Start > End || StartCoverageIndex != total ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + if ( n > 0 && Start <= last ) FT_INVALID_DATA; @@ -102,8 +120,11 @@ FT_INVALID_FORMAT; } - /* no need to check glyph indices used as input to coverage tables */ - /* since even invalid glyph indices return a meaningful result */ + /* Generally, a coverage table offset has an associated count field. */ + /* The number of glyphs in the table should match this field. If */ + /* there is no associated count, a value of -1 tells us not to check. */ + if ( expected_count != -1 && (FT_UInt)expected_count != total ) + FT_INVALID_DATA; OTV_EXIT; } @@ -215,18 +236,21 @@ { case 1: /* ClassDefFormat1 */ { + FT_UInt StartGlyph; FT_UInt GlyphCount; - p += 2; /* skip StartGlyph */ - - OTV_LIMIT_CHECK( 2 ); + OTV_LIMIT_CHECK( 4 ); + StartGlyph = FT_NEXT_USHORT( p ); GlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ + + if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; } break; @@ -252,6 +276,9 @@ if ( Start > End || ( n > 0 && Start <= last ) ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + last = End; } } @@ -291,7 +318,10 @@ EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); - if ( DeltaFormat < 1 || DeltaFormat > 3 || EndSize < StartSize ) + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) FT_INVALID_DATA; count = EndSize - StartSize + 1; @@ -330,7 +360,7 @@ OTV_TRACE(( " (type %d)\n", LookupType )); - if ( LookupType == 0 || LookupType >= valid->type_count ) + if ( LookupType == 0 || LookupType > valid->type_count ) FT_INVALID_DATA; validate = valid->type_funcs[LookupType - 1]; @@ -657,7 +687,7 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, Count ); OTV_LIMIT_CHECK( Count * 2 ); @@ -729,6 +759,7 @@ FT_INVALID_DATA; OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); + p += ( Count1 - 1 ) * 2; for ( ; Count2 > 0; Count2-- ) { @@ -824,7 +855,7 @@ OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef, valid ); OTV_LIMIT_CHECK( ClassSetCount * 2 ); @@ -872,7 +903,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); for ( ; Count > 0; Count-- ) { @@ -913,7 +944,7 @@ OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + BacktrackClassDef, valid ); otv_ClassDef_validate( table + InputClassDef, valid ); @@ -963,7 +994,7 @@ OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); @@ -972,7 +1003,7 @@ OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -981,7 +1012,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); count2 = FT_NEXT_USHORT( p ); diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.h b/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.h index be6ac69c284..898887fc954 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.h +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,27 +85,27 @@ FT_BEGIN_HEADER FT_INVALID_TOO_SHORT; \ FT_END_STMNT -#define OTV_SIZE_CHECK( _size ) \ - FT_BEGIN_STMNT \ - if ( _size > 0 && _size < table_size ) \ - { \ - if ( valid->root->level == FT_VALIDATE_PARANOID ) \ - FT_INVALID_OFFSET; \ - else \ - { \ - /* strip off `const' */ \ - FT_Byte* pp = (FT_Byte*)_size ## _p; \ - \ - \ - FT_TRACE3(( "\n" \ - "Invalid offset to optional table `%s'!\n" \ - "Set to zero.\n" \ - "\n", #_size )); \ - \ - /* always assume 16bit entities */ \ - _size = pp[0] = pp[1] = 0; \ - } \ - } \ +#define OTV_SIZE_CHECK( _size ) \ + FT_BEGIN_STMNT \ + if ( _size > 0 && _size < table_size ) \ + { \ + if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + FT_INVALID_OFFSET; \ + else \ + { \ + /* strip off `const' */ \ + FT_Byte* pp = (FT_Byte*)_size ## _p; \ + \ + \ + FT_TRACE3(( "\n" \ + "Invalid offset to optional table `%s'" \ + " set to zero.\n" \ + "\n", #_size )); \ + \ + /* always assume 16bit entities */ \ + _size = pp[0] = pp[1] = 0; \ + } \ + } \ FT_END_STMNT @@ -192,12 +192,12 @@ FT_BEGIN_HEADER valid->func[2] = OTV_FUNC( z ); \ FT_END_STMNT -#define OTV_INIT do ; while ( 0 ) -#define OTV_ENTER do ; while ( 0 ) -#define OTV_NAME_ENTER( name ) do ; while ( 0 ) -#define OTV_EXIT do ; while ( 0 ) +#define OTV_INIT do { } while ( 0 ) +#define OTV_ENTER do { } while ( 0 ) +#define OTV_NAME_ENTER( name ) do { } while ( 0 ) +#define OTV_EXIT do { } while ( 0 ) -#define OTV_TRACE( s ) do ; while ( 0 ) +#define OTV_TRACE( s ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_TRACE */ @@ -215,7 +215,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator valid, + FT_Int expected_count ); /* return first covered glyph */ FT_LOCAL( FT_UInt ) diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvgdef.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvgdef.c index 7d24902e881..3633ad0de18 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvgdef.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -61,7 +61,7 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; @@ -126,7 +126,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -141,10 +141,13 @@ /*************************************************************************/ /*************************************************************************/ + /* sets valid->glyph_count */ + FT_LOCAL_DEF( void ) otv_GDEF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, + FT_UInt glyph_count, FT_Validator ftvalid ) { OTV_ValidatorRec validrec; @@ -183,6 +186,8 @@ else table_size = 10; /* OpenType < 1.2 */ + valid->glyph_count = glyph_count; + OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvgpos.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvgpos.c index ed347053d65..49b46183a32 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvgpos.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -124,8 +124,8 @@ Array1 = FT_NEXT_USHORT( p ); Array2 = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage1, valid ); - otv_Coverage_validate( table + Coverage2, valid ); + otv_Coverage_validate( table + Coverage1, valid, -1 ); + otv_Coverage_validate( table + Coverage2, valid, -1 ); otv_MarkArray_validate( table + Array1, valid ); @@ -191,7 +191,7 @@ #endif if ( format >= 0x100 ) - FT_INVALID_DATA; + FT_INVALID_FORMAT; for ( count = 4; count > 0; count-- ) { @@ -209,7 +209,7 @@ { if ( format & 1 ) { - FT_UInt table_size; + FT_PtrDist table_size; OTV_OPTIONAL_TABLE( device ); @@ -294,7 +294,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -376,7 +376,7 @@ Coverage = FT_NEXT_USHORT( p ); ValueFormat = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ } break; @@ -395,7 +395,7 @@ len_value = otv_value_length( ValueFormat ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, ValueCount ); OTV_LIMIT_CHECK( ValueCount * len_value ); @@ -409,7 +409,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -498,7 +498,7 @@ OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); OTV_LIMIT_CHECK( PairSetCount * 2 ); @@ -530,7 +530,7 @@ len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef1, valid ); otv_ClassDef_validate( table + ClassDef2, valid ); @@ -558,7 +558,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -605,7 +605,7 @@ OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); @@ -629,7 +629,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -644,7 +644,10 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (0) */ + /* UNDOCUMENTED (in OpenType 1.5): */ + /* BaseRecord tables can contain NULL pointers. */ + + /* sets valid->extra2 (1) */ static void otv_MarkBasePos_validate( FT_Bytes table, @@ -664,13 +667,13 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 0; + valid->extra2 = 1; OTV_NEST2( MarkBasePosFormat1, BaseArray ); OTV_RUN( table, valid ); break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -711,7 +714,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -752,7 +755,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -811,7 +814,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -872,7 +875,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -908,7 +911,8 @@ { case 1: /* ExtensionPosFormat1 */ { - FT_UInt ExtensionLookupType, ExtensionOffset; + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; OTV_Validate_Func validate; @@ -925,7 +929,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -989,7 +993,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvgsub.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvgsub.c index 91dae0bb161..ed499d1e92d 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvgsub.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ Coverage = table + FT_NEXT_USHORT( p ); DeltaGlyphID = FT_NEXT_SHORT( p ); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; if ( idx < 0 ) @@ -91,19 +91,19 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, GlyphCount ); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) - FT_INVALID_DATA; + FT_INVALID_GLYPH_ID; } break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -144,7 +144,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -185,7 +185,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -259,7 +259,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -318,7 +318,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -379,7 +379,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -415,7 +415,8 @@ { case 1: /* ExtensionSubstFormat1 */ { - FT_UInt ExtensionLookupType, ExtensionOffset; + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; OTV_Validate_Func validate; @@ -434,7 +435,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -476,12 +477,12 @@ OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -490,7 +491,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); GlyphCount = FT_NEXT_USHORT( p ); @@ -509,7 +510,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -560,7 +561,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvjstf.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvjstf.c index 80b8dd66043..a616a23432c 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvjstf.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -222,7 +222,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; JstfScriptCount = FT_NEXT_USHORT( p ); diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvmath.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvmath.c new file mode 100644 index 00000000000..50ed10cf284 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvmath.c @@ -0,0 +1,452 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 56 constants, 51 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); + table_size = 2 * ( 56 + 51 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 51; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + FT_UNUSED( isItalic ); /* only used if tracing is active */ + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + for ( i = 0; i < pcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2*4; /* skip the Start, End, Full, and Flags fields */ + } + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + for ( i = 0; i < vcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2; /* skip the size */ + } + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid, vcnt ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid, hcnt ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.c b/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.c index 157272f1ae9..3248564560c 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.c +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,27 @@ FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; + FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; + FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; FT_ValidatorRec volatile valid; - base = gdef = gpos = gsub = jstf = NULL; - len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0; + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; + + /* + * XXX: OpenType tables cannot handle 32-bit glyph index, + * although broken TrueType can have 32-bit glyph index. + */ + if ( face->num_glyphs > 0xFFFFL ) + { + FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", + face->num_glyphs )); + FT_TRACE1(( "are not handled by OpenType tables\n" )); + num_glyphs = 0xFFFF; + } /* load tables */ @@ -123,6 +138,13 @@ goto Exit; } + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + /* validate tables */ if ( base ) @@ -139,7 +161,7 @@ { ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GPOS_validate( gpos, face->num_glyphs, &valid ); + otv_GPOS_validate( gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -149,7 +171,7 @@ { ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GSUB_validate( gsub, face->num_glyphs, &valid ); + otv_GSUB_validate( gsub, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -159,7 +181,7 @@ { ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GDEF_validate( gdef, gsub, gpos, &valid ); + otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -169,7 +191,17 @@ { ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid ); + otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -192,6 +224,12 @@ FT_FREE( gsub ); FT_FREE( jstf ); } + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } return error; } diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.h b/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.h index 1bfc1899fe3..573b2a0c4b9 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.h +++ b/reactos/lib/3rdparty/freetype/src/otvalid/otvmod.h @@ -27,6 +27,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; diff --git a/reactos/lib/3rdparty/freetype/src/otvalid/rules.mk b/reactos/lib/3rdparty/freetype/src/otvalid/rules.mk index 48f12336f79..53bd41e5e7d 100644 --- a/reactos/lib/3rdparty/freetype/src/otvalid/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004 by +# Copyright 2004, 2007 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -31,14 +31,15 @@ OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ $(OTV_DIR)/otvgpos.c \ $(OTV_DIR)/otvgsub.c \ $(OTV_DIR)/otvjstf.c \ + $(OTV_DIR)/otvmath.c \ $(OTV_DIR)/otvmod.c # OTV driver headers # -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otverror.h \ +OTV_DRV_H := $(OTV_DIR)/otvalid.h \ $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otvgpos.h \ + $(OTV_DIR)/otverror.h \ + $(OTV_DIR)/otvgpos.h \ $(OTV_DIR)/otvmod.h diff --git a/reactos/lib/3rdparty/freetype/src/pcf/module.mk b/reactos/lib/3rdparty/freetype/src/pcf/module.mk index 0c51cd6fc42..df383ff0fbe 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/module.mk +++ b/reactos/lib/3rdparty/freetype/src/pcf/module.mk @@ -27,7 +27,7 @@ FTMODULE_H_COMMANDS += PCF_DRIVER define PCF_DRIVER -$(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, pcf_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcf.h b/reactos/lib/3rdparty/freetype/src/pcf/pcf.h index 9d2d8e0e429..1cd56c13a40 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcf.h +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcf.h @@ -72,8 +72,8 @@ FT_BEGIN_HEADER union { FT_String* atom; - FT_Long integer; - FT_ULong cardinal; + FT_Long l; + FT_ULong ul; } value; diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.c b/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.c index c0f0e49ca12..b34e542aeb0 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.c +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 by + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -111,7 +111,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -140,7 +140,7 @@ THE SOFTWARE. PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; FT_UInt min, max, mid; - FT_UInt32 charcode = *acharcode + 1; + FT_ULong charcode = *acharcode + 1; FT_UInt result = 0; @@ -149,7 +149,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -175,7 +175,14 @@ THE SOFTWARE. } Exit: - *acharcode = charcode; + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; return result; } @@ -187,17 +194,24 @@ THE SOFTWARE. pcf_cmap_init, pcf_cmap_done, pcf_cmap_char_index, - pcf_cmap_char_next + pcf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; FT_CALLBACK_DEF( void ) PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ { - PCF_Face face = (PCF_Face)pcfface; - FT_Memory memory = FT_FACE_MEMORY( face ); + PCF_Face face = (PCF_Face)pcfface; + FT_Memory memory; + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + FT_FREE( face->encodings ); FT_FREE( face->metrics ); @@ -259,17 +273,26 @@ THE SOFTWARE. error = pcf_load_font( stream, face ); if ( error ) { - FT_Error error2; - - PCF_Face_Done( pcfface ); - /* this didn't work, try gzip support! */ - error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); - if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) - goto Fail; +#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ + defined( FT_CONFIG_OPTION_USE_LZW ) - error = error2; +#ifdef FT_CONFIG_OPTION_USE_ZLIB + { + FT_Error error2; + + + /* this didn't work, try gzip support! */ + error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) + goto Fail; + + error = error2; + } +#endif /* FT_CONFIG_OPTION_USE_ZLIB */ + +#ifdef FT_CONFIG_OPTION_USE_LZW if ( error ) { FT_Error error3; @@ -281,29 +304,26 @@ THE SOFTWARE. goto Fail; error = error3; - if ( error ) - goto Fail; - - face->gzip_source = stream; - pcfface->stream = &face->gzip_stream; - - stream = pcfface->stream; - - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; } - else - { - face->gzip_source = stream; - pcfface->stream = &face->gzip_stream; +#endif /* FT_CONFIG_OPTION_USE_LZW */ - stream = pcfface->stream; + if ( error ) + goto Fail; - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; - } + face->gzip_source = stream; + pcfface->stream = &face->gzip_stream; + + stream = pcfface->stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + +#else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */ + + goto Fail; + +#endif } /* set up charmap */ @@ -402,7 +422,7 @@ THE SOFTWARE. switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = PCF_Err_Ok; break; @@ -431,11 +451,11 @@ THE SOFTWARE. FT_Int32 load_flags ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); - FT_Stream stream = face->root.stream; + FT_Stream stream; FT_Error error = PCF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; - int bytes; + FT_Offset bytes; FT_UNUSED( load_flags ); @@ -448,6 +468,8 @@ THE SOFTWARE. goto Exit; } + stream = face->root.stream; + if ( glyph_index > 0 ) glyph_index--; @@ -563,12 +585,17 @@ THE SOFTWARE. } else { + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "pcf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } /* Apparently, the PCF driver loads all properties as signed integers! * This really doesn't seem to be a problem, because this is * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = prop->value.integer; + aproperty->u.integer = (FT_Int32)prop->value.l; } return 0; } diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.h b/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.h index 7ddf697e164..a81d7309e5f 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.h +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcfdrivr.h @@ -33,6 +33,10 @@ THE SOFTWARE. FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcfread.c b/reactos/lib/3rdparty/freetype/src/pcf/pcfread.c index b9123cf574f..08becf99ce3 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcfread.c +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -32,7 +32,6 @@ THE SOFTWARE. #include FT_INTERNAL_OBJECTS_H #include "pcf.h" -#include "pcfdrivr.h" #include "pcfread.h" #include "pcferror.h" @@ -48,7 +47,7 @@ THE SOFTWARE. #define FT_COMPONENT trace_pcfread -#if defined( FT_DEBUG_LEVEL_TRACE ) +#ifdef FT_DEBUG_LEVEL_TRACE static const char* const tableNames[] = { "prop", "accl", "mtrcs", "bmps", "imtrcs", @@ -152,7 +151,7 @@ THE SOFTWARE. break; } -#if defined( FT_DEBUG_LEVEL_TRACE ) +#ifdef FT_DEBUG_LEVEL_TRACE { FT_UInt i, j; @@ -290,13 +289,13 @@ THE SOFTWARE. static FT_Error pcf_seek_to_table_type( FT_Stream stream, PCF_Table tables, - FT_Int ntables, + FT_ULong ntables, /* same as PCF_Toc->count */ FT_ULong type, FT_ULong *aformat, FT_ULong *asize ) { FT_Error error = PCF_Err_Invalid_File_Format; - FT_Int i; + FT_ULong i; for ( i = 0; i < ntables; i++ ) @@ -328,10 +327,10 @@ THE SOFTWARE. static FT_Bool pcf_has_table_type( PCF_Table tables, - FT_Int ntables, + FT_ULong ntables, /* same as PCF_Toc->count */ FT_ULong type ) { - FT_Int i; + FT_ULong i; for ( i = 0; i < ntables; i++ ) @@ -400,7 +399,7 @@ THE SOFTWARE. { PCF_ParseProperty props = 0; PCF_Property properties; - FT_UInt nprops, i; + FT_ULong nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE(face)->memory; @@ -434,7 +433,10 @@ THE SOFTWARE. if ( error ) goto Bail; - FT_TRACE4(( " nprop = %d\n", nprops )); + FT_TRACE4(( " nprop = %d (truncate %d props)\n", + (int)nprops, nprops - (int)nprops )); + + nprops = (int)nprops; /* rough estimate */ if ( nprops > size / PCF_PROPERTY_SIZE ) @@ -443,7 +445,7 @@ THE SOFTWARE. goto Bail; } - face->nprops = nprops; + face->nprops = (int)nprops; if ( FT_NEW_ARRAY( props, nprops ) ) goto Bail; @@ -470,7 +472,11 @@ THE SOFTWARE. if ( nprops & 3 ) { i = 4 - ( nprops & 3 ); - FT_Stream_Skip( stream, i ); + if ( FT_STREAM_SKIP( i ) ) + { + error = PCF_Err_Invalid_Stream_Skip; + goto Bail; + } } if ( PCF_BYTE_ORDER( format ) == MSBFirst ) @@ -539,9 +545,9 @@ THE SOFTWARE. } else { - properties[i].value.integer = props[i].value; + properties[i].value.l = props[i].value; - FT_TRACE4(( " %d\n", properties[i].value.integer )); + FT_TRACE4(( " %d\n", properties[i].value.l )); } } @@ -623,7 +629,7 @@ THE SOFTWARE. metrics = face->metrics; for ( i = 0; i < nmetrics; i++ ) { - pcf_get_metric( stream, format, metrics + i ); + error = pcf_get_metric( stream, format, metrics + i ); metrics[i].bits = 0; @@ -658,7 +664,7 @@ THE SOFTWARE. FT_Long* offsets; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; - int nbitmaps, i, sizebitmaps = 0; + FT_ULong nbitmaps, i, sizebitmaps = 0; error = pcf_seek_to_table_type( stream, @@ -689,7 +695,8 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - if ( nbitmaps != face->nmetrics ) + /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ + if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) @@ -735,8 +742,8 @@ THE SOFTWARE. if ( ( offsets[i] < 0 ) || ( (FT_ULong)offsets[i] > size ) ) { - FT_ERROR(( "pcf_get_bitmaps:")); - FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i )); + FT_TRACE0(( "pcf_get_bitmaps:" + " invalid offset to bitmap data of glyph %d\n", i )); } else face->metrics[i].bits = stream->pos + offsets[i]; @@ -989,9 +996,9 @@ THE SOFTWARE. PCF_Property prop; - int nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - int lengths[4]; + size_t nn, len; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4]; face->style_flags = 0; @@ -1073,7 +1080,7 @@ THE SOFTWARE. /* add_style_name and setwidth_name */ if ( nn == 0 || nn == 3 ) { - int mm; + size_t mm; for ( mm = 0; mm < len; mm++ ) @@ -1198,7 +1205,7 @@ THE SOFTWARE. prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); @@ -1206,19 +1213,19 @@ THE SOFTWARE. if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = - (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.integer << 6; + bsize->y_ppem = (FT_Short)prop->value.l << 6; prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.integer; + resolution_x = (FT_Short)prop->value.l; prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.integer; + resolution_y = (FT_Short)prop->value.l; if ( bsize->y_ppem == 0 ) { diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.c b/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.c index 67ddbe8890b..b91274f935b 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.c +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.c @@ -42,9 +42,9 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) BitOrderInvert( unsigned char* buf, - int nbytes ) + size_t nbytes ) { - for ( ; --nbytes >= 0; buf++ ) + for ( ; nbytes > 0; nbytes--, buf++ ) { unsigned int val = *buf; @@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) TwoByteSwap( unsigned char* buf, - int nbytes ) + size_t nbytes ) { unsigned char c; @@ -83,7 +83,7 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) FourByteSwap( unsigned char* buf, - int nbytes ) + size_t nbytes ) { unsigned char c; diff --git a/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.h b/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.h index 1557be3e800..ce10fb541d5 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.h +++ b/reactos/lib/3rdparty/freetype/src/pcf/pcfutil.h @@ -37,15 +37,15 @@ FT_BEGIN_HEADER FT_LOCAL( void ) BitOrderInvert( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_LOCAL( void ) TwoByteSwap( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_LOCAL( void ) FourByteSwap( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/pcf/rules.mk b/reactos/lib/3rdparty/freetype/src/pcf/rules.mk index 1ad4ba897a3..78641528fab 100644 --- a/reactos/lib/3rdparty/freetype/src/pcf/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/pcf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2000, 2001, 2003 by +# Copyright (C) 2000, 2001, 2003, 2008 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -35,15 +35,14 @@ PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) # pcf driver sources (i.e., C files) # -PCF_DRV_SRC := $(PCF_DIR)/pcfread.c \ - $(PCF_DIR)/pcfdrivr.c \ +PCF_DRV_SRC := $(PCF_DIR)/pcfdrivr.c \ + $(PCF_DIR)/pcfread.c \ $(PCF_DIR)/pcfutil.c # pcf driver headers # -PCF_DRV_H := $(PCF_DIR)/pcf.h \ - $(PCF_DIR)/pcfdrivr.h \ - $(PCF_DIR)/pcfutil.h \ +PCF_DRV_H := $(PCF_DRV_SRC:%.c=%.h) \ + $(PCF_DIR)/pcf.h \ $(PCF_DIR)/pcferror.h # pcf driver object(s) diff --git a/reactos/lib/3rdparty/freetype/src/pfr/module.mk b/reactos/lib/3rdparty/freetype/src/pfr/module.mk index 53ab34aa9fe..8d1d28a9d23 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/module.mk +++ b/reactos/lib/3rdparty/freetype/src/pfr/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PFR_DRIVER define PFR_DRIVER -$(OPEN_DRIVER)pfr_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, pfr_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrcmap.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrcmap.c index c8faee04364..9c8f9ed8eb3 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrcmap.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (body). */ /* */ -/* Copyright 2002, 2007 by */ +/* Copyright 2002, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,8 @@ #include "pfrcmap.h" #include "pfrobjs.h" -#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" FT_CALLBACK_DEF( FT_Error ) @@ -87,7 +88,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) pfr_cmap_char_next( PFR_CMap cmap, FT_UInt32 *pchar_code ) { @@ -156,7 +157,9 @@ (FT_CMap_InitFunc) pfr_cmap_init, (FT_CMap_DoneFunc) pfr_cmap_done, (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next + (FT_CMap_CharNextFunc) pfr_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.c index 40206720efb..15cca9854e4 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,10 +66,16 @@ FT_Pos *anadvance ) { PFR_Face face = (PFR_Face)pfrface; - FT_Error error = PFR_Err_Bad_Argument; + FT_Error error = PFR_Err_Invalid_Argument; *anadvance = 0; + + if ( !gindex ) + goto Exit; + + gindex--; + if ( face ) { PFR_PhyFont phys = &face->phy_font; @@ -82,6 +88,7 @@ } } + Exit: return error; } diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.h b/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.h index 36f1205b772..da0a1aa6344 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.h +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrdrivr.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrgload.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrgload.c index 3bb173302d4..6fe6e4225ab 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrgload.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrgload.c @@ -595,7 +595,7 @@ if ( org_count + count > glyph->max_subs ) { - FT_UInt new_max = ( org_count + count + 3 ) & -4; + FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrload.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrload.c index 1ee2c1f8c8b..bc5c035f3da 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrload.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -428,7 +428,8 @@ Too_Short: error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" )); + FT_ERROR(( "pfr_extra_item_load_bitmap_info:" + " invalid bitmap info table\n" )); goto Exit; } @@ -506,7 +507,8 @@ Too_Short: error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" )); + FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + " invalid stem snaps table\n" )); goto Exit; } @@ -603,8 +605,8 @@ FT_FREE( item ); error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " - "invalid kerning pairs table\n" )); + FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" + " invalid kerning pairs table\n" )); goto Exit; } @@ -714,7 +716,8 @@ { FT_Error error; FT_Memory memory = stream->memory; - FT_UInt flags, num_aux; + FT_UInt flags; + FT_ULong num_aux; FT_Byte* p; FT_Byte* limit; diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrobjs.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrobjs.c index 180446d737d..56d617d880a 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrobjs.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,10 +41,15 @@ FT_LOCAL_DEF( void ) pfr_face_done( FT_Face pfrface ) /* PFR_Face */ { - PFR_Face face = (PFR_Face)pfrface; - FT_Memory memory = pfrface->driver->root.memory; + PFR_Face face = (PFR_Face)pfrface; + FT_Memory memory; + if ( !face ) + return; + + memory = pfrface->driver->root.memory; + /* we don't want dangling pointers */ pfrface->family_name = NULL; pfrface->style_name = NULL; diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c index 45ff6663b36..8a38bec1d33 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c @@ -630,18 +630,35 @@ &xpos, &ypos, &xsize, &ysize, &advance, &format ); + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * which causes a size truncation, because truncated + * size properties makes bitmap glyph broken. + */ + if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + { + FT_TRACE1(( "pfr_slot_load_bitmap:" )); + FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", + xpos, ypos )); + error = PFR_Err_Invalid_Pixel_Size; + } + if ( !error ) { glyph->root.format = FT_GLYPH_FORMAT_BITMAP; /* Set up glyph bitmap and metrics */ + + /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ glyph->root.bitmap.width = (FT_Int)xsize; glyph->root.bitmap.rows = (FT_Int)ysize; - glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3; + glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; - glyph->root.metrics.width = (FT_Long)xsize << 6; - glyph->root.metrics.height = (FT_Long)ysize << 6; + /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ + glyph->root.metrics.width = (FT_Pos)xsize << 6; + glyph->root.metrics.height = (FT_Pos)ysize << 6; glyph->root.metrics.horiBearingX = xpos << 6; glyph->root.metrics.horiBearingY = ypos << 6; glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); @@ -649,8 +666,9 @@ glyph->root.metrics.vertBearingY = 0; glyph->root.metrics.vertAdvance = size->root.metrics.height; - glyph->root.bitmap_left = xpos; - glyph->root.bitmap_top = ypos + ysize; + /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ + glyph->root.bitmap_left = (FT_Int)xpos; + glyph->root.bitmap_top = (FT_Int)(ypos + ysize); /* Allocate and read bitmap data */ { diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrtypes.h b/reactos/lib/3rdparty/freetype/src/pfr/pfrtypes.h index c0ae04253a2..918310814c5 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrtypes.h +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrtypes.h @@ -200,7 +200,7 @@ FT_BEGIN_HEADER FT_Byte flags; FT_Short base_adj; FT_UInt pair_size; - FT_UInt32 offset; + FT_Offset offset; FT_UInt32 pair1; FT_UInt32 pair2; @@ -252,7 +252,7 @@ FT_BEGIN_HEADER FT_UInt blue_scale; FT_UInt num_chars; - FT_UInt32 chars_offset; + FT_Offset chars_offset; PFR_Char chars; FT_UInt num_kern_pairs; @@ -260,7 +260,7 @@ FT_BEGIN_HEADER PFR_KernItem* kern_items_tail; /* not part of the spec, but used during load */ - FT_UInt32 bct_offset; + FT_Long bct_offset; FT_Byte* cursor; } PFR_PhyFontRec, *PFR_PhyFont; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/afmparse.c b/reactos/lib/3rdparty/freetype/src/psaux/afmparse.c index 0528fe6ff4f..91a17e2362e 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/afmparse.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,6 @@ #include <ft2build.h> #include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "afmparse.h" #include "psconv.h" @@ -367,11 +366,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ) + FT_UInt n ) { AFM_Stream stream = parser->stream; char* str; - FT_Int i; + FT_UInt i; if ( n > AFM_MAX_ARGUMENTS ) @@ -379,7 +378,7 @@ for ( i = 0; i < n; i++ ) { - FT_UInt len; + FT_Offset len; AFM_Value val = vals + i; @@ -441,7 +440,7 @@ FT_LOCAL_DEF( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ) + FT_Offset* len ) { AFM_Stream stream = parser->stream; char* key = 0; /* make stupid compiler happy */ @@ -489,7 +488,7 @@ } if ( len ) - *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) : 0; return key; @@ -498,7 +497,7 @@ static AFM_Token afm_tokenize( const char* key, - FT_UInt len ) + FT_Offset len ) { int n; @@ -586,7 +585,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_TrackKern tk; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -672,7 +671,12 @@ FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } @@ -682,7 +686,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_KernPair kp; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -770,9 +774,9 @@ static FT_Error afm_parse_kern_data( AFM_Parser parser ) { - FT_Error error; - char* key; - FT_UInt len; + FT_Error error; + char* key; + FT_Offset len; while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) @@ -814,8 +818,8 @@ FT_UInt n, AFM_Token end_section ) { - char* key; - FT_UInt len; + char* key; + FT_Offset len; while ( n-- > 0 ) @@ -846,7 +850,7 @@ AFM_FontInfo fi = parser->FontInfo; FT_Error error = PSaux_Err_Syntax_Error; char* key; - FT_UInt len; + FT_Offset len; FT_Int metrics_sets = 0; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/afmparse.h b/reactos/lib/3rdparty/freetype/src/psaux/afmparse.h index c2fce75c86e..de2a530b2f0 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/afmparse.h +++ b/reactos/lib/3rdparty/freetype/src/psaux/afmparse.h @@ -71,13 +71,13 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ); + FT_UInt n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ); + FT_Offset* len ); FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/psaux/module.mk b/reactos/lib/3rdparty/freetype/src/psaux/module.mk index 5431522084f..42bf6f51999 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/module.mk +++ b/reactos/lib/3rdparty/freetype/src/psaux/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSAUX_MODULE define PSAUX_MODULE -$(OPEN_DRIVER)psaux_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/psaux/psauxmod.h b/reactos/lib/3rdparty/freetype/src/psaux/psauxmod.h index 92ac0560484..35e042dbce7 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/psauxmod.h +++ b/reactos/lib/3rdparty/freetype/src/psaux/psauxmod.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/psconv.c b/reactos/lib/3rdparty/freetype/src/psaux/psconv.c index 3bbeab6d256..1531d8f0fb5 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/psconv.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,10 +18,8 @@ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "psconv.h" -#include "psobjs.h" #include "psauxerr.h" @@ -187,10 +185,18 @@ if ( c < 0 || c >= 10 ) break; - if ( divider < 10000000L ) + if ( !integral && power_ten > 0 ) { + power_ten--; decimal = decimal * 10 + c; - divider *= 10; + } + else + { + if ( divider < 10000000L ) + { + decimal = decimal * 10 + c; + divider *= 10; + } } } } @@ -233,7 +239,7 @@ PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -328,7 +334,7 @@ PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -417,7 +423,7 @@ PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ) { FT_Byte* p; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/psconv.h b/reactos/lib/3rdparty/freetype/src/psaux/psconv.h index e51124185d7..84854ba0d16 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/psconv.h +++ b/reactos/lib/3rdparty/freetype/src/psaux/psconv.h @@ -46,20 +46,20 @@ FT_BEGIN_HEADER PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); #endif FT_LOCAL( FT_UInt ) PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); FT_LOCAL( FT_UInt ) PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ); diff --git a/reactos/lib/3rdparty/freetype/src/psaux/psobjs.c b/reactos/lib/3rdparty/freetype/src/psaux/psobjs.c index 957085668be..fe8398ae388 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/psobjs.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "psobjs.h" #include "psconv.h" @@ -169,17 +170,23 @@ void* object, FT_PtrDist length ) { - if ( idx < 0 || idx > table->max_elems ) + if ( idx < 0 || idx >= table->max_elems ) { FT_ERROR(( "ps_table_add: invalid index\n" )); return PSaux_Err_Invalid_Argument; } + if ( length < 0 ) + { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return PSaux_Err_Invalid_Argument; + } + /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { FT_Error error; - FT_Offset new_size = table->capacity; + FT_Offset new_size = table->capacity; FT_Long in_offset; @@ -376,7 +383,7 @@ /* skip octal escape or ignore backslash */ for ( i = 0; i < 3 && cur < limit; ++i ) { - if ( ! IS_OCTAL_DIGIT( *cur ) ) + if ( !IS_OCTAL_DIGIT( *cur ) ) break; ++cur; @@ -558,8 +565,8 @@ cur++; if ( cur >= limit || *cur != '>' ) /* >> */ { - FT_ERROR(( "ps_parser_skip_PS_token: " - "unexpected closing delimiter `>'\n" )); + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -584,9 +591,10 @@ Exit: if ( cur == parser->cursor ) { - FT_ERROR(( "ps_parser_skip_PS_token: " - "current token is `%c', which is self-delimiting " - "but invalid at this point\n", + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", *cur )); error = PSaux_Err_Invalid_File_Format; @@ -1147,8 +1155,10 @@ } else { - FT_ERROR(( "ps_parser_load_field: expected a name or string " - "but found token of type %d instead\n", + FT_ERROR(( "ps_parser_load_field:" + " expected a name or string\n" + " " + " but found token of type %d instead\n", token.type )); error = PSaux_Err_Invalid_File_Format; goto Exit; @@ -1185,8 +1195,8 @@ if ( result < 0 ) { - FT_ERROR(( "ps_parser_load_field: " - "expected four integers in bounding box\n" )); + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -1259,8 +1269,9 @@ old_cursor = parser->cursor; old_limit = parser->limit; - /* we store the elements count if necessary */ - if ( field->type != T1_FIELD_TYPE_BBOX ) + /* we store the elements count if necessary; */ + /* we further assume that `count_offset' can't be zero */ + if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = (FT_Byte)num_elements; @@ -1302,7 +1313,7 @@ FT_LOCAL_DEF( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ) { @@ -1483,12 +1494,6 @@ builder->hints_funcs = glyph->internal->glyph_hints; } - if ( size ) - { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -1550,16 +1555,9 @@ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - if ( builder->shift ) - { - x >>= 16; - y >>= 16; - } - point->x = x; - point->y = y; + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; } @@ -1640,27 +1638,24 @@ t1_builder_close_contour( T1_Builder builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -1669,8 +1664,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } diff --git a/reactos/lib/3rdparty/freetype/src/psaux/psobjs.h b/reactos/lib/3rdparty/freetype/src/psaux/psobjs.h index c2cbf2c79b3..e380c60dabb 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/psobjs.h +++ b/reactos/lib/3rdparty/freetype/src/psaux/psobjs.h @@ -111,7 +111,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); diff --git a/reactos/lib/3rdparty/freetype/src/psaux/t1cmap.c b/reactos/lib/3rdparty/freetype/src/psaux/t1cmap.c index 29346869660..f933e4da88d 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/t1cmap.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -95,7 +95,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_std_char_next( T1_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -135,7 +135,9 @@ (FT_CMap_InitFunc) t1_cmap_standard_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -154,7 +156,9 @@ (FT_CMap_InitFunc) t1_cmap_expert_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -175,7 +179,7 @@ cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -209,7 +213,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_custom_char_next( T1_CMapCustom cmap, FT_UInt32 *pchar_code ) { @@ -245,7 +249,9 @@ (FT_CMap_InitFunc) t1_cmap_custom_init, (FT_CMap_DoneFunc) t1_cmap_custom_done, (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -306,7 +312,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -326,7 +332,9 @@ (FT_CMap_InitFunc) t1_cmap_unicode_init, (FT_CMap_DoneFunc) t1_cmap_unicode_done, (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c b/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c index f790643f961..b3245a67889 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_OUTLINE_H @@ -144,7 +145,8 @@ FT_String* name = (FT_String*)decoder->glyph_names[n]; - if ( name && name[0] == glyph_name[0] && + if ( name && + name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) return n; } @@ -193,6 +195,16 @@ #endif FT_Vector left_bearing, advance; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } /* seac weirdness */ adx += decoder->builder.left_bearing.x; @@ -201,18 +213,29 @@ /* include an encoding. How can we deal with these? */ if ( decoder->glyph_names == 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " glyph names table not available in this font!\n" )); + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); return PSaux_Err_Syntax_Error; } - bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); - achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); return PSaux_Err_Syntax_Error; } @@ -243,8 +266,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx - asb ); - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -260,7 +283,10 @@ FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -278,7 +304,11 @@ /* Now load `achar' on top of */ /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -327,9 +357,15 @@ FT_Pos x, y, orig_x, orig_y; FT_Int known_othersubr_result_cnt = 0; FT_Int unknown_othersubr_result_cnt = 0; + FT_Bool large_int; + FT_Fixed seed; T1_Hints_Funcs hinter; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + /* we don't want to touch the source code -- use macro trick */ #define start_point t1_builder_start_point @@ -339,6 +375,16 @@ #define add_contour t1_builder_add_contour #define close_contour t1_builder_close_contour + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + /* First of all, initialize the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; @@ -351,15 +397,15 @@ /* a font that reads BuildCharArray without setting */ /* its values first is buggy, but ... */ FT_ASSERT( ( decoder->len_buildchar == 0 ) == - ( decoder->buildchar == NULL ) ); + ( decoder->buildchar == NULL ) ); if ( decoder->len_buildchar > 0 ) - memset( &decoder->buildchar[0], - 0, - sizeof( decoder->buildchar[0] ) * - decoder->len_buildchar ); + ft_memset( &decoder->buildchar[0], + 0, + sizeof( decoder->buildchar[0] ) * decoder->len_buildchar ); - FT_TRACE4(( "\nStart charstring\n" )); + FT_TRACE4(( "\n" + "Start charstring\n" )); zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; @@ -374,18 +420,26 @@ if ( hinter ) hinter->open( hinter->hints ); + large_int = FALSE; + /* now, execute loop */ while ( ip < limit ) { FT_Long* top = decoder->top; T1_Operator op = op_none; - FT_Long value = 0; + FT_Int32 value = 0; FT_ASSERT( known_othersubr_result_cnt == 0 || unknown_othersubr_result_cnt == 0 ); - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif /*********************************************************************/ /* */ @@ -456,8 +510,8 @@ case 12: if ( ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+EOF)\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); goto Syntax_Error; } @@ -492,8 +546,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+%d)\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } @@ -502,42 +556,69 @@ case 255: /* four bytes integer */ if ( ip + 4 > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } - value = (FT_Int32)( ((FT_Long)ip[0] << 24) | - ((FT_Long)ip[1] << 16) | - ((FT_Long)ip[2] << 8 ) | - ip[3] ); + value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) | + ( (FT_Long)ip[1] << 16 ) | + ( (FT_Long)ip[2] << 8 ) | + ip[3] ); ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value <<= 16; + } + break; default: if ( ip[-1] >= 32 ) { if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; + value = (FT_Int32)ip[-1] - 139; else { if ( ++ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } if ( ip[-2] < 251 ) - value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); } + + if ( !large_int ) + value <<= 16; } else { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid byte (%d)\n", ip[-1] )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); goto Syntax_Error; } } @@ -559,6 +640,14 @@ } } + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + /*********************************************************************/ /* */ /* Push value on stack, or process operator */ @@ -568,11 +657,16 @@ { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); goto Syntax_Error; } - FT_TRACE4(( " %ld", value )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); +#endif *top++ = value; decoder->top = top; @@ -583,15 +677,18 @@ FT_Int arg_cnt; - FT_TRACE4(( " callothersubr" )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; - subr_no = (FT_Int)top[1]; - arg_cnt = (FT_Int)top[0]; + subr_no = (FT_Int)( top[1] >> 16 ); + arg_cnt = (FT_Int)( top[0] >> 16 ); /***********************************************************/ /* */ @@ -668,8 +765,8 @@ if ( decoder->flex_state == 0 || decoder->num_flex_vectors != 7 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected flex end\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); goto Syntax_Error; } @@ -685,7 +782,6 @@ if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); - break; case 12: @@ -708,16 +804,16 @@ if ( !blend ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected multiple masters operator!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); goto Syntax_Error; } num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "incorrect number of mm arguments\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " incorrect number of multiple masters arguments\n" )); goto Syntax_Error; } @@ -753,12 +849,6 @@ break; } -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS - - /* We cannot yet enable these since currently */ - /* our T1 stack stores integers which lack the */ - /* precision to express the values */ - case 19: /* <idx> 1 19 callothersubr */ /* => replace elements starting from index cvi( <idx> ) */ @@ -771,16 +861,16 @@ if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); - if ( idx < 0 || - idx + blend->num_designs > decoder->face->len_buildchar ) + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; - memcpy( &decoder->buildchar[idx], - blend->weight_vector, - blend->num_designs * - sizeof( blend->weight_vector[ 0 ] ) ); + ft_memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof( blend->weight_vector[0] ) ); } break; @@ -812,7 +902,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] *= top[1]; /* XXX (over|under)flow */ + top[0] = FT_MulFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -823,24 +913,23 @@ if ( arg_cnt != 2 || top[1] == 0 ) goto Unexpected_OtherSubr; - top[0] /= top[1]; /* XXX (over|under)flow */ + top[0] = FT_DivFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; -#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */ - case 24: - /* <val> <idx> 2 24 callothersubr */ - /* => set BuildCharArray[cvi( <idx> )] = <val> */ + /* <val> <idx> 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 2 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[1]; + idx = (FT_Int)( top[1] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -850,17 +939,18 @@ break; case 25: - /* <idx> 1 25 callothersubr pop */ - /* => push BuildCharArray[cvi( idx )] */ - /* onto T1 stack */ + /* <idx> 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -876,13 +966,13 @@ /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */ /* leave mark on T1 stack */ /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */ - XXX who has left his mark on the (PostScript) stack ?; + XXX which routine has left its mark on the (PostScript) stack?; break; #endif case 27: /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ - /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ + /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ /* otherwise push <res2> */ if ( arg_cnt != 4 ) goto Unexpected_OtherSubr; @@ -893,28 +983,40 @@ known_othersubr_result_cnt = 1; break; -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS case 28: /* 0 28 callothersubr pop */ /* => push random value from interval [0, 1) onto stack */ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - top[0] = FT_rand(); + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + known_othersubr_result_cnt = 1; break; -#endif default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unknown othersubr [%d %d], wish me luck!\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unknown othersubr [%d %d], wish me luck\n", arg_cnt, subr_no )); unknown_othersubr_result_cnt = arg_cnt; break; Unexpected_OtherSubr: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid othersubr [%d %d]!\n", arg_cnt, subr_no )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); goto Syntax_Error; } @@ -951,9 +1053,9 @@ default: if ( top - decoder->stack != num_args ) - FT_TRACE0(( "t1_decoder_parse_charstrings: " - "too much operands on the stack " - "(seen %d, expected %d)\n", + FT_TRACE0(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", top - decoder->stack, num_args )); break; } @@ -965,28 +1067,26 @@ switch ( op ) { case op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); close_contour( builder ); /* close hints recording session */ if ( hinter ) { - if (hinter->close( hinter->hints, builder->current->n_points )) + if ( hinter->close( hinter->hints, builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, - (PSH_Globals) builder->hints_globals, + (PSH_Globals)builder->hints_globals, decoder->hint_mode ); } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); - FT_TRACE4(( "\n" )); - /* the compiler should optimize away this empty loop but ... */ #ifdef FT_DEBUG_LEVEL_TRACE @@ -1020,8 +1120,8 @@ builder->advance.x = top[1]; builder->advance.y = 0; - orig_x = builder->last.x = x = builder->pos_x + top[0]; - orig_y = builder->last.y = y = builder->pos_y; + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1034,9 +1134,12 @@ break; case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], top[2], - (FT_Int)top[3], (FT_Int)top[4] ); + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); case op_sbw: FT_TRACE4(( " sbw" )); @@ -1048,8 +1151,8 @@ builder->advance.x = top[2]; builder->advance.y = top[3]; - builder->last.x = x = builder->pos_x + top[0]; - builder->last.y = y = builder->pos_y + top[1]; + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1062,10 +1165,11 @@ case op_closepath: FT_TRACE4(( " closepath" )); - close_contour( builder ); - if ( !( builder->parse_state == T1_Parse_Have_Path || - builder->parse_state == T1_Parse_Have_Moveto ) ) - goto Syntax_Error; + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + close_contour( builder ); + builder->parse_state = T1_Parse_Have_Width; break; @@ -1134,7 +1238,7 @@ break; case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); + FT_TRACE4(( " rrcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) @@ -1193,16 +1297,13 @@ case op_div: FT_TRACE4(( " div" )); - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); - goto Syntax_Error; - } + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; break; case op_callsubr: @@ -1212,18 +1313,18 @@ FT_TRACE4(( " callsubr" )); - idx = (FT_Int)top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid subrs index\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "too many nested subrs\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); goto Syntax_Error; } @@ -1250,8 +1351,8 @@ if ( !zone->base ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invoking empty subrs!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -1273,8 +1374,8 @@ if ( unknown_othersubr_result_cnt == 0 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "no more operands for othersubr!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no more operands for othersubr\n" )); goto Syntax_Error; } @@ -1287,7 +1388,8 @@ if ( zone <= decoder->zones ) { - FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); goto Syntax_Error; } @@ -1311,7 +1413,6 @@ /* top[0] += builder->left_bearing.y; */ hinter->stem( hinter->hints, 1, top ); } - break; case op_hstem3: @@ -1320,19 +1421,17 @@ /* record horizontal counter-controlled hints */ if ( hinter ) hinter->stem3( hinter->hints, 1, top ); - break; case op_vstem: FT_TRACE4(( " vstem" )); - /* record vertical hint */ + /* record vertical hint */ if ( hinter ) { top[0] += orig_x; hinter->stem( hinter->hints, 0, top ); } - break; case op_vstem3: @@ -1362,9 +1461,8 @@ /* known_othersubr_result_cnt != 0 is already handled above */ if ( decoder->flex_state != 1 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected `setcurrentpoint'\n" )); - + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); goto Syntax_Error; } else @@ -1377,8 +1475,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unhandled opcode %d\n", op )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unhandled opcode %d\n", op )); goto Syntax_Error; } @@ -1389,6 +1487,11 @@ decoder->top = top; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + } /* general operator processing */ } /* while ip < limit */ @@ -1437,8 +1540,8 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "t1_decoder_init: " )); - FT_ERROR(( "the `psnames' module is not available\n" )); + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); return PSaux_Err_Unimplemented_Feature; } diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/Jamfile b/reactos/lib/3rdparty/freetype/src/pshinter/Jamfile index 769dcc4b296..779f1b0b828 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/pshinter/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshalgo pshmod ; + _sources = pshrec pshglob pshalgo pshmod pshpic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/module.mk b/reactos/lib/3rdparty/freetype/src/pshinter/module.mk index cd171d03552..ed24eb7fa89 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/module.mk +++ b/reactos/lib/3rdparty/freetype/src/pshinter/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSHINTER_MODULE define PSHINTER_MODULE -$(OPEN_DRIVER)pshinter_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.c b/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.c index 505d95c5720..417dcee547a 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.c +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -103,7 +103,7 @@ if ( idx >= table->max_hints ) { - FT_ERROR(( "psh_hint_table_record: invalid hint index %d\n", idx )); + FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); return; } @@ -137,7 +137,7 @@ if ( table->num_hints < table->max_hints ) table->sort_global[table->num_hints++] = hint; else - FT_ERROR(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); + FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); } @@ -230,7 +230,7 @@ FT_UInt idx; - FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" )); + FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); count = table->max_hints; for ( idx = 0; idx < count; idx++ ) @@ -282,8 +282,8 @@ { hint2 = sort[0]; if ( psh_hint_overlap( hint, hint2 ) ) - FT_ERROR(( "psh_hint_table_activate_mask:" - " found overlapping hints\n" )) + FT_TRACE0(( "psh_hint_table_activate_mask:" + " found overlapping hints\n" )) } #else count2 = 0; @@ -295,8 +295,8 @@ if ( count < table->max_hints ) table->sort[count++] = hint; else - FT_ERROR(( "psh_hint_tableactivate_mask:" - " too many active hints\n" )); + FT_TRACE0(( "psh_hint_tableactivate_mask:" + " too many active hints\n" )); } } } @@ -898,7 +898,7 @@ #ifdef DEBUG_ZONES -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H static void psh_print_zone( PSH_Zone zone ) @@ -2223,15 +2223,22 @@ FT_Fixed x_scale = dim_x->scale_mult; FT_Fixed y_scale = dim_y->scale_mult; + FT_Fixed old_x_scale = x_scale; + FT_Fixed old_y_scale = y_scale; + FT_Fixed scaled; FT_Fixed fitted; + FT_Bool rescale = FALSE; + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); fitted = FT_PIX_ROUND( scaled ); if ( fitted != 0 && scaled != fitted ) { + rescale = TRUE; + y_scale = FT_MulDiv( y_scale, fitted, scaled ); if ( fitted < scaled ) @@ -2239,43 +2246,47 @@ psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); } - } - glyph->do_horz_hints = 1; - glyph->do_vert_hints = 1; + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; - glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD ); + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); - glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD_V ); + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); - glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); - for ( dimension = 0; dimension < 2; dimension++ ) - { - /* load outline coordinates into glyph */ - psh_glyph_load_points( glyph, dimension ); + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh_glyph_load_points( glyph, dimension ); - /* compute local extrema */ - psh_glyph_compute_extrema( glyph ); + /* compute local extrema */ + psh_glyph_compute_extrema( glyph ); - /* compute aligned stem/hints positions */ - psh_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension, - glyph ); + /* compute aligned stem/hints positions */ + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); - /* find strong points, align them, then interpolate others */ - psh_glyph_find_strong_points( glyph, dimension ); - if ( dimension == 1 ) - psh_glyph_find_blue_points( &globals->blues, glyph ); - psh_glyph_interpolate_strong_points( glyph, dimension ); - psh_glyph_interpolate_normal_points( glyph, dimension ); - psh_glyph_interpolate_other_points( glyph, dimension ); + /* find strong points, align them, then interpolate others */ + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); - /* save hinted coordinates back to outline */ - psh_glyph_save_points( glyph, dimension ); + /* save hinted coordinates back to outline */ + psh_glyph_save_points( glyph, dimension ); + + if ( rescale ) + psh_globals_set_scale( glyph->globals, + old_x_scale, old_y_scale, 0, 0 ); + } } Exit: diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.h b/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.h index f68de71202e..1a248a70524 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.h +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +32,7 @@ FT_BEGIN_HEADER typedef struct PSH_HintRec_* PSH_Hint; /* hint bit-flags */ - typedef enum + typedef enum PSH_Hint_Flags_ { PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshinter.c b/reactos/lib/3rdparty/freetype/src/pshinter/pshinter.c index 8e3f193093b..b35a2a91c53 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshinter.c +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshinter.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "pshpic.c" #include "pshrec.c" #include "pshglob.c" #include "pshalgo.c" diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.c b/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.c index 4eb3d912729..91da5d7e6bc 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.c +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.c @@ -20,6 +20,7 @@ #include FT_INTERNAL_OBJECTS_H #include "pshrec.h" #include "pshalgo.h" +#include "pshpic.h" /* the Postscript Hinter module structure */ @@ -92,30 +93,26 @@ } - static - const PSHinter_Interface pshinter_interface = - { + FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface, pshinter_get_globals_funcs, pshinter_get_t1_funcs, pshinter_get_t2_funcs - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class pshinter_module_class = - { + FT_DEFINE_MODULE(pshinter_module_class, + 0, sizeof ( PS_Hinter_ModuleRec ), "pshinter", 0x10000L, 0x20000L, - &pshinter_interface, /* module-specific interface */ + &FTPSHINTER_INTERFACE_GET, /* module-specific interface */ (FT_Module_Constructor)ps_hinter_init, (FT_Module_Destructor) ps_hinter_done, (FT_Module_Requester) 0 /* no additional interface for now */ - }; - + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.h b/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.h index 1a91025b260..0ae7e96f54e 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.h +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshmod.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) pshinter_module_class; + FT_DECLARE_MODULE( pshinter_module_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.c b/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.c new file mode 100644 index 00000000000..51a08798883 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.c @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* pshpic.c */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from pshmod.c */ + void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*); + + void + pshinter_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->pshinter ) + { + FT_FREE( pic_container->pshinter ); + pic_container->pshinter = NULL; + } + } + + FT_Error + pshinter_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSHinterPIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->pshinter = container; + + /* add call to initialization function when you add new scripts */ + FT_Init_Class_pshinter_interface(library, &container->pshinter_interface); + +/*Exit:*/ + if(error) + pshinter_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.h b/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.h new file mode 100644 index 00000000000..3555d8e8513 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshpic.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* pshpic.h */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHPIC_H__ +#define __PSHPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FTPSHINTER_INTERFACE_GET pshinter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + typedef struct PSHinterPIC_ + { + PSHinter_Interface pshinter_interface; + } PSHinterPIC; + +#define GET_PIC(lib) ((PSHinterPIC*)((lib)->pic_container.autofit)) +#define FTPSHINTER_INTERFACE_GET (GET_PIC(library)->pshinter_interface) + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSHPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.c b/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.c index 2a885ef2763..0910cc5e6a5 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.c +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + #include "pshrec.h" #include "pshalgo.h" @@ -62,7 +64,7 @@ { FT_UInt old_max = table->max_hints; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -81,7 +83,7 @@ FT_Memory memory, PS_Hint *ahint ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Hint hint = 0; @@ -137,7 +139,7 @@ { FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; FT_UInt new_max = ( count + 7 ) >> 3; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -184,7 +186,7 @@ FT_Int idx, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_Byte* p; @@ -234,7 +236,7 @@ { FT_UInt old_max = table->max_masks; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -254,7 +256,7 @@ PS_Mask *amask ) { FT_UInt count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask = 0; @@ -285,7 +287,7 @@ FT_Memory memory, PS_Mask *amask ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Mask mask; @@ -314,7 +316,7 @@ FT_UInt bit_count, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask; @@ -407,7 +409,7 @@ FT_Memory memory ) { FT_UInt temp; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* swap index1 and index2 so that index1 < index2 */ @@ -481,8 +483,8 @@ table->num_masks--; } else - FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", - index1, index2 )); + FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); Exit: return error; @@ -497,7 +499,7 @@ FT_Memory memory ) { FT_Int index1, index2; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) @@ -558,8 +560,8 @@ FT_UInt idx, FT_Memory memory ) { - PS_Mask mask; - FT_Error error = 0; + PS_Mask mask; + FT_Error error = PSH_Err_Ok; /* get last hint mask */ @@ -619,7 +621,7 @@ FT_UInt end_point, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* reset current mask, if any */ @@ -644,7 +646,7 @@ FT_Memory memory, FT_Int *aindex ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt flags = 0; @@ -715,7 +717,7 @@ FT_Int hint3, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count = dim->counters.num_masks; PS_Mask counter = dim->counters.masks; @@ -789,7 +791,7 @@ ps_dimension_done( &hints->dimension[0], memory ); ps_dimension_done( &hints->dimension[1], memory ); - hints->error = 0; + hints->error = PSH_Err_Ok; hints->memory = 0; } @@ -800,7 +802,7 @@ { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; - return 0; + return PSH_Err_Ok; } @@ -813,7 +815,7 @@ { case PS_HINT_TYPE_1: case PS_HINT_TYPE_2: - hints->error = 0; + hints->error = PSH_Err_Ok; hints->hint_type = hint_type; ps_dimension_init( &hints->dimension[0] ); @@ -824,7 +826,7 @@ hints->error = PSH_Err_Invalid_Argument; hints->hint_type = hint_type; - FT_ERROR(( "ps_hints_open: invalid charstring type!\n" )); + FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); break; } } @@ -842,8 +844,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -878,8 +880,8 @@ } default: - FT_ERROR(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); + FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); break; } } @@ -888,11 +890,11 @@ /* add one Type1 counter stem to the current hints table */ static void - ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, - FT_Long* stems ) + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Fixed* stems ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -906,8 +908,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -919,9 +921,10 @@ /* add the three stems to our hints/masks table */ for ( count = 0; count < 3; count++, stems += 2 ) { - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, &idx[count] ); + error = ps_dimension_add_t1stem( dim, + (FT_Int)FIXED_TO_INT( stems[0] ), + (FT_Int)FIXED_TO_INT( stems[1] ), + memory, &idx[count] ); if ( error ) goto Fail; } @@ -934,7 +937,7 @@ } else { - FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" )); + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); error = PSH_Err_Invalid_Argument; goto Fail; } @@ -953,7 +956,7 @@ ps_hints_t1reset( PS_Hints hints, FT_UInt end_point ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -1008,8 +1011,8 @@ /* check bit count; must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2mask: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2mask:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1053,8 +1056,8 @@ /* check bit count, must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2counter: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2counter:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1124,11 +1127,17 @@ } static void - t1_hints_stem( T1_Hints hints, - FT_Int dimension, - FT_Long* coords ) + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Fixed* coords ) { - ps_hints_stem( (PS_Hints)hints, dimension, 1, coords ); + FT_Pos stems[2]; + + + stems[0] = FIXED_TO_INT( coords[0] ); + stems[1] = FIXED_TO_INT( coords[1] ); + + ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); } @@ -1183,7 +1192,7 @@ for ( n = 0; n < count * 2; n++ ) { y += coords[n]; - stems[n] = ( y + 0x8000L ) >> 16; + stems[n] = FIXED_TO_INT( y ); } /* compute lengths */ diff --git a/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.h b/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.h index f7ef9004ea1..dcb3197f94d 100644 --- a/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.h +++ b/reactos/lib/3rdparty/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002, 2003, 2006 by */ +/* Copyright 2001, 2002, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ FT_BEGIN_HEADER typedef struct PS_HintRec_* PS_Hint; /* hint types */ - typedef enum + typedef enum PS_Hint_Type_ { PS_HINT_TYPE_1 = 1, PS_HINT_TYPE_2 = 2 @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* hint flags */ - typedef enum + typedef enum PS_Hint_Flags_ { PS_HINT_FLAG_GHOST = 1, PS_HINT_FLAG_BOTTOM = 2 diff --git a/reactos/lib/3rdparty/freetype/src/psnames/Jamfile b/reactos/lib/3rdparty/freetype/src/psnames/Jamfile index d85c1e97de4..06c0dda66f2 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/psnames/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; if $(FT2_MULTI) { - _sources = psmodule ; + _sources = psmodule pspic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/psnames/module.mk b/reactos/lib/3rdparty/freetype/src/psnames/module.mk index a93063b928d..a6e908257cb 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/module.mk +++ b/reactos/lib/3rdparty/freetype/src/psnames/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSNAMES_MODULE define PSNAMES_MODULE -$(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, psnames_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/psnames/psmodule.c b/reactos/lib/3rdparty/freetype/src/psnames/psmodule.c index 8d8c476a145..35188504936 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/psmodule.c +++ b/reactos/lib/3rdparty/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,16 +24,17 @@ #include "pstables.h" #include "psnamerr.h" +#include "pspic.h" -#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST #define VARIANT_BIT 0x80000000UL -#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT ) +#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) /* Return the Unicode value corresponding to a given glyph. Note that */ @@ -57,7 +58,7 @@ /* `uniXXXXYYYYZZZZ'... */ FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 3; @@ -92,7 +93,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -101,7 +102,7 @@ if ( glyph_name[0] == 'u' ) { FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 1; @@ -132,7 +133,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -154,9 +155,10 @@ /* now look up the glyph in the Adobe Glyph List */ if ( !dot ) - return ft_get_adobe_glyph_index( glyph_name, p ); + return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); else - return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT; + return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | + VARIANT_BIT ); } } @@ -174,9 +176,121 @@ /* sort base glyphs before glyph variants */ if ( unicode1 == unicode2 ) - return map1->unicode - map2->unicode; + { + if ( map1->unicode > map2->unicode ) + return 1; + else if ( map1->unicode < map2->unicode ) + return -1; + else + return 0; + } else - return unicode1 - unicode2; + { + if ( unicode1 > unicode2 ) + return 1; + else if ( unicode1 < unicode2 ) + return -1; + else + return 0; + } + } + + + /* support for extra glyphs not handled (well) in AGL; */ + /* we add extra mappings for them if necessary */ + +#define EXTRA_GLYPH_LIST_SIZE 10 + + static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = + { + /* WGL 4 */ + 0x0394, + 0x03A9, + 0x2215, + 0x00AD, + 0x02C9, + 0x03BC, + 0x2219, + 0x00A0, + /* Romanian */ + 0x021A, + 0x021B + }; + + static const char ft_extra_glyph_names[] = + { + 'D','e','l','t','a',0, + 'O','m','e','g','a',0, + 'f','r','a','c','t','i','o','n',0, + 'h','y','p','h','e','n',0, + 'm','a','c','r','o','n',0, + 'm','u',0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, + 's','p','a','c','e',0, + 'T','c','o','m','m','a','a','c','c','e','n','t',0, + 't','c','o','m','m','a','a','c','c','e','n','t',0 + }; + + static const FT_Int + ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = + { + 0, + 6, + 12, + 21, + 28, + 35, + 38, + 53, + 59, + 72 + }; + + + static void + ps_check_extra_glyph_name( const char* gname, + FT_UInt glyph, + FT_UInt* extra_glyphs, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( ft_strcmp( ft_extra_glyph_names + + ft_extra_glyph_name_offsets[n], gname ) == 0 ) + { + if ( states[n] == 0 ) + { + /* mark this extra glyph as a candidate for the cmap */ + states[n] = 1; + extra_glyphs[n] = glyph; + } + + return; + } + } + } + + + static void + ps_check_extra_glyph_unicode( FT_UInt32 uni_char, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( uni_char == ft_extra_glyph_unicodes[n] ) + { + /* disable this extra glyph from being added to the cmap */ + states[n] = 2; + + return; + } + } } @@ -191,12 +305,15 @@ { FT_Error error; + FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; + /* we first allocate the table */ table->num_maps = 0; table->maps = 0; - if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) + if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) { FT_UInt n; FT_UInt count; @@ -213,10 +330,14 @@ if ( gname ) { + ps_check_extra_glyph_name( gname, n, + extra_glyphs, extra_glyph_list_states ); uni_char = ps_unicode_value( gname ); if ( BASE_GLYPH( uni_char ) != 0 ) { + ps_check_extra_glyph_unicode( uni_char, + extra_glyph_list_states ); map->unicode = uni_char; map->glyph_index = n; map++; @@ -227,6 +348,19 @@ } } + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( extra_glyph_list_states[n] == 1 ) + { + /* This glyph name has an additional representation. */ + /* Add it to the cmap. */ + + map->unicode = ft_extra_glyph_unicodes[n]; + map->glyph_index = extra_glyphs[n]; + map++; + } + } + /* now compress the table a bit */ count = (FT_UInt)( map - table->maps ); @@ -303,7 +437,7 @@ } - static FT_ULong + static FT_UInt32 ps_unicodes_char_next( PS_Unicodes table, FT_UInt32 *unicode ) { @@ -384,56 +518,66 @@ } - static - const FT_Service_PsCMapsRec pscmaps_interface = - { #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, (PS_Unicode_ValueFunc) ps_unicode_value, (PS_Unicodes_InitFunc) ps_unicodes_init, (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, -#else - - 0, - 0, - 0, - 0, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, t1_standard_encoding, t1_expert_encoding - }; + ) + +#else + + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, + 0, + 0, + 0, + 0, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding + ) + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + FT_DEFINE_SERVICEDESCREC1(pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET + ) - static const FT_ServiceDescRec pscmaps_services[] = - { - { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface }, - { NULL, NULL } - }; static FT_Pointer psnames_get_service( FT_Module module, const char* service_id ) { - FT_UNUSED( module ); + FT_Library library = module->library; + FT_UNUSED(library); - return ft_service_list_lookup( pscmaps_services, service_id ); + return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id ); } -#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES_SERVICE(a) 0 +#else +#define PUT_PS_NAMES_SERVICE(a) a +#endif - FT_CALLBACK_TABLE_DEF - const FT_Module_Class psnames_module_class = - { + FT_DEFINE_MODULE(psnames_module_class, + 0, /* this is not a font driver, nor a renderer */ sizeof ( FT_ModuleRec ), @@ -441,18 +585,12 @@ 0x10000L, /* driver version */ 0x20000L, /* driver requires FreeType 2 or above */ -#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - 0, + PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 -#else - (void*)&pscmaps_interface, /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) psnames_get_service -#endif - }; + (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service) + ) + /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/psnames/psmodule.h b/reactos/lib/3rdparty/freetype/src/psnames/psmodule.h index 232fdfb9a90..28fa14807c0 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/psmodule.h +++ b/reactos/lib/3rdparty/freetype/src/psnames/psmodule.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; + FT_DECLARE_MODULE( psnames_module_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/psnames/psnames.c b/reactos/lib/3rdparty/freetype/src/psnames/psnames.c index d6ed998bfb1..1ede225dc9c 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/psnames.c +++ b/reactos/lib/3rdparty/freetype/src/psnames/psnames.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "pspic.c" #include "psmodule.c" diff --git a/reactos/lib/3rdparty/freetype/src/psnames/pspic.c b/reactos/lib/3rdparty/freetype/src/psnames/pspic.c new file mode 100644 index 00000000000..ed7dadda393 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/psnames/pspic.c @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* pspic.c */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from psmodule.c */ + FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*); + + void + psnames_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->psnames ) + { + PSModulePIC* container = (PSModulePIC*)pic_container->psnames; + if(container->pscmaps_services) + FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services); + container->pscmaps_services = NULL; + FT_FREE( container ); + pic_container->psnames = NULL; + } + } + + FT_Error + psnames_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->psnames = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services); + if(error) + goto Exit; + FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface); + +Exit: + if(error) + psnames_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/psnames/pspic.h b/reactos/lib/3rdparty/freetype/src/psnames/pspic.h new file mode 100644 index 00000000000..75a14fdcb9b --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/psnames/pspic.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* pspic.h */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSPIC_H__ +#define __PSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_PSCMAPS_SERVICES_GET pscmaps_services +#define FT_PSCMAPS_INTERFACE_GET pscmaps_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + typedef struct PSModulePIC_ + { + FT_ServiceDescRec* pscmaps_services; + FT_Service_PsCMapsRec pscmaps_interface; + } PSModulePIC; + +#define GET_PIC(lib) ((PSModulePIC*)((lib)->pic_container.psnames)) +#define FT_PSCMAPS_SERVICES_GET (GET_PIC(library)->pscmaps_services) +#define FT_PSCMAPS_INTERFACE_GET (GET_PIC(library)->pscmaps_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/psnames/pstables.h b/reactos/lib/3rdparty/freetype/src/psnames/pstables.h index cc40ef735d6..1521e9c2854 100644 --- a/reactos/lib/3rdparty/freetype/src/psnames/pstables.h +++ b/reactos/lib/3rdparty/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -561,7 +561,10 @@ * The lookup function to get the Unicode value for a given string * is defined below the table. */ - static const unsigned char ft_adobe_glyph_list[54791] = + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + static const unsigned char ft_adobe_glyph_list[54791L] = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, @@ -4086,5 +4089,7 @@ return 0; } +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/raster/Jamfile b/reactos/lib/3rdparty/freetype/src/raster/Jamfile index f6e4251cb8f..4f60e87c788 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/raster/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) raster ; if $(FT2_MULTI) { - _sources = ftraster ftrend1 ; + _sources = ftraster ftrend1 rastpic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/raster/ftmisc.h b/reactos/lib/3rdparty/freetype/src/raster/ftmisc.h index c5dbd50d003..f04b5404bb8 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/ftmisc.h +++ b/reactos/lib/3rdparty/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ /* Miscellaneous macros for stand-alone rasterizer (specification */ /* only). */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -27,7 +27,8 @@ #ifndef __FTMISC_H__ #define __FTMISC_H__ -#include <string.h> /* memset */ + /* memset */ +#include FT_CONFIG_STANDARD_LIBRARY_H #define FT_BEGIN_HEADER #define FT_END_HEADER @@ -51,6 +52,31 @@ (FT_ULong)_x4 ) + /* from include/freetype2/ftsystem.h */ + + typedef struct FT_MemoryRec_* FT_Memory; + + typedef void* (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + typedef void (*FT_Free_Func)( FT_Memory memory, + void* block ); + + typedef void* (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + typedef struct FT_MemoryRec_ + { + void* user; + + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemoryRec; + /* from src/ftcalc.c */ #include <inttypes.h> diff --git a/reactos/lib/3rdparty/freetype/src/raster/ftraster.c b/reactos/lib/3rdparty/freetype/src/raster/ftraster.c index 4cfca4ed035..23ad592653c 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/ftraster.c +++ b/reactos/lib/3rdparty/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,6 +49,10 @@ #ifdef _STANDALONE_ +#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> + +#include <string.h> /* for memset */ + #include "ftmisc.h" #include "ftimage.h" @@ -58,6 +62,8 @@ #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ +#include "rastpic.h" + #endif /* !_STANDALONE_ */ @@ -72,13 +78,15 @@ /* profile is simply an array of scanline intersections on a given */ /* dimension. A profile's main attributes are */ /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ /* */ /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax'. */ + /* between `Ymin' and `Ymax' */ /* */ /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules. */ + /* `down', as this is very important for filling rules */ + /* */ + /* o its drop-out mode */ /* */ /* 2 - Sweeping the target map's scanlines in order to compute segment */ /* `spans' which are then filled. Additionally, this pass */ @@ -88,15 +96,15 @@ /* built from the bottom of the render pool, used as a stack. The */ /* following graphics shows the profile list under construction: */ /* */ - /* ____________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|___________________|_________|_________________|__ _ _ */ + /* __________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|_________________|_________|_________________|__ _ _ */ /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ /* */ /* The top of the profile stack is kept in the `top' variable. */ /* */ @@ -140,13 +148,11 @@ /*************************************************************************/ /* define DEBUG_RASTER if you want to compile a debugging version */ -#define xxxDEBUG_RASTER +/* #define DEBUG_RASTER */ - /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ - /* 5-levels anti-aliasing */ -#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS -#define FT_RASTER_OPTION_ANTI_ALIASING -#endif + /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ + /* 5-levels anti-aliasing */ +/* #define FT_RASTER_OPTION_ANTI_ALIASING */ /* The size of the two-lines intermediate bitmap used */ /* for anti-aliasing, in bytes. */ @@ -183,13 +189,13 @@ /* Disable the tracing mechanism for simplicity -- developers can */ /* activate it easily by redefining these two macros. */ #ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ #endif #ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#define FT_TRACE1( x ) do ; while ( 0 ) /* nothing */ -#define FT_TRACE6( x ) do ; while ( 0 ) /* nothing */ +#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ #endif #define Raster_Err_None 0 @@ -199,9 +205,22 @@ #define Raster_Err_Invalid -4 #define Raster_Err_Unsupported -5 -#define ft_memset memset +#define ft_memset memset -#else /* _STANDALONE_ */ +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* !_STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -217,7 +236,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* _STANDALONE_ */ +#endif /* !_STANDALONE_ */ #ifndef FT_MEM_SET @@ -306,13 +325,10 @@ } TPoint; - typedef enum TFlow_ - { - Flow_None = 0, - Flow_Up = 1, - Flow_Down = -1 - - } TFlow; + /* values for the `flags' bit field */ +#define Flow_Up 0x8 +#define Overshoot_Top 0x10 +#define Overshoot_Bottom 0x20 /* States of each line, arc, and profile */ @@ -331,18 +347,21 @@ struct TProfile_ { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile - various purpose */ - PLong offset; /* start of profile's data in render pool */ - int flow; /* Profile orientation: Asc/Descending */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile (various purposes) */ + PLong offset; /* start of profile's data in render pool */ + unsigned flags; /* Bit 0-2: drop-out mode */ + /* Bit 3: profile orientation (up/down) */ + /* Bit 4: is top profile? */ + /* Bit 5: is bottom profile? */ + long height; /* profile's height in scanlines */ + long start; /* profile's starting scanline */ - unsigned countL; /* number of lines to step before this */ - /* profile becomes drawable */ + unsigned countL; /* number of lines to step before this */ + /* profile becomes drawable */ - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ }; typedef PProfile TProfileList; @@ -372,10 +391,10 @@ #define RAS_VARS /* void */ #define RAS_VAR /* void */ -#define FT_UNUSED_RASTER do ; while ( 0 ) +#define FT_UNUSED_RASTER do { } while ( 0 ) -#else /* FT_STATIC_RASTER */ +#else /* !FT_STATIC_RASTER */ #define RAS_ARGS PWorker worker, @@ -387,10 +406,10 @@ #define FT_UNUSED_RASTER FT_UNUSED( worker ) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ - typedef struct TWorker_ TWorker, *PWorker; + typedef struct TWorker_ TWorker, *PWorker; /* prototypes used for sweep function dispatch */ @@ -417,65 +436,68 @@ #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) #define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) - /* Note that I have moved the location of some fields in the */ - /* structure to ensure that the most used variables are used */ - /* at the top. Thus, their offset can be coded with less */ - /* opcodes, and it results in a smaller executable. */ +#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) +#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half ) + + /* The most used variables are positioned at the top of the structure. */ + /* Thus, their offset can be coded with less opcodes, resulting in a */ + /* smaller executable. */ struct TWorker_ { - Int precision_bits; /* precision related variables */ - Int precision; - Int precision_half; - Long precision_mask; - Int precision_shift; - Int precision_step; - Int precision_jitter; + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; - Int scale_shift; /* == precision_shift for bitmaps */ + Int scale_shift; /* == precision_shift for bitmaps */ /* == precision_shift+1 for pixmaps */ - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ - FT_Error error; + FT_Error error; - Int numTurns; /* number of Y-turns in outline */ + Int numTurns; /* number of Y-turns in outline */ - TPoint* arc; /* current Bezier arc pointer */ + TPoint* arc; /* current Bezier arc pointer */ - UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ - Long lastX, lastY, minY, maxY; + Long lastX, lastY; + Long minY, maxY; - UShort num_Profs; /* current number of profiles */ + UShort num_Profs; /* current number of profiles */ - Bool fresh; /* signals a fresh new profile which */ - /* 'start' field must be completed */ - Bool joint; /* signals that the last arc ended */ + Bool fresh; /* signals a fresh new profile which */ + /* `start' field must be completed */ + Bool joint; /* signals that the last arc ended */ /* exactly on a scanline. Allows */ /* removal of doublets */ - PProfile cProfile; /* current profile */ - PProfile fProfile; /* head of linked list of profiles */ - PProfile gProfile; /* contour's first profile in case */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ /* of impact */ - TStates state; /* rendering state */ + TStates state; /* rendering state */ FT_Bitmap target; /* description of target bit/pixmap */ FT_Outline outline; - Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ - Short traceIncr; /* sweep's increment in target bitmap */ + Short traceIncr; /* sweep's increment in target bitmap */ - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ /* dispatch variables */ @@ -484,31 +506,31 @@ Function_Sweep_Span* Proc_Sweep_Drop; Function_Sweep_Step* Proc_Sweep_Step; - Byte dropOutControl; /* current drop_out control method */ + Byte dropOutControl; /* current drop_out control method */ - Bool second_pass; /* indicates whether a horizontal pass */ + Bool second_pass; /* indicates whether a horizontal pass */ /* should be performed to control */ /* drop-out accurately when calling */ /* Render_Glyph. Note that there is */ /* no horizontal pass during gray */ /* rendering. */ - TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ - TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ #ifdef FT_RASTER_OPTION_ANTI_ALIASING - Byte* grays; + Byte* grays; - Byte gray_lines[RASTER_GRAY_LINES]; + Byte gray_lines[RASTER_GRAY_LINES]; /* Intermediate table used to render the */ /* graylevels pixmaps. */ /* gray_lines is a buffer holding two */ /* monochrome scanlines */ - Short gray_width; /* width in bytes of one monochrome */ + Short gray_width; /* width in bytes of one monochrome */ /* intermediate scanline of gray_lines. */ /* Each gray pixel takes 2 bits long there */ @@ -520,47 +542,90 @@ }; - typedef struct TRaster_ + typedef struct TRaster_ { - char* buffer; - long buffer_size; - void* memory; - PWorker worker; - Byte grays[5]; - Short gray_width; + char* buffer; + long buffer_size; + void* memory; + PWorker worker; + Byte grays[5]; + Short gray_width; } TRaster, *PRaster; #ifdef FT_STATIC_RASTER - static TWorker cur_ras; + static TWorker cur_ras; #define ras cur_ras -#else +#else /* !FT_STATIC_RASTER */ #define ras (*worker) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ -static const char count_table[256] = -{ - 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 }; +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /* A lookup table used to quickly count set bits in four gray 2x2 */ + /* cells. The values of the table have been produced with the */ + /* following code: */ + /* */ + /* for ( i = 0; i < 256; i++ ) */ + /* { */ + /* l = 0; */ + /* j = i; */ + /* */ + /* for ( c = 0; c < 4; c++ ) */ + /* { */ + /* l <<= 4; */ + /* */ + /* if ( j & 0x80 ) l++; */ + /* if ( j & 0x40 ) l++; */ + /* */ + /* j = ( j << 2 ) & 0xFF; */ + /* } */ + /* printf( "0x%04X", l ); */ + /* } */ + /* */ + + static const short count_table[256] = + { + 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, + 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, + 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, + 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, + 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 + }; + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ @@ -579,7 +644,7 @@ static const char count_table[256] = /* Set_High_Precision */ /* */ /* <Description> */ - /* Sets precision variables according to param flag. */ + /* Set precision variables according to param flag. */ /* */ /* <Input> */ /* High :: Set to True for high precision (typically for ppem < 18), */ @@ -590,9 +655,9 @@ static const char count_table[256] = { if ( High ) { - ras.precision_bits = 10; - ras.precision_step = 128; - ras.precision_jitter = 24; + ras.precision_bits = 12; + ras.precision_step = 256; + ras.precision_jitter = 50; } else { @@ -616,17 +681,21 @@ static const char count_table[256] = /* New_Profile */ /* */ /* <Description> */ - /* Creates a new profile in the render pool. */ + /* Create a new profile in the render pool. */ /* */ /* <Input> */ - /* aState :: The state/orientation of the new profile. */ + /* aState :: The state/orientation of the new profile. */ + /* */ + /* overshoot :: Whether the profile's unrounded start position */ + /* differs by at least a half pixel. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ /* profile. */ /* */ static Bool - New_Profile( RAS_ARGS TStates aState ) + New_Profile( RAS_ARGS TStates aState, + Bool overshoot ) { if ( !ras.fProfile ) { @@ -641,29 +710,35 @@ static const char count_table[256] = return FAILURE; } - switch ( aState ) - { - case Ascending_State: - ras.cProfile->flow = Flow_Up; - FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); - break; - - case Descending_State: - ras.cProfile->flow = Flow_Down; - FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); - break; - - default: - FT_ERROR(( "New_Profile: invalid profile direction!\n" )); - ras.error = Raster_Err_Invalid; - return FAILURE; - } - + ras.cProfile->flags = 0; ras.cProfile->start = 0; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; ras.cProfile->link = (PProfile)0; ras.cProfile->next = (PProfile)0; + ras.cProfile->flags = ras.dropOutControl; + + switch ( aState ) + { + case Ascending_State: + ras.cProfile->flags |= Flow_Up; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Bottom; + + FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending_State: + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Top; + FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + FT_ERROR(( "New_Profile: invalid profile direction\n" )); + ras.error = Raster_Err_Invalid; + return FAILURE; + } if ( !ras.gProfile ) ras.gProfile = ras.cProfile; @@ -682,13 +757,17 @@ static const char count_table[256] = /* End_Profile */ /* */ /* <Description> */ - /* Finalizes the current profile. */ + /* Finalize the current profile. */ + /* */ + /* <Input> */ + /* overshoot :: Whether the profile's unrounded end position differs */ + /* by at least a half pixel. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ /* */ static Bool - End_Profile( RAS_ARG ) + End_Profile( RAS_ARGS Bool overshoot ) { Long h; PProfile oldProfile; @@ -698,7 +777,7 @@ static const char count_table[256] = if ( h < 0 ) { - FT_ERROR(( "End_Profile: negative height encountered!\n" )); + FT_ERROR(( "End_Profile: negative height encountered\n" )); ras.error = Raster_Err_Neg_Height; return FAILURE; } @@ -708,15 +787,24 @@ static const char count_table[256] = FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", (long)ras.cProfile, ras.cProfile->start, h )); - oldProfile = ras.cProfile; ras.cProfile->height = h; - ras.cProfile = (PProfile)ras.top; + if ( overshoot ) + { + if ( ras.cProfile->flags & Flow_Up ) + ras.cProfile->flags |= Overshoot_Top; + else + ras.cProfile->flags |= Overshoot_Bottom; + } - ras.top += AlignProfileSize; + oldProfile = ras.cProfile; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; - oldProfile->next = ras.cProfile; + + oldProfile->next = ras.cProfile; ras.num_Profs++; } @@ -739,7 +827,7 @@ static const char count_table[256] = /* Insert_Y_Turn */ /* */ /* <Description> */ - /* Inserts a salient into the sorted list placed on top of the render */ + /* Insert a salient into the sorted list placed on top of the render */ /* pool. */ /* */ /* <Input> */ @@ -794,7 +882,7 @@ static const char count_table[256] = /* Finalize_Profile_Table */ /* */ /* <Description> */ - /* Adjusts all links in the profiles list. */ + /* Adjust all links in the profiles list. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow. */ @@ -808,10 +896,10 @@ static const char count_table[256] = n = ras.num_Profs; + p = ras.fProfile; - if ( n > 1 ) + if ( n > 1 && p ) { - p = ras.fProfile; while ( n > 0 ) { if ( n > 1 ) @@ -819,23 +907,21 @@ static const char count_table[256] = else p->link = NULL; - switch ( p->flow ) + if ( p->flags & Flow_Up ) + { + bottom = (Int)p->start; + top = (Int)( p->start + p->height - 1 ); + } + else { - case Flow_Down: bottom = (Int)( p->start - p->height + 1 ); top = (Int)p->start; p->start = bottom; p->offset += p->height - 1; - break; - - case Flow_Up: - default: - bottom = (Int)p->start; - top = (Int)( p->start + p->height - 1 ); } - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top + 1 ) ) return FAILURE; p = p->link; @@ -855,7 +941,7 @@ static const char count_table[256] = /* Split_Conic */ /* */ /* <Description> */ - /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */ + /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ /* stack. */ /* */ /* <Input> */ @@ -894,7 +980,7 @@ static const char count_table[256] = /* Split_Cubic */ /* */ /* <Description> */ - /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */ + /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ /* Bezier stack. */ /* */ /* <Note> */ @@ -936,7 +1022,7 @@ static const char count_table[256] = /* Line_Up */ /* */ /* <Description> */ - /* Computes the x-coordinates of an ascending line segment and stores */ + /* Compute the x-coordinates of an ascending line segment and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1075,8 +1161,8 @@ static const char count_table[256] = /* Line_Down */ /* */ /* <Description> */ - /* Computes the x-coordinates of an descending line segment and */ - /* stores them in the render pool. */ + /* Compute the x-coordinates of an descending line segment and store */ + /* them in the render pool. */ /* */ /* <Input> */ /* x1 :: The x-coordinate of the segment's start point. */ @@ -1126,7 +1212,7 @@ static const char count_table[256] = /* Bezier_Up */ /* */ /* <Description> */ - /* Computes the x-coordinates of an ascending Bezier arc and stores */ + /* Compute the x-coordinates of an ascending Bezier arc and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1227,7 +1313,7 @@ static const char count_table[256] = } else { - *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, + *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, e - y1, y2 - y1 ); arc -= degree; e += ras.precision; @@ -1259,7 +1345,7 @@ static const char count_table[256] = /* Bezier_Down */ /* */ /* <Description> */ - /* Computes the x-coordinates of an descending Bezier arc and stores */ + /* Compute the x-coordinates of an descending Bezier arc and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1308,7 +1394,7 @@ static const char count_table[256] = /* Line_To */ /* */ /* <Description> */ - /* Injects a new line segment and adjusts Profiles list. */ + /* Inject a new line segment and adjust the Profiles list. */ /* */ /* <Input> */ /* x :: The x-coordinate of the segment's end point (its start point */ @@ -1332,13 +1418,15 @@ static const char count_table[256] = case Unknown_State: if ( y > ras.lastY ) { - if ( New_Profile( RAS_VARS Ascending_State ) ) + if ( New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } else { if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending_State ) ) + if ( New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1346,8 +1434,9 @@ static const char count_table[256] = case Ascending_State: if ( y < ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Descending_State ) ) + if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1355,8 +1444,9 @@ static const char count_table[256] = case Descending_State: if ( y > ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Ascending_State ) ) + if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1371,13 +1461,13 @@ static const char count_table[256] = { case Ascending_State: if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; case Descending_State: if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; @@ -1398,7 +1488,7 @@ static const char count_table[256] = /* Conic_To */ /* */ /* <Description> */ - /* Injects a new conic arc and adjusts the profile list. */ + /* Inject a new conic arc and adjust the profile list. */ /* */ /* <Input> */ /* cx :: The x-coordinate of the arc's new control point. */ @@ -1428,8 +1518,10 @@ static const char count_table[256] = ras.arc = ras.arcs; ras.arc[2].x = ras.lastX; ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; ras.arc[1].y = cy; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[1].x = cx; + ras.arc[1].y = cy; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1469,13 +1561,17 @@ static const char count_table[256] = state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + /* finalize current profile if any */ - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1508,7 +1604,7 @@ static const char count_table[256] = /* Cubic_To */ /* */ /* <Description> */ - /* Injects a new cubic arc and adjusts the profile list. */ + /* Inject a new cubic arc and adjust the profile list. */ /* */ /* <Input> */ /* cx1 :: The x-coordinate of the arc's first new control point. */ @@ -1544,9 +1640,12 @@ static const char count_table[256] = ras.arc = ras.arcs; ras.arc[3].x = ras.lastX; ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; ras.arc[2].y = cy1; - ras.arc[1].x = cx2; ras.arc[1].y = cy2; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[2].x = cx1; + ras.arc[2].y = cy1; + ras.arc[1].x = cx2; + ras.arc[1].y = cy2; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1598,11 +1697,16 @@ static const char count_table[256] = /* detect a change of direction */ if ( ras.state != state_bez ) { - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1646,7 +1750,7 @@ static const char count_table[256] = /* Decompose_Curve */ /* */ /* <Description> */ - /* Scans the outline arrays in order to emit individual segments and */ + /* Scan the outline arrays in order to emit individual segments and */ /* Beziers by calling Line_To() and Bezier_To(). It handles all */ /* weird cases, like when the first point is off the curve, or when */ /* there are simply no `on' points in the contour! */ @@ -1695,8 +1799,13 @@ static const char count_table[256] = v_control = v_start; point = points + first; - tags = ras.outline.tags + first; - tag = FT_CURVE_TAG( tags[0] ); + tags = ras.outline.tags + first; + + /* set scan mode if necessary */ + if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) + ras.dropOutControl = (Byte)tags[0] >> 5; + + tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ if ( tag == FT_CURVE_TAG_CUBIC ) @@ -1867,7 +1976,7 @@ static const char count_table[256] = /* Convert_Glyph */ /* */ /* <Description> */ - /* Converts a glyph into a series of segments and arcs and makes a */ + /* Convert a glyph into a series of segments and arcs and make a */ /* profiles list with them. */ /* */ /* <Input> */ @@ -1902,27 +2011,36 @@ static const char count_table[256] = for ( i = 0; i < ras.outline.n_contours; i++ ) { + Bool o; + + ras.state = Unknown_State; ras.gProfile = NULL; if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], - flipped ) ) + ras.outline.contours[i], + flipped ) ) return FAILURE; start = ras.outline.contours[i] + 1; - /* We must now see whether the extreme arcs join or not */ + /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && ras.lastY >= ras.minY && ras.lastY <= ras.maxY ) - if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) + if ( ras.gProfile && + ( ras.gProfile->flags & Flow_Up ) == + ( ras.cProfile->flags & Flow_Up ) ) ras.top--; /* Note that ras.gProfile can be nil if the contour was too small */ /* to be drawn. */ lastProfile = ras.cProfile; - if ( End_Profile( RAS_VAR ) ) + if ( ras.cProfile->flags & Flow_Up ) + o = IS_TOP_OVERSHOOT( ras.lastY ); + else + o = IS_BOTTOM_OVERSHOOT( ras.lastY ); + if ( End_Profile( RAS_VARS o ) ) return FAILURE; /* close the `next profile in contour' linked list */ @@ -2042,7 +2160,7 @@ static const char count_table[256] = while ( current ) { current->X = *current->offset; - current->offset += current->flow; + current->offset += current->flags & Flow_Up ? 1 : -1; current->height--; current = current->link; } @@ -2148,8 +2266,10 @@ static const char count_table[256] = f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1; - if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2; + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = (short)c1; + if ( ras.gray_max_x < c2 ) + ras.gray_max_x = (short)c2; target = ras.bTarget + ras.traceOfs + c1; c2 -= c1; @@ -2182,38 +2302,63 @@ static const char count_table[256] = PProfile left, PProfile right ) { - Long e1, e2; + Long e1, e2, pxl; Short c1, f1; /* Drop-out control */ - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); + /* e2 x2 x1 e1 */ + /* */ + /* ^ | */ + /* | | */ + /* +-------------+---------------------+------------+ */ + /* | | */ + /* | v */ + /* */ + /* pixel contour contour pixel */ + /* center center */ + + /* drop-out mode scan conversion rules (as defined in OpenType) */ + /* --------------------------------------------------------------- */ + /* 0 1, 2, 3 */ + /* 1 1, 2, 4 */ + /* 2 1, 2 */ + /* 3 same as mode 2 */ + /* 4 1, 2, 5 */ + /* 5 1, 2, 6 */ + /* 6, 7 same as mode 2 */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: - e1 = e2; + case 0: /* simple drop-outs including stubs */ + pxl = e2; break; - case 4: - e1 = CEILING( (x1 + x2 + 1) / 2 ); + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - /* Drop-out Control Rule #4 */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ + /* Drop-out Control Rules #4 and #6 */ + + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ /* */ - /* Here, we only get rid of stubs recognized if: */ + /* Here the constraints we use to recognize a stub. */ /* */ /* upper stub: */ /* */ @@ -2227,59 +2372,64 @@ static const char count_table[256] = /* - P_Left is the successor of P_Right in that contour */ /* - y is the bottom of P_Left */ /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ - /* FIXXXME: uncommenting this line solves the disappearing */ - /* bit problem in the `7' of verdana 10pts, but */ - /* makes a new one in the `C' of arial 14pts */ - -#if 0 - if ( x2 - x1 < ras.precision_half ) -#endif - { - /* upper stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* lower stub test */ - if ( right->next == left && left->start == y ) - return; - } - - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); - - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + /* upper stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) return; - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + /* lower stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + return; } else return; } - e1 = TRUNC( e1 ); + e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.bWidth ) { c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) + ras.gray_max_x = c1; ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } @@ -2363,74 +2513,88 @@ static const char count_table[256] = PProfile left, PProfile right ) { - Long e1, e2; + Long e1, e2, pxl; PByte bits; Byte f1; /* During the horizontal sweep, we only take care of drop-outs */ - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); + /* e1 + <-- pixel center */ + /* | */ + /* x1 ---+--> <-- contour */ + /* | */ + /* | */ + /* x2 <--+--- <-- contour */ + /* | */ + /* | */ + /* e2 + <-- pixel center */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: - e1 = e2; + case 0: /* simple drop-outs including stubs */ + pxl = e2; break; - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) return; /* leftmost stub test */ - if ( right->next == left && left->start == y ) + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) return; - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; - - if ( ras.dropOutControl == 2 ) - e1 = e2; + if ( dropOutControl == 1 ) + pxl = e2; else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; } else return; @@ -2439,7 +2603,7 @@ static const char count_table[256] = bits = ras.bTarget + ( y >> 3 ); f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( e1 ); + e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.target.rows ) { @@ -2509,10 +2673,10 @@ static const char count_table[256] = static void Vertical_Gray_Sweep_Step( RAS_ARG ) { - Int c1, c2; - PByte pix, bit, bit2; - char* count = (char*)count_table; - Byte* grays; + Int c1, c2; + PByte pix, bit, bit2; + short* count = (short*)count_table; + Byte* grays; ras.traceOfs += ras.gray_width; @@ -2524,10 +2688,10 @@ static const char count_table[256] = if ( ras.gray_max_x >= 0 ) { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; + Long last_pixel = ras.target.width - 1; + Int last_cell = last_pixel >> 2; + Int last_bit = last_pixel & 3; + Bool over = 0; if ( ras.gray_max_x >= last_cell && last_bit != 3 ) @@ -2539,8 +2703,8 @@ static const char count_table[256] = if ( ras.gray_min_x < 0 ) ras.gray_min_x = 0; - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; c1 = ras.gray_max_x - ras.gray_min_x; @@ -2625,32 +2789,30 @@ static const char count_table[256] = /* During the horizontal sweep, we only take care of drop-outs */ + e1 = CEILING( x1 ); e2 = FLOOR ( x2 ); if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: + case 0: /* simple drop-outs including stubs */ e1 = e2; break; - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + case 4: /* smart drop-outs including stubs */ + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ if ( left->next == right && left->height <= 0 ) @@ -2660,15 +2822,15 @@ static const char count_table[256] = if ( right->next == left && left->start == y ) return; - if ( ras.dropOutControl == 2 ) + if ( dropOutControl == 1 ) e1 = e2; else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } } else @@ -2720,7 +2882,7 @@ static const char count_table[256] = TProfileList draw_left, draw_right; - /* Init empty linked lists */ + /* initialize empty linked lists */ Init_Linked( &waiting ); @@ -2740,8 +2902,10 @@ static const char count_table[256] = bottom = (Short)P->start; top = (Short)( P->start + P->height - 1 ); - if ( min_Y > bottom ) min_Y = bottom; - if ( max_Y < top ) max_Y = top; + if ( min_Y > bottom ) + min_Y = bottom; + if ( max_Y < top ) + max_Y = top; P->X = 0; InsNew( &waiting, P ); @@ -2749,18 +2913,18 @@ static const char count_table[256] = P = Q; } - /* Check the Y-turns */ + /* check the Y-turns */ if ( ras.numTurns == 0 ) { ras.error = Raster_Err_Invalid; return FAILURE; } - /* Now inits the sweep */ + /* now initialize the sweep */ ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); - /* Then compute the distance of each profile from min_Y */ + /* then compute the distance of each profile from min_Y */ P = waiting; @@ -2770,18 +2934,18 @@ static const char count_table[256] = P = P->link; } - /* Let's go */ + /* let's go */ y = min_Y; y_height = 0; - if ( ras.numTurns > 0 && + if ( ras.numTurns > 0 && ras.sizeBuff[-ras.numTurns] == min_Y ) ras.numTurns--; while ( ras.numTurns > 0 ) { - /* look in the waiting list for new activations */ + /* check waiting list for new activations */ P = waiting; @@ -2793,22 +2957,16 @@ static const char count_table[256] = { DelOld( &waiting, P ); - switch ( P->flow ) - { - case Flow_Up: + if ( P->flags & Flow_Up ) InsNew( &draw_left, P ); - break; - - case Flow_Down: + else InsNew( &draw_right, P ); - break; - } } P = Q; } - /* Sort the drawing lists */ + /* sort the drawing lists */ Sort( &draw_left ); Sort( &draw_right ); @@ -2818,7 +2976,7 @@ static const char count_table[256] = while ( y < y_change ) { - /* Let's trace */ + /* let's trace */ dropouts = 0; @@ -2837,22 +2995,28 @@ static const char count_table[256] = x2 = xs; } - if ( x2 - x1 <= ras.precision ) + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( x2 - x1 <= ras.precision && + e1 != x1 && e2 != x2 ) { - e1 = FLOOR( x1 ); - e2 = CEILING( x2 ); - - if ( ras.dropOutControl != 0 && - ( e1 > e2 || e2 == e1 + ras.precision ) ) + if ( e1 > e2 || e2 == e1 + ras.precision ) { - /* a drop out was detected */ + Int dropOutControl = P_Left->flags & 7; - P_Left ->X = x1; - P_Right->X = x2; - /* mark profile for drop-out processing */ - P_Left->countL = 1; - dropouts++; + if ( dropOutControl != 2 ) + { + /* a drop-out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + } goto Skip_To_Next; } @@ -2866,9 +3030,9 @@ static const char count_table[256] = P_Right = P_Right->link; } - /* now perform the dropouts _after_ the span drawing -- */ - /* drop-outs processing has been moved out of the loop */ - /* for performance tuning */ + /* handle drop-outs _after_ the span drawing -- */ + /* drop-out processing has been moved out of the loop */ + /* for performance tuning */ if ( dropouts > 0 ) goto Scan_DropOuts; @@ -2885,7 +3049,7 @@ static const char count_table[256] = } } - /* Now finalize the profiles that needs it */ + /* now finalize the profiles that need it */ P = draw_left; while ( P ) @@ -2906,7 +3070,7 @@ static const char count_table[256] = } } - /* for gray-scaling, flushes the bitmap scanline cache */ + /* for gray-scaling, flush the bitmap scanline cache */ while ( y <= max_Y ) { ras.Proc_Sweep_Step( RAS_VAR ); @@ -2949,7 +3113,7 @@ static const char count_table[256] = /* Render_Single_Pass */ /* */ /* <Description> */ - /* Performs one sweep with sub-banding. */ + /* Perform one sweep with sub-banding. */ /* */ /* <Input> */ /* flipped :: If set, flip the direction of the outline. */ @@ -3024,7 +3188,7 @@ static const char count_table[256] = /* Render_Glyph */ /* */ /* <Description> */ - /* Renders a glyph in a bitmap. Sub-banding if needed. */ + /* Render a glyph in a bitmap. Sub-banding if needed. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -3036,14 +3200,24 @@ static const char count_table[256] = Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift; - /* Drop-out mode 2 is hard-coded since this is the only mode used */ - /* on Windows platforms. Using other modes, as specified by the */ - /* font, results in misplaced pixels. */ - ras.dropOutControl = 2; - ras.second_pass = (FT_Byte)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = (FT_Byte)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); /* Vertical Sweep */ ras.Proc_Sweep_Init = Vertical_Sweep_Init; @@ -3062,7 +3236,7 @@ static const char count_table[256] = return error; /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) + if ( ras.second_pass && ras.dropOutControl != 2 ) { ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Sweep_Span; @@ -3083,14 +3257,13 @@ static const char count_table[256] = #ifdef FT_RASTER_OPTION_ANTI_ALIASING - /*************************************************************************/ /* */ /* <Function> */ /* Render_Gray_Glyph */ /* */ /* <Description> */ - /* Renders a glyph with grayscaling. Sub-banding if needed. */ + /* Render a glyph with grayscaling. Sub-banding if needed. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -3103,13 +3276,23 @@ static const char count_table[256] = Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift + 1; - /* Drop-out mode 2 is hard-coded since this is the only mode used */ - /* on Windows platforms. Using other modes, as specified by the */ - /* font, results in misplaced pixels. */ - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift + 1; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); /* Vertical Sweep */ @@ -3137,7 +3320,7 @@ static const char count_table[256] = return error; /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) + if ( ras.second_pass && ras.dropOutControl != 2 ) { ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; @@ -3172,8 +3355,6 @@ static const char count_table[256] = static void ft_black_init( PRaster raster ) { - FT_UNUSED( raster ); - #ifdef FT_RASTER_OPTION_ANTI_ALIASING FT_UInt n; @@ -3183,7 +3364,8 @@ static const char count_table[256] = raster->grays[n] = n * 255 / 4; raster->gray_width = RASTER_GRAY_LINES / 2; - +#else + FT_UNUSED( raster ); #endif } @@ -3196,7 +3378,7 @@ static const char count_table[256] = static int - ft_black_new( void* memory, + ft_black_new( void* memory, FT_Raster *araster ) { static TRaster the_raster; @@ -3254,9 +3436,9 @@ static const char count_table[256] = static void - ft_black_reset( PRaster raster, - char* pool_base, - long pool_size ) + ft_black_reset( PRaster raster, + char* pool_base, + long pool_size ) { if ( raster ) { @@ -3281,9 +3463,9 @@ static const char count_table[256] = static void - ft_black_set_mode( PRaster raster, - unsigned long mode, - const char* palette ) + ft_black_set_mode( PRaster raster, + unsigned long mode, + const char* palette ) { #ifdef FT_RASTER_OPTION_ANTI_ALIASING @@ -3319,14 +3501,18 @@ static const char count_table[256] = if ( !raster || !raster->buffer || !raster->buffer_size ) return Raster_Err_Not_Ini; + if ( !outline ) + return Raster_Err_Invalid; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return Raster_Err_None; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return Raster_Err_Invalid; - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) return Raster_Err_Invalid; worker = raster->worker; @@ -3335,35 +3521,43 @@ static const char count_table[256] = if ( params->flags & FT_RASTER_FLAG_DIRECT ) return Raster_Err_Unsupported; - if ( !target_map || !target_map->buffer ) + if ( !target_map ) return Raster_Err_Invalid; - ras.outline = *outline; - ras.target = *target_map; + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return Raster_Err_None; - worker->buff = (PLong) raster->buffer; - worker->sizeBuff = worker->buff + - raster->buffer_size / sizeof ( Long ); + if ( !target_map->buffer ) + return Raster_Err_Invalid; + + ras.outline = *outline; + ras.target = *target_map; + + worker->buff = (PLong) raster->buffer; + worker->sizeBuff = worker->buff + + raster->buffer_size / sizeof ( Long ); #ifdef FT_RASTER_OPTION_ANTI_ALIASING - worker->grays = raster->grays; - worker->gray_width = raster->gray_width; + worker->grays = raster->grays; + worker->gray_width = raster->gray_width; + + FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); #endif - return ( ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ) ); + return ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( RAS_VAR ) + : Render_Glyph( RAS_VAR ); } - const FT_Raster_Funcs ft_standard_raster = - { + FT_DEFINE_RASTER_FUNCS( ft_standard_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) ft_black_new, (FT_Raster_Reset_Func) ft_black_reset, (FT_Raster_Set_Mode_Func)ft_black_set_mode, (FT_Raster_Render_Func) ft_black_render, (FT_Raster_Done_Func) ft_black_done - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/raster/ftrend1.c b/reactos/lib/3rdparty/freetype/src/raster/ftrend1.c index 3cc8d07413b..1ed8af61217 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/ftrend1.c +++ b/reactos/lib/3rdparty/freetype/src/raster/ftrend1.c @@ -21,6 +21,7 @@ #include FT_OUTLINE_H #include "ftrend1.h" #include "ftraster.h" +#include "rastpic.h" #include "rasterrs.h" @@ -118,6 +119,7 @@ } /* check rendering mode */ +#ifndef FT_CONFIG_OPTION_PIC if ( mode != FT_RENDER_MODE_MONO ) { /* raster1 is only capable of producing monochrome bitmaps */ @@ -130,6 +132,25 @@ if ( render->clazz == &ft_raster5_renderer_class ) return Raster_Err_Cannot_Render_Glyph; } +#else /* FT_CONFIG_OPTION_PIC */ + /* When PIC is enabled, we cannot get to the class object */ + /* so instead we check the final character in the class name */ + /* ("raster5" or "raster1"). Yes this is a hack. */ + /* The "correct" thing to do is have different render function */ + /* for each of the classes. */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz->root.module_name[6] == '1' ) + return Raster_Err_Cannot_Render_Glyph; + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz->root.module_name[6] == '5' ) + return Raster_Err_Cannot_Render_Glyph; + } +#endif /* FT_CONFIG_OPTION_PIC */ outline = &slot->outline; @@ -208,10 +229,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster1_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster1_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -224,7 +243,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -233,18 +252,17 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* This renderer is _NOT_ part of the default modules; you will need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster5_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster5_renderer_class, + + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -257,7 +275,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -266,8 +284,8 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/raster/ftrend1.h b/reactos/lib/3rdparty/freetype/src/raster/ftrend1.h index 76e9a5f581e..4cf128622a9 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/ftrend1.h +++ b/reactos/lib/3rdparty/freetype/src/raster/ftrend1.h @@ -27,13 +27,13 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; + FT_DECLARE_RENDERER( ft_raster1_renderer_class ) /* this renderer is _NOT_ part of the default modules, you'll need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; + FT_DECLARE_RENDERER( ft_raster5_renderer_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/raster/module.mk b/reactos/lib/3rdparty/freetype/src/raster/module.mk index 59c737b9303..cbff5df96ea 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/module.mk +++ b/reactos/lib/3rdparty/freetype/src/raster/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += RASTER_MODULE define RASTER_MODULE -$(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_raster1_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/raster/raster.c b/reactos/lib/3rdparty/freetype/src/raster/raster.c index f13a67a209d..1202a116cdf 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/raster.c +++ b/reactos/lib/3rdparty/freetype/src/raster/raster.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "rastpic.c" #include "ftraster.c" #include "ftrend1.c" diff --git a/reactos/lib/3rdparty/freetype/src/raster/rastpic.c b/reactos/lib/3rdparty/freetype/src/raster/rastpic.c new file mode 100644 index 00000000000..3c264877b6d --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/raster/rastpic.c @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* rastpic.c */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "rastpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftraster.c */ + void FT_Init_Class_ft_standard_raster(FT_Raster_Funcs*); + + void + ft_raster1_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->raster ) + { + RasterPIC* container = (RasterPIC*)pic_container->raster; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->raster = NULL; + } + } + + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + RasterPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve raster5 renderer, + it implements reference counting */ + if(pic_container->raster) + { + ((RasterPIC*)pic_container->raster)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->raster = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_standard_raster(&container->ft_standard_raster); +/*Exit:*/ + if(error) + ft_raster1_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_raster5_renderer_class_pic_init(FT_Library library) + { + return ft_raster1_renderer_class_pic_init(library); + } + void ft_raster5_renderer_class_pic_free(FT_Library library) + { + ft_raster1_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/raster/rastpic.h b/reactos/lib/3rdparty/freetype/src/raster/rastpic.h new file mode 100644 index 00000000000..dcd82b8ca8f --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/raster/rastpic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* rastpic.h */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __RASTPIC_H__ +#define __RASTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_STANDARD_RASTER_GET ft_standard_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct RasterPIC_ + { + int ref_count; + FT_Raster_Funcs ft_standard_raster; + } RasterPIC; + +#define GET_PIC(lib) ((RasterPIC*)((lib)->pic_container.raster)) +#define FT_STANDARD_RASTER_GET (GET_PIC(library)->ft_standard_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __RASTPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/raster/rules.mk b/reactos/lib/3rdparty/freetype/src/raster/rules.mk index 0dc8782ea45..9703b1298a1 100644 --- a/reactos/lib/3rdparty/freetype/src/raster/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2000, 2001, 2003, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/Jamfile b/reactos/lib/3rdparty/freetype/src/sfnt/Jamfile index 6b8a4018223..cb20b1b04b1 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/sfnt/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ttbdf ; + _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/module.mk b/reactos/lib/3rdparty/freetype/src/sfnt/module.mk index d33913809cc..95fd6a31437 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/module.mk +++ b/reactos/lib/3rdparty/freetype/src/sfnt/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += SFNT_MODULE define SFNT_MODULE -$(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, sfnt_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/rules.mk b/reactos/lib/3rdparty/freetype/src/sfnt/rules.mk index ff7840e7fe3..abda74fcaaa 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -37,8 +37,11 @@ SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ # SFNT driver headers # -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR)/sferrors.h +# Note that ttsbit0.c gets #included by ttsbit.c. +# +SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ + $(SFNT_DIR)/sferrors.h \ + $(SFNT_DIR)/ttsbit0.c # SFNT driver object(s) diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c index 5ba22a6c51c..1d157b7e9d6 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,12 +17,14 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H #include "sfdriver.h" #include "ttload.h" #include "sfobjs.h" +#include "sfntpic.h" #include "sferrors.h" @@ -48,6 +50,15 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_TT_CMAP_H + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfdriver + /* * SFNT TABLE SERVICE @@ -103,27 +114,28 @@ sfnt_table_info( TT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ) { - if ( !tag || !length ) + if ( !tag || !offset || !length ) return SFNT_Err_Invalid_Argument; if ( idx >= face->num_tables ) return SFNT_Err_Table_Missing; *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; *length = face->dir_tables[idx].Length; return SFNT_Err_Ok; } - static const FT_Service_SFNT_TableRec sfnt_service_sfnt_table = - { + FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table, (FT_SFNT_TableLoadFunc)tt_face_load_any, (FT_SFNT_TableGetFunc) get_sfnt_table, (FT_SFNT_TableInfoFunc)sfnt_table_info - }; + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -151,11 +163,43 @@ } - static const FT_Service_GlyphDictRec sfnt_service_glyph_dict = + static FT_UInt + sfnt_get_name_index( TT_Face face, + FT_String* glyph_name ) { + FT_Face root = &face->root; + FT_UInt i, max_gid = FT_UINT_MAX; + + + if ( root->num_glyphs < 0 ) + return 0; + else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX ) + max_gid = ( FT_UInt ) root->num_glyphs; + else + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); + + for ( i = 0; i < max_gid; i++ ) + { + FT_String* gname; + FT_Error error = tt_face_get_ps_name( face, i, &gname ); + + + if ( error ) + continue; + + if ( !ft_strcmp( glyph_name, gname ) ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict, (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)NULL - }; + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -275,19 +319,17 @@ return result; } - static const FT_Service_PsFontNameRec sfnt_service_ps_name = - { + FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name, (FT_PsName_GetFunc)sfnt_get_ps_name - }; + ) /* * TT CMAP INFO */ - static const FT_Service_TTCMapsRec tt_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info, (TT_CMap_Info_GetFunc)tt_get_cmap_info - }; + ) #ifdef TT_CONFIG_OPTION_BDF @@ -328,11 +370,10 @@ } - static const FT_Service_BDFRec sfnt_service_bdf = - { + FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf, (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop, - }; + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -341,29 +382,46 @@ * SERVICE LIST */ - static const FT_ServiceDescRec sfnt_services[] = - { - { FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name }, -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, +#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC5(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) #endif -#ifdef TT_CONFIG_OPTION_BDF - { FT_SERVICE_ID_BDF, &sfnt_service_bdf }, -#endif - { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, - - { NULL, NULL } - }; FT_CALLBACK_DEF( FT_Module_Interface ) sfnt_get_interface( FT_Module module, const char* module_interface ) { + FT_Library library = module->library; + FT_UNUSED(library); FT_UNUSED( module ); - return ft_service_list_lookup( sfnt_services, module_interface ); + return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); } @@ -494,10 +552,18 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS(a) a +#else +#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES(a) a +#else +#define PUT_PS_NAMES(a) 0 +#endif - static - const SFNT_Interface sfnt_interface = - { + FT_DEFINE_SFNT_INTERFACE(sfnt_interface, tt_face_goto_table, sfnt_init_face, @@ -507,10 +573,8 @@ tt_face_load_any, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_sfnt_header_stub, - tt_face_load_directory_stub, -#endif + tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_head, tt_face_load_hhea, @@ -522,53 +586,32 @@ tt_face_load_name, tt_face_free_name, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_hdmx_stub, - tt_face_free_hdmx_stub, -#endif + tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_kern, tt_face_load_gasp, tt_face_load_pclt, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttload.h' */ - tt_face_load_bhed, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_bhed), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_set_sbit_strike_stub, - tt_face_load_sbit_stub, + tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_find_sbit_image, - tt_load_sbit_metrics, -#endif + tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_face_load_sbit_image, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_free_sbit_stub, -#endif + tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES /* see `ttpost.h' */ - tt_face_get_ps_name, - tt_face_free_ps_names, -#else - 0, - 0, -#endif + PUT_PS_NAMES(tt_face_get_ps_name), + PUT_PS_NAMES(tt_face_free_ps_names), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_charmap_stub, - tt_face_free_charmap_stub, -#endif + tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* since version 2.1.8 */ @@ -579,27 +622,19 @@ tt_face_load_font_dir, tt_face_load_hmtx, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttsbit.h' and `sfnt.h' */ - tt_face_load_eblc, - tt_face_free_eblc, + PUT_EMBEDDED_BITMAPS(tt_face_load_eblc), + PUT_EMBEDDED_BITMAPS(tt_face_free_eblc), - tt_face_set_sbit_strike, - tt_face_load_strike_metrics, -#else - 0, - 0, - 0, - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike), + PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics), tt_face_get_metrics - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class sfnt_module_class = - { + FT_DEFINE_MODULE(sfnt_module_class, + 0, /* not a font driver or renderer */ sizeof( FT_ModuleRec ), @@ -607,12 +642,12 @@ 0x10000L, /* driver version 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or higher */ - (const void*)&sfnt_interface, /* module specific interface */ + (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) sfnt_get_interface - }; + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.h b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.h index 92db79694d0..5de25d51ca4 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.h +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; + FT_DECLARE_MODULE( sfnt_module_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfnt.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfnt.c index 45a820b718d..fc507b49613 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfnt.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfnt.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "sfntpic.c" #include "ttload.c" #include "ttmtx.c" #include "ttcmap.c" diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.c new file mode 100644 index 00000000000..fd3cf4e923e --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*); + void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*); + void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*); + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**); + void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*); + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + if(container->sfnt_services) + FT_Destroy_Class_sfnt_services(library, container->sfnt_services); + container->sfnt_services = NULL; + if(container->tt_cmap_classes) + FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes); + container->tt_cmap_classes = NULL; + FT_FREE( container ); + pic_container->sfnt = NULL; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->sfnt = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_sfnt_services(library, &container->sfnt_services); + if(error) + goto Exit; + error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes); + if(error) + goto Exit; + FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); + FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); + FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); + FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); +#endif + FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); + +Exit: + if(error) + sfnt_module_class_pic_free(library); + return error; + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.h b/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.h new file mode 100644 index 00000000000..6943b4250a2 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfntpic.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + #ifndef FT_CONFIG_OPTION_PIC +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict +#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name +#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes +#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table +#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf +#define FT_SFNT_INTERFACE_GET sfnt_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +/* some include files required for members of sfntModulePIC */ +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include "ttcmap.h" + +typedef struct sfntModulePIC_ + { + FT_ServiceDescRec* sfnt_services; + FT_Service_GlyphDictRec sfnt_service_glyph_dict; + FT_Service_PsFontNameRec sfnt_service_ps_name; + FT_Service_TTCMapsRec tt_service_get_cmap_info; + TT_CMap_Class* tt_cmap_classes; + FT_Service_SFNT_TableRec sfnt_service_sfnt_table; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + SFNT_Interface sfnt_interface; + } sfntModulePIC; + +#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt)) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict) +#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name) +#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes) +#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table) +#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf) +#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c index cc901100d1d..cef3cd959e4 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -123,14 +123,20 @@ /* */ /* nameid :: The name id of the name record to return. */ /* */ - /* <Return> */ - /* Character string. NULL if no name is present. */ + /* <InOut> */ + /* name :: The address of a string pointer. NULL if no name is */ + /* present. */ /* */ - static FT_String* - tt_face_get_name( TT_Face face, - FT_UShort nameid ) + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ) { FT_Memory memory = face->root.memory; + FT_Error error = SFNT_Err_Ok; FT_String* result = NULL; FT_UShort n; TT_NameEntryRec* rec; @@ -145,6 +151,8 @@ TT_NameEntry_ConvertFunc convert; + FT_ASSERT( name ); + rec = face->name_table.names; for ( n = 0; n < face->num_names; n++, rec++ ) { @@ -256,11 +264,8 @@ { if ( rec->string == NULL ) { - FT_Error error = SFNT_Err_Ok; FT_Stream stream = face->name_table.stream; - FT_UNUSED( error ); - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || FT_STREAM_SEEK( rec->stringOffset ) || @@ -277,7 +282,8 @@ } Exit: - return result; + *name = result; + return error; } @@ -285,7 +291,7 @@ sfnt_find_encoding( int platform_id, int encoding_id ) { - typedef struct TEncoding + typedef struct TEncoding_ { int platform_id; int encoding_id; @@ -363,11 +369,12 @@ if ( FT_READ_ULONG( tag ) ) return error; - if ( tag != 0x00010000UL && - tag != TTAG_ttcf && - tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) && - tag != TTAG_true && - tag != 0x00020000UL ) + if ( tag != 0x00010000UL && + tag != TTAG_ttcf && + tag != TTAG_OTTO && + tag != TTAG_true && + tag != TTAG_typ1 && + tag != 0x00020000UL ) return SFNT_Err_Unknown_File_Format; face->ttc_header.tag = TTAG_ttcf; @@ -401,7 +408,7 @@ face->ttc_header.version = 1 << 16; face->ttc_header.count = 1; - if ( FT_NEW( face->ttc_header.offsets) ) + if ( FT_NEW( face->ttc_header.offsets ) ) return error; face->ttc_header.offsets[0] = offset; @@ -451,7 +458,7 @@ face_index = 0; if ( face_index >= face->ttc_header.count ) - return SFNT_Err_Bad_Argument; + return SFNT_Err_Invalid_Argument; if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; @@ -461,7 +468,8 @@ if ( error ) return error; - face->root.num_faces = face->ttc_header.count; + face->root.num_faces = face->ttc_header.count; + face->root.face_index = face_index; return error; } @@ -498,6 +506,13 @@ FT_TRACE3(( "\n" )); \ } while ( 0 ) +#define GET_NAME( id, field ) \ + do { \ + error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \ + if ( error ) \ + goto Exit; \ + } while ( 0 ) + FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, @@ -506,7 +521,10 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error, psnames_error; + FT_Error error; +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Error psnames_error; +#endif FT_Bool has_outline; FT_Bool is_apple_sbit; @@ -581,7 +599,10 @@ /* don't check for errors */ LOAD_( name ); LOAD_( post ); + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES psnames_error = error; +#endif /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ @@ -660,19 +681,20 @@ face->os2.version = 0xFFFFU; } - } /* the optional tables */ - /* embedded bitmap support. */ + /* embedded bitmap support */ if ( sfnt->load_eblc ) { LOAD_( eblc ); if ( error ) { - /* return an error if this font file has no outlines */ - if ( error == SFNT_Err_Table_Missing && has_outline ) + /* a font which contains neither bitmaps nor outlines is */ + /* still valid (although rather useless in most cases); */ + /* however, you can find such stripped fonts in PDFs */ + if ( error == SFNT_Err_Table_Missing ) error = SFNT_Err_Ok; else goto Exit; @@ -692,26 +714,43 @@ LOAD_( gasp ); LOAD_( kern ); - error = SFNT_Err_Ok; - face->root.num_glyphs = face->max_profile.numGlyphs; - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_FAMILY ); - if ( !face->root.family_name ) - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_FONT_FAMILY ); + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag has been introduced in version */ + /* 1.5 of the OpenType specification (May 2008). */ - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_SUBFAMILY ); - if ( !face->root.style_name ) - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_FONT_SUBFAMILY ); + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) + { + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + else + { + GET_NAME( WWS_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Long flags = root->face_flags; /*********************************************************************/ @@ -727,7 +766,7 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( psnames_error == SFNT_Err_Ok && + if ( psnames_error == SFNT_Err_Ok && face->postscript.FormatType != 0x00030000L ) flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif @@ -759,19 +798,26 @@ /* */ /* Compute style flags. */ /* */ + flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { - /* we have an OS/2 table; use the `fsSelection' field */ - if ( face->os2.fsSelection & 1 ) + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag has been */ + /* introduced in version 1.5 of the OpenType specification. */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ flags |= FT_STYLE_FLAG_ITALIC; - if ( face->os2.fsSelection & 32 ) + if ( face->os2.fsSelection & 32 ) /* bit 5 */ flags |= FT_STYLE_FLAG_BOLD; } else { /* this is an old Mac font, use the header field */ + if ( face->header.Mac_Style & 1 ) flags |= FT_STYLE_FLAG_BOLD; @@ -816,12 +862,78 @@ } } +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. + */ + { + FT_UInt i, count; + + +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + count = face->sbit_num_strikes; +#else + count = (FT_UInt)face->num_sbit_strikes; +#endif + + if ( count > 0 ) + { + FT_Memory memory = face->root.stream->memory; + FT_UShort em_size = face->header.Units_Per_EM; + FT_Short avgwidth = face->os2.xAvgCharWidth; + FT_Size_Metrics metrics; + + + if ( em_size == 0 || face->os2.version == 0xFFFFU ) + { + avgwidth = 0; + em_size = 1; + } + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + for ( i = 0; i < count; i++ ) + { + FT_Bitmap_Size* bsize = root->available_sizes + i; + + + error = sfnt->load_strike_metrics( face, i, &metrics ); + if ( error ) + goto Exit; + + bsize->height = (FT_Short)( metrics.height >> 6 ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + + bsize->x_ppem = metrics.x_ppem << 6; + bsize->y_ppem = metrics.y_ppem << 6; + + /* assume 72dpi */ + bsize->size = metrics.y_ppem << 6; + } + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)count; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* a font with no bitmaps and no outlines is scalable; */ + /* it has only empty glyphs then */ + if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) + root->face_flags |= FT_FACE_FLAG_SCALABLE; + /*********************************************************************/ /* */ /* Set up metrics. */ /* */ - if ( has_outline == TRUE ) + if ( FT_IS_SCALABLE( root ) ) { /* XXX What about if outline header is missing */ /* (e.g. sfnt wrapped bitmap)? */ @@ -874,10 +986,9 @@ /* this computation is based on various versions of Times New Roman */ if ( face->horizontal.Line_Gap == 0 ) root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); -#endif +#endif /* 0 */ #if 0 - /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ if ( face->os2.version != 0xFFFFU && root->ascender ) @@ -892,80 +1003,21 @@ if ( height > root->height ) root->height = height; } - #endif /* 0 */ - root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); - - root->underline_position = face->postscript.underlinePosition; + /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; root->underline_thickness = face->postscript.underlineThickness; } -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* - * Now allocate the root array of FT_Bitmap_Size records and - * populate them. Unfortunately, it isn't possible to indicate bit - * depths in the FT_Bitmap_Size record. This is a design error. - */ - { - FT_UInt i, count; - - -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS - count = face->sbit_num_strikes; -#else - count = (FT_UInt)face->num_sbit_strikes; -#endif - - if ( count > 0 ) - { - FT_Memory memory = face->root.stream->memory; - FT_UShort em_size = face->header.Units_Per_EM; - FT_Short avgwidth = face->os2.xAvgCharWidth; - FT_Size_Metrics metrics; - - - if ( em_size == 0 || face->os2.version == 0xFFFFU ) - { - avgwidth = 0; - em_size = 1; - } - - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) - goto Exit; - - for ( i = 0; i < count; i++ ) - { - FT_Bitmap_Size* bsize = root->available_sizes + i; - - - error = sfnt->load_strike_metrics( face, i, &metrics ); - if ( error ) - goto Exit; - - bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); - - bsize->x_ppem = metrics.x_ppem << 6; - bsize->y_ppem = metrics.y_ppem << 6; - - /* assume 72dpi */ - bsize->size = metrics.y_ppem << 6; - } - - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - } Exit: @@ -977,15 +1029,22 @@ #undef LOAD_ #undef LOADM_ +#undef GET_NAME FT_LOCAL_DEF( void ) sfnt_done_face( TT_Face face ) { - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + FT_Memory memory; + SFNT_Service sfnt; + if ( !face ) + return; + + memory = face->root.memory; + sfnt = (SFNT_Service)face->sfnt; + if ( sfnt ) { /* destroy the postscript names table if it is loaded */ @@ -1023,7 +1082,7 @@ } /* freeing the horizontal metrics */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS { FT_Stream stream = FT_FACE_STREAM( face ); @@ -1051,7 +1110,8 @@ face->gasp.numRanges = 0; /* freeing the name table */ - sfnt->free_name( face ); + if ( sfnt ) + sfnt->free_name( face ); /* freeing family and style name */ FT_FREE( face->root.family_name ); diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttbdf.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttbdf.c index 6c95387adb8..206cecee5ed 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttbdf.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttbdf.c @@ -84,7 +84,7 @@ FT_Byte* p = bdf->table; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_UInt32 strings = FT_NEXT_ULONG ( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); FT_UInt count; FT_Byte* strike; @@ -141,13 +141,13 @@ const char* property_name, BDF_PropertyRec *aprop ) { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; - FT_Error error = 0; - FT_Byte* p; - FT_UInt count; - FT_Byte* strike; - FT_UInt property_len; + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = 0; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; aprop->type = BDF_PROPERTY_TYPE_NONE; diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c index 2da43360eb6..26ea83c16c8 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include FT_INTERNAL_STREAM_H #include "ttload.h" #include "ttcmap.h" +#include "sfntpic.h" /*************************************************************************/ @@ -39,11 +40,13 @@ #define TT_PEEK_SHORT FT_PEEK_SHORT #define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_UINT24 FT_PEEK_UOFF3 #define TT_PEEK_LONG FT_PEEK_LONG #define TT_PEEK_ULONG FT_PEEK_ULONG #define TT_NEXT_SHORT FT_NEXT_SHORT #define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_UINT24 FT_NEXT_UOFF3 #define TT_NEXT_LONG FT_NEXT_LONG #define TT_NEXT_ULONG FT_NEXT_ULONG @@ -122,7 +125,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap0_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -132,7 +135,7 @@ FT_UInt gindex = 0; - table += 6; /* go to glyph ids */ + table += 6; /* go to glyph IDs */ while ( ++charcode < 256 ) { gindex = table[charcode]; @@ -155,28 +158,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 0; + cmap_info->format = 0; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap0_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap0_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap0_char_next, + + NULL, NULL, NULL, NULL, NULL + , 0, (TT_CMap_ValidateFunc) tt_cmap0_validate, (TT_CMap_Info_GetFunc) tt_cmap0_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -227,7 +229,7 @@ /* language 4 USHORT Mac language code */ /* keys 6 USHORT[256] sub-header keys */ /* subs 518 SUBHEAD[NSUBS] sub-headers array */ - /* glyph_ids 518+NSUB*8 USHORT[] glyph id array */ + /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ /* */ /* The `keys' table is used to map charcode high-bytes to sub-headers. */ /* The value of `NSUBS' is the number of sub-headers defined in the */ @@ -256,14 +258,14 @@ /* */ /* * The value of `offset' is read. This is a _byte_ distance from the */ /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it's a USHORT[] too). */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ /* */ /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ /* no glyph for the charcode. Otherwise, the value of `delta' is */ /* added to it (modulo 65536) to form a new glyph index. */ /* */ /* It is up to the validation routine to check that all offsets fall */ - /* within the glyph ids table (and not within the `subs' table itself or */ + /* within the glyph IDs table (and not within the `subs' table itself or */ /* outside of the CMap). */ /* */ @@ -278,7 +280,7 @@ FT_UInt n, max_subs; FT_Byte* keys; /* keys table */ FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph id array */ + FT_Byte* glyph_ids; /* glyph ID array */ if ( table + length > valid->limit || length < 6 + 512 ) @@ -324,6 +326,10 @@ delta = TT_NEXT_SHORT( p ); offset = TT_NEXT_USHORT( p ); + /* many Dynalab fonts have empty sub-headers */ + if ( code_count == 0 ) + continue; + /* check range within 0..255 */ if ( valid->level >= FT_VALIDATE_PARANOID ) { @@ -338,7 +344,7 @@ if ( ids < glyph_ids || ids + code_count*2 > table + length ) FT_INVALID_OFFSET; - /* check glyph ids */ + /* check glyph IDs */ if ( valid->level >= FT_VALIDATE_TIGHT ) { FT_Byte* limit = p + code_count * 2; @@ -389,7 +395,7 @@ sub = subs; /* jump to first sub-header */ /* check that the sub-header for this byte is 0, which */ - /* indicates that it's really a valid one-byte value */ + /* indicates that it is really a valid one-byte value */ /* Otherwise, return 0 */ /* */ p += char_lo * 2; @@ -454,7 +460,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap2_char_next( TT_CMap cmap, FT_UInt32 *pcharcode ) { @@ -528,28 +534,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 2; + cmap_info->format = 2; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap2_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap2_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap2_char_next, + + NULL, NULL, NULL, NULL, NULL + , 2, (TT_CMap_ValidateFunc) tt_cmap2_validate, (TT_CMap_Info_GetFunc) tt_cmap2_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -595,14 +600,14 @@ /* each segment; can be */ /* zero */ /* */ - /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph id */ + /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ /* ranges */ /* */ /* Character codes are modelled by a series of ordered (increasing) */ /* intervals called segments. Each segment has start and end codes, */ /* provided by the `startCount' and `endCount' arrays. Segments must */ - /* not be overlapping and the last segment should always contain the */ - /* `0xFFFF' endCount. */ + /* not overlap, and the last segment should always contain the value */ + /* 0xFFFF for `endCount'. */ /* */ /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ /* ignored (they are traces of over-engineering in the TrueType */ @@ -615,14 +620,14 @@ /* charcode within the segment is obtained by adding the value of */ /* `idDelta' directly to the charcode, modulo 65536. */ /* */ - /* Otherwise, a glyph index is taken from the glyph ids sub-array for */ + /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ /* the segment, and the value of `idDelta' is added to it. */ /* */ /* */ - /* Finally, note that certain fonts contain invalid charmaps that */ - /* contain end=0xFFFF, start=0xFFFF, delta=0x0001, offset=0xFFFF at the */ - /* of their charmaps (e.g. opens___.ttf which comes with OpenOffice.org) */ - /* we need special code to deal with them correctly... */ + /* Finally, note that a lot of fonts contain an invalid last segment, */ + /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ + /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ + /* OpenOffice.org). We need special code to deal with them correctly. */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_4 @@ -654,7 +659,7 @@ p = table + 6; cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; return SFNT_Err_Ok; @@ -687,6 +692,23 @@ p += num_ranges * 2; offset = FT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( range_index >= num_ranges - 1 && + cmap->cur_start == 0xFFFFU && + cmap->cur_end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + cmap->cur_delta = 1; + offset = 0; + } + } + if ( offset != 0xFFFFU ) { cmap->cur_values = offset ? p + offset : NULL; @@ -715,7 +737,7 @@ if ( cmap->cur_charcode >= 0xFFFFUL ) goto Fail; - charcode = cmap->cur_charcode + 1; + charcode = (FT_UInt)cmap->cur_charcode + 1; if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; @@ -777,7 +799,7 @@ } Fail: - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; } @@ -825,7 +847,7 @@ /* */ if ( valid->level >= FT_VALIDATE_PARANOID ) { - /* check the values of 'searchRange', 'entrySelector', 'rangeShift' */ + /* check the values of `searchRange', `entrySelector', `rangeShift' */ FT_UInt search_range = TT_NEXT_USHORT( p ); FT_UInt entry_selector = TT_NEXT_USHORT( p ); FT_UInt range_shift = TT_NEXT_USHORT( p ); @@ -852,7 +874,7 @@ offsets = deltas + num_segs * 2; glyph_ids = offsets + num_segs * 2; - /* check last segment, its end count must be FFFF */ + /* check last segment; its end count value must be 0xFFFF */ if ( valid->level >= FT_VALIDATE_PARANOID ) { p = ends + ( num_segs - 1 ) * 2; @@ -861,9 +883,9 @@ } { - FT_UInt start, end, offset, n; - FT_UInt last_start = 0, last_end = 0; - FT_Int delta; + FT_UInt start, end, offset, n; + FT_UInt last_start = 0, last_end = 0; + FT_Int delta; FT_Byte* p_start = starts; FT_Byte* p_end = ends; FT_Byte* p_delta = deltas; @@ -881,10 +903,10 @@ if ( start > end ) FT_INVALID_DATA; - /* this test should be performed at default validation level; */ - /* unfortunately, some popular Asian fonts present overlapping */ - /* ranges in their charmaps */ - /* */ + /* this test should be performed at default validation level; */ + /* unfortunately, some popular Asian fonts have overlapping */ + /* ranges in their charmaps */ + /* */ if ( start <= last_end && n > 0 ) { if ( valid->level >= FT_VALIDATE_TIGHT ) @@ -892,7 +914,7 @@ else { /* allow overlapping segments, provided their start points */ - /* and end points, respectively, are in ascending order. */ + /* and end points, respectively, are in ascending order */ /* */ if ( last_start > start || last_end > end ) error |= TT_CMAP_FLAG_UNSORTED; @@ -903,16 +925,27 @@ if ( offset && offset != 0xFFFFU ) { - p += offset; /* start of glyph id array */ + p += offset; /* start of glyph ID array */ - /* check that we point within the glyph ids table only */ + /* check that we point within the glyph IDs table only */ if ( valid->level >= FT_VALIDATE_TIGHT ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > table + length ) FT_INVALID_DATA; } - else + /* Some fonts handle the last segment incorrectly. In */ + /* theory, 0xFFFF might point to an ordinary glyph -- */ + /* a cmap 4 is versatile and could be used for any */ + /* encoding, not only Unicode. However, reality shows */ + /* that far too many fonts are sloppy and incorrectly */ + /* set all fields but `start' and `end' for the last */ + /* segment if it contains only a single character. */ + /* */ + /* We thus omit the test here, delaying it to the */ + /* routines which actually access the cmap. */ + else if ( n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > valid->limit ) @@ -940,12 +973,12 @@ } else if ( offset == 0xFFFFU ) { - /* Some fonts (erroneously?) use a range offset of 0xFFFF */ + /* some fonts (erroneously?) use a range offset of 0xFFFF */ /* to mean missing glyph in cmap table */ /* */ - if ( valid->level >= FT_VALIDATE_PARANOID || - n != num_segs - 1 || - !( start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) ) + if ( valid->level >= FT_VALIDATE_PARANOID || + n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) FT_INVALID_DATA; } @@ -959,9 +992,9 @@ static FT_UInt - tt_cmap4_char_map_linear( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_linear( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; @@ -1003,6 +1036,22 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + if ( offset == 0xFFFFU ) continue; @@ -1032,14 +1081,14 @@ static FT_UInt - tt_cmap4_char_map_binary( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_binary( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; - FT_UInt charcode = *pcharcode; + FT_UInt charcode = (FT_UInt)*pcharcode; FT_UInt gindex = 0; FT_Byte* p; @@ -1082,6 +1131,22 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( mid >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + /* search the first segment containing `charcode' */ if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) { @@ -1265,7 +1330,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap4_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1305,27 +1370,26 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 4; + cmap_info->format = 4; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap4_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap4_class_rec, sizeof ( TT_CMap4Rec ), (FT_CMap_InitFunc) tt_cmap4_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap4_char_next, + + NULL, NULL, NULL, NULL, NULL + , 4, (TT_CMap_ValidateFunc) tt_cmap4_validate, (TT_CMap_Info_GetFunc) tt_cmap4_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1351,7 +1415,7 @@ /* */ /* first 6 USHORT first segment code */ /* count 8 USHORT segment size in chars */ - /* glyphIds 10 USHORT[count] glyph ids */ + /* glyphIds 10 USHORT[count] glyph IDs */ /* */ /* A very simplified segment mapping. */ /* */ @@ -1417,7 +1481,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap6_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1465,28 +1529,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 6; + cmap_info->format = 6; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap6_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap6_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap6_char_next, + + NULL, NULL, NULL, NULL, NULL + , 6, (TT_CMap_ValidateFunc) tt_cmap6_validate, (TT_CMap_Info_GetFunc) tt_cmap6_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1496,7 +1559,7 @@ /***** *****/ /***** FORMAT 8 *****/ /***** *****/ - /***** It's hard to completely understand what the OpenType spec *****/ + /***** It is hard to completely understand what the OpenType spec *****/ /***** says about this format, but here is my conclusion. *****/ /***** *****/ /***** The purpose of this format is to easily map UTF-16 text to *****/ @@ -1511,7 +1574,7 @@ /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ /***** Area. *****/ /***** *****/ - /***** The 'is32' table embedded in the charmap indicates whether a *****/ + /***** The `is32' table embedded in the charmap indicates whether a *****/ /***** given 16-bit value is in the surrogates area or not. *****/ /***** *****/ /***** So, for any given `char_code', we can assert the following: *****/ @@ -1538,11 +1601,11 @@ /* is32 12 BYTE[8192] 32-bitness bitmap */ /* count 8204 ULONG number of groups */ /* */ - /* This header is followed by 'count' groups of the following format: */ + /* This header is followed by `count' groups of the following format: */ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph id for the group */ + /* startId 8 ULONG start glyph ID for the group */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_8 @@ -1561,7 +1624,7 @@ FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 8208 ) + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) FT_INVALID_TOO_SHORT; is32 = table + 12; @@ -1671,7 +1734,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1719,28 +1782,27 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 8; + cmap_info->format = 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap8_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap8_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap8_char_next, + + NULL, NULL, NULL, NULL, NULL + , 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, (TT_CMap_Info_GetFunc) tt_cmap8_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1787,7 +1849,8 @@ p = table + 16; count = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 20 + count * 2 ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1829,7 +1892,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap10_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1868,28 +1931,27 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 10; + cmap_info->format = 10; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap10_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap10_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap10_char_next, + + NULL, NULL, NULL, NULL, NULL + , 10, (TT_CMap_ValidateFunc) tt_cmap10_validate, (TT_CMap_Info_GetFunc) tt_cmap10_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -1920,7 +1982,7 @@ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph id for the group */ + /* startId 8 ULONG start glyph ID for the group */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_12 @@ -1970,7 +2032,8 @@ p = table + 12; num_groups = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 16 + 12 * num_groups ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2039,7 +2102,7 @@ if ( gindex ) { - cmap->cur_charcode = char_code; + cmap->cur_charcode = char_code;; cmap->cur_gindex = gindex; cmap->cur_group = n; @@ -2147,7 +2210,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap12_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2165,8 +2228,10 @@ if ( cmap12->valid ) { gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2174,7 +2239,8 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - return gindex; + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; } @@ -2185,7 +2251,323 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 12; + cmap_info->format = 12; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap12_class_rec, + sizeof ( TT_CMap12Rec ), + + (FT_CMap_InitFunc) tt_cmap12_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, + (FT_CMap_CharNextFunc) tt_cmap12_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 12, + (TT_CMap_ValidateFunc) tt_cmap12_validate, + (TT_CMap_Info_GetFunc) tt_cmap12_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_12 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; @@ -2193,58 +2575,814 @@ FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap12_class_rec = + const TT_CMap_ClassRec tt_cmap13_class_rec = { { - sizeof ( TT_CMap12Rec ), + sizeof ( TT_CMap13Rec ), - (FT_CMap_InitFunc) tt_cmap12_init, + (FT_CMap_InitFunc) tt_cmap13_init, (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, + (FT_CMap_CharNextFunc) tt_cmap13_char_next, + + NULL, NULL, NULL, NULL, NULL }, - 12, - (TT_CMap_ValidateFunc) tt_cmap12_validate, - (TT_CMap_Info_GetFunc) tt_cmap12_get_info + 13, + (TT_CMap_ValidateFunc) tt_cmap13_validate, + (TT_CMap_Info_GetFunc) tt_cmap13_get_info }; +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ -#endif /* TT_CONFIG_CMAP_FORMAT_12 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 14 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 14 */ + /* length 2 ULONG table length in bytes */ + /* numSelector 6 ULONG number of variation sel. records */ + /* */ + /* Followed by numSelector records, each of which looks like */ + /* */ + /* varSelector 0 UINT24 Unicode codepoint of sel. */ + /* defaultOff 3 ULONG offset to a default UVS table */ + /* describing any variants to be found in */ + /* the normal Unicode subtable. */ + /* nonDefOff 7 ULONG offset to a non-default UVS table */ + /* describing any variants not in the */ + /* standard cmap, with GIDs here */ + /* (either offset may be 0 NULL) */ + /* */ + /* Selectors are sorted by code point. */ + /* */ + /* A default Unicode Variation Selector (UVS) subtable is just a list of */ + /* ranges of code points which are to be found in the standard cmap. No */ + /* glyph IDs (GIDs) here. */ + /* */ + /* numRanges 0 ULONG number of ranges following */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* additionalCnt 3 UBYTE count of additional characters in this */ + /* range (zero means a range of a single */ + /* character) */ + /* */ + /* Ranges are sorted by `uniStart'. */ + /* */ + /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ + /* mappings from codepoint to GID. */ + /* */ + /* numMappings 0 ULONG number of mappings */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* GID 3 USHORT and its GID */ + /* */ + /* Ranges are sorted by `uniStart'. */ + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + + typedef struct TT_CMap14Rec_ + { + TT_CMapRec cmap; + FT_ULong num_selectors; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt32 max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt32 num_results, + FT_Memory memory ) + { + FT_UInt32 old_max = cmap->max_results; + FT_Error error = 0; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_init( TT_CMap14 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 6; + cmap->num_selectors = FT_PEEK_ULONG( table ); + cmap->max_results = 0; + cmap->results = NULL; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_ULong length = TT_NEXT_ULONG( p ); + FT_ULong num_selectors = TT_NEXT_ULONG( p ); + + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) + FT_INVALID_TOO_SHORT; + + /* check selectors, they must be in increasing order */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* check the default table (these glyphs should be reached */ + /* through the normal Unicode cmap, no GIDs, just check order) */ + if ( defOff != 0 ) + { + FT_Byte* defp = table + defOff; + FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_ULong i; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* and the non-default table (these glyphs are specified here) */ + if ( nondefOff != 0 ) { + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings = TT_NEXT_ULONG( ndp ); + FT_ULong i, lastUni = 0; + + + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + if ( valid->level >= FT_VALIDATE_TIGHT && + gid >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UNUSED( cmap ); + FT_UNUSED( char_code ); + + /* This can't happen */ + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap14_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UNUSED( cmap ); + + /* This can't happen */ + *pchar_code = 0; + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_UNUSED( cmap ); + + cmap_info->format = 14; + /* subtable 14 does not define a language field */ + cmap_info->language = 0xFFFFFFFFUL; + + return SFNT_Err_Ok; + } + + + static FT_UInt + tt_cmap14_char_map_def_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt cnt = FT_NEXT_BYTE( p ); + + + if ( char_code < start ) + max = mid; + else if ( char_code > start+cnt ) + min = mid + 1; + else + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + tt_cmap14_char_map_nondef_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong varSel = TT_NEXT_UINT24( p ); + + + if ( variantCode < varSel ) + max = mid; + else if ( variantCode > varSel ) + min = mid + 1; + else + return p; + } + + return NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return 0; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_PEEK_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + { + /* This is the default variant of this charcode. GID not stored */ + /* here; stored in the normal Unicode charmap instead. */ + return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + } + + if ( nondefOff != 0 ) + return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ); + + return 0; + } + + + FT_CALLBACK_DEF( FT_Int ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return -1; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + return 1; + + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ) != 0 ) + return 0; + + return -1; + } + + + FT_CALLBACK_DEF( FT_UInt32* ) + tt_cmap14_variants( TT_CMap cmap, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14)cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt32 i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_char_variants( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 charCode ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charCode ) != 0 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first `cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt32* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + for ( i = 0; i < numMappings; ++i ) + { + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + ret[i] = 0; + + return ret; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_variant_chars( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 variantSelector ) + { + FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, + variantSelector ); + FT_UInt32 *ret; + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return NULL; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff == 0 && nondefOff == 0 ) + return NULL; + + if ( defOff == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + else + { + /* Both a default and a non-default glyph set? That's probably not */ + /* good font design, but the spec allows for it... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + p = cmap->data + nondefOff; + dp = cmap->data + defOff; + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + dcnt = tt_cmap14_def_char_count( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); + + if ( numMappings == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + di = 1; + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ni = 1; + i = 0; + + for ( ;; ) + { + if ( nuni > duni + dcnt ) + { + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + ++di; + + if ( di > numRanges ) + break; + + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + else + { + if ( nuni < duni ) + ret[i++] = nuni; + /* If it is within the default range then ignore it -- */ + /* that should not have happened */ + ++ni; + if ( ni > numMappings ) + break; + + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + } + + if ( ni <= numMappings ) + { + /* If we get here then we have run out of all default ranges. */ + /* We have read one non-default mapping which we haven't stored */ + /* and there may be others that need to be read. */ + ret[i++] = nuni; + while ( ni < numMappings ) + { + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ++ni; + } + } + else if ( di <= numRanges ) + { + /* If we get here then we have run out of all non-default */ + /* mappings. We have read one default range which we haven't */ + /* stored and there may be others that need to be read. */ + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + while ( di < numRanges ) + { + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + ++di; + } + } + + ret[i] = 0; + + return ret; + } + } + + + FT_DEFINE_TT_CMAP(tt_cmap14_class_rec, + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, + (FT_CMap_DoneFunc) tt_cmap14_done, + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, + (FT_CMap_CharNextFunc) tt_cmap14_char_next, + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars + , + 14, + (TT_CMap_ValidateFunc)tt_cmap14_validate, + (TT_CMap_Info_GetFunc)tt_cmap14_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_14 */ + + +#ifndef FT_CONFIG_OPTION_PIC static const TT_CMap_Class tt_cmap_classes[] = { -#ifdef TT_CONFIG_CMAP_FORMAT_0 - &tt_cmap0_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_2 - &tt_cmap2_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_4 - &tt_cmap4_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_6 - &tt_cmap6_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_8 - &tt_cmap8_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_10 - &tt_cmap10_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_12 - &tt_cmap12_class_rec, -#endif - +#define TTCMAPCITEM(a) &a, +#include "ttcmapc.h" NULL, }; +#else /*FT_CONFIG_OPTION_PIC*/ + + void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class) + { + TT_CMap_Class* clazz; + TT_CMap_ClassRec* recs; + FT_Error error; + FT_Memory memory = library->memory; + int i = 0; + +#define TTCMAPCITEM(a) i++; +#include "ttcmapc.h" + + /* allocate enough space for both the pointers +terminator and the class instances */ + if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) ) + return error; + + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); + i=0; + +#undef TTCMAPCITEM +#define TTCMAPCITEM(a) \ + FT_Init_Class_##a(&recs[i]); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" + + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ + /* parse the `cmap' table and build the corresponding TT_CMap objects */ /* in the current face */ @@ -2256,6 +3394,8 @@ FT_Byte* limit = table + face->cmap_size; FT_UInt volatile num_cmaps; FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY(face); + FT_UNUSED(library); if ( p + 4 > limit ) @@ -2265,7 +3405,8 @@ if ( TT_NEXT_USHORT( p ) != 0 ) { p -= 2; - FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); return SFNT_Err_Invalid_Table; } @@ -2288,7 +3429,7 @@ { FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = tt_cmap_classes; + const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET; TT_CMap_Class volatile clazz; @@ -2318,6 +3459,10 @@ FT_CMap ttcmap; + /* It might make sense to store the single variation selector */ + /* cmap somewhere special. But it would have to be in the */ + /* public FT_FaceRec, and we can't change that. */ + if ( !FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, &ttcmap ) ) { @@ -2328,12 +3473,18 @@ } else { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " broken cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); } break; } } + + if ( *pclazz == NULL ) + { + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); + } } } diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.h b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.h index a10a3e2502c..15a4a21e500 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.h +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.h @@ -55,6 +55,46 @@ FT_BEGIN_HEADER } TT_CMap_ClassRec; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + FT_CALLBACK_TABLE_DEF \ + const TT_CMap_ClassRec class_ = \ + { \ + {size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_}, \ + format_, validate_, get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \ + { \ + clazz->clazz.size = size_; \ + clazz->clazz.init = init_; \ + clazz->clazz.done = done_; \ + clazz->clazz.char_index = char_index_; \ + clazz->clazz.char_next = char_next_; \ + clazz->clazz.char_var_index = char_var_index_; \ + clazz->clazz.char_var_default = char_var_default_; \ + clazz->clazz.variant_list = variant_list_; \ + clazz->clazz.charvariant_list = charvariant_list_; \ + clazz->clazz.variantchar_list = variantchar_list_; \ + clazz->format = format_; \ + clazz->validate = validate_; \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ typedef struct TT_ValidatorRec_ { diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmapc.h b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmapc.h new file mode 100644 index 00000000000..4c9c6a56f72 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmapc.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM(tt_cmap0_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM(tt_cmap2_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM(tt_cmap4_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM(tt_cmap6_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM(tt_cmap8_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM(tt_cmap10_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM(tt_cmap12_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM(tt_cmap13_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM(tt_cmap14_class_rec) +#endif + + /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttkern.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttkern.c index 28e52c333e8..c1540802b87 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttkern.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttkern.h" -#include "ttload.h" #include "sferrors.h" @@ -60,14 +59,16 @@ if ( table_size < 4 ) /* the case of a malformed table */ { - FT_ERROR(( "kerning table is too small - ignored\n" )); + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); error = SFNT_Err_Table_Missing; goto Exit; } if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) { - FT_ERROR(( "could not extract kerning table\n" )); + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); goto Exit; } @@ -86,7 +87,7 @@ { FT_UInt num_pairs, length, coverage; FT_Byte* p_next; - FT_UInt32 mask = 1UL << nn; + FT_UInt32 mask = (FT_UInt32)1UL << nn; if ( p + 6 > p_limit ) @@ -103,6 +104,9 @@ p_next += length; + if ( p_next > p_limit ) /* handle broken table */ + p_next = p_limit; + /* only use horizontal kerning tables */ if ( ( coverage & ~8 ) != 0x0001 || p + 8 > p_limit ) @@ -111,8 +115,8 @@ num_pairs = FT_NEXT_USHORT( p ); p += 6; - if ( p + 6 * num_pairs > p_limit ) - goto NextTable; + if ( ( p_next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); avail |= mask; @@ -122,8 +126,8 @@ */ if ( num_pairs > 0 ) { - FT_UInt count; - FT_UInt old_pair; + FT_ULong count; + FT_ULong old_pair; old_pair = FT_NEXT_ULONG( p ); @@ -181,18 +185,22 @@ FT_Int result = 0; FT_UInt count, mask = 1; FT_Byte* p = face->kern_table; + FT_Byte* p_limit = p + face->kern_table_size; p += 4; mask = 0x0001; - for ( count = face->num_kern_tables; count > 0; count--, mask <<= 1 ) + for ( count = face->num_kern_tables; + count > 0 && p + 6 <= p_limit; + count--, mask <<= 1 ) { FT_Byte* base = p; FT_Byte* next = base; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt length = FT_NEXT_USHORT( p ); FT_UInt coverage = FT_NEXT_USHORT( p ); + FT_UInt num_pairs; FT_Int value = 0; FT_UNUSED( version ); @@ -200,22 +208,28 @@ next = base + length; + if ( next > p_limit ) /* handle broken table */ + next = p_limit; + if ( ( face->kern_avail_bits & mask ) == 0 ) goto NextTable; if ( p + 8 > next ) goto NextTable; + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( next - p ) / 6 ); + switch ( coverage >> 8 ) { case 0: { - FT_UInt num_pairs = FT_NEXT_USHORT( p ); - FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); + FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); - p += 6; - if ( face->kern_order_bits & mask ) /* binary search */ { FT_UInt min = 0; diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c index abe0278a253..f08f6403983 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,6 +58,9 @@ { TT_Table entry; TT_Table limit; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool zero_length = FALSE; +#endif FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", @@ -72,17 +75,28 @@ for ( ; entry < limit; entry++ ) { - /* For compatibility with Windows, we consider 0-length */ - /* tables the same as missing tables. */ - if ( entry->Tag == tag && entry->Length != 0 ) - { - FT_TRACE4(( "found table.\n" )); - return entry; + /* For compatibility with Windows, we consider */ + /* zero-length tables the same as missing tables. */ + if ( entry->Tag == tag ) { + if ( entry->Length != 0 ) + { + FT_TRACE4(( "found table.\n" )); + return entry; + } +#ifdef FT_DEBUG_LEVEL_TRACE + zero_length = TRUE; +#endif } } - FT_TRACE4(( "could not find table!\n" )); - return 0; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( zero_length ) + FT_TRACE4(( "ignoring empty table\n" )); + else + FT_TRACE4(( "could not find table\n" )); +#endif + + return NULL; } @@ -124,7 +138,7 @@ *length = table->Length; if ( FT_STREAM_SEEK( table->Offset ) ) - goto Exit; + goto Exit; } else error = SFNT_Err_Table_Missing; @@ -134,27 +148,30 @@ } - /* Here, we */ - /* */ - /* - check that `num_tables' is valid */ - /* - look for a `head' table, check its size, and parse it to check */ - /* whether its `magic' field is correctly set */ - /* */ - /* When checking directory entries, ignore the tables `glyx' and `locx' */ - /* which are hacked-out versions of `glyf' and `loca' in some PostScript */ - /* Type 42 fonts, and which are generally invalid. */ - /* */ + /* Here, we */ + /* */ + /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* */ + /* - look for a `head' table, check its size, and parse it to check */ + /* whether its `magic' field is correctly set */ + /* */ + /* - errors (except errors returned by stream handling) */ + /* */ + /* SFNT_Err_Unknown_File_Format: */ + /* no table is defined in directory, it is not sfnt-wrapped */ + /* data */ + /* SFNT_Err_Table_Missing: */ + /* table directory is valid, but essential tables */ + /* (head/bhed/SING) are missing */ + /* */ static FT_Error check_table_dir( SFNT_Header sfnt, FT_Stream stream ) { - FT_Error error; - FT_UInt nn; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; - - const FT_ULong glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' ); - const FT_ULong locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' ); + FT_Error error; + FT_UInt nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; static const FT_Frame_Field table_dir_entry_fields[] = { @@ -170,12 +187,8 @@ }; - if ( sfnt->num_tables == 0 || - offset + sfnt->num_tables * 16 > stream->size ) - return SFNT_Err_Unknown_File_Format; - if ( FT_STREAM_SEEK( offset ) ) - return error; + goto Exit; for ( nn = 0; nn < sfnt->num_tables; nn++ ) { @@ -183,12 +196,23 @@ if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) - return error; + { + nn--; + FT_TRACE2(( "check_table_dir:" + " can read only %d table%s in font (instead of %d)\n", + nn, nn == 1 ? "" : "s", sfnt->num_tables )); + sfnt->num_tables = nn; + break; + } - if ( table.Offset + table.Length > stream->size && - table.Tag != glyx_tag && - table.Tag != locx_tag ) - return SFNT_Err_Unknown_File_Format; + /* we ignore invalid tables */ + if ( table.Offset + table.Length > stream->size ) + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + else + valid_entries++; if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) { @@ -210,17 +234,26 @@ * */ if ( table.Length < 0x36 ) - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + error = SFNT_Err_Table_Missing; + goto Exit; + } if ( FT_STREAM_SEEK( table.Offset + 12 ) || FT_READ_ULONG( magic ) ) - return error; + goto Exit; if ( magic != 0x5F0F3CF5UL ) - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir:" + " no magic number found in `head' table\n")); + error = SFNT_Err_Table_Missing; + goto Exit; + } if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) - return error; + goto Exit; } else if ( table.Tag == TTAG_SING ) has_sing = 1; @@ -228,11 +261,34 @@ has_meta = 1; } + sfnt->num_tables = valid_entries; + + if ( sfnt->num_tables == 0 ) + { + FT_TRACE2(( "check_table_dir: no tables found\n" )); + error = SFNT_Err_Unknown_File_Format; + goto Exit; + } + /* if `sing' and `meta' tables are present, there is no `head' table */ if ( has_head || ( has_sing && has_meta ) ) - return SFNT_Err_Ok; + { + error = SFNT_Err_Ok; + goto Exit; + } else - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir:" )); +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); +#else + FT_TRACE2(( " neither `head' nor `sing' table found\n" )); +#endif + error = SFNT_Err_Table_Missing; + } + + Exit: + return error; } @@ -266,7 +322,7 @@ FT_Error error; FT_Memory memory = stream->memory; TT_TableRec* entry; - TT_TableRec* limit; + FT_Int nn; static const FT_Frame_Field offset_table_fields[] = { @@ -290,7 +346,7 @@ if ( FT_READ_ULONG( sfnt.format_tag ) || FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) - return error; + goto Exit; /* many fonts don't have these fields set correctly */ #if 0 @@ -301,51 +357,59 @@ /* load the table directory */ - FT_TRACE2(( "-- Tables count: %12u\n", sfnt.num_tables )); - FT_TRACE2(( "-- Format version: %08lx\n", sfnt.format_tag )); + FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); + FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); /* check first */ error = check_table_dir( &sfnt, stream ); if ( error ) { - FT_TRACE2(( "tt_face_load_font_dir: invalid table directory!\n" )); + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); - return error; + goto Exit; } face->num_tables = sfnt.num_tables; face->format_tag = sfnt.format_tag; if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) - return error; + goto Exit; if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || FT_FRAME_ENTER( face->num_tables * 16L ) ) - return error; + goto Exit; entry = face->dir_tables; - limit = entry + face->num_tables; - for ( ; entry < limit; entry++ ) + for ( nn = 0; nn < sfnt.num_tables; nn++ ) { entry->Tag = FT_GET_TAG4(); entry->CheckSum = FT_GET_ULONG(); entry->Offset = FT_GET_LONG(); entry->Length = FT_GET_LONG(); - FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length )); + /* ignore invalid tables */ + if ( entry->Offset + entry->Length > stream->size ) + continue; + else + { + FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (FT_Char)( entry->Tag >> 24 ), + (FT_Char)( entry->Tag >> 16 ), + (FT_Char)( entry->Tag >> 8 ), + (FT_Char)( entry->Tag ), + entry->Offset, + entry->Length )); + entry++; + } } FT_FRAME_EXIT(); FT_TRACE2(( "table directory loaded\n\n" )); + Exit: return error; } @@ -618,6 +682,17 @@ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); @@ -707,7 +782,7 @@ if ( storage_start > storage_limit ) { - FT_ERROR(( "invalid `name' table\n" )); + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttmtx.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttmtx.c index 286bd0c311c..53e6ac7881f 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttmtx.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,7 +60,7 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, @@ -97,7 +97,7 @@ return error; } -#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, @@ -161,7 +161,9 @@ if ( num_shorts < 0 ) { - FT_ERROR(( "%cmtx has more metrics than glyphs.\n" )); + FT_TRACE0(( "tt_face_load_hmtx:" + " %cmtx has more metrics than glyphs.\n", + vertical ? "v" : "h" )); /* Adobe simply ignores this problem. So we shall do the same. */ #if 0 @@ -229,7 +231,7 @@ return error; } -#endif /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ /*************************************************************************/ @@ -341,7 +343,7 @@ /* */ /* advance :: The advance width resp. advance height. */ /* */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, @@ -420,7 +422,7 @@ return SFNT_Err_Ok; } -#else /* OLD_INTERNALS */ +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, @@ -431,7 +433,8 @@ { void* v = &face->vertical; void* h = &face->horizontal; - TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h; + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v + : (TT_HoriHeader*)h; TT_LongMetrics longs_m; FT_UShort k = header->number_Of_HMetrics; @@ -459,7 +462,7 @@ return SFNT_Err_Ok; } -#endif /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttpost.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttpost.c index 1e6163646dc..aa0bf1ec419 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttpost.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttpost.h" -#include "ttload.h" #include "sferrors.h" @@ -62,11 +61,11 @@ /* table of Mac names. Thus, it is possible to build a version of */ /* FreeType without the Type 1 driver & PSNames module. */ -#define MAC_NAME( x ) tt_post_default_names[x] +#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) /* the 258 default Mac PS glyph names */ - static const FT_String* tt_post_default_names[258] = + static const FT_String* const tt_post_default_names[258] = { /* 0 */ ".notdef", ".null", "CR", "space", "exclam", @@ -416,13 +415,14 @@ /* tt_face_get_ps_name */ /* */ /* <Description> */ - /* Gets the PostScript glyph name of a glyph. */ + /* Get the PostScript glyph name of a glyph. */ /* */ /* <Input> */ /* face :: A handle to the parent face. */ /* */ /* idx :: The glyph index. */ /* */ + /* <InOut> */ /* PSname :: The address of a string pointer. Will be NULL in case */ /* of error, otherwise it is a pointer to the glyph name. */ /* */ @@ -436,9 +436,9 @@ FT_UInt idx, FT_String** PSname ) { - FT_Error error; - TT_Post_Names names; - FT_Fixed format; + FT_Error error; + TT_Post_Names names; + FT_Fixed format; #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_Service_PsCMaps psnames; diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.c index eff49dadd9a..833bb2add29 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,11 +24,11 @@ * Alas, the memory-optimized sbit loader can't be used when implementing * the `old internals' hack */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS #include "ttsbit0.c" -#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ +#else /* FT_CONFIG_OPTION_OLD_INTERNALS */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H @@ -83,7 +83,8 @@ FT_Int line_bits, FT_Bool byte_padded, FT_Int x_offset, - FT_Int y_offset ) + FT_Int y_offset, + FT_Int source_height ) { FT_Byte* line_buff; FT_Int line_incr; @@ -116,7 +117,7 @@ acc = 0; /* clear accumulator */ loaded = 0; /* no bits were loaded */ - for ( height = target->rows; height > 0; height-- ) + for ( height = source_height; height > 0; height-- ) { FT_Byte* cur = line_buff; /* current write cursor */ FT_Int count = line_bits; /* # of bits to extract per line */ @@ -382,8 +383,9 @@ break; case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); + error = Load_SBit_Const_Metrics( range, stream ); + if ( !error ) + error = Load_SBit_Range_Codes( range, stream, 0 ); break; default: @@ -492,7 +494,7 @@ if ( version != 0x00020000L || num_strikes >= 0x10000L ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; @@ -771,7 +773,7 @@ Found: /* return successfully! */ *arange = range; - return 0; + return SFNT_Err_Ok; } } @@ -1229,7 +1231,7 @@ /* the sbit blitter doesn't make a difference between pixmap */ /* depths. */ blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, - x_offset * pix_bits, y_offset ); + x_offset * pix_bits, y_offset, metrics->height ); FT_FRAME_EXIT(); } @@ -1323,7 +1325,11 @@ range->image_format, metrics, stream ); case 8: /* compound format */ - FT_Stream_Skip( stream, 1L ); + if ( FT_STREAM_SKIP( 1L ) ) + { + error = SFNT_Err_Invalid_Stream_Skip; + goto Exit; + } /* fallthrough */ case 9: @@ -1495,7 +1501,7 @@ return error; } -#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.h b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.h index c6067c0e3e6..7ea2af18436 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.h +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_ULong strike_index, FT_Size_Metrics* metrics ); -#if defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL( FT_Error ) tt_find_sbit_image( TT_Face face, FT_UInt glyph_index, diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit0.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit0.c index f8adc64a735..38bcf210ead 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit0.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttsbit0.c @@ -5,7 +5,7 @@ /* TrueType and OpenType embedded bitmap support (body). */ /* This is a heap-optimized version. */ /* */ -/* Copyright 2005, 2006, 2007 by */ +/* Copyright 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,65 +39,16 @@ #define FT_COMPONENT trace_ttsbit - static const FT_Frame_Field tt_sbit_line_metrics_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_SBit_LineMetricsRec - - /* no FT_FRAME_START */ - FT_FRAME_CHAR( ascender ), - FT_FRAME_CHAR( descender ), - FT_FRAME_BYTE( max_width ), - - FT_FRAME_CHAR( caret_slope_numerator ), - FT_FRAME_CHAR( caret_slope_denominator ), - FT_FRAME_CHAR( caret_offset ), - - FT_FRAME_CHAR( min_origin_SB ), - FT_FRAME_CHAR( min_advance_SB ), - FT_FRAME_CHAR( max_before_BL ), - FT_FRAME_CHAR( min_after_BL ), - FT_FRAME_CHAR( pads[0] ), - FT_FRAME_CHAR( pads[1] ), - FT_FRAME_END - }; - - static const FT_Frame_Field tt_strike_start_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_SBit_StrikeRec - - /* no FT_FRAME_START */ - FT_FRAME_ULONG( ranges_offset ), - FT_FRAME_SKIP_LONG, - FT_FRAME_ULONG( num_ranges ), - FT_FRAME_ULONG( color_ref ), - FT_FRAME_END - }; - - static const FT_Frame_Field tt_strike_end_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( start_glyph ), - FT_FRAME_USHORT( end_glyph ), - FT_FRAME_BYTE ( x_ppem ), - FT_FRAME_BYTE ( y_ppem ), - FT_FRAME_BYTE ( bit_depth ), - FT_FRAME_CHAR ( flags ), - FT_FRAME_END - }; - - FT_LOCAL_DEF( FT_Error ) tt_face_load_eblc( TT_Face face, FT_Stream stream ) { - FT_Error error = SFNT_Err_Ok; - FT_Fixed version; - FT_ULong num_strikes, table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt count; + FT_Error error = SFNT_Err_Ok; + FT_Fixed version; + FT_ULong num_strikes, table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt count; face->sbit_num_strikes = 0; @@ -111,7 +62,7 @@ if ( table_size < 8 ) { - FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" )); + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; } @@ -129,8 +80,7 @@ if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) { - FT_ERROR(( "%s: invalid table version!\n", - "tt_face_load_sbit_strikes" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Fail; } @@ -182,7 +132,7 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - FT_Byte* strike; + FT_Byte* strike; if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) @@ -207,7 +157,7 @@ } - typedef struct + typedef struct TT_SBitDecoderRec_ { TT_Face face; FT_Stream stream; @@ -374,14 +324,11 @@ if ( p + 5 > limit ) goto Fail; - if ( !decoder->metrics_loaded ) - { - metrics->height = p[0]; - metrics->width = p[1]; - metrics->horiBearingX = (FT_Char)p[2]; - metrics->horiBearingY = (FT_Char)p[3]; - metrics->horiAdvance = p[4]; - } + metrics->height = p[0]; + metrics->width = p[1]; + metrics->horiBearingX = (FT_Char)p[2]; + metrics->horiBearingY = (FT_Char)p[3]; + metrics->horiAdvance = p[4]; p += 5; if ( big ) @@ -389,19 +336,16 @@ if ( p + 3 > limit ) goto Fail; - if ( !decoder->metrics_loaded ) - { - metrics->vertBearingX = (FT_Char)p[0]; - metrics->vertBearingY = (FT_Char)p[1]; - metrics->vertAdvance = p[2]; - } + metrics->vertBearingX = (FT_Char)p[0]; + metrics->vertBearingY = (FT_Char)p[1]; + metrics->vertAdvance = p[2]; p += 3; } decoder->metrics_loaded = 1; *pp = p; - return 0; + return SFNT_Err_Ok; Fail: return SFNT_Err_Invalid_Argument; @@ -507,7 +451,7 @@ if ( w > 0 ) wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); - /* all bits read and there are ( x_pos + w ) bits to be written */ + /* all bits read and there are `x_pos + w' bits to be written */ write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); @@ -525,6 +469,41 @@ } + /* + * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap + * (with pointer `write'). In the example below, the width is 3 pixel, + * and `x_pos' is 1 pixel. + * + * p p+1 + * | | | + * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... + * | | | + * +-------+ +-------+ +-------+ ... + * . . . + * . . . + * v . . + * +-------+ . . + * | | . + * | 7 6 5 4 3 2 1 0 | . + * | | . + * write . . + * . . + * v . + * +-------+ . + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+1 . + * . + * v + * +-------+ + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+2 + * + */ + static FT_Error tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, FT_Byte* p, @@ -570,6 +549,8 @@ } /* now do the blit */ + + /* adjust `line' to point to the first byte of the bitmap */ line += y_pos * pitch + ( x_pos >> 3 ); x_pos &= 7; @@ -580,16 +561,23 @@ for ( h = height; h > 0; h--, line += pitch ) { FT_Byte* write = line; - FT_Int w = width; + FT_Int w = width; + /* handle initial byte (in target bitmap) specially if necessary */ if ( x_pos ) { w = ( width < 8 - x_pos ) ? width : 8 - x_pos; - if ( nbits < w ) + if ( h == height ) { - rval |= *p++; + rval = *p++; + nbits = x_pos; + } + else if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; nbits += 8 - w; } else @@ -598,12 +586,14 @@ nbits -= w; } - *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w ); + *write++ |= ( ( rval >> nbits ) & 0xFF ) & + ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); rval <<= 8; w = width - w; } + /* handle medial bytes */ for ( ; w >= 8; w -= 8 ) { rval |= *p++; @@ -612,11 +602,13 @@ rval <<= 8; } + /* handle final byte if necessary */ if ( w > 0 ) { if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); nbits += 8 - w; @@ -645,6 +637,13 @@ FT_Error error = SFNT_Err_Ok; FT_UInt num_components, nn; + FT_Char horiBearingX = decoder->metrics->horiBearingX; + FT_Char horiBearingY = decoder->metrics->horiBearingY; + FT_Byte horiAdvance = decoder->metrics->horiAdvance; + FT_Char vertBearingX = decoder->metrics->vertBearingX; + FT_Char vertBearingY = decoder->metrics->vertBearingY; + FT_Byte vertAdvance = decoder->metrics->vertAdvance; + if ( p + 2 > limit ) goto Fail; @@ -653,6 +652,13 @@ if ( p + 4 * num_components > limit ) goto Fail; + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder ); + if ( error ) + goto Exit; + } + for ( nn = 0; nn < num_components; nn++ ) { FT_UInt gindex = FT_NEXT_USHORT( p ); @@ -667,6 +673,15 @@ break; } + decoder->metrics->horiBearingX = horiBearingX; + decoder->metrics->horiBearingY = horiBearingY; + decoder->metrics->horiAdvance = horiAdvance; + decoder->metrics->vertBearingX = vertBearingX; + decoder->metrics->vertBearingY = vertBearingY; + decoder->metrics->vertAdvance = vertAdvance; + decoder->metrics->width = (FT_UInt)decoder->bitmap->width; + decoder->metrics->height = (FT_UInt)decoder->bitmap->rows; + Exit: return error; diff --git a/reactos/lib/3rdparty/freetype/src/smooth/Jamfile b/reactos/lib/3rdparty/freetype/src/smooth/Jamfile index 8a792df056c..a8496aa2c2c 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/smooth/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; if $(FT2_MULTI) { - _sources = ftgrays ftsmooth ; + _sources = ftgrays ftsmooth ftspic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c index 5a4a544e5a5..4a4d375c809 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,11 +91,19 @@ #define FT_COMPONENT trace_smooth - - #ifdef _STANDALONE_ -#include <string.h> /* for ft_memcpy() */ + + /* define this to dump debugging information */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + +#ifdef FT_DEBUG_LEVEL_TRACE +#include <stdio.h> +#include <stdarg.h> +#endif + +#include <string.h> #include <setjmp.h> #include <limits.h> #define FT_UINT_MAX UINT_MAX @@ -118,24 +126,81 @@ #include "ftimage.h" #include "ftgrays.h" + /* This macro is used to indicate that a function parameter is unused. */ /* Its purpose is simply to reduce compiler warnings. Note also that */ /* simply defining it as `(void)x' doesn't avoid warnings with certain */ /* ANSI compilers (e.g. LCC). */ #define FT_UNUSED( x ) (x) = (x) - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ + + /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + void + FT_Message( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + /* we don't handle tracing levels in stand-alone mode; */ +#ifndef FT_TRACE5 +#define FT_TRACE5( varformat ) FT_Message varformat +#endif +#ifndef FT_TRACE7 +#define FT_TRACE7( varformat ) FT_Message varformat +#endif #ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( varformat ) FT_Message varformat #endif -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define FT_DEFINE_OUTLINE_FUNCS( class_, \ + move_to_, line_to_, \ + conic_to_, cubic_to_, \ + shift_, delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ + raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; #else /* !_STANDALONE_ */ + #include <ft2build.h> #include "ftgrays.h" #include FT_INTERNAL_OBJECTS_H @@ -144,14 +209,15 @@ #include "ftsmerrs.h" -#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Invalid_Argument Smooth_Err_Bad_Argument +#include "ftspic.h" + +#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline +#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory +#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument #endif /* !_STANDALONE_ */ - #ifndef FT_MEM_SET #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) #endif @@ -160,35 +226,23 @@ #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif - /* define this to dump debugging information */ -#define xxxDEBUG_GRAYS - - /* as usual, for the speed hungry :-) */ #ifndef FT_STATIC_RASTER - #define RAS_ARG PWorker worker #define RAS_ARG_ PWorker worker, #define RAS_VAR worker #define RAS_VAR_ worker, -#define ras (*worker) - - #else /* FT_STATIC_RASTER */ - #define RAS_ARG /* empty */ #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ - static TWorker ras; - - #endif /* FT_STATIC_RASTER */ @@ -221,7 +275,7 @@ /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ /* determine the type used to store cell areas. This normally takes at */ @@ -252,8 +306,8 @@ typedef struct TCell_ { - int x; - int cover; + TPos x; /* same with TWorker.ex */ + TCoord cover; /* same with TWorker.cover */ TArea area; PCell next; @@ -268,12 +322,12 @@ TPos count_ex, count_ey; TArea area; - int cover; + TCoord cover; int invalid; PCell cells; - int max_cells; - int num_cells; + FT_PtrDist max_cells; + FT_PtrDist num_cells; TCoord cx, cy; TPos x, y; @@ -305,11 +359,18 @@ long buffer_size; PCell* ycells; - int ycount; + TPos ycount; } TWorker, *PWorker; +#ifndef FT_STATIC_RASTER +#define ras (*worker) +#else + static TWorker ras; +#endif + + typedef struct TRaster_ { void* buffer; @@ -395,11 +456,11 @@ gray_find_cell( RAS_ARG ) { PCell *pcell, cell; - int x = ras.ex; + TPos x = ras.ex; - if ( x > ras.max_ex ) - x = ras.max_ex; + if ( x > ras.count_ex ) + x = ras.count_ex; pcell = &ras.ycells[ras.ey]; for (;;) @@ -527,9 +588,9 @@ TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta; + TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem; long p, first, dx; - int incr, lift, mod, rem; + int incr; dx = x2 - x1; @@ -551,7 +612,7 @@ if ( ex1 == ex2 ) { delta = y2 - y1; - ras.area += (TArea)( fx1 + fx2 ) * delta; + ras.area += (TArea)(( fx1 + fx2 ) * delta); ras.cover += delta; return; } @@ -579,7 +640,7 @@ mod += (TCoord)dx; } - ras.area += (TArea)( fx1 + first ) * delta; + ras.area += (TArea)(( fx1 + first ) * delta); ras.cover += delta; ex1 += incr; @@ -609,7 +670,7 @@ delta++; } - ras.area += (TArea)ONE_PIXEL * delta; + ras.area += (TArea)(ONE_PIXEL * delta); ras.cover += delta; y1 += delta; ex1 += incr; @@ -618,7 +679,7 @@ } delta = y2 - y1; - ras.area += (TArea)( fx2 + ONE_PIXEL - first ) * delta; + ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); ras.cover += delta; } @@ -631,10 +692,10 @@ gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2; + TCoord ey1, ey2, fy1, fy2, mod; TPos dx, dy, x, x2; long p, first; - int delta, rem, mod, lift, incr; + int delta, rem, lift, incr; ey1 = TRUNC( ras.last_ey ); @@ -678,7 +739,7 @@ { TCoord ex = TRUNC( ras.x ); TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); - TPos area; + TArea area; first = ONE_PIXEL; @@ -693,7 +754,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); delta = (int)( first + first - ONE_PIXEL ); area = (TArea)two_fx * delta; @@ -703,7 +764,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); } delta = (int)( fy2 - ONE_PIXEL + first ); @@ -1071,13 +1132,13 @@ /* record current cell, if any */ - gray_record_cell( worker ); + gray_record_cell( RAS_VAR ); /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( worker, TRUNC( x ), TRUNC( y ) ); + gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); worker->x = x; worker->y = y; @@ -1089,7 +1150,7 @@ gray_line_to( const FT_Vector* to, PWorker worker ) { - gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) ); + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); return 0; } @@ -1099,7 +1160,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_conic( worker, control, to ); + gray_render_conic( RAS_VAR_ control, to ); return 0; } @@ -1110,7 +1171,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_cubic( worker, control1, control2, to ); + gray_render_cubic( RAS_VAR_ control1, control2, to ); return 0; } @@ -1170,7 +1231,7 @@ gray_hline( RAS_ARG_ TCoord x, TCoord y, TPos area, - int acount ) + TCoord acount ) { FT_Span* span; int count; @@ -1207,9 +1268,13 @@ x += (TCoord)ras.min_ex; /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32768 ) + if ( x >= 32767 ) x = 32767; + /* FT_Span.y is an integer, so limit our coordinates appropriately */ + if ( y >= FT_INT_MAX ) + y = FT_INT_MAX; + if ( coverage ) { /* see whether we can add this span to the current list */ @@ -1229,27 +1294,26 @@ if ( ras.render_span && count > 0 ) ras.render_span( ras.span_y, count, ras.gray_spans, ras.render_span_data ); - /* ras.render_span( span->y, ras.gray_spans, count ); */ -#ifdef DEBUG_GRAYS +#ifdef FT_DEBUG_LEVEL_TRACE - if ( ras.span_y >= 0 ) + if ( count > 0 ) { int n; - fprintf( stderr, "y=%3d ", ras.span_y ); + FT_TRACE7(( "y = %3d ", ras.span_y )); span = ras.gray_spans; for ( n = 0; n < count; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); + FT_TRACE7(( "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage )); + FT_TRACE7(( "\n" )); } -#endif /* DEBUG_GRAYS */ +#endif /* FT_DEBUG_LEVEL_TRACE */ ras.num_gray_spans = 0; - ras.span_y = y; + ras.span_y = (int)y; count = 0; span = ras.gray_spans; @@ -1267,9 +1331,11 @@ } -#ifdef DEBUG_GRAYS +#ifdef FT_DEBUG_LEVEL_TRACE - /* to be called while in the debugger */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ + static void gray_dump_cells( RAS_ARG ) { int yindex; @@ -1283,12 +1349,12 @@ printf( "%3d:", yindex ); for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); + printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); printf( "\n" ); } } -#endif /* DEBUG_GRAYS */ +#endif /* FT_DEBUG_LEVEL_TRACE */ static void @@ -1304,6 +1370,8 @@ ras.num_gray_spans = 0; + FT_TRACE7(( "gray_sweep: start\n" )); + for ( yindex = 0; yindex < ras.ycount; yindex++ ) { PCell cell = ras.ycells[yindex]; @@ -1313,7 +1381,7 @@ for ( ; cell != NULL; cell = cell->next ) { - TArea area; + TPos area; if ( cell->x > x && cover != 0 ) @@ -1337,6 +1405,8 @@ if ( ras.render_span && ras.num_gray_spans > 0 ) ras.render_span( ras.span_y, ras.num_gray_spans, ras.gray_spans, ras.render_span_data ); + + FT_TRACE7(( "gray_sweep: end\n" )); } @@ -1344,7 +1414,7 @@ /*************************************************************************/ /* */ - /* The following function should only compile in stand_alone mode, */ + /* The following function should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1355,18 +1425,19 @@ /* FT_Outline_Decompose */ /* */ /* <Description> */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bzier arcs. This function is also able to emit */ /* `move to' and `close to' operations to indicate the start and end */ /* of new contours in the outline. */ /* */ /* <Input> */ /* outline :: A pointer to the source target. */ /* */ - /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* func_interface :: A table of `emitters', i.e., function pointers */ /* called during decomposition to indicate path */ /* operations. */ /* */ + /* <InOut> */ /* user :: A typeless pointer which is passed to each */ /* emitter during the decomposition. It can be */ /* used to store the state during the */ @@ -1375,17 +1446,13 @@ /* <Return> */ /* Error code. 0 means success. */ /* */ - static - int FT_Outline_Decompose( const FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ) + static int + FT_Outline_Decompose( const FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) { #undef SCALED -#if 0 #define SCALED( x ) ( ( (x) << shift ) - delta ) -#else -#define SCALED( x ) (x) -#endif FT_Vector v_last; FT_Vector v_control; @@ -1395,17 +1462,21 @@ FT_Vector* limit; char* tags; + int error; + int n; /* index of contour in outline */ int first; /* index of first point in contour */ - int error; char tag; /* current point's state */ -#if 0 - int shift = func_interface->shift; - TPos delta = func_interface->delta; -#endif + int shift; + TPos delta; + if ( !outline || !func_interface ) + return ErrRaster_Invalid_Argument; + + shift = func_interface->shift; + delta = func_interface->delta; first = 0; for ( n = 0; n < outline->n_contours; n++ ) @@ -1413,22 +1484,25 @@ int last; /* index of last point in contour */ + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; limit = outline->points + last; - v_start = outline->points[first]; - v_last = outline->points[last]; - + v_start = outline->points[first]; v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); - v_last.y = SCALED( v_last.y ); + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -1459,6 +1533,8 @@ tags--; } + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->move_to( &v_start, user ); if ( error ) goto Exit; @@ -1479,6 +1555,8 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); error = func_interface->line_to( &vec, user ); if ( error ) goto Exit; @@ -1486,53 +1564,60 @@ } case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) { - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); + FT_Vector vec; + FT_Vector v_middle; - Do_Conic: - if ( point < limit ) + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - error = func_interface->conic_to( &v_control, &vec, - user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = func_interface->conic_to( &v_control, &v_middle, - user ); + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); if ( error ) goto Exit; - - v_control = vec; - goto Do_Conic; + continue; } - error = func_interface->conic_to( &v_control, &v_start, - user ); - goto Close; + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; } + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + default: /* FT_CURVE_TAG_CUBIC */ { FT_Vector vec1, vec2; @@ -1559,12 +1644,22 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); if ( error ) goto Exit; continue; } + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); goto Close; } @@ -1572,6 +1667,8 @@ } /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->line_to( &v_start, user ); Close: @@ -1581,9 +1678,11 @@ first = last + 1; } + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); return 0; Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); return error; Invalid_Outline: @@ -1599,32 +1698,33 @@ } TBand; - - static int - gray_convert_glyph_inner( RAS_ARG ) - { - static - const FT_Outline_Funcs func_interface = - { + FT_DEFINE_OUTLINE_FUNCS(func_interface, (FT_Outline_MoveTo_Func) gray_move_to, (FT_Outline_LineTo_Func) gray_line_to, (FT_Outline_ConicTo_Func)gray_conic_to, (FT_Outline_CubicTo_Func)gray_cubic_to, 0, 0 - }; + ) + + static int + gray_convert_glyph_inner( RAS_ARG ) + { volatile int error = 0; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs func_interface; + Init_Class_func_interface(&func_interface); +#endif + if ( ft_setjmp( ras.jump_buffer ) == 0 ) { error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); gray_record_cell( RAS_VAR ); } else - { error = ErrRaster_Memory_Overflow; - } return error; } @@ -1659,14 +1759,14 @@ ras.count_ex = ras.max_ex - ras.min_ex; ras.count_ey = ras.max_ey - ras.min_ey; - /* simple heuristic used to speed-up the bezier decomposition -- see */ + /* simple heuristic used to speed up the bezier decomposition -- see */ /* the code in gray_render_conic() and gray_render_cubic() for more */ /* details */ ras.conic_level = 32; ras.cubic_level = 16; { - int level = 0; + int level = 0; if ( ras.count_ex > 24 || ras.count_ey > 24 ) @@ -1678,10 +1778,12 @@ ras.cubic_level <<= level; } - /* setup vertical bands */ + /* set up vertical bands */ num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) num_bands = 1; - if ( num_bands >= 39 ) num_bands = 39; + if ( num_bands == 0 ) + num_bands = 1; + if ( num_bands >= 39 ) + num_bands = 39; ras.band_shoot = 0; @@ -1760,8 +1862,8 @@ /* be some problems. */ if ( middle == bottom ) { -#ifdef DEBUG_GRAYS - fprintf( stderr, "Rotten glyph!\n" ); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); #endif return 1; } @@ -1796,11 +1898,14 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( !outline ) + return ErrRaster_Invalid_Outline; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return 0; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return ErrRaster_Invalid_Outline; if ( outline->n_points != @@ -1810,7 +1915,7 @@ worker = raster->worker; /* if direct mode is not set, we must have a target bitmap */ - if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { if ( !target_map ) return ErrRaster_Invalid_Argument; @@ -1828,7 +1933,7 @@ return ErrRaster_Invalid_Mode; /* compute clipping box */ - if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ ras.clip_box.xMin = 0; @@ -1837,9 +1942,7 @@ ras.clip_box.yMax = target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - { ras.clip_box = params->clip_box; - } else { ras.clip_box.xMin = -32768L; @@ -1848,32 +1951,32 @@ ras.clip_box.yMax = 32767L; } - gray_init_cells( worker, raster->buffer, raster->buffer_size ); + gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = raster->band_size; ras.num_gray_spans = 0; - if ( target_map ) - ras.target = *target_map; - - ras.render_span = (FT_Raster_Span_Func)gray_render_span; - ras.render_span_data = &ras; - if ( params->flags & FT_RASTER_FLAG_DIRECT ) { ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; } + else + { + ras.target = *target_map; + ras.render_span = (FT_Raster_Span_Func)gray_render_span; + ras.render_span_data = &ras; + } - return gray_convert_glyph( worker ); + return gray_convert_glyph( RAS_VAR ); } - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ + /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ + /**** a static object. *****/ #ifdef _STANDALONE_ @@ -1968,8 +2071,7 @@ } - const FT_Raster_Funcs ft_grays_raster = - { + FT_DEFINE_RASTER_FUNCS(ft_grays_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) gray_raster_new, @@ -1977,7 +2079,12 @@ (FT_Raster_Set_Mode_Func)0, (FT_Raster_Render_Func) gray_raster_render, (FT_Raster_Done_Func) gray_raster_done - }; + ) /* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.h b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.h index 2d409543dce..f20f55f14b6 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.h +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.h @@ -28,6 +28,7 @@ #include "ftimage.h" #else #include <ft2build.h> +#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ #include FT_IMAGE_H #endif diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.c b/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.c index 85d04eb458e..eed63531572 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.c +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,10 +17,12 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include "ftsmooth.h" #include "ftgrays.h" +#include "ftspic.h" #include "ftsmerrs.h" @@ -153,7 +155,7 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - /* allocate new one, depends on pixel format */ + /* allocate new one */ pitch = width; if ( hmul ) { @@ -192,6 +194,19 @@ } } +#endif + +#if FT_UINT_MAX > 0xFFFFU + + /* Required check is ( pitch * height < FT_ULONG_MAX ), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0xFFFFU || height > 0xFFFFU ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", + width, height )); + return Smooth_Err_Raster_Overflow; + } + #endif bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; @@ -294,13 +309,13 @@ for ( hh = height_org; hh > 0; hh-- ) { - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; read += pitch; } @@ -310,12 +325,19 @@ FT_Outline_Translate( outline, x_shift, y_shift ); + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) + return Smooth_Err_Invalid_Pixel_Size; + if ( error ) goto Exit; slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = x_left; - slot->bitmap_top = y_top; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; Exit: if ( outline && origin ) @@ -376,10 +398,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -392,7 +412,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -401,14 +421,12 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcd_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -421,7 +439,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -430,15 +448,11 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class, - - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcdv_renderer_class = - { - { FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -451,7 +465,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -460,8 +474,8 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.h b/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.h index 62cced44873..3708790df17 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.h +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftsmooth.h @@ -28,15 +28,15 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; + FT_DECLARE_RENDERER( ft_std_renderer_class ) #endif #ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_v_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) #endif diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftspic.c b/reactos/lib/3rdparty/freetype/src/smooth/ftspic.c new file mode 100644 index 00000000000..aa547fceb6d --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftspic.c @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* ftspic.c */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ftspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftgrays.c */ + void FT_Init_Class_ft_grays_raster(FT_Raster_Funcs*); + + void + ft_smooth_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->smooth ) + { + SmoothPIC* container = (SmoothPIC*)pic_container->smooth; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->smooth = NULL; + } + } + + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve smooth_lcd and smooth_lcdv renderers, + it implements reference counting */ + if(pic_container->smooth) + { + ((SmoothPIC*)pic_container->smooth)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->smooth = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_grays_raster(&container->ft_grays_raster); +/*Exit:*/ + if(error) + ft_smooth_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_smooth_lcd_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcd_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + FT_Error ft_smooth_lcdv_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcdv_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftspic.h b/reactos/lib/3rdparty/freetype/src/smooth/ftspic.h new file mode 100644 index 00000000000..c7e0ce9d892 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftspic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* ftspic.h */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSPIC_H__ +#define __FTSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_GRAYS_RASTER_GET ft_grays_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct SmoothPIC_ + { + int ref_count; + FT_Raster_Funcs ft_grays_raster; + } SmoothPIC; + +#define GET_PIC(lib) ((SmoothPIC*)((lib)->pic_container.smooth)) +#define FT_GRAYS_RASTER_GET (GET_PIC(library)->ft_grays_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTSPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/smooth/module.mk b/reactos/lib/3rdparty/freetype/src/smooth/module.mk index 05ad4ba0a89..47f6c040764 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/module.mk +++ b/reactos/lib/3rdparty/freetype/src/smooth/module.mk @@ -16,11 +16,11 @@ FTMODULE_H_COMMANDS += SMOOTH_RENDERER define SMOOTH_RENDERER -$(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER)ft_smooth_lcd_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER)ft_smooth_lcdv_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/smooth/smooth.c b/reactos/lib/3rdparty/freetype/src/smooth/smooth.c index ff6be3e4007..a8ac51f9f8c 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/smooth.c +++ b/reactos/lib/3rdparty/freetype/src/smooth/smooth.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "ftspic.c" #include "ftgrays.c" #include "ftsmooth.c" diff --git a/reactos/lib/3rdparty/freetype/src/tools/apinames.c b/reactos/lib/3rdparty/freetype/src/tools/apinames.c index f08919bee6c..19aec500bf2 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/apinames.c +++ b/reactos/lib/3rdparty/freetype/src/tools/apinames.c @@ -10,7 +10,7 @@ * accepted if you are using GCC for compilation (and probably by * other compilers too). * - * Author: David Turner, 2005, 2006 + * Author: David Turner, 2005, 2006, 2008 * * This code is explicitly placed into the public domain. * @@ -26,7 +26,7 @@ #define LINEBUFF_SIZE 1024 -typedef enum +typedef enum OutputFormat_ { OUTPUT_LIST = 0, /* output the list of names, one per line */ OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ @@ -44,7 +44,7 @@ panic( const char* message ) } -typedef struct +typedef struct NameRec_ { char* name; unsigned int hash; @@ -191,7 +191,7 @@ names_dump( FILE* out, /* states of the line parser */ -typedef enum +typedef enum State_ { STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */ STATE_TYPE /* type was read, waiting for function name */ diff --git a/reactos/lib/3rdparty/freetype/src/tools/chktrcmp.py b/reactos/lib/3rdparty/freetype/src/tools/chktrcmp.py new file mode 100644 index 00000000000..d0f342e6bdd --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/tools/chktrcmp.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# Check trace components in FreeType 2 source. +# Author: suzuki toshiya, 2009 +# +# This code is explicitly into the public domain. + + +import sys +import os +import re + +SRC_FILE_LIST = [] +USED_COMPONENT = {} +KNOWN_COMPONENT = {} + +SRC_FILE_DIRS = [ "src" ] +TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ] + + +# -------------------------------------------------------------- +# Parse command line options +# + +for i in range( 1, len( sys.argv ) ): + if sys.argv[i].startswith( "--help" ): + print "Usage: %s [option]" % sys.argv[0] + print "Search used-but-defined and defined-but-not-used trace_XXX macros" + print "" + print " --help:" + print " Show this help" + print "" + print " --src-dirs=dir1:dir2:..." + print " Specify the directories of C source files to be checked" + print " Default is %s" % ":".join( SRC_FILE_DIRS ) + print "" + print " --def-files=file1:file2:..." + print " Specify the header files including FT_TRACE_DEF()" + print " Default is %s" % ":".join( TRACE_DEF_FILES ) + print "" + exit(0) + if sys.argv[i].startswith( "--src-dirs=" ): + SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" ) + elif sys.argv[i].startswith( "--def-files=" ): + TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" ) + + +# -------------------------------------------------------------- +# Scan C source and header files using trace macros. +# + +c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE ) +trace_use_pat = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' ) + +for d in SRC_FILE_DIRS: + for ( p, dlst, flst ) in os.walk( d ): + for f in flst: + if c_pathname_pat.match( f ) != None: + src_pathname = os.path.join( p, f ) + + line_num = 0 + for src_line in open( src_pathname, 'r' ): + line_num = line_num + 1 + src_line = src_line.strip() + if trace_use_pat.match( src_line ) != None: + component_name = trace_use_pat.sub( '', src_line ) + if component_name in USED_COMPONENT: + USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) ) + else: + USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ] + + +# -------------------------------------------------------------- +# Scan header file(s) defining trace macros. +# + +trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' ) +trace_def_pat_cls = re.compile( '[ \t\)].*$' ) + +for f in TRACE_DEF_FILES: + line_num = 0 + for hdr_line in open( f, 'r' ): + line_num = line_num + 1 + hdr_line = hdr_line.strip() + if trace_def_pat_opn.match( hdr_line ) != None: + component_name = trace_def_pat_opn.sub( '', hdr_line ) + component_name = trace_def_pat_cls.sub( '', component_name ) + if component_name in KNOWN_COMPONENT: + print "trace component %s is defined twice, see %s and fttrace.h:%d" % \ + ( component_name, KNOWN_COMPONENT[component_name], line_num ) + else: + KNOWN_COMPONENT[component_name] = "%s:%d" % \ + ( os.path.basename( f ), line_num ) + + +# -------------------------------------------------------------- +# Compare the used and defined trace macros. +# + +print "# Trace component used in the implementations but not defined in fttrace.h." +cmpnt = USED_COMPONENT.keys() +cmpnt.sort() +for c in cmpnt: + if c not in KNOWN_COMPONENT: + print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) ) + +print "# Trace component is defined but not used in the implementations." +cmpnt = KNOWN_COMPONENT.keys() +cmpnt.sort() +for c in cmpnt: + if c not in USED_COMPONENT: + if c != "any": + print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] ) + diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/content.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/content.py index b14c52edefd..b398955b81d 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/content.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/content.py @@ -1,4 +1,5 @@ -# Content (c) 2002, 2004, 2006, 2007 David Turner <david@freetype.org> +# Content (c) 2002, 2004, 2006, 2007, 2008, 2009 +# David Turner <david@freetype.org> # # This file contains routines used to parse the content of documentation # comment blocks and build more structured objects out of them. @@ -34,6 +35,13 @@ re_code_end = re.compile( r"(\s*)}\s*$" ) re_identifier = re.compile( r'(\w*)' ) +# we collect macros ending in `_H'; while outputting the object data, we use +# this info together with the object's file location to emit the appropriate +# header file macro and name before the object itself +# +re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' ) + + ############################################################################# # # The DocCode class is used to store source code lines. @@ -44,11 +52,11 @@ re_identifier = re.compile( r'(\w*)' ) # The object is filled line by line by the parser; it strips the leading # "margin" space from each input line before storing it in 'self.lines'. # -class DocCode: +class DocCode: - def __init__( self, margin, lines ): - self.lines = [] - self.words = None + def __init__( self, margin, lines ): + self.lines = [] + self.words = None # remove margin spaces for l in lines: @@ -56,15 +64,15 @@ class DocCode: l = l[margin:] self.lines.append( l ) - def dump( self, prefix = "", width=60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] for l in self.lines: - result.append( " "*margin + l ) + result.append( " " * margin + l ) return result @@ -75,34 +83,34 @@ class DocCode: # # 'self.words' contains the list of words that make up the paragraph # -class DocPara: +class DocPara: - def __init__( self, lines ): + def __init__( self, lines ): self.lines = None self.words = [] for l in lines: - l = string.strip(l) + l = string.strip( l ) self.words.extend( string.split( l ) ) - def dump( self, prefix = "", width = 60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width = 60 ): + def dump_lines( self, margin = 0, width = 60 ): cur = "" # current line col = 0 # current width result = [] for word in self.words: - ln = len(word) + ln = len( word ) if col > 0: - ln = ln+1 + ln = ln + 1 if col + ln > width: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) cur = word - col = len(word) + col = len( word ) else: if col > 0: cur = cur + " " @@ -110,31 +118,29 @@ class DocPara: col = col + ln if col > 0: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) return result - ############################################################################# # # The DocField class is used to store a list containing either DocPara or # DocCode objects. Each DocField also has an optional "name" which is used # when the object corresponds to a field or value definition # -class DocField: - - def __init__( self, name, lines ): +class DocField: + def __init__( self, name, lines ): self.name = name # can be None for normal paragraphs/sources - self.items = [] # list of items + self.items = [] # list of items - mode_none = 0 # start parsing mode - mode_code = 1 # parsing code sequences - mode_para = 3 # parsing normal paragraph + mode_none = 0 # start parsing mode + mode_code = 1 # parsing code sequences + mode_para = 3 # parsing normal paragraph - margin = -1 # current code sequence indentation + margin = -1 # current code sequence indentation cur_lines = [] # now analyze the markup lines to see if they contain paragraphs, @@ -142,14 +148,13 @@ class DocField: # start = 0 mode = mode_none - for l in lines: + for l in lines: # are we parsing a code sequence ? if mode == mode_code: - m = re_code_end.match( l ) - if m and len(m.group(1)) <= margin: - # that's it, we finised the code sequence + if m and len( m.group( 1 ) ) <= margin: + # that's it, we finished the code sequence code = DocCode( 0, cur_lines ) self.items.append( code ) margin = -1 @@ -169,9 +174,8 @@ class DocField: cur_lines = [] # switch to code extraction mode - margin = len(m.group(1)) + margin = len( m.group( 1 ) ) mode = mode_code - else: if not string.split( l ) and cur_lines: # if the line is empty, we end the current paragraph, @@ -188,12 +192,11 @@ class DocField: # unexpected end of code sequence code = DocCode( margin, cur_lines ) self.items.append( code ) - elif cur_lines: para = DocPara( cur_lines ) self.items.append( para ) - def dump( self, prefix = "" ): + def dump( self, prefix = "" ): if self.field: print prefix + self.field + " ::" prefix = prefix + "----" @@ -205,9 +208,10 @@ class DocField: p.dump( prefix ) first = 0 - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] nl = None + for p in self.items: if nl: result.append( "" ) @@ -217,17 +221,19 @@ class DocField: return result + + # this regular expression is used to detect field definitions # -re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) +re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) -class DocMarkup: +class DocMarkup: - def __init__( self, tag, lines ): - self.tag = string.lower(tag) - self.fields = [] + def __init__( self, tag, lines ): + self.tag = string.lower( tag ) + self.fields = [] cur_lines = [] field = None @@ -245,10 +251,10 @@ class DocMarkup: cur_lines = [] field = None - field = m.group(1) # record field name - ln = len(m.group(0)) - l = " "*ln + l[ln:] - cur_lines = [ l ] + field = m.group( 1 ) # record field name + ln = len( m.group( 0 ) ) + l = " " * ln + l[ln:] + cur_lines = [l] else: cur_lines.append( l ) @@ -256,51 +262,48 @@ class DocMarkup: f = DocField( field, cur_lines ) self.fields.append( f ) - def get_name( self ): + def get_name( self ): try: return self.fields[0].items[0].words[0] - except: return None - def get_start( self ): + def get_start( self ): try: result = "" for word in self.fields[0].items[0].words: result = result + " " + word return result[1:] - except: return "ERROR" - def dump( self, margin ): - print " "*margin + "<" + self.tag + ">" + def dump( self, margin ): + print " " * margin + "<" + self.tag + ">" for f in self.fields: f.dump( " " ) - print " "*margin + "</" + self.tag + ">" + print " " * margin + "</" + self.tag + ">" +class DocChapter: -class DocChapter: - - def __init__( self, block ): + def __init__( self, block ): self.block = block self.sections = [] if block: - self.name = block.name - self.title = block.get_markup_words( "title" ) - self.order = block.get_markup_words( "sections" ) + self.name = block.name + self.title = block.get_markup_words( "title" ) + self.order = block.get_markup_words( "sections" ) else: - self.name = "Other" - self.title = string.split( "Miscellaneous" ) - self.order = [] + self.name = "Other" + self.title = string.split( "Miscellaneous" ) + self.order = [] -class DocSection: +class DocSection: - def __init__( self, name = "Other" ): + def __init__( self, name = "Other" ): self.name = name self.blocks = {} self.block_names = [] # ordered block names in section @@ -311,15 +314,15 @@ class DocSection: self.title = "ERROR" self.chapter = None - def add_def( self, block ): + def add_def( self, block ): self.defs.append( block ) - def add_block( self, block ): + def add_block( self, block ): self.block_names.append( block.name ) - self.blocks[ block.name ] = block + self.blocks[block.name] = block - def process( self ): - # lookup one block that contains a valid section description + def process( self ): + # look up one block that contains a valid section description for block in self.defs: title = block.get_markup_text( "title" ) if title: @@ -329,49 +332,51 @@ class DocSection: self.order = block.get_markup_words( "order" ) return - def reorder( self ): - + def reorder( self ): self.block_names = sort_order_list( self.block_names, self.order ) -class ContentProcessor: - def __init__( self ): +class ContentProcessor: + + def __init__( self ): """initialize a block content processor""" self.reset() self.sections = {} # dictionary of documentation sections self.section = None # current documentation section - self.chapters = [] # list of chapters + self.chapters = [] # list of chapters - def set_section( self, section_name ): + self.headers = {} # dictionary of header macros + + def set_section( self, section_name ): """set current section during parsing""" if not self.sections.has_key( section_name ): section = DocSection( section_name ) - self.sections[ section_name ] = section - self.section = section + self.sections[section_name] = section + self.section = section else: - self.section = self.sections[ section_name ] + self.section = self.sections[section_name] - def add_chapter( self, block ): + def add_chapter( self, block ): chapter = DocChapter( block ) self.chapters.append( chapter ) - def reset( self ): + def reset( self ): """reset the content processor for a new block""" self.markups = [] self.markup = None self.markup_lines = [] - def add_markup( self ): + def add_markup( self ): """add a new markup section""" if self.markup and self.markup_lines: # get rid of last line of markup if it's empty marks = self.markup_lines - if len(marks) > 0 and not string.strip(marks[-1]): + if len( marks ) > 0 and not string.strip( marks[-1] ): self.markup_lines = marks[:-1] m = DocMarkup( self.markup, self.markup_lines ) @@ -381,8 +386,7 @@ class ContentProcessor: self.markup = None self.markup_lines = [] - - def process_content( self, content ): + def process_content( self, content ): """process a block content and return a list of DocMarkup objects corresponding to it""" markup = None @@ -394,9 +398,9 @@ class ContentProcessor: for t in re_markup_tags: m = t.match( line ) if m: - found = string.lower(m.group(1)) - prefix = len(m.group(0)) - line = " "*prefix + line[prefix:] # remove markup from line + found = string.lower( m.group( 1 ) ) + prefix = len( m.group( 0 ) ) + line = " " * prefix + line[prefix:] # remove markup from line break # is it the start of a new markup section ? @@ -404,7 +408,7 @@ class ContentProcessor: first = 0 self.add_markup() # add current markup content self.markup = found - if len(string.strip( line )) > 0: + if len( string.strip( line ) ) > 0: self.markup_lines.append( line ) elif first == 0: self.markup_lines.append( line ) @@ -413,28 +417,25 @@ class ContentProcessor: return self.markups - def parse_sources( self, source_processor ): blocks = source_processor.blocks - count = len(blocks) - for n in range(count): + count = len( blocks ) + for n in range( count ): source = blocks[n] if source.content: # this is a documentation comment, we need to catch # all following normal blocks in the "follow" list # follow = [] - m = n+1 + m = n + 1 while m < count and not blocks[m].content: follow.append( blocks[m] ) - m = m+1 + m = m + 1 doc_block = DocBlock( source, follow, self ) - def finish( self ): - # process all sections to extract their abstract, description # and ordered list of items # @@ -445,13 +446,13 @@ class ContentProcessor: # listed there for chap in self.chapters: for sec in chap.order: - if self.sections.has_key(sec): - section = self.sections[ sec ] + if self.sections.has_key( sec ): + section = self.sections[sec] section.chapter = chap section.reorder() chap.sections.append( section ) else: - sys.stderr.write( "WARNING: chapter '" + + sys.stderr.write( "WARNING: chapter '" + \ chap.name + "' in " + chap.block.location() + \ " lists unknown section '" + sec + "'\n" ) @@ -460,7 +461,7 @@ class ContentProcessor: others = [] for sec in self.sections.values(): if not sec.chapter: - others.append(sec) + others.append( sec ) # create a new special chapter for all remaining sections # when necessary @@ -472,18 +473,17 @@ class ContentProcessor: -class DocBlock: - - def __init__( self, source, follow, processor ): +class DocBlock: + def __init__( self, source, follow, processor ): processor.reset() - self.source = source - self.code = [] - self.type = "ERRTYPE" - self.name = "ERRNAME" - self.section = processor.section - self.markups = processor.process_content( source.content ) + self.source = source + self.code = [] + self.type = "ERRTYPE" + self.name = "ERRNAME" + self.section = processor.section + self.markups = processor.process_content( source.content ) # compute block type from first markup tag try: @@ -491,7 +491,6 @@ class DocBlock: except: pass - # compute block name from first markup paragraph try: markup = self.markups[0] @@ -499,20 +498,18 @@ class DocBlock: name = para.words[0] m = re_identifier.match( name ) if m: - name = m.group(1) + name = m.group( 1 ) self.name = name except: pass - # detect new section starts if self.type == "section": + # detect new section starts processor.set_section( self.name ) processor.section.add_def( self ) - - # detect new chapter elif self.type == "chapter": + # detect new chapter processor.add_chapter( self ) - else: processor.section.add_block( self ) @@ -523,6 +520,11 @@ class DocBlock: if b.format: break for l in b.lines: + # collect header macro definitions + m = re_header_macro.match( l ) + if m: + processor.headers[m.group( 2 )] = m.group( 1 ); + # we use "/* */" as a separator if re_source_sep.match( l ): break @@ -530,7 +532,7 @@ class DocBlock: # now strip the leading and trailing empty lines from the sources start = 0 - end = len( source )-1 + end = len( source ) - 1 while start < end and not string.strip( source[start] ): start = start + 1 @@ -538,25 +540,22 @@ class DocBlock: while start < end and not string.strip( source[end] ): end = end - 1 - source = source[start:end+1] + if start == end and not string.strip( source[start] ): + self.code = [] + else: + self.code = source[start:end + 1] - self.code = source - - - def location( self ): + def location( self ): return self.source.location() - - - def get_markup( self, tag_name ): + def get_markup( self, tag_name ): """return the DocMarkup corresponding to a given tag in a block""" for m in self.markups: - if m.tag == string.lower(tag_name): + if m.tag == string.lower( tag_name ): return m return None - - def get_markup_name( self, tag_name ): + def get_markup_name( self, tag_name ): """return the name of a given primary markup in a block""" try: m = self.get_markup( tag_name ) @@ -564,21 +563,18 @@ class DocBlock: except: return None - - def get_markup_words( self, tag_name ): + def get_markup_words( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items[0].words except: return [] - - def get_markup_text( self, tag_name ): + def get_markup_text( self, tag_name ): result = self.get_markup_words( tag_name ) return string.join( result ) - - def get_markup_items( self, tag_name ): + def get_markup_items( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py index 55c43297f1f..3ddf4a94a15 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py @@ -1,23 +1,24 @@ #!/usr/bin/env python # -# DocBeauty (c) 2003, 2004 David Turner <david@freetype.org> +# DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org> # # This program is used to beautify the documentation comments used # in the FreeType 2 public headers. # -from sources import * -from content import * -from utils import * +from sources import * +from content import * +from utils import * import utils import sys, os, time, string, getopt + content_processor = ContentProcessor() -def beautify_block( block ): +def beautify_block( block ): if block.content: content_processor.reset() @@ -30,7 +31,7 @@ def beautify_block( block ): first = 0 # now beautify the documentation "borders" themselves - lines = [ " /*************************************************************************" ] + lines = [" /*************************************************************************"] for l in text: lines.append( " *" + l ) lines.append( " */" ) @@ -38,9 +39,9 @@ def beautify_block( block ): block.lines = lines -def usage(): +def usage(): print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [ file2 ... ]\n" + print " docbeauty [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -b : backup original files with the 'orig' extension" @@ -48,16 +49,15 @@ def usage(): print " --backup : same as -b" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "hb", - [ "help", "backup" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "hb", \ + ["help", "backup"] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -80,16 +80,19 @@ def main( argv ): do_backup = 1 # create context and processor - source_processor = SourceProcessor() + source_processor = SourceProcessor() # retrieve the list of files to process file_list = make_file_list( args ) for filename in file_list: source_processor.parse_file( filename ) + for block in source_processor.blocks: beautify_block( block ) + new_name = filename + ".new" ok = None + try: file = open( new_name, "wt" ) for block in source_processor.blocks: @@ -100,6 +103,7 @@ def main( argv ): except: ok = 0 + # if called from the command line # if __name__ == '__main__': diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py index d34b6e8f96b..1d9de9fbff2 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# DocMaker (c) 2002, 2004 David Turner <david@freetype.org> +# DocMaker (c) 2002, 2004, 2008 David Turner <david@freetype.org> # # This program is a re-write of the original DocMaker took used # to generate the API Reference of the FreeType font engine @@ -24,9 +24,9 @@ import utils import sys, os, time, string, glob, getopt -def usage(): +def usage(): print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [ file2 ... ]\n" + print " docmaker [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -t : set project title, as in '-t \"My Project\"'" @@ -38,16 +38,15 @@ def usage(): print " --prefix : same as -p, as in '--prefix=ft2'" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - [ "help", "title=", "output=", "prefix=" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "ht:o:p:", \ + ["help", "title=", "output=", "prefix="] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -76,7 +75,7 @@ def main( argv ): if opt[0] in ( "-p", "--prefix" ): project_prefix = opt[1] - check_output( ) + check_output() # create context and processor source_processor = SourceProcessor() diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/formatter.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/formatter.py index 363410efc76..f62ce676c15 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/formatter.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/formatter.py @@ -1,4 +1,4 @@ -# Formatter (c) 2002, 2004, 2007 David Turner <david@freetype.org> +# Formatter (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org> # from sources import * @@ -14,10 +14,9 @@ from utils import * # used to output -- you guessed it -- HTML. # -class Formatter: - - def __init__( self, processor ): +class Formatter: + def __init__( self, processor ): self.processor = processor self.identifiers = {} self.chapters = processor.chapters @@ -25,7 +24,7 @@ class Formatter: self.block_index = [] # store all blocks in a dictionary - self.blocks = [] + self.blocks = [] for section in self.sections: for block in section.blocks.values(): self.add_identifier( block.name, block ) @@ -36,26 +35,22 @@ class Formatter: for field in markup.fields: self.add_identifier( field.name, block ) - self.block_index = self.identifiers.keys() self.block_index.sort( index_sort ) - - def add_identifier( self, name, block ): + def add_identifier( self, name, block ): if self.identifiers.has_key( name ): - # duplicate name !! - sys.stderr.write( \ + # duplicate name! + sys.stderr.write( \ "WARNING: duplicate definition for '" + name + "' in " + \ block.location() + ", previous definition in " + \ - self.identifiers[ name ].location() + "\n" ) + self.identifiers[name].location() + "\n" ) else: self.identifiers[name] = block - # # Formatting the table of contents # - def toc_enter( self ): pass @@ -78,7 +73,6 @@ class Formatter: pass def toc_dump( self, toc_filename = None, index_filename = None ): - output = None if toc_filename: output = open_output( toc_filename ) @@ -93,7 +87,7 @@ class Formatter: self.toc_section_enter( section ) self.toc_section_exit( section ) - self.toc_chapter_exit ( chap ) + self.toc_chapter_exit( chap ) self.toc_index( index_filename ) @@ -105,7 +99,6 @@ class Formatter: # # Formatting the index # - def index_enter( self ): pass @@ -119,7 +112,6 @@ class Formatter: pass def index_dump( self, index_filename = None ): - output = None if index_filename: output = open_output( index_filename ) @@ -128,7 +120,7 @@ class Formatter: for name in self.block_index: self.index_name_enter( name ) - self.index_name_exit ( name ) + self.index_name_exit( name ) self.index_exit() @@ -162,9 +154,7 @@ class Formatter: def section_exit( self, section ): pass - def section_dump( self, section, section_filename = None ): - output = None if section_filename: output = open_output( section_filename ) @@ -172,33 +162,27 @@ class Formatter: self.section_enter( section ) for name in section.block_names: - block = self.identifiers[ name ] + block = self.identifiers[name] self.block_enter( block ) - for markup in block.markups[1:]: # always ignore first markup !! + for markup in block.markups[1:]: # always ignore first markup! self.markup_enter( markup, block ) for field in markup.fields: self.field_enter( field, markup, block ) - - self.field_exit ( field, markup, block ) + self.field_exit( field, markup, block ) self.markup_exit( markup, block ) self.block_exit( block ) - self.section_exit ( section ) + self.section_exit( section ) if output: close_output( output ) - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section ) - # - # Formatting a block - # - # eof diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/sources.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/sources.py index 09ff7f9970d..7b68c07019d 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/sources.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/sources.py @@ -1,4 +1,4 @@ -# Sources (c) 2002, 2003, 2004, 2006, 2007 +# Sources (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009 # David Turner <david@freetype.org> # # @@ -18,13 +18,11 @@ # the classes and methods found here only deal with text parsing # and basic documentation block extraction # + import fileinput, re, sys, os, string - - - ################################################################ ## ## BLOCK FORMAT PATTERN @@ -36,11 +34,10 @@ import fileinput, re, sys, os, string ## note that the 'column' pattern must contain a group that will ## be used to "unbox" the content of documentation comment blocks ## -class SourceBlockFormat: +class SourceBlockFormat: - def __init__( self, id, start, column, end ): + def __init__( self, id, start, column, end ): """create a block pattern, used to recognize special documentation blocks""" - self.id = id self.start = re.compile( start, re.VERBOSE ) self.column = re.compile( column, re.VERBOSE ) @@ -61,9 +58,9 @@ class SourceBlockFormat: # start = r''' - \s* # any number of whitespace - /\*{2,}/ # followed by '/' and at least two asterisks then '/' - \s*$ # eventually followed by whitespace + \s* # any number of whitespace + /\*{2,}/ # followed by '/' and at least two asterisks then '/' + \s*$ # probably followed by whitespace ''' column = r''' @@ -71,11 +68,12 @@ column = r''' /\*{1} # followed by '/' and precisely one asterisk ([^*].*) # followed by anything (group 1) \*{1}/ # followed by one asterisk and a '/' - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) + # # format 2 documentation comment blocks look like the following: # @@ -91,27 +89,28 @@ re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) start = r''' \s* # any number of whitespace /\*{2,} # followed by '/' and at least two asterisks - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' column = r''' - \s* # any number of whitespace - \*{1}(?!/) # followed by precisely one asterisk not followed by `/' - (.*) # then anything (group1) + \s* # any number of whitespace + \*{1}(?!/) # followed by precisely one asterisk not followed by `/' + (.*) # then anything (group1) ''' end = r''' - \s* # any number of whitespace - \*+/ # followed by at least one asterisk, then '/' + \s* # any number of whitespace + \*+/ # followed by at least one asterisk, then '/' ''' re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) + # # the list of supported documentation block formats, we could add new ones # relatively easily # -re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] +re_source_block_formats = [re_source_block_format1, re_source_block_format2] # @@ -128,7 +127,7 @@ re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format # the list of supported markup tags, we could add new ones relatively # easily # -re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] +re_markup_tags = [re_markup_tag1, re_markup_tag2] # # used to detect a cross-reference, after markup tags have been stripped @@ -175,18 +174,19 @@ re_source_keywords = re.compile( '''\\b ( typedef | \#else | \#endif ) \\b''', re.VERBOSE ) + ################################################################ ## ## SOURCE BLOCK CLASS ## -## A SourceProcessor is in charge or reading a C source file +## A SourceProcessor is in charge of reading a C source file ## and decomposing it into a series of different "SourceBlocks". ## each one of these blocks can be made of the following data: ## ## - A documentation comment block that starts with "/**" and ## whose exact format will be discussed later ## -## - normal sources lines, include comments +## - normal sources lines, including comments ## ## the important fields in a text block are the following ones: ## @@ -198,8 +198,9 @@ re_source_keywords = re.compile( '''\\b ( typedef | ## (i.e. sources or ordinary comments with no starting ## markup tag) ## -class SourceBlock: - def __init__( self, processor, filename, lineno, lines ): +class SourceBlock: + + def __init__( self, processor, filename, lineno, lines ): self.processor = processor self.filename = filename self.lineno = lineno @@ -218,24 +219,22 @@ class SourceBlock: for line0 in self.lines: m = self.format.column.match( line0 ) if m: - lines.append( m.group(1) ) + lines.append( m.group( 1 ) ) # now, look for a markup tag for l in lines: - l = string.strip(l) - if len(l) > 0: + l = string.strip( l ) + if len( l ) > 0: for tag in re_markup_tags: if tag.match( l ): self.content = lines - return - - def location( self ): - return "(" + self.filename + ":" + repr(self.lineno) + ")" + return + def location( self ): + return "(" + self.filename + ":" + repr( self.lineno ) + ")" # debugging only - not used in normal operations - def dump( self ): - + def dump( self ): if self.content: print "{{{content start---" for l in self.content: @@ -245,17 +244,18 @@ class SourceBlock: fmt = "" if self.format: - fmt = repr(self.format.id) + " " + fmt = repr( self.format.id ) + " " for line in self.lines: print line + ################################################################ ## ## SOURCE PROCESSOR CLASS ## -## The SourceProcessor is in charge or reading a C source file +## The SourceProcessor is in charge of reading a C source file ## and decomposing it into a series of different "SourceBlock" ## objects. ## @@ -267,7 +267,7 @@ class SourceBlock: ## - normal sources lines, include comments ## ## -class SourceProcessor: +class SourceProcessor: def __init__( self ): """initialize a source processor""" @@ -281,39 +281,33 @@ class SourceProcessor: self.blocks = [] self.format = None - def parse_file( self, filename ): - """parse a C source file, and adds its blocks to the processor's list""" - + """parse a C source file, and add its blocks to the processor's list""" self.reset() self.filename = filename fileinput.close() - self.format = None - self.lineno = 0 - self.lines = [] + self.format = None + self.lineno = 0 + self.lines = [] for line in fileinput.input( filename ): - - # strip trailing newlines, important on Windows machines !! - if line[-1] == '\012': + # strip trailing newlines, important on Windows machines! + if line[-1] == '\012': line = line[0:-1] if self.format == None: self.process_normal_line( line ) - else: if self.format.end.match( line ): - # that's a normal block end, add it to lines and + # that's a normal block end, add it to 'lines' and # create a new block self.lines.append( line ) self.add_block_lines() - elif self.format.column.match( line ): # that's a normal column line, add it to 'lines' self.lines.append( line ) - else: # humm.. this is an unexpected block end, # create a new block, but don't process the line @@ -325,22 +319,18 @@ class SourceProcessor: # record the last lines self.add_block_lines() - - - def process_normal_line( self, line ): - """process a normal line and check if it's the start of a new block""" + def process_normal_line( self, line ): + """process a normal line and check whether it is the start of a new block""" for f in re_source_block_formats: - if f.start.match( line ): - self.add_block_lines() - self.format = f - self.lineno = fileinput.filelineno() + if f.start.match( line ): + self.add_block_lines() + self.format = f + self.lineno = fileinput.filelineno() self.lines.append( line ) - - - def add_block_lines( self ): - """add the current accumulated lines, and create a new block""" + def add_block_lines( self ): + """add the current accumulated lines and create a new block""" if self.lines != []: block = SourceBlock( self, self.filename, self.lineno, self.lines ) @@ -348,9 +338,8 @@ class SourceProcessor: self.format = None self.lines = [] - # debugging only, not used in normal operations - def dump( self ): + def dump( self ): """print all blocks in a processor""" for b in self.blocks: b.dump() diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py index 04dfba3f46a..fffa120973d 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py @@ -1,4 +1,4 @@ -# ToHTML (c) 2002, 2003, 2005, 2006, 2007 +# ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008 # David Turner <david@freetype.org> from sources import * @@ -7,17 +7,19 @@ from formatter import * import time + # The following defines the HTML header used by all generated pages. -# html_header_1 = """\ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<title>""" +<title>\ +""" -html_header_2= """ API Reference +html_header_2 = """\ + API Reference -

""" +""" -html_header_3=""" API Reference

+html_header_3 = """ + + + +
[
[Index][TOC]
+

\ +""" + +html_header_5t = """\ +">Index] + +

\ +""" + +html_header_6 = """\ + API Reference

""" - # The HTML footer used by all generated pages. -# html_footer = """\ -""" +\ +""" # The header and footer used for each section. -# section_title_header = "

" section_title_footer = "

" # The header and footer used for code segments. -# code_header = '
'
 code_footer = '
' # Paragraph header and footer. -# para_header = "

" para_footer = "

" # Block header and footer. -# block_header = '
' block_footer_start = """\

- -
[
[Index] [TOC]
""" # Description header/footer. -# description_header = '
' description_footer = "

" # Marker header/inter/footer combination. -# marker_header = '
' marker_inter = "
" marker_footer = "
" +# Header location header/footer. +header_location_header = '
' +header_location_footer = "

" + # Source code extracts header/footer. -# source_header = '
\n'
 source_footer = "\n

" # Chapter header/inter/footer. -# chapter_header = '

' chapter_inter = '

  • ' chapter_footer = '
' @@ -114,86 +140,108 @@ chapter_footer = '' index_footer_start = """\
-
[TOC]
""" +# TOC footer. +toc_footer_start = """\ +
+ + +
[Index]
+""" + # source language keyword coloration/styling -# keyword_prefix = '' keyword_suffix = '' section_synopsis_header = '

Synopsis

' section_synopsis_footer = '' + # Translate a single line of source to HTML. This will convert # a "<" into "<.", ">" into ">.", etc. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) +def html_quote( line ): + result = string.replace( line, "&", "&" ) result = string.replace( result, "<", "<" ) result = string.replace( result, ">", ">" ) return result # same as 'html_quote', but ignores left and right brackets -# -def html_quote0( line ): +def html_quote0( line ): return string.replace( line, "&", "&" ) -def dump_html_code( lines, prefix = "" ): +def dump_html_code( lines, prefix = "" ): # clean the last empty lines - # l = len( self.lines ) while l > 0 and string.strip( self.lines[l - 1] ) == "": l = l - 1 # The code footer should be directly appended to the last code # line to avoid an additional blank line. - # print prefix + code_header, - for line in self.lines[0 : l+1]: - print '\n' + prefix + html_quote(line), + for line in self.lines[0 : l + 1]: + print '\n' + prefix + html_quote( line ), print prefix + code_footer, -class HtmlFormatter(Formatter): - - def __init__( self, processor, project_title, file_prefix ): +class HtmlFormatter( Formatter ): + def __init__( self, processor, project_title, file_prefix ): Formatter.__init__( self, processor ) - global html_header_1, html_header_2, html_header_3, html_footer + global html_header_1, html_header_2, html_header_3 + global html_header_4, html_header_5, html_footer if file_prefix: file_prefix = file_prefix + "-" else: file_prefix = "" - self.project_title = project_title - self.file_prefix = file_prefix - self.html_header = html_header_1 + project_title + html_header_2 + \ - project_title + html_header_3 + self.headers = processor.headers + self.project_title = project_title + self.file_prefix = file_prefix + self.html_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3 + file_prefix + "index.html" + \ + html_header_4 + file_prefix + "toc.html" + \ + html_header_5 + project_title + \ + html_header_6 - self.html_footer = "
generated on " + \ - time.asctime( time.localtime( time.time() ) ) + \ - "
" + html_footer + self.html_index_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3i + file_prefix + "toc.html" + \ + html_header_5 + project_title + \ + html_header_6 + + self.html_toc_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3 + file_prefix + "index.html" + \ + html_header_5t + project_title + \ + html_header_6 + + self.html_footer = "
generated on " + \ + time.asctime( time.localtime( time.time() ) ) + \ + "
" + html_footer self.columns = 3 def make_section_url( self, section ): return self.file_prefix + section.name + ".html" - def make_block_url( self, block ): return self.make_section_url( block.section ) + "#" + block.name - def make_html_words( self, words ): """ convert a series of simple words into some HTML text """ line = "" @@ -204,16 +252,14 @@ class HtmlFormatter(Formatter): return line - def make_html_word( self, word ): """analyze a simple word to detect cross-references and styling""" # look for cross-references - # m = re_crossref.match( word ) if m: try: - name = m.group(1) - rest = m.group(2) + name = m.group( 1 ) + rest = m.group( 2 ) block = self.identifiers[name] url = self.make_block_url( block ) return '' + name + '' + rest @@ -226,34 +272,34 @@ class HtmlFormatter(Formatter): # look for italics and bolds m = re_italic.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '' + name + '' + rest m = re_bold.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '' + name + '' + rest - return html_quote(word) - + return html_quote( word ) def make_html_para( self, words ): - """ convert a paragraph's words into tagged HTML text, handle xrefs """ + """ convert words of a paragraph into tagged HTML text, handle xrefs """ line = "" if words: line = self.make_html_word( words[0] ) for word in words[1:]: line = line + " " + self.make_html_word( word ) # convert `...' quotations into real left and right single quotes - line = re.sub( r"(^|\W)`(.*?)'(\W|$)", - r'\1‘\2’\3', + line = re.sub( r"(^|\W)`(.*?)'(\W|$)", \ + r'\1‘\2’\3', \ line ) + # convert tilde into non-breakable space + line = string.replace( line, "~", " " ) return para_header + line + para_footer - def make_html_code( self, lines ): """ convert a code sequence to HTML """ line = code_header + '\n' @@ -262,7 +308,6 @@ class HtmlFormatter(Formatter): return line + code_footer - def make_html_items( self, items ): """ convert a field's content into some valid HTML """ lines = [] @@ -274,59 +319,54 @@ class HtmlFormatter(Formatter): return string.join( lines, '\n' ) - def print_html_items( self, items ): print self.make_html_items( items ) - - def print_html_field( self, field ): + def print_html_field( self, field ): if field.name: - print "

"+field.name+"

" + print "
" + field.name + "" print self.make_html_items( field.items ) if field.name: print "
" - - def html_source_quote( self, line, block_name = None ): + def html_source_quote( self, line, block_name = None ): result = "" while line: m = re_source_crossref.match( line ) if m: - name = m.group(2) - prefix = html_quote( m.group(1) ) - length = len( m.group(0) ) + name = m.group( 2 ) + prefix = html_quote( m.group( 1 ) ) + length = len( m.group( 0 ) ) if name == block_name: # this is the current block name, if any result = result + prefix + '' + name + '' - - elif re_source_keywords.match(name): + elif re_source_keywords.match( name ): # this is a C keyword result = result + prefix + keyword_prefix + name + keyword_suffix - - elif self.identifiers.has_key(name): + elif self.identifiers.has_key( name ): # this is a known identifier block = self.identifiers[name] result = result + prefix + '' + name + '' + self.make_block_url( block ) + '">' + name + '' else: - result = result + html_quote(line[:length]) + result = result + html_quote( line[:length] ) line = line[length:] else: - result = result + html_quote(line) + result = result + html_quote( line ) line = [] return result - - def print_html_field_list( self, fields ): + def print_html_field_list( self, fields ): + print "

" print "" for field in fields: - if len(field.name) > 22: - print "" + if len( field.name ) > 22: + print "" print "" print "
"+field.name+"
" + field.name + "
" else: print "
" + field.name + "" @@ -335,8 +375,7 @@ class HtmlFormatter(Formatter): print "
" - - def print_html_markup( self, markup ): + def print_html_markup( self, markup ): table_fields = [] for field in markup.fields: if field.name: @@ -345,7 +384,6 @@ class HtmlFormatter(Formatter): # all of them as a single table # table_fields.append( field ) - else: if table_fields: self.print_html_field_list( table_fields ) @@ -359,9 +397,8 @@ class HtmlFormatter(Formatter): # # Formatting the index # - def index_enter( self ): - print self.html_header + print self.html_index_header self.index_items = {} def index_name_enter( self, name ): @@ -370,16 +407,15 @@ class HtmlFormatter(Formatter): self.index_items[name] = url def index_exit( self ): - # block_index already contains the sorted list of index names count = len( self.block_index ) - rows = (count + self.columns - 1) / self.columns + rows = ( count + self.columns - 1 ) / self.columns print "" - for r in range(rows): + for r in range( rows ): line = "" - for c in range(self.columns): - i = r + c*rows + for c in range( self.columns ): + i = r + c * rows if i < count: bname = self.block_index[r + c * rows] url = self.index_items[bname] @@ -391,14 +427,15 @@ class HtmlFormatter(Formatter): print "
" - print index_footer_start + \ + print index_footer_start + \ self.file_prefix + "toc.html" + \ index_footer_end + print self.html_footer + self.index_items = {} def index_dump( self, index_filename = None ): - if index_filename == None: index_filename = self.file_prefix + "index.html" @@ -408,15 +445,15 @@ class HtmlFormatter(Formatter): # Formatting the table of content # def toc_enter( self ): - print self.html_header + print self.html_toc_header print "

Table of Contents

" def toc_chapter_enter( self, chapter ): - print chapter_header + string.join(chapter.title) + chapter_inter + print chapter_header + string.join( chapter.title ) + chapter_inter print "" def toc_section_enter( self, section ): - print "
" + print '
' print '' + \ section.title + '' @@ -427,12 +464,18 @@ class HtmlFormatter(Formatter): def toc_chapter_exit( self, chapter ): print "
" - print chapter_footer + print chapter_footer def toc_index( self, index_filename ): - print chapter_header + 'Global Index' + chapter_inter + chapter_footer + print chapter_header + \ + 'Global Index' + \ + chapter_inter + chapter_footer def toc_exit( self ): + print toc_footer_start + \ + self.file_prefix + "index.html" + \ + toc_footer_end + print self.html_footer def toc_dump( self, toc_filename = None, index_filename = None ): @@ -459,7 +502,7 @@ class HtmlFormatter(Formatter): if len( b.name ) > maxwidth: maxwidth = len( b.name ) - width = 70 # XXX magic number + width = 70 # XXX magic number if maxwidth <> 0: # print section synopsis print section_synopsis_header @@ -501,12 +544,26 @@ class HtmlFormatter(Formatter): # dump the block C source lines now if block.code: + header = '' + for f in self.headers.keys(): + if block.source.filename.find( f ) >= 0: + header = self.headers[f] + ' (' + f + ')' + break; + +# if not header: +# sys.stderr.write( \ +# 'WARNING: No header macro for ' + block.source.filename + '.\n' ) + + if header: + print header_location_header + print 'Defined in ' + header + '.' + print header_location_footer + print source_header for l in block.code: print self.html_source_quote( l, block.name ) print source_footer - def markup_enter( self, markup, block ): if markup.tag == "description": print description_header @@ -523,15 +580,13 @@ class HtmlFormatter(Formatter): def block_exit( self, block ): print block_footer_start + self.file_prefix + "index.html" + \ - block_footer_middle + self.file_prefix + "toc.html" + \ + block_footer_middle + self.file_prefix + "toc.html" + \ block_footer_end - def section_exit( self, section ): print html_footer - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section, self.file_prefix + section.name + '.html' ) diff --git a/reactos/lib/3rdparty/freetype/src/tools/docmaker/utils.py b/reactos/lib/3rdparty/freetype/src/tools/docmaker/utils.py index e751c563186..1d96658c7d5 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/docmaker/utils.py +++ b/reactos/lib/3rdparty/freetype/src/tools/docmaker/utils.py @@ -1,4 +1,4 @@ -# Utils (c) 2002, 2004, 2007 David Turner +# Utils (c) 2002, 2004, 2007, 2008 David Turner # import string, sys, os, glob @@ -11,7 +11,7 @@ output_dir = None # This function is used to sort the index. It is a simple lexicographical # sort, except that it places capital letters before lowercase ones. # -def index_sort( s1, s2 ): +def index_sort( s1, s2 ): if not s1: return -1 @@ -41,9 +41,10 @@ def index_sort( s1, s2 ): return 0 + # Sort input_list, placing the elements of order_list in front. # -def sort_order_list( input_list, order_list ): +def sort_order_list( input_list, order_list ): new_list = order_list[:] for id in input_list: if not id in order_list: @@ -51,12 +52,11 @@ def sort_order_list( input_list, order_list ): return new_list - # Open the standard output to a given project documentation file. Use # "output_dir" to determine the filename location if necessary and save the # old stdout in a tuple that is returned by this function. # -def open_output( filename ): +def open_output( filename ): global output_dir if output_dir and output_dir != "": @@ -71,25 +71,26 @@ def open_output( filename ): # Close the output that was returned by "close_output". # -def close_output( output ): +def close_output( output ): output[0].close() sys.stdout = output[1] # Check output directory. # -def check_output( ): +def check_output(): global output_dir if output_dir: if output_dir != "": if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" + " '" + output_dir + "' " + + sys.stderr.write( "argument" + " '" + output_dir + "' " + \ "is not a valid directory" ) sys.exit( 2 ) else: output_dir = None -def file_exists( pathname ): + +def file_exists( pathname ): """checks that a given file exists""" result = 1 try: @@ -102,9 +103,8 @@ def file_exists( pathname ): return result -def make_file_list( args = None ): +def make_file_list( args = None ): """builds a list of input files from command-line arguments""" - file_list = [] # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) diff --git a/reactos/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c b/reactos/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c index fcff27bc350..4daac0dc1d4 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c +++ b/reactos/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 by George Williams */ +/* Copyright (C) 2005, 2007, 2008 by George Williams */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -151,8 +151,8 @@ int load_flags = FT_LOAD_DEFAULT; - if ( check_outlines && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + if ( check_outlines && + FT_IS_SCALABLE( face ) ) load_flags = FT_LOAD_NO_BITMAP; if ( nohints ) @@ -162,8 +162,8 @@ for ( gid = 0; gid < face->num_glyphs; ++gid ) { - if ( check_outlines && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + if ( check_outlines && + FT_IS_SCALABLE( face ) ) { if ( !FT_Load_Glyph( face, gid, load_flags ) ) FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); diff --git a/reactos/lib/3rdparty/freetype/src/tools/glnames.py b/reactos/lib/3rdparty/freetype/src/tools/glnames.py index 9a6da383172..55573b22fe8 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/glnames.py +++ b/reactos/lib/3rdparty/freetype/src/tools/glnames.py @@ -6,7 +6,7 @@ # -# Copyright 1996-2000, 2003, 2005, 2007 by +# Copyright 1996-2000, 2003, 2005, 2007, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,7 +21,7 @@ usage: %s This python script generates the glyph names tables defined in the - PSNames module. + `psnames' module. Its single argument is the name of the header file to be created. """ @@ -5011,7 +5011,7 @@ def dump_array( the_array, write, array_name ): """dumps a given encoding""" write( " static const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "] =\n" ) + "[" + repr( len( the_array ) ) + "L] =\n" ) write( " {\n" ) line = "" @@ -5067,7 +5067,7 @@ def main(): write( "/* */\n" ) write( "/* PostScript glyph names. */\n" ) write( "/* */\n" ) - write( "/* Copyright 2005 by */\n" ) + write( "/* Copyright 2005, 2008 by */\n" ) write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) write( "/* */\n" ) write( "/* This file is part of the FreeType project, and may only be used, */\n" ) @@ -5117,6 +5117,9 @@ def main(): * The lookup function to get the Unicode value for a given string * is defined below the table. */ + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + """ ) dump_array( dict_array, write, "ft_adobe_glyph_list" ) @@ -5219,6 +5222,8 @@ def main(): return 0; } +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + """ ) if 0: # generate unit test, or don't diff --git a/reactos/lib/3rdparty/freetype/src/tools/test_afm.c b/reactos/lib/3rdparty/freetype/src/tools/test_afm.c index d53cb332562..f5f99363cab 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/test_afm.c +++ b/reactos/lib/3rdparty/freetype/src/tools/test_afm.c @@ -63,7 +63,7 @@ int dummy_get_index( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ) { if ( len ) diff --git a/reactos/lib/3rdparty/freetype/src/truetype/Jamfile b/reactos/lib/3rdparty/freetype/src/truetype/Jamfile index a166909f4cc..a8cccfe1372 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/Jamfile +++ b/reactos/lib/3rdparty/freetype/src/truetype/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; if $(FT2_MULTI) { - _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ; + _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; } else { diff --git a/reactos/lib/3rdparty/freetype/src/truetype/module.mk b/reactos/lib/3rdparty/freetype/src/truetype/module.mk index 3b05afc7fda..baee81a7730 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/module.mk +++ b/reactos/lib/3rdparty/freetype/src/truetype/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TRUETYPE_DRIVER define TRUETYPE_DRIVER -$(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, tt_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/truetype/truetype.c b/reactos/lib/3rdparty/freetype/src/truetype/truetype.c index b36473a72df..4bd1209787e 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/truetype.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/truetype.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "ttpic.c" #include "ttdriver.c" /* driver interface */ #include "ttpload.c" /* tables loader */ #include "ttgload.c" /* glyph loader */ diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c index c2cf45298a5..dca009a104d 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_SERVICE_XFREE86_NAME_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -41,6 +40,7 @@ #include "tterrors.h" +#include "ttpic.h" /*************************************************************************/ /* */ @@ -125,6 +125,49 @@ #undef PAIR_TAG + static FT_Error + tt_get_advances( FT_Face ttface, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *advances ) + { + FT_UInt nn; + TT_Face face = (TT_Face) ttface; + FT_Bool check = FT_BOOL( + !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) ); + + + /* XXX: TODO: check for sbits */ + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short tsb; + FT_UShort ah; + + + TT_Get_VMetrics( face, start + nn, check, &tsb, &ah ); + advances[nn] = ah; + } + } + else + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short lsb; + FT_UShort aw; + + + TT_Get_HMetrics( face, start + nn, check, &lsb, &aw ); + advances[nn] = aw; + } + } + + return TT_Err_Ok; + } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -229,7 +272,7 @@ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ + /* FT_LOAD_XXX constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ @@ -258,11 +301,24 @@ if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) return TT_Err_Invalid_Argument; + if ( load_flags & FT_LOAD_NO_HINTING ) + { + /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ + /* are necessary to disable hinting for tricky fonts */ + + if ( FT_IS_TRICKY( face ) ) + load_flags &= ~FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_AUTOHINT ) + load_flags |= FT_LOAD_NO_HINTING; + } + if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) { - load_flags |= FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP | - FT_LOAD_NO_SCALE; + load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; + + if ( !FT_IS_TRICKY( face ) ) + load_flags |= FT_LOAD_NO_HINTING; } /* now load the glyph outline if necessary */ @@ -288,14 +344,13 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - static const FT_Service_MultiMastersRec tt_service_gx_multi_masters = - { + FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters, (FT_Get_MM_Func) NULL, (FT_Set_MM_Design_Func) NULL, (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, (FT_Get_MM_Var_Func) TT_Get_MM_Var, (FT_Set_Var_Design_Func)TT_Set_Var_Design - }; + ) #endif static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = @@ -315,33 +370,36 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; - static const FT_Service_TTGlyfRec tt_service_truetype_glyf = - { + FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf, (TT_Glyf_GetLocationFunc)tt_face_get_location - }; + ) - static const FT_ServiceDescRec tt_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, + FT_DEFINE_SERVICEDESCREC4(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) #endif - { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine }, - { FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) tt_get_interface( FT_Module driver, /* TT_Driver */ const char* tt_interface ) { + FT_Library library = driver->library; FT_Module_Interface result; FT_Module sfntd; SFNT_Service sfnt; + FT_UNUSED(library); - - result = ft_service_list_lookup( tt_services, tt_interface ); + result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); if ( result != NULL ) return result; @@ -360,17 +418,24 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec tt_driver_class = - { - { +#ifdef TT_USE_BYTECODE_INTERPRETER +#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER +#else +#define TT_HINTER_FLAG 0 +#endif + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define TT_SIZE_SELECT tt_size_select +#else +#define TT_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(tt_driver_class, + + FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_MODULE_DRIVER_HAS_HINTER, -#else - 0, -#endif + TT_HINTER_FLAG, sizeof ( TT_DriverRec ), @@ -383,7 +448,6 @@ tt_driver_init, tt_driver_done, tt_get_interface, - }, sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), @@ -396,23 +460,18 @@ tt_slot_init, 0, /* FT_Slot_DoneFunc */ -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + Load_Glyph, tt_get_kerning, 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + tt_get_advances, tt_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + TT_SIZE_SELECT + ) /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.h b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.h index f6f26e4b59a..aae00f2617f 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.h +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) tt_driver_class; + FT_DECLARE_DRIVER( tt_driver_class ) FT_END_HEADER diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c index ae476a41711..28ddb99553a 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,12 +69,12 @@ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ - static void - Get_HMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* lsb, - FT_UShort* aw ) + FT_LOCAL_DEF(void) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ) { ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); @@ -96,12 +96,12 @@ /* The monospace `check' is probably not meaningful here, but we leave */ /* it in for a consistent interface. */ /* */ - static void - Get_VMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* tsb, - FT_UShort* ah ) + FT_LOCAL_DEF(void) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) { FT_UNUSED( check ); @@ -267,7 +267,11 @@ if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) goto Invalid_Outline; - cont[0] = prev_cont = FT_NEXT_USHORT( p ); + prev_cont = FT_NEXT_USHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + for ( cont++; cont < cont_limit; cont++ ) { cont[0] = FT_NEXT_USHORT( p ); @@ -313,7 +317,7 @@ if ( n_ins > face->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", n_ins )); error = TT_Err_Too_Many_Hints; goto Fail; @@ -321,7 +325,7 @@ if ( ( limit - p ) < n_ins ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); + FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } @@ -378,8 +382,8 @@ for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos y = 0; + FT_Byte f = *flag; if ( f & 2 ) @@ -401,7 +405,8 @@ x += y; vec->x = x; - *flag = f & ~( 2 | 16 ); + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & ~( 2 | 16 ) ); } /* reading the Y coordinates */ @@ -413,8 +418,8 @@ for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos y = 0; + FT_Byte f = *flag; if ( f & 4 ) @@ -436,7 +441,8 @@ x += y; vec->y = x; - *flag = f & FT_CURVE_TAG_ON; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); } outline->n_points = (FT_UShort)n_points; @@ -553,10 +559,10 @@ FT_Stream stream = loader->stream; - /* we must undo the FT_FRAME_ENTER in order to point to the */ - /* composite instructions, if we find some. */ - /* we will process them later... */ - /* */ + /* we must undo the FT_FRAME_ENTER in order to point */ + /* to the composite instructions, if we find some. */ + /* We will process them later. */ + /* */ loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + p - limit ); } @@ -627,7 +633,13 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - n_ins = loader->glyph->control_len; + if ( loader->glyph->control_len > 0xFFFFL ) + { + FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); + FT_TRACE1(( "(0x%lx byte) is truncated\n", + loader->glyph->control_len )); + } + n_ins = (FT_UInt)( loader->glyph->control_len ); #endif origin = zone->cur[zone->n_points - 4].x; @@ -639,6 +651,26 @@ /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } #endif /* round pp2 and pp4 */ @@ -654,6 +686,9 @@ FT_Bool debug; FT_Error error; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current_outline = gloader->current.outline; + error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, loader->exec->glyphIns, n_ins ); @@ -669,6 +704,10 @@ error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) return error; + + /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ + current_outline.tags[0] |= + ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; } #endif @@ -702,7 +741,7 @@ FT_GlyphLoader gloader = loader->gloader; FT_Error error = TT_Err_Ok; FT_Outline* outline; - FT_UInt n_points; + FT_Int n_points; outline = &gloader->current.outline; @@ -729,7 +768,7 @@ /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = loader->face->memory; - FT_UInt i; + FT_Int i; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), @@ -903,15 +942,15 @@ /* This algorithm is a guess and works much better than the above. */ /* */ FT_Fixed mac_xscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.xx, - subglyph->transform.xx ) + - FT_MulFix( subglyph->transform.xy, - subglyph->transform.xy ) ); + (FT_Int32)FT_MulFix( subglyph->transform.xx, + subglyph->transform.xx ) + + (FT_Int32)FT_MulFix( subglyph->transform.xy, + subglyph->transform.xy ) ); FT_Fixed mac_yscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.yy, - subglyph->transform.yy ) + - FT_MulFix( subglyph->transform.yx, - subglyph->transform.yx ) ); + (FT_Int32)FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + (FT_Int32)FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); x = FT_MulFix( x, mac_xscale ); @@ -1004,7 +1043,7 @@ /* check it */ if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n", n_ins )); return TT_Err_Too_Many_Hints; @@ -1027,8 +1066,7 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ for ( i = start_point; i < loader->zone.n_points; i++ ) - loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X | - FT_CURVE_TAG_TOUCH_Y ); + loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; loader->zone.n_points += 4; @@ -1084,7 +1122,10 @@ #endif - if ( recurse_count > face->max_profile.maxComponentDepth ) + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) { error = TT_Err_Invalid_Composite; goto Exit; @@ -1116,16 +1157,16 @@ FT_UShort advance_width = 0, advance_height = 0; - Get_HMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &left_bearing, - &advance_width ); - Get_VMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &top_bearing, - &advance_height ); + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -1214,10 +1255,31 @@ offset = tt_face_get_location( face, glyph_index, (FT_UInt*)&loader->byte_len ); - if ( loader->byte_len == 0 ) + if ( loader->byte_len > 0 ) + { + if ( !loader->glyf_offset ) + { + FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); + error = TT_Err_Invalid_Table; + goto Exit; + } + + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read first glyph header */ + error = face->read_glyph_header( loader ); + if ( error ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* as described by Frederic Loyer, these are spaces or */ - /* the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; @@ -1260,19 +1322,6 @@ goto Exit; } - error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, - loader->byte_len ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Exit; - TT_LOADER_SET_PP( loader ); /***********************************************************************/ @@ -1281,7 +1330,7 @@ /* if it is a simple glyph, load it */ - if ( loader->n_contours >= 0 ) + if ( loader->n_contours > 0 ) { error = face->read_simple_glyph( loader ); if ( error ) @@ -1351,8 +1400,11 @@ { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 += deltas[i].x; - subglyph->arg2 += deltas[i].y; + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* deltas[i].{x,y} must be within signed 16-bit, */ + /* but the restriction of summed delta is not clear */ + subglyph->arg1 += (FT_Int16)deltas[i].x; + subglyph->arg2 += (FT_Int16)deltas[i].y; } } @@ -1390,20 +1442,15 @@ /*********************************************************************/ { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; - FT_Stream old_stream = loader->stream; + FT_Stream old_stream = loader->stream; - TT_GraphicsState saved_GS; - - - if ( loader->exec ) - saved_GS = loader->exec->GS; FT_GlyphLoader_Add( gloader ); @@ -1413,10 +1460,6 @@ FT_Vector pp[4]; - /* reinitialize graphics state */ - if ( loader->exec ) - loader->exec->GS = saved_GS; - /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ @@ -1551,17 +1594,35 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* Now take care of vertical metrics. In the case where there is */ - /* no vertical information within the font (relatively common), make */ - /* up some metrics by `hand'... */ + /* adjust advance width to the value contained in the hdmx table */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widthp; + + widthp = tt_face_get_device_metrics( face, + size->root.metrics.x_ppem, + glyph_index ); + + if ( widthp ) + glyph->metrics.horiAdvance = *widthp << 6; + } + + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), */ + /* create some metrics manually */ { FT_Pos top; /* scaled vertical top side bearing */ FT_Pos advance; /* scaled vertical advance height */ /* Get the unscaled top bearing and advance height. */ - if ( face->vertical_info && + if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, @@ -1643,30 +1704,12 @@ /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ /* */ - glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2; + glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - + glyph->metrics.horiAdvance / 2; glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; } - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widthp; - - - widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, - glyph_index ); - - if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - return 0; } @@ -1819,12 +1862,15 @@ FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - if ( error ) + if ( error == TT_Err_Table_Missing ) + loader->glyf_offset = 0; + else if ( error ) { - FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); + FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); return error; } - loader->glyf_offset = FT_STREAM_POS(); + else + loader->glyf_offset = FT_STREAM_POS(); } /* get face's glyph loader */ @@ -1836,7 +1882,7 @@ loader->gloader = gloader; } - loader->load_flags = load_flags; + loader->load_flags = load_flags; loader->face = (FT_Face)face; loader->size = (FT_Size)size; @@ -1939,6 +1985,40 @@ FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 ); } +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load_flags ) ) + { + if ( loader.exec->GS.scan_control ) + { + /* convert scan conversion mode to FT_OUTLINE_XXX flags */ + switch ( loader.exec->GS.scan_type ) + { + case 0: /* simple drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; + break; + case 1: /* simple drop-outs excluding stubs */ + /* nothing; it's the default rendering mode */ + break; + case 4: /* smart drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | + FT_OUTLINE_INCLUDE_STUBS; + break; + case 5: /* smart drop-outs excluding stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; + break; + + default: /* no drop-out control */ + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + break; + } + } + else + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + compute_glyph_metrics( &loader, glyph_index ); } diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.h b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.h index b261e97dee0..958d67d20d7 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.h +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,6 +34,20 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Init_Glyph_Loading( TT_Face face ); + FT_LOCAL( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ); + + FT_LOCAL( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ); + FT_LOCAL( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c index 0dc2c4f3e4a..1456a8cc0a6 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,30 +16,31 @@ /***************************************************************************/ -/***************************************************************************/ -/* */ -/* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ -/* */ -/* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ -/* */ -/* The documentation for `fvar' is inconsistent. At one point it says */ -/* that `countSizePairs' should be 3, at another point 2. It should be 2. */ -/* */ -/* The documentation for `gvar' is not intelligible; `cvar' refers you to */ -/* `gvar' and is thus also incomprehensible. */ -/* */ -/* The documentation for `avar' appears correct, but Apple has no fonts */ -/* with an `avar' table, so it is hard to test. */ -/* */ -/* Many thanks to John Jenkins (at Apple) in figuring this out. */ -/* */ -/* */ -/* Apple's `kern' table has some references to tuple indices, but as there */ -/* is no indication where these indices are defined, nor how to */ -/* interpolate the kerning values (different tuples have different */ -/* classes) this issue is ignored. */ -/* */ -/***************************************************************************/ + /*************************************************************************/ + /* */ + /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ + /* */ + /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* */ + /* The documentation for `fvar' is inconsistent. At one point it says */ + /* that `countSizePairs' should be 3, at another point 2. It should */ + /* be 2. */ + /* */ + /* The documentation for `gvar' is not intelligible; `cvar' refers you */ + /* to `gvar' and is thus also incomprehensible. */ + /* */ + /* The documentation for `avar' appears correct, but Apple has no fonts */ + /* with an `avar' table, so it is hard to test. */ + /* */ + /* Many thanks to John Jenkins (at Apple) in figuring this out. */ + /* */ + /* */ + /* Apple's `kern' table has some references to tuple indices, but as */ + /* there is no indication where these indices are defined, nor how to */ + /* interpolate the kerning values (different tuples have different */ + /* classes) this issue is ignored. */ + /* */ + /*************************************************************************/ #include @@ -47,11 +48,9 @@ #include FT_CONFIG_CONFIG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_MULTIPLE_MASTERS_H -#include "ttdriver.h" #include "ttpload.h" #include "ttgxvar.h" @@ -158,6 +157,9 @@ runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; first = points[i++] = FT_GET_USHORT(); + if ( runcnt < 1 ) + goto Exit; + /* first point not included in runcount */ for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); @@ -166,11 +168,15 @@ { first = points[i++] = FT_GET_BYTE(); + if ( runcnt < 1 ) + goto Exit; + for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); } } + Exit: return points; } @@ -205,12 +211,12 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, - FT_Int delta_cnt ) + FT_Offset delta_cnt ) { FT_Short *deltas; FT_Int runcnt; - FT_Int i; - FT_Int j; + FT_Offset i; + FT_Offset j; FT_Memory memory = stream->memory; FT_Error error = TT_Err_Ok; @@ -337,7 +343,8 @@ } - typedef struct GX_GVar_Head_ { + typedef struct GX_GVar_Head_ + { FT_Long version; FT_UShort axisCount; FT_UShort globalCoordCount; @@ -564,7 +571,8 @@ /*************************************************************************/ - typedef struct GX_FVar_Head_ { + typedef struct GX_FVar_Head_ + { FT_Long version; FT_UShort offsetToData; FT_UShort countSizePairs; @@ -576,7 +584,8 @@ } GX_FVar_Head; - typedef struct fvar_axis { + typedef struct fvar_axis_ + { FT_ULong axisTag; FT_ULong minValue; FT_ULong defaultValue; @@ -754,7 +763,7 @@ } ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i ) + for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) { if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) goto Exit; @@ -902,13 +911,15 @@ } else { - for ( i = 0; - i < num_coords && blend->normalizedcoords[i] == coords[i]; - ++i ); - if ( i == num_coords ) - manageCvt = mcvt_retain; - else + manageCvt = mcvt_retain; + for ( i = 0; i < num_coords; ++i ) + { + if ( blend->normalizedcoords[i] != coords[i] ) + { manageCvt = mcvt_load; + break; + } + } /* If we don't change the blend coords then we don't need to do */ /* anything to the cvt table. It will be correct. Otherwise we */ @@ -1127,7 +1138,7 @@ if ( blend == NULL ) { - FT_TRACE2(( "no blend specified!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); error = TT_Err_Ok; goto Exit; @@ -1135,7 +1146,7 @@ if ( face->cvt == NULL ) { - FT_TRACE2(( "no `cvt ' table!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); error = TT_Err_Ok; goto Exit; @@ -1144,7 +1155,7 @@ error = face->goto_table( face, TTAG_cvar, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); error = TT_Err_Ok; goto Exit; @@ -1159,7 +1170,7 @@ table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) { - FT_TRACE2(( "bad table version!\n" )); + FT_TRACE2(( "bad table version\n" )); error = TT_Err_Ok; goto FExit; diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.h b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.h index 706cb4d369b..82dfc4431f2 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.h +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.h @@ -84,7 +84,7 @@ FT_BEGIN_HEADER FT_Fixed* normalizedcoords; FT_MM_Var* mmvar; - FT_Int mmvar_len; + FT_Offset mmvar_len; FT_Bool avar_checked; GX_AVarSegment avar_segment; diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c b/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c index 85c8529ac73..13aa9a27c4c 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -693,7 +693,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* TrueTyoe error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -748,6 +748,13 @@ } + /* The default value for `scan_control' is documented as FALSE in the */ + /* TrueType specification. This is confusing since it implies a */ + /* Boolean value. However, this is not the case, thus both the */ + /* default values of our `scan_type' and `scan_control' fields (which */ + /* the documentation's `scan_control' variable is split into) are */ + /* zero. */ + const TT_GraphicsState tt_default_graphics_state = { 0, 0, 0, @@ -761,7 +768,7 @@ 1, 64, 1, TRUE, 68, 0, 0, 9, 3, - 0, FALSE, 2, 1, 1, 1 + 0, FALSE, 0, 1, 1, 1 }; @@ -784,9 +791,9 @@ /* allocate object */ if ( FT_NEW( exec ) ) - goto Exit; + goto Fail; - /* initialize it */ + /* initialize it; in case of error this deallocates `exec' too */ error = Init_Context( exec, memory ); if ( error ) goto Fail; @@ -795,13 +802,10 @@ driver->context = exec; } - Exit: return driver->context; Fail: - FT_FREE( exec ); - - return 0; + return NULL; } @@ -2190,7 +2194,7 @@ FT_ASSERT( !CUR.face->unpatented_hinting ); #endif - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.projVector.x, CUR.GS.projVector.y ); } @@ -2216,7 +2220,7 @@ Dual_Project( EXEC_OP_ FT_Pos dx, FT_Pos dy ) { - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.dualVector.x, CUR.GS.dualVector.y ); } @@ -4286,13 +4290,21 @@ CUR.numFDefs++; } + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + rec->range = CUR.curRange; - rec->opc = n; + rec->opc = (FT_UInt16)n; rec->start = CUR.IP + 1; rec->active = TRUE; if ( n > CUR.maxFunc ) - CUR.maxFunc = n; + CUR.maxFunc = (FT_UInt16)n; /* Now skip the whole function definition. */ /* We don't allow nested IDEFS & FDEFs. */ @@ -4549,13 +4561,20 @@ CUR.numIDefs++; } - def->opc = args[0]; + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + + def->opc = (FT_Byte)args[0]; def->start = CUR.IP+1; def->range = CUR.curRange; def->active = TRUE; if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = args[0]; + CUR.maxIns = (FT_Byte)args[0]; /* Now skip the whole function definition. */ /* We don't allow nested IDEFs & FDEFs. */ @@ -4821,7 +4840,28 @@ if ( CUR.opcode & 1 ) D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); else - D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + { + FT_Vector* vec1 = CUR.zp0.orus + L; + FT_Vector* vec2 = CUR.zp1.orus + K; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + D = CUR_Func_dualproj( vec1, vec2 ); + D = TT_MULFIX( D, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); + + D = CUR_fast_dualproj( &vec ); + } + } } args[0] = D; @@ -5071,12 +5111,8 @@ return; } - A *= 64; - -#if 0 - if ( ( args[0] & 0x100 ) != 0 && CUR.metrics.pointSize <= A ) + if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) CUR.GS.scan_control = TRUE; -#endif if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) CUR.GS.scan_control = TRUE; @@ -5084,10 +5120,8 @@ if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) CUR.GS.scan_control = TRUE; -#if 0 - if ( ( args[0] & 0x800 ) != 0 && CUR.metrics.pointSize > A ) + if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) CUR.GS.scan_control = FALSE; -#endif if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) CUR.GS.scan_control = FALSE; @@ -5106,16 +5140,8 @@ static void Ins_SCANTYPE( INS_ARG ) { - /* for compatibility with future enhancements, */ - /* we must ignore new modes */ - - if ( args[0] >= 0 && args[0] <= 5 ) - { - if ( args[0] == 3 ) - args[0] = 2; - + if ( args[0] >= 0 ) CUR.GS.scan_type = (FT_Int)args[0]; - } } @@ -5428,7 +5454,7 @@ /* XXX: this is probably wrong... at least it prevents memory */ /* corruption when zp2 is the twilight zone */ - if ( last_point > CUR.zp2.n_points ) + if ( BOUNDS( last_point, CUR.zp2.n_points ) ) { if ( CUR.zp2.n_points > 0 ) last_point = (FT_UShort)(CUR.zp2.n_points - 1); @@ -5516,20 +5542,20 @@ { if ( CUR.GS.both_x_axis ) { - dx = TT_MulFix14( args[0], 0x4000 ); + dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); dy = 0; } else { dx = 0; - dy = TT_MulFix14( args[0], 0x4000 ); + dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); } } else #endif { - dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); + dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); } while ( CUR.GS.loop > 0 ) @@ -5695,8 +5721,8 @@ if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ { - CUR.zp0.org[point].x = TT_MulFix14( distance, CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ), + CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x ); + CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ), CUR.zp0.cur[point] = CUR.zp0.org[point]; } @@ -5883,10 +5909,12 @@ if ( CUR.GS.gep1 == 0 ) { CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.x ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.x ); CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.y ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.y ); CUR.zp1.cur[point] = CUR.zp0.cur[point]; } @@ -6211,9 +6239,13 @@ org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); - new_dist = ( old_range != 0 ) - ? TT_MULDIV( org_dist, cur_range, old_range ) - : cur_dist; + + if ( org_dist ) + new_dist = ( old_range != 0 ) + ? TT_MULDIV( org_dist, cur_range, old_range ) + : cur_dist; + else + new_dist = 0; CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); } @@ -6257,7 +6289,7 @@ /* Local variables for Ins_IUP: */ - typedef struct + typedef struct IUP_WorkerRec_ { FT_Vector* orgs; /* original and current coordinate */ FT_Vector* curs; /* arrays */ @@ -6370,7 +6402,7 @@ { scale_valid = 1; scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ), - 0x10000, orus2 - orus1 ); + 0x10000L, orus2 - orus1 ); } x = ( org1 + delta1 ) + @@ -6434,6 +6466,9 @@ end_point = CUR.pts.contours[contour] - CUR.pts.first_point; first_point = point; + if ( CUR.pts.n_points <= end_point ) + end_point = CUR.pts.n_points; + while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) point++; diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.c b/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.c index 0294a1b7e66..11d662d2d49 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,9 +18,7 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H @@ -144,6 +142,40 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ + /* Compare the face with a list of well-known `tricky' fonts. */ + /* This list shall be expanded as we find more of them. */ + + static FT_Bool + tt_check_trickyness( FT_String* name ) + { +#define TRICK_NAMES_MAX_CHARACTERS 16 +#define TRICK_NAMES_COUNT 7 + static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] = + { + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiShu", + "DFKai-SB", /* kaiu.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ + }; + int nn; + + + if ( !name ) + return FALSE; + + /* Note that we only check the face name at the moment; it might */ + /* be worth to do more checks for a few special cases. */ + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) + if ( ft_strstr( name, trick_names[nn] ) ) + return TRUE; + + return FALSE; + } + + /*************************************************************************/ /* */ /* */ @@ -180,7 +212,7 @@ TT_Face face = (TT_Face)ttface; - library = face->root.driver->root.library; + library = ttface->driver->root.library; sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); if ( !sfnt ) goto Bad_Format; @@ -206,7 +238,7 @@ } #ifdef TT_USE_BYTECODE_INTERPRETER - face->root.face_flags |= FT_FACE_FLAG_HINTER; + ttface->face_flags |= FT_FACE_FLAG_HINTER; #endif /* If we are performing a simple font format check, exit immediately. */ @@ -218,29 +250,37 @@ if ( error ) goto Exit; + if ( tt_check_trickyness( ttface->family_name ) ) + ttface->face_flags |= FT_FACE_FLAG_TRICKY; + error = tt_face_load_hdmx( face, stream ); if ( error ) goto Exit; - if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) + if ( FT_IS_SCALABLE( ttface ) ) { #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !face->root.internal->incremental_interface ) + if ( !ttface->internal->incremental_interface ) error = tt_face_load_loca( face, stream ); if ( !error ) - error = tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #else if ( !error ) - error = tt_face_load_loca( face, stream ) || - tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #endif @@ -262,38 +302,8 @@ if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) unpatented_hinting = TRUE; - /* Compare the face with a list of well-known `tricky' fonts. */ - /* This list shall be expanded as we find more of them. */ if ( !unpatented_hinting ) - { - static const char* const trick_names[] = - { - "DFKaiSho-SB", /* dfkaisb.ttf */ - "DFKai-SB", /* kaiu.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ - NULL - }; - int nn; - - - /* Note that we only check the face name at the moment; it might */ - /* be worth to do more checks for a few special cases. */ - for ( nn = 0; trick_names[nn] != NULL; nn++ ) - { - if ( ttface->family_name && - ft_strstr( ttface->family_name, trick_names[nn] ) ) - { - unpatented_hinting = 1; - break; - } - } - } - - ttface->internal->ignore_unpatented_hinter = - FT_BOOL( !unpatented_hinting ); + ttface->internal->ignore_unpatented_hinter = TRUE; } #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && @@ -325,12 +335,18 @@ FT_LOCAL_DEF( void ) tt_face_done( FT_Face ttface ) /* TT_Face */ { - TT_Face face = (TT_Face)ttface; - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; + TT_Face face = (TT_Face)ttface; + FT_Memory memory; + FT_Stream stream; + SFNT_Service sfnt; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + if ( !face ) + return; + + memory = ttface->memory; + stream = ttface->stream; + sfnt = (SFNT_Service)face->sfnt; /* for `extended TrueType formats' (i.e. compressed versions) */ if ( face->extra.finalizer ) @@ -595,18 +611,15 @@ /* Set default metrics */ { - FT_Size_Metrics* metrics = &size->metrics; - TT_Size_Metrics* metrics2 = &size->ttmetrics; + TT_Size_Metrics* metrics = &size->ttmetrics; - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics2->rotated = FALSE; - metrics2->stretched = FALSE; + metrics->rotated = FALSE; + metrics->stretched = FALSE; /* set default compensation (all 0) */ for ( i = 0; i < 4; i++ ) - metrics2->compensations[i] = 0; + metrics->compensations[i] = 0; } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -669,7 +682,7 @@ if ( !size->cvt_ready ) { FT_UInt i; - TT_Face face = (TT_Face) size->root.face; + TT_Face face = (TT_Face)size->root.face; /* Scale the cvt values to the new ppem. */ @@ -694,8 +707,9 @@ error = tt_size_run_prep( size ); if ( !error ) - size->cvt_ready = 1; + size->cvt_ready = 1; } + Exit: return error; } diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.h b/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.h index 6971013af90..30c8669cb2d 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.h +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -99,6 +99,10 @@ FT_BEGIN_HEADER FT_Short delta_shift; FT_Byte instruct_control; + /* According to Greg Hitchcock from Microsoft, the `scan_control' */ + /* variable as documented in the TrueType specification is a 32-bit */ + /* integer; the high-word part holds the SCANTYPE value, the low-word */ + /* part the SCANCTRL value. We separate it into two fields. */ FT_Bool scan_control; FT_Int scan_type; @@ -190,45 +194,13 @@ FT_BEGIN_HEADER } TT_Transform; - /*************************************************************************/ - /* */ - /* Subglyph loading record. Used to load composite components. */ - /* */ - typedef struct TT_SubglyphRec_ - { - FT_Long index; /* subglyph index; initialized with -1 */ - FT_Bool is_scaled; /* is the subglyph scaled? */ - FT_Bool is_hinted; /* should it be hinted? */ - FT_Bool preserve_pps; /* preserve phantom points? */ - - FT_Long file_offset; - - FT_BBox bbox; - FT_Pos left_bearing; - FT_Pos advance; - - TT_GlyphZoneRec zone; - - FT_Long arg1; /* first argument */ - FT_Long arg2; /* second argument */ - - FT_UShort element_flag; /* current load element flag */ - - TT_Transform transform; /* transformation matrix */ - - FT_Vector pp1, pp2; /* phantom points (horizontal) */ - FT_Vector pp3, pp4; /* phantom points (vertical) */ - - } TT_SubGlyphRec, *TT_SubGlyph_Stack; - - /*************************************************************************/ /* */ /* A note regarding non-squared pixels: */ /* */ /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TIns_Metrics */ - /* record). */ + /* is kept here to explain some definitions in the TT_Size_Metrics */ + /* record). */ /* */ /* The CVT is a one-dimensional array containing values that control */ /* certain important characteristics in a font, like the height of all */ diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttpic.c b/reactos/lib/3rdparty/freetype/src/truetype/ttpic.c new file mode 100644 index 00000000000..27ec4a1d5e5 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttpic.c @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* ttpic.c */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ttpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ttdriver.c */ + FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*); + void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*); + + void + tt_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->truetype ) + { + TTModulePIC* container = (TTModulePIC*)pic_container->truetype; + if(container->tt_services) + FT_Destroy_Class_tt_services(library, container->tt_services); + container->tt_services = NULL; + FT_FREE( container ); + pic_container->truetype = NULL; + } + } + + FT_Error + tt_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + TTModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->truetype = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_tt_services(library, &container->tt_services); + if(error) + goto Exit; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters); +#endif + FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf); +Exit: + if(error) + tt_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttpic.h b/reactos/lib/3rdparty/freetype/src/truetype/ttpic.h new file mode 100644 index 00000000000..84de0fee9e3 --- /dev/null +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttpic.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttpic.h */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPIC_H__ +#define __TTPIC_H__ + + +FT_BEGIN_HEADER + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_TT_SERVICES_GET tt_services +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + typedef struct TTModulePIC_ + { + FT_ServiceDescRec* tt_services; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MultiMastersRec tt_service_gx_multi_masters; +#endif + FT_Service_TTGlyfRec tt_service_truetype_glyf; + } TTModulePIC; + +#define GET_PIC(lib) ((TTModulePIC*)((lib)->pic_container.truetype)) +#define FT_TT_SERVICES_GET (GET_PIC(library)->tt_services) +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET (GET_PIC(library)->tt_service_gx_multi_masters) +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET (GET_PIC(library)->tt_service_truetype_glyf) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __TTPIC_H__ */ + + +/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttpload.c b/reactos/lib/3rdparty/freetype/src/truetype/ttpload.c index 9d3381bf056..a311b03c00c 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttpload.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,18 +58,23 @@ /* */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF( FT_Error ) tt_face_load_loca( TT_Face face, FT_Stream stream ) { FT_Error error; FT_ULong table_len; + FT_Int shift; /* we need the size of the `glyf' table for malformed `loca' tables */ error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); - if ( error ) + + /* it is possible that a font doesn't have a glyf table at all */ + /* or its size is zero */ + if ( error == TT_Err_Table_Missing ) + face->glyf_len = 0; + else if ( error ) goto Exit; FT_TRACE2(( "Locations " )); @@ -82,23 +87,65 @@ if ( face->header.Index_To_Loc_Format != 0 ) { + shift = 2; + if ( table_len >= 0x40000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> 2 ); + face->num_locations = table_len >> shift; } else { + shift = 1; + if ( table_len >= 0x20000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> 1 ); + face->num_locations = table_len >> shift; + } + + if ( face->num_locations != (FT_ULong)face->root.num_glyphs ) + { + FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", + face->num_locations, face->root.num_glyphs )); + + /* we only handle the case where `maxp' gives a larger value */ + if ( face->num_locations < (FT_ULong)face->root.num_glyphs ) + { + FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; + + TT_Table entry = face->dir_tables; + TT_Table limit = entry + face->num_tables; + + FT_Long pos = FT_Stream_Pos( stream ); + FT_Long dist = 0x7FFFFFFFL; + + + /* compute the distance to next table in font file */ + for ( ; entry < limit; entry++ ) + { + FT_Long diff = entry->Offset - pos; + + + if ( diff > 0 && diff < dist ) + dist = diff; + } + + if ( new_loca_len <= dist ) + { + face->num_locations = face->root.num_glyphs; + table_len = new_loca_len; + + FT_TRACE2(( "adjusting num_locations to %d\n", + face->num_locations )); + } + } } /* @@ -156,12 +203,14 @@ } } - /* It isn't mentioned explicitly that the `loca' table must be */ - /* ordered, but implicitly it refers to the length of an entry */ - /* as the difference between the current and the next position. */ - /* Anyway, there do exist (malformed) fonts which don't obey */ - /* this rule, so we are only able to provide an upper bound for */ - /* the size. */ + /* The `loca' table must be ordered; it refers to the length of */ + /* an entry as the difference between the current and the next */ + /* position. However, there do exist (malformed) fonts which */ + /* don't obey this rule, so we are only able to provide an */ + /* upper bound for the size. */ + /* */ + /* We get (intentionally) a wrong, non-zero result in case the */ + /* `glyf' table is missing. */ if ( pos2 >= pos1 ) *asize = (FT_UInt)( pos2 - pos1 ); else @@ -216,7 +265,7 @@ error = face->goto_table( face, TTAG_cvt, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); face->cvt_size = 0; face->cvt = NULL; @@ -301,7 +350,7 @@ face->font_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { @@ -362,7 +411,7 @@ face->cvt_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { diff --git a/reactos/lib/3rdparty/freetype/src/type1/module.mk b/reactos/lib/3rdparty/freetype/src/type1/module.mk index baf98c00ea5..ade0210d76c 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/module.mk +++ b/reactos/lib/3rdparty/freetype/src/type1/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE1_DRIVER define TYPE1_DRIVER -$(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t1_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1afm.c b/reactos/lib/3rdparty/freetype/src/type1/t1afm.c index b81a8df83ab..16dc471c57f 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1afm.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,13 +50,17 @@ /* read a glyph name and return the equivalent glyph index */ static FT_Int t1_get_index( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ) { T1_Font type1 = (T1_Font)user_data; FT_Int n; + /* PS string/name length must be < 16-bit */ + if ( ( len - 0xFFFFU ) > 0 ) + return 0; + for ( n = 0; n < type1->num_glyphs; n++ ) { char* gname = (char*)type1->glyph_names[n]; @@ -88,7 +92,12 @@ FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1driver.c b/reactos/lib/3rdparty/freetype/src/type1/t1driver.c index 3ca21dc1783..8c398eee228 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1driver.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,6 +84,7 @@ return 0; } + static const FT_Service_GlyphDictRec t1_service_glyph_dict = { (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, @@ -91,10 +92,10 @@ }; - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* t1_get_ps_name( T1_Face face ) @@ -102,16 +103,17 @@ return (const char*) face->type1.font_name; } + static const FT_Service_PsFontNameRec t1_service_ps_name = { (FT_PsName_GetFunc)t1_get_ps_name }; - /* - * MULTIPLE MASTERS SERVICE - * - */ + /* + * MULTIPLE MASTERS SERVICE + * + */ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = @@ -125,17 +127,28 @@ #endif - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error t1_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((T1_Face)face)->type1.font_info; - return 0; + + return T1_Err_Ok; + } + + + static FT_Error + t1_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T1_Face)face)->type1.font_extra; + + return T1_Err_Ok; } @@ -143,6 +156,7 @@ t1_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); + return 1; } @@ -152,17 +166,20 @@ PS_PrivateRec* afont_private ) { *afont_private = ((T1_Face)face)->type1.private_dict; - return 0; + + return T1_Err_Ok; } static const FT_Service_PsInfoRec t1_service_ps_info = { (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_GetFontExtraFunc) t1_ps_get_font_extra, (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, (PS_GetFontPrivateFunc)t1_ps_get_font_private, }; + #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { @@ -170,10 +187,11 @@ }; #endif - /* - * SERVICE LIST - * - */ + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec t1_services[] = { @@ -304,7 +322,7 @@ (FT_Face_GetKerningFunc) Get_Kerning, (FT_Face_AttachFunc) T1_Read_Metrics, #endif - (FT_Face_GetAdvancesFunc) 0, + (FT_Face_GetAdvancesFunc) T1_Get_Advances, (FT_Size_RequestFunc) T1_Size_Request, (FT_Size_SelectFunc) 0 }; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1driver.h b/reactos/lib/3rdparty/freetype/src/type1/t1driver.h index ad429440de9..9fecbeb0f8f 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1driver.h +++ b/reactos/lib/3rdparty/freetype/src/type1/t1driver.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1gload.c b/reactos/lib/3rdparty/freetype/src/type1/t1gload.c index e08a4289742..16586153fb8 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1gload.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +18,7 @@ #include #include "t1gload.h" +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H @@ -62,6 +63,11 @@ T1_Font type1 = &face->type1; FT_Error error = T1_Err_Ok; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + decoder->font_matrix = type1->font_matrix; decoder->font_offset = type1->font_offset; @@ -70,10 +76,9 @@ /* For incremental fonts get the character data using the */ /* callback function. */ - if ( face->root.internal->incremental_interface ) - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, char_string ); + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, char_string ); else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -92,21 +97,21 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - decoder->builder.left_bearing.x = metrics.bearing_x; - decoder->builder.left_bearing.y = metrics.bearing_y; - decoder->builder.advance.x = metrics.advance; + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); decoder->builder.advance.y = 0; } @@ -202,6 +207,63 @@ } + FT_LOCAL_DEF( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ) + { + T1_DecoderRec decoder; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_UInt nn; + FT_Error error; + + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + advances[nn] = 0; + + return T1_Err_Ok; + } + + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + for ( nn = 0; nn < count; nn++ ) + { + error = T1_Parse_Glyph( &decoder, first + nn ); + if ( !error ) + advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); + else + advances[nn] = 0; + } + + return T1_Err_Ok; + } + + FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, @@ -236,8 +298,16 @@ if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + else + { + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + } glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -303,11 +373,14 @@ FT_Slot_Internal internal = glyph->root.internal; - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - internal->glyph_matrix = font_matrix; - internal->glyph_delta = font_offset; - internal->glyph_transformed = 1; + glyph->root.metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + glyph->root.metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; } else { @@ -317,8 +390,10 @@ /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - glyph->root.linearHoriAdvance = decoder.builder.advance.x; + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + glyph->root.linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); glyph->root.internal->glyph_transformed = 0; /* make up vertical ones */ @@ -371,8 +446,8 @@ } /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } /* compute the other metrics */ diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1gload.h b/reactos/lib/3rdparty/freetype/src/type1/t1gload.h index de87896dc0e..100df06e8e3 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1gload.h +++ b/reactos/lib/3rdparty/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,13 @@ FT_BEGIN_HEADER T1_Compute_Max_Advance( T1_Face face, FT_Pos* max_advance ); + FT_LOCAL( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ); + FT_LOCAL( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1load.c b/reactos/lib/3rdparty/freetype/src/type1/t1load.c index 55177eed438..d867e942c95 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1load.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,6 +65,7 @@ #include FT_CONFIG_CONFIG_H #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_CALC_H #include "t1load.h" #include "t1errors.h" @@ -213,10 +214,6 @@ } -#define FT_INT_TO_FIXED( a ) ( (a) << 16 ) -#define FT_FIXED_TO_INT( a ) ( FT_RoundFix( a ) >> 16 ) - - /*************************************************************************/ /* */ /* Given a normalized (blend) coordinate, figure out the design */ @@ -230,7 +227,7 @@ if ( ncv <= axismap->blend_points[0] ) - return axismap->design_points[0]; + return INT_TO_FIXED( axismap->design_points[0] ); for ( j = 1; j < axismap->num_points; ++j ) { @@ -241,8 +238,7 @@ axismap->blend_points[j] - axismap->blend_points[j - 1] ); - - return axismap->design_points[j - 1] + + return INT_TO_FIXED( axismap->design_points[j - 1] ) + FT_MulDiv( t, axismap->design_points[j] - axismap->design_points[j - 1], @@ -250,7 +246,7 @@ } } - return axismap->design_points[axismap->num_points - 1]; + return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); } @@ -332,13 +328,13 @@ for ( i = 0 ; i < mmaster.num_axis; ++i ) { mmvar->axis[i].name = mmaster.axis[i].name; - mmvar->axis[i].minimum = FT_INT_TO_FIXED( mmaster.axis[i].minimum); - mmvar->axis[i].maximum = FT_INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ - mmvar->axis[i].strid = 0xFFFFFFFFUL; /* Does not apply */ - mmvar->axis[i].tag = 0xFFFFFFFFUL; /* Does not apply */ + mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */ + mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */ if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); @@ -348,16 +344,15 @@ mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); } - if ( blend->num_designs == 1U << blend->num_axis ) + if ( blend->num_designs == ( 1U << blend->num_axis ) ) { mm_weights_unmap( blend->default_weight_vector, axiscoords, blend->num_axis ); for ( i = 0; i < mmaster.num_axis; ++i ) - mmvar->axis[i].def = - FT_INT_TO_FIXED( mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ) ); + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); } *master = mmvar; @@ -504,7 +499,7 @@ if ( num_coords <= 4 && num_coords > 0 ) { for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FT_FIXED_TO_INT( coords[i] ); + lcoords[i] = FIXED_TO_INT( coords[i] ); error = T1_Set_MM_Design( face, num_coords, lcoords ); } @@ -656,8 +651,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_blend_design_positions:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_blend_design_positions:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -674,7 +669,7 @@ for ( n = 0; n < num_designs; n++ ) { - T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; T1_Token token; FT_Int axis, n_axis; @@ -687,6 +682,15 @@ if ( n == 0 ) { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " invalid number of axes: %d\n", + n_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + num_axis = n_axis; error = t1_allocate_blend( face, num_designs, num_axis ); if ( error ) @@ -835,8 +839,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_weight_vector:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_weight_vector:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -852,9 +856,9 @@ else if ( blend->num_designs != (FT_UInt)num_designs ) { FT_ERROR(( "parse_weight_vector:" - " /BlendDesignPosition and /WeightVector have\n" )); - FT_ERROR(( " " - " different number of elements!\n" )); + " /BlendDesignPosition and /WeightVector have\n" + " " + " different number of elements\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -941,6 +945,12 @@ } break; + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + objects = &dummy_object; + max_objects = 0; + break; + case T1_FIELD_LOCATION_PRIVATE: dummy_object = &face->type1.private_dict; objects = &dummy_object; @@ -1130,7 +1140,7 @@ cur = parser->root.cursor; if ( cur >= limit ) { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); + FT_ERROR(( "parse_encoding: out of bounds\n" )); parser->root.error = T1_Err_Invalid_File_Format; return; } @@ -1265,6 +1275,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = FT_Err_Unknown_File_Format; + return; + } } else { @@ -1310,9 +1333,9 @@ PS_Table table = &loader->subrs; FT_Memory memory = parser->root.memory; FT_Error error; - FT_Int n, num_subrs; + FT_Int num_subrs; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)face->psaux; T1_Skip_Spaces( parser ); @@ -1346,18 +1369,17 @@ goto Fail; } - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - for ( n = 0; n < num_subrs; n++ ) + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for (;;) { FT_Long idx, size; FT_Byte* base; - /* If the next token isn't `dup', we are also done. This */ - /* happens when there are `holes' in the Subrs array. */ + /* If the next token isn't `dup' we are done. */ if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) break; @@ -1397,7 +1419,10 @@ FT_Byte* temp; - if ( size <= face->type1.private_dict.lenIV ) + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) { error = T1_Err_Invalid_File_Format; goto Fail; @@ -1603,15 +1628,11 @@ } } - if ( loader->num_glyphs ) - return; - else - loader->num_glyphs = n; + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)name_table->elements[0] ) && - notdef_found ) + if ( notdef_found && + ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) { /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ /* name and code entries to swap_table. Then place notdef_index */ @@ -1680,7 +1701,7 @@ /* and add our own /.notdef glyph to index 0. */ /* 0 333 hsbw endchar */ - FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; + FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; char* notdef_name = (char *)".notdef"; @@ -1718,7 +1739,7 @@ goto Fail; /* we added a glyph. */ - loader->num_glyphs = n + 1; + loader->num_glyphs += 1; } return; @@ -2132,7 +2153,7 @@ #endif if ( !loader.charstrings.init ) { - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" )); + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); error = T1_Err_Invalid_File_Format; } @@ -2161,8 +2182,8 @@ /* the index is then stored in type1.encoding.char_index, and */ /* a the name to type1.encoding.char_name */ - min_char = +32000; - max_char = -32000; + min_char = 0; + max_char = 0; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) @@ -2188,25 +2209,14 @@ { if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) - max_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; } break; } } } - /* - * Yes, this happens: Certain PDF-embedded fonts have only a - * `.notdef' glyph defined! - */ - - if ( min_char > max_char ) - { - min_char = 0; - max_char = loader.encoding_table.max_elems; - } - type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1objs.c b/reactos/lib/3rdparty/freetype/src/type1/t1objs.c index 3d08336c600..e9357e6c573 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1objs.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_IDS_H @@ -90,7 +91,7 @@ FT_LOCAL_DEF( FT_Error ) T1_Size_Init( T1_Size size ) { - FT_Error error = 0; + FT_Error error = T1_Err_Ok; PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); @@ -191,72 +192,75 @@ FT_LOCAL_DEF( void ) T1_Face_Done( T1_Face face ) { - if ( face ) - { - FT_Memory memory = face->root.memory; - T1_Font type1 = &face->type1; + FT_Memory memory; + T1_Font type1; + if ( !face ) + return; + + memory = face->root.memory; + type1 = &face->type1; + #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - if ( face->buildchar ) - { - FT_FREE( face->buildchar ); + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); - face->buildchar = NULL; - face->len_buildchar = 0; - } + face->buildchar = NULL; + face->len_buildchar = 0; + } - T1_Done_Blend( face ); - face->blend = 0; + T1_Done_Blend( face ); + face->blend = 0; #endif - /* release font info strings */ - { - PS_FontInfo info = &type1->font_info; + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - } + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); - FT_FREE( type1->subrs ); - FT_FREE( type1->subrs_len ); + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); - FT_FREE( type1->subrs_block ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); #ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); #endif - /* release unicode map, if any */ + /* release unicode map, if any */ #if 0 - FT_FREE( face->unicode_map_rec.maps ); - face->unicode_map_rec.num_maps = 0; - face->unicode_map = NULL; + FT_FREE( face->unicode_map_rec.maps ); + face->unicode_map_rec.num_maps = 0; + face->unicode_map = NULL; #endif - face->root.family_name = 0; - face->root.style_name = 0; - } + face->root.family_name = NULL; + face->root.style_name = NULL; } @@ -298,7 +302,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -324,7 +327,7 @@ goto Exit; /* check the face index */ - if ( face_index != 0 ) + if ( face_index > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = T1_Err_Invalid_Argument; @@ -341,7 +344,7 @@ root->num_glyphs = type1->num_glyphs; - root->face_index = face_index; + root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | @@ -356,11 +359,18 @@ /* XXX: TODO -- add kerning with .afm support */ + + /* The following code to extract the family and the style is very */ + /* simplistic and might get some things wrong. For a full-featured */ + /* algorithm you might have a look at the whitepaper given at */ + /* */ + /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; - /* assume "Regular" style if we don't know better */ - root->style_name = (char *)"Regular"; + root->style_name = NULL; + if ( root->family_name ) { char* full = info->full_name; @@ -369,6 +379,9 @@ if ( full ) { + FT_Bool the_same = TRUE; + + while ( *full ) { if ( *full == *family ) @@ -384,12 +397,17 @@ family++; else { + the_same = FALSE; + if ( !*family ) root->style_name = full; break; } } } + + if ( the_same ) + root->style_name = (char *)"Regular"; } } else @@ -399,6 +417,15 @@ root->family_name = type1->font_name; } + if ( !root->style_name ) + { + if ( info->weight ) + root->style_name = info->weight; + else + /* assume `Regular' style because we don't know better */ + root->style_name = (char *)"Regular"; + } + /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) @@ -441,9 +468,9 @@ /* in case of error, keep the standard width */ if ( !error ) - root->max_advance_width = (FT_Short)max_advance; + root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); else - error = 0; /* clear error */ + error = T1_Err_Ok; /* clear error */ } root->max_advance_height = root->height; @@ -465,7 +492,7 @@ charmap.face = root; - /* first of all, try to synthetize a Unicode charmap */ + /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1parse.c b/reactos/lib/3rdparty/freetype/src/type1/t1parse.c index 1b252c74833..1bef56bcfac 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1parse.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -65,14 +64,16 @@ /*************************************************************************/ + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + static FT_Error read_pfb_tag( FT_Stream stream, FT_UShort *atag, - FT_Long *asize ) + FT_ULong *asize ) { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; *atag = 0; @@ -82,7 +83,7 @@ { if ( tag == 0x8001U || tag == 0x8002U ) { - if ( !FT_READ_LONG_LE( size ) ) + if ( !FT_READ_ULONG_LE( size ) ) *asize = size; } @@ -100,22 +101,25 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong dummy; if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = read_pfb_tag( stream, &tag, &size ); + error = read_pfb_tag( stream, &tag, &dummy ); if ( error ) goto Exit; + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) goto Exit; if ( !FT_FRAME_ENTER( header_length ) ) { - error = 0; + error = T1_Err_Ok; if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) error = T1_Err_Unknown_File_Format; @@ -136,7 +140,7 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); @@ -170,19 +174,19 @@ /* Here a short summary of what is going on: */ /* */ /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ + /* the base dictionary if this is possible (i.e., for PFB */ /* files). Otherwise, we load the whole font into memory. */ /* */ /* When `loading' the base dictionary, we only setup pointers */ /* in the case of a memory-based stream. Otherwise, we */ /* allocate and load the base dictionary in it. */ /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ /* parser->in_memory is set if we have a memory stream. */ /* */ - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ if ( FT_STREAM_SEEK( 0L ) ) goto Exit; @@ -217,7 +221,7 @@ } else { - /* read segment in memory - this is clumsy, but so does the format */ + /* read segment in memory -- this is clumsy, but so does the format */ if ( FT_ALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; @@ -260,7 +264,7 @@ FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; FT_Error error = T1_Err_Ok; - FT_Long size; + FT_ULong size; if ( parser->in_pfb ) @@ -293,13 +297,13 @@ /* and allocate private dictionary buffer */ if ( parser->private_len == 0 ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); error = T1_Err_Invalid_File_Format; goto Fail; } - if ( FT_STREAM_SEEK( start_pos ) || + if ( FT_STREAM_SEEK( start_pos ) || FT_ALLOC( parser->private_dict, parser->private_len ) ) goto Fail; @@ -349,8 +353,8 @@ cur++; if ( cur >= limit ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " could not find `eexec' keyword\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " could not find `eexec' keyword\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -403,13 +407,13 @@ cur++; else { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " `eexec' not properly terminated\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " `eexec' not properly terminated\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } - size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - ( cur - parser->base_dict ); if ( parser->in_memory ) { diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1parse.h b/reactos/lib/3rdparty/freetype/src/type1/t1parse.h index 6fa4ca624a2..fb1c8a88308 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1parse.h +++ b/reactos/lib/3rdparty/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,10 +64,10 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* base_dict; - FT_Long base_len; + FT_ULong base_len; FT_Byte* private_dict; - FT_Long private_len; + FT_ULong private_len; FT_Bool in_pfb; FT_Bool in_memory; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1tokens.h b/reactos/lib/3rdparty/freetype/src/type1/t1tokens.h index 788c811b049..2d692f0e619 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1tokens.h +++ b/reactos/lib/3rdparty/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,13 @@ T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, T1_FIELD_DICT_FONTDICT ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, + T1_FIELD_DICT_FONTDICT ) #undef FT_STRUCTURE #define FT_STRUCTURE PS_PrivateRec @@ -87,7 +94,9 @@ T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, T1_FIELD_DICT_PRIVATE ) - + T1_FIELD_BOOL ( "ForceBold", force_bold, + T1_FIELD_DICT_PRIVATE ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec diff --git a/reactos/lib/3rdparty/freetype/src/type42/module.mk b/reactos/lib/3rdparty/freetype/src/type42/module.mk index 8bd40a5cc49..b3f10a8d3c8 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/module.mk +++ b/reactos/lib/3rdparty/freetype/src/type42/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE42_DRIVER define TYPE42_DRIVER -$(OPEN_DRIVER)t42_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t42_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/type42/rules.mk b/reactos/lib/3rdparty/freetype/src/type42/rules.mk index 55630619554..eac1081eb1f 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/rules.mk +++ b/reactos/lib/3rdparty/freetype/src/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003 by +# Copyright 2002, 2003, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -32,7 +32,8 @@ T42_DRV_SRC := $(T42_DIR)/t42objs.c \ # Type42 driver headers # T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ - $(T42_DIR)/t42error.h + $(T42_DIR)/t42error.h \ + $(T42_DIR)/t42types.h # Type42 driver object(s) diff --git a/reactos/lib/3rdparty/freetype/src/type42/t42drivr.c b/reactos/lib/3rdparty/freetype/src/type42/t42drivr.c index a6e4cf4b651..820c679612e 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/t42drivr.c +++ b/reactos/lib/3rdparty/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2006, 2007, 2009 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -49,11 +49,11 @@ #define FT_COMPONENT trace_t42 - /* - * - * GLYPH DICT SERVICE - * - */ + /* + * + * GLYPH DICT SERVICE + * + */ static FT_Error t42_get_glyph_name( T42_Face face, @@ -94,11 +94,11 @@ }; - /* - * - * POSTSCRIPT NAME SERVICE - * - */ + /* + * + * POSTSCRIPT NAME SERVICE + * + */ static const char* t42_get_ps_font_name( T42_Face face ) @@ -113,17 +113,28 @@ }; - /* - * - * POSTSCRIPT INFO SERVICE - * - */ + /* + * + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error t42_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((T42_Face)face)->type1.font_info; + + return T42_Err_Ok; + } + + + static FT_Error + t42_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T42_Face)face)->type1.font_extra; + return T42_Err_Ok; } @@ -132,6 +143,7 @@ t42_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); + return 1; } @@ -141,6 +153,7 @@ PS_PrivateRec* afont_private ) { *afont_private = ((T42_Face)face)->type1.private_dict; + return T42_Err_Ok; } @@ -148,16 +161,17 @@ static const FT_Service_PsInfoRec t42_service_ps_info = { (PS_GetFontInfoFunc) t42_ps_get_font_info, + (PS_GetFontExtraFunc) t42_ps_get_font_extra, (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, (PS_GetFontPrivateFunc)t42_ps_get_font_private }; - /* - * - * SERVICE LIST - * - */ + /* + * + * SERVICE LIST + * + */ static const FT_ServiceDescRec t42_services[] = { diff --git a/reactos/lib/3rdparty/freetype/src/type42/t42drivr.h b/reactos/lib/3rdparty/freetype/src/type42/t42drivr.h index 98b7410b670..4717e4613f3 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/t42drivr.h +++ b/reactos/lib/3rdparty/freetype/src/type42/t42drivr.h @@ -25,6 +25,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; diff --git a/reactos/lib/3rdparty/freetype/src/type42/t42objs.c b/reactos/lib/3rdparty/freetype/src/type42/t42objs.c index db04fde367a..9081ffc6d22 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/t42objs.c +++ b/reactos/lib/3rdparty/freetype/src/type42/t42objs.c @@ -4,7 +4,8 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -19,7 +20,6 @@ #include "t42parse.h" #include "t42error.h" #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H #include FT_LIST_H @@ -70,7 +70,7 @@ if ( !loader.charstrings.init ) { - FT_ERROR(( "T42_Open_Face: no charstrings array in face!\n" )); + FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); error = T42_Err_Invalid_File_Format; } @@ -100,8 +100,8 @@ /* The index is then stored in type1.encoding.char_index, and */ /* the name in type1.encoding.char_name */ - min_char = +32000; - max_char = -32000; + min_char = 0; + max_char = 0; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) @@ -127,13 +127,14 @@ { if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) - max_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; } break; } } } + type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; @@ -188,7 +189,7 @@ goto Exit; /* check the face index */ - if ( face_index != 0 ) + if ( face_index > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = T42_Err_Invalid_Argument; @@ -202,7 +203,7 @@ root->num_glyphs = type1->num_glyphs; root->num_charmaps = 0; - root->face_index = face_index; + root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | @@ -328,7 +329,7 @@ charmap.face = root; - /* first of all, try to synthetize a Unicode charmap */ + /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; @@ -392,50 +393,50 @@ FT_Memory memory; - if ( face ) - { - type1 = &face->type1; - info = &type1->font_info; - memory = face->root.memory; + if ( !face ) + return; - /* delete internal ttf face prior to freeing face->ttf_data */ - if ( face->ttf_face ) - FT_Done_Face( face->ttf_face ); + type1 = &face->type1; + info = &type1->font_info; + memory = face->root.memory; - /* release font info strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); + /* delete internal ttf face prior to freeing face->ttf_data */ + if ( face->ttf_face ) + FT_Done_Face( face->ttf_face ); - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); + /* release font info strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); - FT_FREE( face->ttf_data ); + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + + FT_FREE( face->ttf_data ); #if 0 - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); #endif - /* release unicode map, if any */ - FT_FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; - face->root.family_name = 0; - face->root.style_name = 0; - } + face->root.family_name = 0; + face->root.style_name = 0; } @@ -519,7 +520,7 @@ FT_Activate_Size( size->ttsize ); - error = FT_Select_Size( face->ttf_face, strike_index ); + error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); if ( !error ) ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; diff --git a/reactos/lib/3rdparty/freetype/src/type42/t42parse.c b/reactos/lib/3rdparty/freetype/src/type42/t42parse.c index 7148379644f..13bda64c837 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/t42parse.c +++ b/reactos/lib/3rdparty/freetype/src/type42/t42parse.c @@ -4,7 +4,8 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -19,7 +20,6 @@ #include "t42error.h" #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H -#include FT_LIST_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -69,6 +69,13 @@ T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec #undef T1CODE @@ -296,7 +303,7 @@ cur = parser->root.cursor; if ( cur >= limit ) { - FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); + FT_ERROR(( "t42_parse_encoding: out of bounds\n" )); parser->root.error = T42_Err_Invalid_File_Format; return; } @@ -464,14 +471,14 @@ else { - FT_ERROR(( "t42_parse_encoding: invalid token!\n" )); + FT_ERROR(( "t42_parse_encoding: invalid token\n" )); parser->root.error = T42_Err_Invalid_File_Format; } } } - typedef enum + typedef enum T42_Load_Status_ { BEFORE_START, BEFORE_TABLE_DIR, @@ -517,7 +524,7 @@ if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) { - FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector!\n" )); + FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -562,7 +569,7 @@ if ( allocated ) { FT_ERROR(( "t42_parse_sfnts: " - "can't handle mixed binary and hex strings!\n" )); + "can't handle mixed binary and hex strings\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -578,7 +585,7 @@ parser->root.cursor += string_size + 1; if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -586,7 +593,7 @@ if ( !string_buf ) { - FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array!\n" )); + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -597,7 +604,7 @@ if ( !string_size ) { - FT_ERROR(( "t42_parse_sfnts: invalid string!\n" )); + FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -662,7 +669,7 @@ /* all other tables are just copied */ if ( count >= ttf_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -709,7 +716,7 @@ if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -751,14 +758,14 @@ } else { - FT_ERROR(( "t42_parse_charstrings: invalid token!\n" )); + FT_ERROR(( "t42_parse_charstrings: invalid token\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -818,7 +825,7 @@ if ( cur + 1 >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -849,7 +856,7 @@ (void)T1_ToInt( parser ); if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -872,7 +879,7 @@ if ( !notdef_found ) { - FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph!\n" )); + FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -976,6 +983,10 @@ dummy_object = &face->type1.font_info; break; + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + break; + case T1_FIELD_LOCATION_BBOX: dummy_object = &face->type1.font_bbox; break; diff --git a/reactos/lib/3rdparty/freetype/src/type42/t42types.h b/reactos/lib/3rdparty/freetype/src/type42/t42types.h index 6626b04458a..c7c2db490df 100644 --- a/reactos/lib/3rdparty/freetype/src/type42/t42types.h +++ b/reactos/lib/3rdparty/freetype/src/type42/t42types.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002, 2003, 2006 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -35,7 +35,9 @@ FT_BEGIN_HEADER T1_FontRec type1; const void* psnames; const void* psaux; +#if 0 const void* afm_data; +#endif FT_Byte* ttf_data; FT_ULong ttf_size; FT_Face ttf_face; @@ -48,7 +50,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* __T42TYPES_H__ */ /* END */ diff --git a/reactos/lib/3rdparty/freetype/src/winfonts/module.mk b/reactos/lib/3rdparty/freetype/src/winfonts/module.mk index 0ace3ae6de0..b44d7f0570a 100644 --- a/reactos/lib/3rdparty/freetype/src/winfonts/module.mk +++ b/reactos/lib/3rdparty/freetype/src/winfonts/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += WINDOWS_DRIVER define WINDOWS_DRIVER -$(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, winfnt_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) endef diff --git a/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.c b/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.c index 4aa974410f3..6b3a4e17f20 100644 --- a/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.c +++ b/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -342,7 +342,7 @@ if ( !font_count || !font_offset ) { - FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); + FT_TRACE2(( "this file doesn't contain any FNT resources\n" )); error = FNT_Err_Invalid_File_Format; goto Exit; } @@ -360,9 +360,11 @@ if ( face_index >= font_count ) { - error = FNT_Err_Bad_Argument; + error = FNT_Err_Invalid_Argument; goto Exit; } + else if ( face_index < 0 ) + goto Exit; if ( FT_NEW( face->font ) ) goto Exit; @@ -564,7 +566,7 @@ if ( face_index >= face->root.num_faces ) { - error = FNT_Err_Bad_Argument; + error = FNT_Err_Invalid_Argument; goto Exit; } } @@ -610,13 +612,14 @@ char_code -= cmap->first; if ( char_code < cmap->count ) - gindex = char_code + 1; /* we artificially increase the glyph index; */ - /* FNT_Load_Glyph reverts to the right one */ + /* we artificially increase the glyph index; */ + /* FNT_Load_Glyph reverts to the right one */ + gindex = (FT_UInt)( char_code + 1 ); return gindex; } - static FT_UInt + static FT_UInt32 fnt_cmap_char_next( FNT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -636,7 +639,7 @@ if ( char_code < cmap->count ) { result = cmap->first + char_code; - gindex = char_code + 1; + gindex = (FT_UInt)( char_code + 1 ); } } @@ -652,7 +655,9 @@ (FT_CMap_InitFunc) fnt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)fnt_cmap_char_index, - (FT_CMap_CharNextFunc) fnt_cmap_char_next + (FT_CMap_CharNextFunc) fnt_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; @@ -661,16 +666,18 @@ static void FNT_Face_Done( FNT_Face face ) { - if ( face ) - { - FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Memory memory; - fnt_font_done( face ); + if ( !face ) + return; - FT_FREE( face->root.available_sizes ); - face->root.num_fixed_sizes = 0; - } + memory = FT_FACE_MEMORY( face ); + + fnt_font_done( face ); + + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; } @@ -690,18 +697,14 @@ /* try to load font from a DLL */ error = fnt_face_get_dll_font( face, face_index ); + if ( !error && face_index < 0 ) + goto Exit; + if ( error == FNT_Err_Unknown_File_Format ) { /* this didn't work; try to load a single FNT font */ FNT_Font font; - - if ( face_index > 0 ) - { - error = FNT_Err_Bad_Argument; - goto Exit; - } - if ( FT_NEW( face->font ) ) goto Exit; @@ -712,6 +715,14 @@ font->fnt_size = stream->size; error = fnt_font_load( font, stream ); + + if ( !error ) + { + if ( face_index > 0 ) + error = FNT_Err_Invalid_Argument; + else if ( face_index < 0 ) + goto Exit; + } } if ( error ) @@ -725,6 +736,8 @@ FT_PtrDist family_size; + root->face_index = face_index; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL; @@ -772,7 +785,7 @@ * => nominal_point_size contains incorrect value; * use pixel_height as the nominal height */ - if ( bsize->y_ppem > font->header.pixel_height << 6 ) + if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) ) { FT_TRACE2(( "use pixel_height as the nominal height\n" )); @@ -820,7 +833,7 @@ if ( font->header.face_name_offset >= font->header.file_size ) { - FT_TRACE2(( "invalid family name offset!\n" )); + FT_TRACE2(( "invalid family name offset\n" )); error = FNT_Err_Invalid_File_Format; goto Fail; } @@ -901,7 +914,7 @@ switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = FNT_Err_Ok; break; @@ -967,7 +980,7 @@ if ( offset >= font->header.file_size ) { - FT_TRACE2(( "invalid FNT offset!\n" )); + FT_TRACE2(( "invalid FNT offset\n" )); error = FNT_Err_Invalid_File_Format; goto Exit; } diff --git a/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.h b/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.h index ca75c9501a2..70a90861abf 100644 --- a/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.h +++ b/reactos/lib/3rdparty/freetype/src/winfonts/winfnt.h @@ -28,6 +28,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + typedef struct WinMZ_HeaderRec_ { FT_UShort magic; From 66aae4c0fa670dc3d38247b0a7e893aea7c6c58e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 26 May 2010 11:07:12 +0000 Subject: [PATCH 045/292] [FREETYPE] - Cleanup old files - Remove setjmplongjmp.s - Correction to last commit message: the conversion patch was already applied svn path=/trunk/; revision=47361 --- reactos/lib/3rdparty/freetype/README.CVS | 50 ---------- reactos/lib/3rdparty/freetype/freetype.rbuild | 5 - .../3rdparty/freetype/i386/setjmplongjmp.s | 91 ------------------ .../3rdparty/freetype/src/base/_ftbase_ros.c | 42 --------- .../freetype/src/base/_ftmulfix_ros.c | 92 ------------------- 5 files changed, 280 deletions(-) delete mode 100644 reactos/lib/3rdparty/freetype/README.CVS delete mode 100644 reactos/lib/3rdparty/freetype/i386/setjmplongjmp.s delete mode 100644 reactos/lib/3rdparty/freetype/src/base/_ftbase_ros.c delete mode 100644 reactos/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c diff --git a/reactos/lib/3rdparty/freetype/README.CVS b/reactos/lib/3rdparty/freetype/README.CVS deleted file mode 100644 index 63afddfbb52..00000000000 --- a/reactos/lib/3rdparty/freetype/README.CVS +++ /dev/null @@ -1,50 +0,0 @@ -The CVS archive doesn't contain pre-built configuration scripts for -UNIXish platforms. To generate them say - - sh autogen.sh - -which in turn depends on the following packages: - - automake (1.9.6) - libtool (1.5.22) - autoconf (2.59c) - -The versions given in parentheses are known to work. Newer versions -should work too, of course. Note that autogen.sh also sets up proper -file permissions for the `configure' and auxiliary scripts. - -A very common problem is that this script complains that the `aclocal' -program doesn't accept a `--force' option: - - generating `configure.ac' - running `aclocal -I . --force' - aclocal: unrecognized option -- `--force' - Try `aclocal --help' for more information. - error while running `aclocal -I . --force' - -This means that your version of the automake package is too old. -Please update it before trying to build FreeType. - - -For static builds which don't use platform specific optimizations, no -configure script is necessary at all; saying - - make setup ansi - make - -should work on all platforms which have GNU make (or makepp). - - ----------------------------------------------------------------------- - -Copyright 2005, 2006, 2007 by -David Turner, Robert Wilhelm, and Werner Lemberg. - -This file is part of the FreeType project, and may only be used, -modified, and distributed under the terms of the FreeType project -license, LICENSE.TXT. By continuing to use, modify, or distribute -this file you indicate that you have read the license and understand -and accept it fully. - - ---- end of README.CVS --- diff --git a/reactos/lib/3rdparty/freetype/freetype.rbuild b/reactos/lib/3rdparty/freetype/freetype.rbuild index 25fbc6065fe..5c41eb1d442 100644 --- a/reactos/lib/3rdparty/freetype/freetype.rbuild +++ b/reactos/lib/3rdparty/freetype/freetype.rbuild @@ -10,11 +10,6 @@ - - - setjmplongjmp.s - - ftbase.c diff --git a/reactos/lib/3rdparty/freetype/i386/setjmplongjmp.s b/reactos/lib/3rdparty/freetype/i386/setjmplongjmp.s deleted file mode 100644 index d0e13a5b064..00000000000 --- a/reactos/lib/3rdparty/freetype/i386/setjmplongjmp.s +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: FreeType implementation for ReactOS - * PURPOSE: Implementation of _setjmp/longjmp - * FILE: thirdparty/freetype/i386/setjmplongjmp.s - * PROGRAMMER: Ge van Geldorp (ge@gse.nl) - * NOTES: Copied from glibc. - * I have the feeling this could be implemented using the SEH - * routines, but if it's good enough for glibc it's propably - * good enough for me... - * The MingW headers define jmp_buf to be an array of 16 ints, - * based on the jmp_buf used by MSCVRT. We're using only 6 of - * them, so plenty of space. - */ - -#define JB_BX 0 -#define JB_SI 1 -#define JB_DI 2 -#define JB_BP 3 -#define JB_SP 4 -#define JB_PC 5 - -#define PCOFF 0 - -#define JMPBUF 4 - -/* - * int - * _setjmp(jmp_buf env); - * - * Parameters: - * [ESP+04h] - jmp_buf env - * Registers: - * None - * Returns: - * 0 - * Notes: - * Sets up the jmp_buf - */ -.globl __setjmp -__setjmp: - xorl %eax, %eax - movl JMPBUF(%esp), %edx - - /* Save registers. */ - movl %ebx, (JB_BX*4)(%edx) - movl %esi, (JB_SI*4)(%edx) - movl %edi, (JB_DI*4)(%edx) - leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ - movl %ecx, (JB_SP*4)(%edx) - movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */ - movl %ecx, (JB_PC*4)(%edx) - movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ - ret - -#define VAL 8 - -/* - * void - * longjmp(jmp_buf env, int value); - * - * Parameters: - * [ESP+04h] - jmp_buf setup by _setjmp - * [ESP+08h] - int value to return - * Registers: - * None - * Returns: - * Doesn't return - * Notes: - * Non-local goto - */ -.globl _longjmp -_longjmp: - movl JMPBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ - - movl VAL(%esp), %eax /* Second argument is return value. */ - testl %eax, %eax - jnz 0f - incl %eax -0: - /* Save the return address now. */ - movl (JB_PC*4)(%ecx), %edx - /* Restore registers. */ - movl (JB_BX*4)(%ecx), %ebx - movl (JB_SI*4)(%ecx), %esi - movl (JB_DI*4)(%ecx), %edi - movl (JB_BP*4)(%ecx), %ebp - movl (JB_SP*4)(%ecx), %esp - /* Jump to saved PC. */ - jmp *%edx diff --git a/reactos/lib/3rdparty/freetype/src/base/_ftbase_ros.c b/reactos/lib/3rdparty/freetype/src/base/_ftbase_ros.c deleted file mode 100644 index e1d32483287..00000000000 --- a/reactos/lib/3rdparty/freetype/src/base/_ftbase_ros.c +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbase.c */ -/* */ -/* Single object library component (body only). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#define FT_MulFix FT_MulFix_wrong -#include "ftcalc.c" -#undef FT_MulFix -#include "_ftmulfix_ros.c" - -#include "ftdbgmem.c" -#include "ftgloadr.c" -#include "ftnames.c" -#include "ftobjs.c" -#include "ftoutln.c" -#include "ftrfork.c" -#include "ftstream.c" -#include "fttrigon.c" -#include "ftutil.c" - -#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include -#endif - -/* END */ diff --git a/reactos/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c b/reactos/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c deleted file mode 100644 index b5d448c9509..00000000000 --- a/reactos/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c +++ /dev/null @@ -1,92 +0,0 @@ - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { - /* use inline assembly to speed up things a bit */ - -#if defined( __GNUC__ ) && defined( i386 ) - - FT_Long result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - "mov %%eax, %0\n" - : "=r"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx" - ); - return result; - -#elif 1 - - FT_Long sa, sb; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFU; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); - } - - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); - - return (FT_Long)ua; - -#else /* 0 */ - - FT_Long s; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000UL ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFUL; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); - } - - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); - -#endif /* 0 */ - - } From 7dc83b2932efd55e8cfe27cc665a567af9b2094c Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 26 May 2010 11:28:02 +0000 Subject: [PATCH 046/292] [USETUP] - Spanish translation update by Javier Remacha. Fixes bug 4367. - Fixed a typo in Italian and English. - Some other Spanish and Italian translation updates by Javier and me. svn path=/trunk/; revision=47362 --- reactos/base/setup/usetup/lang/en-US.h | 2 +- reactos/base/setup/usetup/lang/es-ES.h | 20 ++- reactos/base/setup/usetup/lang/it-IT.h | 12 +- reactos/base/setup/welcome/lang/es-ES.rc | 2 +- reactos/dll/cpl/usrmgr/lang/es-ES.rc | 219 +++++++++++++++++++++++ reactos/dll/cpl/usrmgr/rsrc.rc | 1 + reactos/dll/win32/devmgr/lang/es-ES.rc | 54 +++--- reactos/dll/win32/shell32/lang/es-ES.rc | 12 +- reactos/dll/win32/shell32/lang/it-IT.rc | 10 ++ reactos/dll/win32/syssetup/lang/es-ES.rc | 4 +- 10 files changed, 291 insertions(+), 45 deletions(-) create mode 100644 reactos/dll/cpl/usrmgr/lang/es-ES.rc diff --git a/reactos/base/setup/usetup/lang/en-US.h b/reactos/base/setup/usetup/lang/en-US.h index 1467dc764dc..9038002050d 100644 --- a/reactos/base/setup/usetup/lang/en-US.h +++ b/reactos/base/setup/usetup/lang/en-US.h @@ -93,7 +93,7 @@ static MUI_ENTRY enUSWelcomePageEntries[] = { 8, 19, - "\x07 Press L to view the ReactOS Licensing Terms and Conditions", + "\x07 Press L to view the ReactOS Licensing Terms and Conditions.", TEXT_STYLE_NORMAL }, { diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index 1d5599f720f..c01630efcb7 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -94,7 +94,7 @@ static MUI_ENTRY esESWelcomePageEntries[] = { 8, 19, - "\x07 Presione L para ver las condiciones y t‚rminos de licencia", + "\x07 Presione L para ver las condiciones y t‚rminos de licencia.", TEXT_STYLE_NORMAL }, { @@ -194,18 +194,24 @@ static MUI_ENTRY esESIntroPageEntries[] = { 8, 19, - "- El comprobador de integridad del sistema de archivos no est  a£n implementado.", + "- El comprobador de integridad del sistema de archivos no est  a£n", TEXT_STYLE_NORMAL }, { 8, - 23, - "\x07 Presione ENTER para instalar ReactOS.", + 20, + " implementado.", TEXT_STYLE_NORMAL }, { 8, 25, + "\x07 Presione ENTER para instalar ReactOS.", + TEXT_STYLE_NORMAL + }, + { + 8, + 27, "\x07 Presione F3 para salir sin instalar ReactOS.", TEXT_STYLE_NORMAL }, @@ -358,7 +364,7 @@ static MUI_ENTRY esESDevicePageEntries[] = { 6, 8, - "La lista inferior muestra la configuraci¢n del dispositivo actual.", + "La lista inferior muestra la configuraci¢n actual de dispositivos.", TEXT_STYLE_NORMAL }, { @@ -1598,7 +1604,7 @@ MUI_STRING esESStrings[] = {STRING_INSTALLDELETEPARTITION, " ENTER = Instalar D = Borrar Partici¢n F3 = Salir"}, {STRING_PARTITIONSIZE, - "Tamaño de la nueva partici¢n:"}, + "Tama¤o de la nueva partici¢n:"}, {STRING_CHOOSENEWPARTITION, "Ha elegido crear una nueva partici¢n en"}, {STRING_HDDSIZE, @@ -1696,6 +1702,6 @@ MUI_STRING esESStrings[] = {STRING_GB, "GB"}, {STRING_ADDKBLAYOUTS, - "Adding keyboard layouts"}, + "A¤adiendo disposici¢n de teclado"}, {0, 0} }; diff --git a/reactos/base/setup/usetup/lang/it-IT.h b/reactos/base/setup/usetup/lang/it-IT.h index 81bb197c760..b3e6ef496ed 100644 --- a/reactos/base/setup/usetup/lang/it-IT.h +++ b/reactos/base/setup/usetup/lang/it-IT.h @@ -94,7 +94,7 @@ static MUI_ENTRY itITWelcomePageEntries[] = { 8, 19, - "\x07 Premere L per vedere i termini e condizioni della licenza", + "\x07 Premere L per vedere i termini e condizioni della licenza.", TEXT_STYLE_NORMAL }, { @@ -158,7 +158,7 @@ static MUI_ENTRY itITIntroPageEntries[] = { 6, 12, - "Ci sono delle limitazioni:", + "Si applicano le seguenti limitazioni:", TEXT_STYLE_NORMAL }, { @@ -358,7 +358,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 6, 8, - "La lista inferiore mostra la configurazione della periferica corrente.", + "L'elenco che segue mostra le impostazioni correnti delle periferiche.", TEXT_STYLE_NORMAL }, { @@ -382,7 +382,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 3, 14, - "Nazionalit… tastiera:", + "Layout di tastiera:", TEXT_STYLE_NORMAL }, { @@ -393,7 +393,7 @@ static MUI_ENTRY itITDevicePageEntries[] = }, { 25, - 16, "Procedere con questa configurazione", + 16, "Accettare queste impostazioni", TEXT_STYLE_NORMAL }, { @@ -423,7 +423,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 6, 24, - "\"Procedere con questa configurazione\" e premere INVIO.", + "\"Accettare queste impostazioni\" e premere INVIO.", TEXT_STYLE_NORMAL }, { diff --git a/reactos/base/setup/welcome/lang/es-ES.rc b/reactos/base/setup/welcome/lang/es-ES.rc index 8d95d5cc1a5..3d44ee308d0 100644 --- a/reactos/base/setup/welcome/lang/es-ES.rc +++ b/reactos/base/setup/welcome/lang/es-ES.rc @@ -9,7 +9,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_APPTITLE "ReactOS - Bienvenido" IDS_DEFAULTTOPICTITLE "ReactOS" - IDS_DEFAULTTOPICDESC "Bienvenido al Sistema Operativo React.\n\nHaz Click en una opcion a la izquierda." + IDS_DEFAULTTOPICDESC "Bienvenido al Sistema Operativo React.\n\nHaz Click en una opción a la izquierda." // IDS_CHECKTEXT "Mostrar este dialogo otra vez" // IDS_CLOSETEXT "Salir" END diff --git a/reactos/dll/cpl/usrmgr/lang/es-ES.rc b/reactos/dll/cpl/usrmgr/lang/es-ES.rc new file mode 100644 index 00000000000..e2afc79cbb8 --- /dev/null +++ b/reactos/dll/cpl/usrmgr/lang/es-ES.rc @@ -0,0 +1,219 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + + +/* Dialogs */ + +IDD_USERS DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Usuarios" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_USERS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 7, 238, 85, WS_EX_CLIENTEDGE +END + + +IDD_GROUPS DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Grupos" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_GROUPS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 7, 238, 85, WS_EX_CLIENTEDGE +END + + +IDD_EXTRA DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Extra" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "This space is intentionally left blank", IDC_STATIC, 66, 90, 112, 8 +END + + +IDD_USER_GENERAL DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "General" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "", IDC_USER_GENERAL_NAME, 7, 12, 112, 8 + LTEXT "Nombre completo:", -1, 7, 46, 63, 8 + EDITTEXT IDC_USER_GENERAL_FULL_NAME,77,43,168,13,ES_AUTOHSCROLL + LTEXT "Descripción:", -1, 7, 64, 63, 8 + EDITTEXT IDC_USER_GENERAL_DESCRIPTION,77,61,168,13,ES_AUTOHSCROLL + AUTOCHECKBOX "El usuario debe cambiar la contraseña en el siguiente inicio de sesión",IDC_USER_GENERAL_FORCE_CHANGE,7,82,210,10 + AUTOCHECKBOX "El usuario no puede cambiar la contraseña",IDC_USER_GENERAL_CANNOT_CHANGE,7,95,210,10 + AUTOCHECKBOX "La contraseña nunca caduca",IDC_USER_GENERAL_NEVER_EXPIRES,7,108,210,10 + AUTOCHECKBOX "Cuenta deshabilitada",IDC_USER_GENERAL_DISABLED,7,121,210,10 + AUTOCHECKBOX "La cuenta está bloqueada",IDC_USER_GENERAL_LOCKED,7,134,210,10 +END + + +IDD_USER_MEMBERSHIP DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Miembro de" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Miembro de:", -1, 7, 7, 56, 8 + CONTROL "", IDC_USER_MEMBERSHIP_LIST, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 18, 238, 173, WS_EX_CLIENTEDGE + PUSHBUTTON "Agregar...", IDC_USER_MEMBERSHIP_ADD, 7, 197, 50, 14 + PUSHBUTTON "Quitar", IDC_USER_MEMBERSHIP_REMOVE, 61, 197, 50, 14, WS_DISABLED +END + + +IDD_USER_PROFILE DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Perfil" +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Perfil de usuario ", -1, 7, 7, 238, 54 + LTEXT "Ruta de acceso al perfil:", -1, 16, 22, 55, 8 + EDITTEXT IDC_USER_PROFILE_PATH, 78, 19, 160, 13, ES_AUTOHSCROLL + LTEXT "Archivo de comandos de inicio de sesión:", -1, 16, 40, 55, 8 + EDITTEXT IDC_USER_PROFILE_SCRIPT, 78, 37, 160, 13, ES_AUTOHSCROLL + + GROUPBOX "Carpeta particular ", -1, 7, 68, 238, 54 + AUTORADIOBUTTON "Ruta de acceso local:", IDC_USER_PROFILE_LOCAL, 16, 83, 60, 10 + AUTORADIOBUTTON "Conectar:", IDC_USER_PROFILE_REMOTE, 16, 100, 60, 10 + EDITTEXT IDC_USER_PROFILE_LOCAL_PATH, 78, 81, 160, 13, ES_AUTOHSCROLL + COMBOBOX IDC_USER_PROFILE_DRIVE, 78, 99, 26, 160, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL + LTEXT "A:", -1, 112, 101, 12, 8 + EDITTEXT IDC_USER_PROFILE_REMOTE_PATH, 130, 99, 108, 13, ES_AUTOHSCROLL +END + + +IDD_GROUP_GENERAL DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "General" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "", IDC_GROUP_GENERAL_NAME, 7, 12, 112, 8 + LTEXT "Descripción:", -1, 7, 45, 46, 8 + EDITTEXT IDC_GROUP_GENERAL_DESCRIPTION,65,42,180,13,ES_AUTOHSCROLL + LTEXT "Miembros:", -1, 7, 63, 45, 8 + CONTROL "", IDC_GROUP_GENERAL_MEMBERS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 74, 238, 117, WS_EX_CLIENTEDGE + PUSHBUTTON "Añadir...", IDC_GROUP_GENERAL_ADD, 7, 197, 50, 14 + PUSHBUTTON "Quitar", IDC_GROUP_GENERAL_REMOVE, 61, 197, 50, 14, WS_DISABLED +END + + +IDD_CHANGE_PASSWORD DIALOGEX DISCARDABLE 0, 0, 267, 74 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Cambiar contraseña" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Nueva contraseña:", -1,7,10,96,8 + EDITTEXT IDC_EDIT_PASSWORD2,107,25,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Confirmar la contraseña:", -1,7,28,96,8 + DEFPUSHBUTTON "Aceptar",IDOK,156,53,50,14 + PUSHBUTTON "Cancelar",IDCANCEL,210,53,50,14 +END + + +IDD_USER_NEW DIALOGEX DISCARDABLE 0, 0, 267, 200 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Nuevo usuario" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_USER_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL + RTEXT "Nombre de usuario:", -1,7,10,96,8 + EDITTEXT IDC_USER_NEW_FULL_NAME,107,25,153,14,ES_AUTOHSCROLL + RTEXT "Nombre completo:", -1,7,28,96,8 + EDITTEXT IDC_USER_NEW_DESCRIPTION,107,43,153,14,ES_AUTOHSCROLL + RTEXT "Descripción:", -1,7,46,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD1,107,67,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Contraseña:", -1,7,70,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD2,107,85,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Confirmar la contraseña:", -1,7,88,96,8 + AUTOCHECKBOX "El usuario debe cambiar la contraseña en el siguiente inicio de sesión",IDC_USER_NEW_FORCE_CHANGE,7,109,200,10 + AUTOCHECKBOX "El usuario no puede cambiar la contraseña",IDC_USER_NEW_CANNOT_CHANGE,7,123,200,10,WS_DISABLED + AUTOCHECKBOX "La contraseña nunca caduca",IDC_USER_NEW_NEVER_EXPIRES,7,137,200,10,WS_DISABLED + AUTOCHECKBOX "Cuenta deshabilitada",IDC_USER_NEW_DISABLED,7,151,200,10 + DEFPUSHBUTTON "Aceptar",IDOK,156,179,50,14,WS_DISABLED + PUSHBUTTON "Cancelar",IDCANCEL,210,179,50,14 +END + + +IDD_GROUP_NEW DIALOGEX DISCARDABLE 0, 0, 267, 74 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Nuevo grupo" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_GROUP_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL + RTEXT "Nombre del grupo:", -1,7,10,96,8 + EDITTEXT IDC_GROUP_NEW_DESCRIPTION,107,25,153,14,ES_AUTOHSCROLL + RTEXT "Descripción:", -1,7,28,96,8 + DEFPUSHBUTTON "Aceptar",IDOK,156,53,50,14,WS_DISABLED + PUSHBUTTON "Cancelar",IDCANCEL,210,53,50,14 +END + + +IDD_USER_ADD_MEMBERSHIP DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Pertenencia a grupos" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Miembro de:", -1, 7, 7, 56, 8 + CONTROL "", IDC_USER_ADD_MEMBERSHIP_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 18, 238, 173, WS_EX_CLIENTEDGE + DEFPUSHBUTTON "Aceptar",IDOK,141,197,50,14 + PUSHBUTTON "Cancelar",IDCANCEL,195,197,50,14 +END + + +/* Menus */ + +IDM_POPUP_GROUP MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "Nuevo grupo...", IDM_GROUP_NEW + END + POPUP "" + BEGIN + MENUITEM "Añadir miembro", IDM_GROUP_ADD_MEMBER, GRAYED + MENUITEM SEPARATOR + MENUITEM "Borrar", IDM_GROUP_DELETE + MENUITEM "Renombrar", IDM_GROUP_RENAME + MENUITEM SEPARATOR + MENUITEM "Propiedades", IDM_GROUP_PROPERTIES + END +END + + +IDM_POPUP_USER MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "Nuevo usuario...", IDM_USER_NEW + END + POPUP "" + BEGIN + MENUITEM "Cambiar contraseña", IDM_USER_CHANGE_PASSWORD + MENUITEM SEPARATOR + MENUITEM "Borrar", IDM_USER_DELETE + MENUITEM "Renombrar", IDM_USER_RENAME + MENUITEM SEPARATOR + MENUITEM "Propiedades", IDM_USER_PROPERTIES + END +END + + +/* Strings */ + +STRINGTABLE +BEGIN + IDS_CPLNAME "Cuentas de usuario" + IDS_CPLDESCRIPTION "Gestiona Usuarios y Grupos." +END + +STRINGTABLE +BEGIN + IDS_NAME "Nombre" + IDS_FULLNAME "Nombre completo" + IDS_DESCRIPTION "Descripción" +END diff --git a/reactos/dll/cpl/usrmgr/rsrc.rc b/reactos/dll/cpl/usrmgr/rsrc.rc index 5e400c134c0..3c5ab7370fe 100644 --- a/reactos/dll/cpl/usrmgr/rsrc.rc +++ b/reactos/dll/cpl/usrmgr/rsrc.rc @@ -3,5 +3,6 @@ #include "lang/de-DE.rc" #include "lang/en-US.rc" +#include "lang/es-ES.rc" #include "lang/pl-PL.rc" #include "lang/ru-RU.rc" diff --git a/reactos/dll/win32/devmgr/lang/es-ES.rc b/reactos/dll/win32/devmgr/lang/es-ES.rc index 32b3820f5c0..d3e80b4950a 100644 --- a/reactos/dll/win32/devmgr/lang/es-ES.rc +++ b/reactos/dll/win32/devmgr/lang/es-ES.rc @@ -94,30 +94,30 @@ END STRINGTABLE BEGIN - IDS_PROP_DEVICEID "Device Instance ID" - IDS_PROP_HARDWAREIDS "Hardware IDs" - IDS_PROP_COMPATIBLEIDS "Compatible IDs" - IDS_PROP_MATCHINGDEVICEID "Matching Device ID" - IDS_PROP_SERVICE "Service" - IDS_PROP_ENUMERATOR "Enumerator" - IDS_PROP_CAPABILITIES "Capabilities" - IDS_PROP_DEVNODEFLAGS "Devnode Flags" - IDS_PROP_CONFIGFLAGS "Config Flags" - IDS_PROP_CSCONFIGFLAGS "CSConfig Flags" - IDS_PROP_EJECTIONRELATIONS "Ejection Relations" - IDS_PROP_REMOVALRELATIONS "Removal Relations" - IDS_PROP_BUSRELATIONS "Bus Relations" - IDS_PROP_DEVUPPERFILTERS "Device Upper Filters" - IDS_PROP_DEVLOWERFILTERS "Device Lower Filters" - IDS_PROP_CLASSUPPERFILTERS "Class Upper Filters" - IDS_PROP_CLASSLOWERFILTERS "Class Lower Filters" - IDS_PROP_CLASSINSTALLER "Class Installers" - IDS_PROP_CLASSCOINSTALLER "Class Coinstallers" - IDS_PROP_DEVICECOINSTALLER "Device Coinstallers" - IDS_PROP_FIRMWAREREVISION "Firmware Revision" - IDS_PROP_CURRENTPOWERSTATE "Current Power State" - IDS_PROP_POWERCAPABILITIES "Power Capabilities" - IDS_PROP_POWERSTATEMAPPINGS "Power State Mappings" + IDS_PROP_DEVICEID "Id. de instancia de dispositivo" + IDS_PROP_HARDWAREIDS "Identificadores de hardware" + IDS_PROP_COMPATIBLEIDS "Identificadores compatibles" + IDS_PROP_MATCHINGDEVICEID "Id. de dispositivo coincidente" + IDS_PROP_SERVICE "Servicio" + IDS_PROP_ENUMERATOR "Enumerador" + IDS_PROP_CAPABILITIES "Recursos" + IDS_PROP_DEVNODEFLAGS "Marcadores Devnode" + IDS_PROP_CONFIGFLAGS "Marcadores Config" + IDS_PROP_CSCONFIGFLAGS "Marcadores CSConfig" + IDS_PROP_EJECTIONRELATIONS "Relaciones de extracción" + IDS_PROP_REMOVALRELATIONS "Relaciones de eliminación" + IDS_PROP_BUSRELATIONS "Relaciones de bus" + IDS_PROP_DEVUPPERFILTERS "Filtros superiores de dispositivo" + IDS_PROP_DEVLOWERFILTERS "Filtros inferiores de dispositivo" + IDS_PROP_CLASSUPPERFILTERS "Filtros superiores de clase" + IDS_PROP_CLASSLOWERFILTERS "Filtros inferiores de clase" + IDS_PROP_CLASSINSTALLER "Instaladores de clase" + IDS_PROP_CLASSCOINSTALLER "Coinstaladores de clase" + IDS_PROP_DEVICECOINSTALLER "Coinstaladores de dispositivo" + IDS_PROP_FIRMWAREREVISION "Revisión de firmware" + IDS_PROP_CURRENTPOWERSTATE "Estado actual de energía" + IDS_PROP_POWERCAPABILITIES "Capacidad de energía" + IDS_PROP_POWERSTATEMAPPINGS "Asignaciones de estado de energía" END IDD_HARDWARE DIALOGEX DISCARDABLE 0, 0, 300, 400 @@ -200,7 +200,7 @@ END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Details" +CAPTION "Detalles" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -213,7 +213,7 @@ END IDD_DEVICERESOURCES DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Resources" +CAPTION "Recursos" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -222,7 +222,7 @@ END IDD_DEVICEPOWER DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Power" +CAPTION "Administración de energía" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 diff --git a/reactos/dll/win32/shell32/lang/es-ES.rc b/reactos/dll/win32/shell32/lang/es-ES.rc index f26e1d4b616..c619493d3f2 100644 --- a/reactos/dll/win32/shell32/lang/es-ES.rc +++ b/reactos/dll/win32/shell32/lang/es-ES.rc @@ -376,6 +376,16 @@ BEGIN PUSHBUTTON "Cancelar", 14006, 226, 236, 50, 14 END +IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Copiando..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Cancelar", 14002, 195, 14, 60, 16 + CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10 + LTEXT "Archivo", 14001, 8, 6, 169, 10 +END + FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 294, 240 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION CAPTION "General" @@ -755,5 +765,5 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Tamaño asignado por defecto" IDS_COPY_OF "Copia de" - IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." + IDS_SHLEXEC_NOASSOC "No hay ningún programa configurado en ReactOS para abrir este tipo de archivo." END diff --git a/reactos/dll/win32/shell32/lang/it-IT.rc b/reactos/dll/win32/shell32/lang/it-IT.rc index 18bafe2a6fd..824eb22a88e 100644 --- a/reactos/dll/win32/shell32/lang/it-IT.rc +++ b/reactos/dll/win32/shell32/lang/it-IT.rc @@ -374,6 +374,16 @@ BEGIN PUSHBUTTON "Annulla", 14006, 206, 236, 50, 14 END +IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Copia in corso..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Annulla", 14002, 195, 14, 60, 16 + CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10 + LTEXT "File", 14001, 8, 6, 169, 10 +END + FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION CAPTION "Generale" diff --git a/reactos/dll/win32/syssetup/lang/es-ES.rc b/reactos/dll/win32/syssetup/lang/es-ES.rc index 3b5fabc6482..878aa3b8e43 100644 --- a/reactos/dll/win32/syssetup/lang/es-ES.rc +++ b/reactos/dll/win32/syssetup/lang/es-ES.rc @@ -254,7 +254,7 @@ BEGIN IDS_SYS_ENTERTAINMENT "Entretenimiento" IDS_CMT_MPLAY32 "Ejecutar Reproductor multimedia" IDS_CMT_SNDVOL32 "Ejecutar Control de volumen" - IDS_CMT_SNDREC32 "Launch Sound Recorder" + IDS_CMT_SNDREC32 "Ejecutar Grabadora de sonidos" END STRINGTABLE @@ -292,7 +292,7 @@ BEGIN IDS_SHORT_EVENTVIEW "Visor de sucesos.lnk" IDS_SHORT_MSCONFIG "Configuración del sistema.lnk" IDS_SHORT_SNDVOL32 "Control de volumen.lnk" - IDS_SHORT_SNDREC32 "Audiorecorder.lnk" + IDS_SHORT_SNDREC32 "Grabadora de sonidos.lnk" IDS_SHORT_DXDIAG "Diagnóstico de ReactX.lnk" IDS_SHORT_PAINT "Paint.lnk" IDS_SHORT_SPIDER "Solitario Spider.lnk" From 21e28a541fd75f553c3348921a020f95e7434bd6 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 26 May 2010 11:30:35 +0000 Subject: [PATCH 047/292] [FREETYPE] Update to 2.3.12, conversion patch already applied svn path=/trunk/; revision=47363 --- reactos/lib/3rdparty/freetype/ChangeLog | 718 ++++++++++++++---- reactos/lib/3rdparty/freetype/Jamfile | 2 +- reactos/lib/3rdparty/freetype/README | 10 +- reactos/lib/3rdparty/freetype/autogen.sh | 7 +- .../lib/3rdparty/freetype/devel/ftoption.h | 28 +- .../include/freetype/config/ftconfig.h | 36 +- .../include/freetype/config/ftoption.h | 16 +- .../freetype/include/freetype/freetype.h | 21 +- .../freetype/include/freetype/ftglyph.h | 2 +- .../freetype/include/freetype/ftimage.h | 38 +- .../freetype/include/freetype/ftincrem.h | 8 +- .../freetype/include/freetype/ftoutln.h | 7 +- .../freetype/include/freetype/ftsnames.h | 31 +- .../3rdparty/freetype/src/autofit/aflatin.c | 8 +- .../3rdparty/freetype/src/autofit/aflatin2.c | 8 +- .../lib/3rdparty/freetype/src/base/ftbase.h | 6 +- .../lib/3rdparty/freetype/src/base/ftbbox.c | 6 +- .../lib/3rdparty/freetype/src/base/ftdbgmem.c | 2 +- .../lib/3rdparty/freetype/src/base/ftglyph.c | 6 +- .../lib/3rdparty/freetype/src/base/ftinit.c | 4 +- .../lib/3rdparty/freetype/src/base/ftobjs.c | 28 +- .../lib/3rdparty/freetype/src/base/ftoutln.c | 8 +- .../lib/3rdparty/freetype/src/base/ftpatent.c | 9 +- .../lib/3rdparty/freetype/src/base/ftstroke.c | 14 +- .../lib/3rdparty/freetype/src/base/ftsynth.c | 4 +- .../3rdparty/freetype/src/cache/ftcglyph.c | 4 +- .../lib/3rdparty/freetype/src/cff/cffdrivr.c | 5 +- .../lib/3rdparty/freetype/src/cff/cffgload.c | 165 +++- .../lib/3rdparty/freetype/src/cff/cffgload.h | 8 +- .../lib/3rdparty/freetype/src/cff/cffobjs.c | 9 +- .../lib/3rdparty/freetype/src/cff/cffparse.c | 4 +- .../lib/3rdparty/freetype/src/cid/cidgload.c | 19 +- .../lib/3rdparty/freetype/src/cid/cidobjs.c | 9 +- .../lib/3rdparty/freetype/src/cid/cidtoken.h | 2 +- reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c | 12 +- .../lib/3rdparty/freetype/src/pfr/pfrsbit.c | 6 +- .../3rdparty/freetype/src/psaux/t1decode.c | 21 +- .../lib/3rdparty/freetype/src/sfnt/sfdriver.c | 2 - .../lib/3rdparty/freetype/src/sfnt/sfobjs.c | 31 +- .../lib/3rdparty/freetype/src/sfnt/ttcmap.c | 9 +- .../lib/3rdparty/freetype/src/sfnt/ttload.c | 8 +- .../3rdparty/freetype/src/smooth/ftgrays.c | 2 +- .../3rdparty/freetype/src/tools/apinames.c | 4 +- .../3rdparty/freetype/src/truetype/ttdriver.c | 18 +- .../3rdparty/freetype/src/truetype/ttgload.c | 216 ++++-- .../3rdparty/freetype/src/truetype/ttgxvar.c | 11 +- .../lib/3rdparty/freetype/src/type1/t1afm.c | 18 +- .../lib/3rdparty/freetype/src/type1/t1gload.c | 40 +- .../lib/3rdparty/freetype/src/type1/t1objs.c | 9 +- .../lib/3rdparty/freetype/src/type1/t1parse.c | 21 +- 50 files changed, 1241 insertions(+), 439 deletions(-) diff --git a/reactos/lib/3rdparty/freetype/ChangeLog b/reactos/lib/3rdparty/freetype/ChangeLog index 0407890537c..83a7d53c6d4 100644 --- a/reactos/lib/3rdparty/freetype/ChangeLog +++ b/reactos/lib/3rdparty/freetype/ChangeLog @@ -1,3 +1,461 @@ +2010-02-13 Werner Lemberg + + * Version 2.3.12 released. + ========================== + + + Tag sources with `VER-2-3-12'. + + * docs/CHANGES: Updated. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.12. + + * README, Jamfile (RefDoc), + builds/win32/vc2005/freetype.vcproj, builds/win32/vc2005/index.html, + builds/win32/vc2008/freetype.vcproj, builds/win32/vc2008/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualc/index.html, builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj, + builds/win32/visualce/index.html, + builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/freetype.vcproj, + builds/wince/vc2008-ce/index.html: s/2.3.11/2.3.12/, s/2311/2312/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 12. + + * builds/unix/configure.raw (version_info): Set to 10:0:4. + +2010-02-12 suzuki toshiya + + Improve autotool version checking to work with beta releases. + + * autogen.sh (check_tool_version): Improve the extraction of version + number from "tool --version" output. Some beta releases of + autotools have extra strings before version number. + +2010-02-12 suzuki toshiya + + Fix overallocating bug in FT_Outline_New_Internal(). + + * src/base/ftoutln.c (FT_Outline_New_Internal): The length of + FT_Outline->points[] should be numPoints, not 2 * numPoints. + Found by Paul Messmer, see + http://lists.gnu.org/archive/html/freetype-devel/2010-02/msg00003.html + +2010-02-10 Ken Sharp + + Really fix Savannah bug #28678 (part 2). + + Since we consider `sbw' for the horizontal direction only, we still have + to synthesize vertical metrics if the user wants to use the vertical + writing direction. + + * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c + (cid_slot_load_glyph), src/type1/t1gload.c (T1_Load_Glyph): + Synthesize vertical metrics (only) if FT_LOAD_VERTICAL_LAYOUT is + set. + +2010-02-10 Ken Sharp + + Really fix Savannah bug #28678 (part 1). + + After long discussion, we now consider the character width vector + (wx,wy) returned by the `sbw' Type 1 operator as being part of *one* + direction only. For example, if you are using the horizontal + writing direction, you get the horizontal and vertical components of + the advance width for this direction. Note that OpenType and CFF fonts + don't have such a vertical component; instead, the GPOS table can be + used to generate two-dimensional advance widths (but this isn't + handled by FreeType). + + * include/freetype/ftincrem.h (FT_Incremental_MetricsRec): Add + `advance_v' field to hold the vertical component of the advance + value. + + * src/truetype/ttgload.c (tt_get_metrics), src/cff/cffgload.c + (cff_slot_load), src/type1/t1gload.c + (T1_Parse_Glyph_And_Get_Char_String), src/cid/cidgload.c + (cid_load_glyph): Use it. + +2010-02-08 Werner Lemberg + + * devel/ftoption.h [FT_CONFIG_OPTION_PIC]: Define. + +2010-02-04 suzuki toshiya + + Prevent NULL pointer dereference passed to FT_Module_Requester. + + * src/sfnt/sfdriver.c (sfnt_get_interface): Don't use `module'. + * src/psnames/psmodule.c (psnames_get_interface): Ditto. + + * src/cff/cffdrivr.c (cff_get_interface): Check NULL `driver'. + * src/truetype/ttdriver.c (tt_get_interface): Ditto. + +2010-01-29 suzuki toshiya + + Fix memory leaks in previous patch. + + * src/sfnt/sfobjs.c (sfnt_load_face): Don't overwrite the strings + allocated for face->root.family_name and style_name. + +2010-01-29 suzuki toshiya + + New parameters for FT_Open_Face() to ignore preferred family names. + + Preferred family names should be used for legacy systems that + can hold only a few faces (<= 4) for a family name. Suggested by + Andreas Heinrich. + http://lists.gnu.org/archive/html/freetype/2010-01/msg00001.html + + * include/freetype/ftsnames.h (FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY, + FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY): Define. + + * src/sfnt/sfobjs.h (sfnt_load_face): Check the arguments and + ignore preferred family and subfamily names if requested. + +2010-01-27 Ken Sharp + + Fix Savannah bug #28678. + + * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c + (cid_load_glyph): Handle vertical metrics correctly. + + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Handle + vertical metrics correctly. + (T1_Load_Glyph): Don't synthesize vertical metrics. + +2010-01-14 Werner Lemberg + + Make FT_Set_Transform work if no renderer is available. + + * src/base/ftobjs.c (FT_Load_Glyph): Apply `standard' transformation + if no renderer is compiled into the library. + +2010-01-14 Werner Lemberg + + Fix compilation warning. + + * src/base/ftbase.h: s/LOCAL_DEF/LOCAL/. + * src/base/ftobjc.s: Include ftbase.h conditionally. + +2010-01-11 Kwang Yul Seo + + Provide inline assembly code for RVCT compiler. + This is Savannah patch #7059. + + * include/freetype/config/ftconfig.h (FT_MULFIX_ASSEMBLER, + FT_MulFix_arm) [__CC_ARM || __ARM_CC]: Define. + +2010-01-08 Ken Sharp + + Fix Savannah bug #28521. + + Issue #28226 involved a work-around for a font which used the + `setcurrentpoint' operator in an invalid way; this operator is only + supposed to be used with the result of OtherSubrs, and the font used + it directly. The supplied patch removed the block of code which + checked this usage entirely. + + This turns out to be a Bad Thing. If `setcurrentpoint' is being + used correctly it should reset the flex flag in the decoder. If we + don't do this then the flag never gets reset and we omit any further + contours from the glyph (at least until we close the path or + similar). + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : Handle `flex_state' correctly. + +2010-01-05 Werner Lemberg + + Apply reports from clang static analyzer. + + * src/lzw/ftlzw.c (ft_lzw_file_init), src/base/ftstroke.c + (FT_Stroker_ParseOutline), src/base/ftsynth.c + (FT_GlyphSlot_Embolden): Remove dead code. + + * src/base/ftpatent.c (_tt_check_patents_in_table): Initialize + `offset_i' and `length_i'. + +2010-01-05 Ralph Giles + + Enable the incremental font interface by default. + + Ghostscript requires the incremental font interface for handling + some Postscript documents. It is moving to using FreeType as its + primary renderer; supporting this in the default build makes it + Ghostscript to be linked against the system FreeType when one is + available. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_INCREMENTAL): + Uncomment. + +2010-01-05 Werner Lemberg + + Fix Savannah bug #28395. + + * src/truetype/ttdriver.c (Load_Glyph), src/type1/t1gload.c + (T1_Loada_Glyph): Don't check `num_glyphs' if incremental interface + is used. + +2010-01-05 Ken Sharp + + Make Type 1 `seac' operator work with incremental interface. + This fixes Savannah bug #28480. + + * src/psaux/t1decode.c (t1operator_seac): Don't check `glyph_names' + if incremental interface is used. + +2010-01-04 Ken Sharp + + Make incremental interface work with TrueType fonts. + This fixes Savannah bug #28478. + + * src/truetype/ttgload.c (load_truetype_glyph): Don't check + `glyf_offset' if incremental interface is used. + +2009-12-31 Lars Abrahamsson + + Make compilation with FT_CONFIG_OPTION_PIC work again. + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap) [FT_CONFIG_OPTION_PIC]: + Declare `library' for FT_BITMAP_GLYPH_CLASS_GET. + + * src/base/ftinit.c (ft_destroy_default_module_classes, + ft_create_default_module_classes): Use proper casts (needed for C++ + compilation). + + * src/sfnt/ttcmap.c (tt_cmap13_class_rec): Use FT_DEFINE_TT_CMAP. + +2009-12-22 Marc Kleine-Budde + + Make freetype-config aware of $SYSROOT. + This is Savannah patch #7040. + + * builds/unix/freetype-config.in: Decorate with ${SYSROOT} where + appropriate. + +2009-12-20 Werner Lemberg + + Fix compiler warning. + Reported by Sean. + + * src/base/ftdbgmem.c [!FT_DEBUG_MEMORY]: ANSI C doesn't like empty + source files; however, some compilers warn about an unused variable + declaration. This is now replaced with a typedef. + +2009-12-18 Werner Lemberg + + Fix Savannah bug #28320. + + There exist corrupt, subsetted fonts (embedded in PDF files) which + contain a private dict that ends with an unterminated floating point + number (no operator following). We now ignore this error (as + acrobat does). + + * src/cff/cffparse.c (cff_parser_run): Don't emit a syntax error for + unterminated floating point numbers. + +2009-12-16 Werner Lemberg + + Really fix compiler warnings. + Reported by Sean. + + * src/truetype/ttgxvar.c (GX_PT_POINTS_ARE_WORDS, + GX_PT_POINT_RUN_COUNT_MASK): Convert enum values to macros. + +2009-12-16 suzuki toshiya + + Improve configure.raw to copy some options from CFLAGS to LDFLAGS. + The linker of Mac OS X 10.6 is sensitive to the architecture. If + the architectures are specified explicitly for the C compiler, the + linker requires the architecture specifications too. + + * builds/unix/configure.raw: Replace `-isysroot' option parser by + more generic argument parser. + +2009-12-15 Werner Lemberg + + Fix compiler warnings. + Reported by Sean. + + * src/truetype/ttgxvar.c (ft_var_readpackeddeltas): Fix counter data + type. + +2009-12-14 Ken Sharp + + Ignore invalid `setcurrentpoint' operations in Type 1 fonts. + This fixes Savannah bug #28226. + + At least two wild PostScript files of unknown provenance contain + Type 1 fonts, apparently converted from TrueType fonts in earlier + PDF versions of the files, which use the `setcurrentpoint' operator + inappropriately. + + FreeType currently throws an error in this case, but Ghostscript and + Adobe Distiller both accept the fonts and ignore the problem. This + commit #ifdefs out the check so PostScript interpreters using + FreeType can render these files. + + The specification says `setcurrentpoint' should only be used to set + the point after a `Subr' call, but these fonts use it to set the + initial point to (0,0). Unnecessarily so, as they correctly use an + `hsbw' operation which implicitly sets the initial point. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : Comment out code. + +2009-12-14 Bram Tassyns + + Fix parsing of /CIDFontVersion. + This fixes Savannah bug #28287. + + * src/cid/cidtoken.h: `cid_version' in CID_FaceInfoRec (in + t1tables.h) is of type FT_Fixed. + +2009-12-14 Werner Lemberg + + Trace glyph index in CID module. + Suggested in Savannah patch #7023. + + * src/cid/cidgload.c (cid_load_glyph): Add tracing message. + +2009-12-03 Werner Lemberg + + Fix compiler warnings. + + * src/truetype/ttgload.c (tt_get_metrics): Put `Exit' label into the + proper preprocessor conditional. + * src/pfr/pfrobjs.c (pfr_slot_load): Pacify gcc. + +2009-11-25 John Tytgat + + Better handling of start of `eexec' section. + This fixes Savannah bug #28090. + + * src/type1/t1parse.c (T1_Get_Private_Dict): Skip all whitespace + characters before start of `eexec' section. + +2009-11-20 Werner Lemberg + + Fix Savannah bug #27742. + + * src/base/ftstroke.c (ft_stroker_outside): Avoid silent division by + zero, using a threshold for `theta'. + +2009-11-20 Werner Lemberg + + Fix Savannah bug #28036. + + * src/type1/t1afm.c (t1_get_index): Fix comparison. + +2009-11-16 Werner Lemberg + + Fix compiler warnings. + Reported by Kevin Blenkinsopp . + + * src/sfnt/ttload.c (check_table_dir): Use proper data type. + +2009-11-15 Werner Lemberg + + Really fix FreeDesktop bug #21197. + This also fixes Savannah bug #28021. + + * src/autofit/aflatin.c (af_latin_metrics_check_digits), + src/autofit/aflatin2.c (af_latin2_metrics_check_digits): Fix loop. + +2009-11-15 Werner Lemberg + + Add tracing messages for advance values. + + * src/base/ftobjs.c (FT_Load_Glyph), src/truetype/ttgload.c + (TT_Get_HMetrics, TT_Get_VMetrics): Do it. + +2009-11-08 Werner Lemberg + + Fix compiler warning. + Reported by Jeremy Manson . + + * src/truetype/ttgload.c (load_truetype_glyph): Initialize `error'. + +2009-11-04 Werner Lemberg + + Remove compiler warning. + Reported by Sean McBride . + + * src/tools/apinames.c (read_header_file): Use a cast to + `int', as specified in the printf(3) man page. + +2009-11-04 Werner Lemberg + + Fix Savannah bug #27921. + + * src/cff/cffobjs.c (cff_face_init), src/cid/cidobjs.c + (cid_face_init), src/type1/t1afm.c (T1_Read_Metrics), + src/type1/t1objs.c (T1_Face_Init): Don't use unsigned constant + values for rounding if the argument can be negative. + +2009-11-03 Bram Tassyns + + Add basic support for Type1 charstrings in CFF. + This fixes Savannah bug #27922. + + * src/cff/cffgload.c (CFF_Operator, cff_argument_counts): Handle + `seac', `sbw', and `setcurrentpoint' opcodes. + (cff_compute_bias): Add parameter to indicate the charstring type. + Update all callers. + (cff_operator_seac): Add parameter for side bearing. + (cff_decoder_parse_charstrings): Updated for more Type1 support. + +2009-11-03 Werner Lemberg + + Return correct `linearHoriAdvance' value for embedded TT bitmaps too. + Reported by Jeremy Manson . + + src/truetype/ttgload.c (load_truetype_glyph): Add parameter to + quickly load the glyph header only. + Update all callers. + (tt_loader_init): Add parameter to quickly load the `glyf' table + only. + Update all callers. + (TT_Load_Glyph): Compute linear advance values for embedded bitmap + glyphs too. + +2009-11-03 Werner Lemberg + + Improve code readability. + + * src/ttgload.c (load_truetype_glyph): Move metrics calculation + to... + (tt_get_metrics): This new function. + +2009-10-26 Bram Tassyns + + Fix Savannah bug #27811. + + * src/truetype/ttxgvar.c (ft_var_readpackeddeltas): Fix + signed/unsigned mismatch. + +2009-10-19 Ning Dong + + Fix handling of `get' and `put' CFF instructions. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings) : Appendix B of Adobe Technote #5177 limits the number of + elements for the `get' and `put' operators to 32. + * src/cff/cffgload.h (CFF_MAX_TRANS_ELEMENTS): Define. + (CFF_Decoder): Use it for `buildchar' and remove `len_buildchar'. + +2009-10-18 Werner Lemberg + + Fix handling of `dup' CFF instruction. + Problem and solution reported by Ning Dong . + + * src/cff/cffgload.c (cff_decoder_parse_charstrings) : + Increase `args' by 2, not 1. + 2009-10-10 Werner Lemberg * Version 2.3.11 released. @@ -67,13 +525,13 @@ 2009-09-27 suzuki toshiya [cache] Fix Savannah bug #27441, clean up Redhat bugzilla #513582. - Tricky casts in FTC_{CACHE,GCACHE,MRULIST}_LOOKUP_CMP() are removed. + Tricky casts in FTC_{CACHE,GCACHE,MRULIST}_LOOKUP_CMP() are removed. Now these functions should be called with FTC_Node or FTC_MruNode variable, and the caller should cast them to appropriate pointers to concrete data. These tricky casts can GCC-4.4 optimizer (-O2) confused and the crashing binaries are generated. - * src/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Drop tricky cast. + * src/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Drop tricky cast. Now the 4th argument `node' of this function should be typed as FTC_MruNode. @@ -624,7 +1082,7 @@ * include/freetype/internal/tttypes.h: The type of TT_BDF->string_size is extended from FT_UInt32 - to FT_ULong, because BDF specification does not + to FT_ULong, because BDF specification does not restrict the length of string. * src/sfnt/ttbdf.c: The scratch variable `strings' to load TT_BDF->string_size is matched with @@ -796,7 +1254,7 @@ and `rem' are changed to TCoord, because their values are set with explicit casts to TCoord. When ras.area is updated by the differential values including - `delta', they are explicitly casted to TArea, because + `delta', they are explicitly cast to TArea, because the type of `delta' is not TArea but TCoord. (gray_render_line): The type of `mod' is extended from int to TCoord, because (TCoord)dy is added to mod. @@ -971,8 +1429,8 @@ * src/base/fttrigon.c (ft_trig_downscale): The FT_Fixed variable `val' and unsigned long constant FT_TRIG_SCALE - are casted to FT_UInt32, when calculates FT_UInt32. - (FT_Vector_Rotate): The long constant 1L is casted to + are cast to FT_UInt32, when calculates FT_UInt32. + (FT_Vector_Rotate): The long constant 1L is cast to FT_Int32 to calculate FT_Int32 `half'. 2009-07-31 suzuki toshiya @@ -1015,7 +1473,7 @@ `code' is matched to PCF_Encoding->enc. (pcf_cmap_char_next): The type of `charcode' is matched to PCF_Encoding->enc. When *acharcode is set by charcode, - an overflow is checked and casted to unsigned 32-bit + an overflow is checked and cast to unsigned 32-bit integer. 2009-07-31 suzuki toshiya @@ -1046,7 +1504,7 @@ (bdf_cmap_char_next): The type of `charcode' is matched with BDF_encoding_el->enc. When *acharcode is set by charcode, an overflow is checked and - casted to unsigned 32-bit integer. + cast to unsigned 32-bit integer. 2009-07-31 suzuki toshiya @@ -1174,7 +1632,7 @@ * afmparse.c (afm_parser_read_vals): To call AFM_ParserRec.get_index, the length of token - `len' is casted to size_t. + `len' is cast to size_t. 2009-07-31 suzuki toshiya @@ -1304,7 +1762,7 @@ * src/gzip/ftgzip.c (zcalloc, zcfree): Disable all zcalloc() & zfree() by zlib in zutil.c, those in - ftgzip.c by FT2 are enabled by default. To use + ftgzip.c by FT2 are enabled by default. To use zlib zcalloc() & zfree(), define USE_ZLIB_ZCALLOC. See discussion: http://lists.gnu.org/archive/html/freetype-devel/2009-02/msg00000.html @@ -1494,7 +1952,7 @@ the check for too large glyph. Replace the pair of `pitch' and `height' by the pair of `width' and `height'. `pitch' cannot be greater than `height'. The required is checking the product - `pitch' * `height' <= FT_ULONG_MAX, but we use cheap checks for + `pitch' * `height' <= FT_ULONG_MAX, but we use cheap checks for the realistic case only. 2009-07-09 suzuki toshiya @@ -1610,7 +2068,7 @@ Improve configure.raw for cross-building on exe-suffixed systems. * builds/unix/configure.raw: Fix a bug in sed script to extract - native suffix for binary executables, patch by Peter Breitenlohner. + native suffix for binary executables, patch by Peter Breitenlohner. http://lists.gnu.org/archive/html/freetype-devel/2009-04/msg00036.html 2009-06-26 Werner Lemberg @@ -1949,7 +2407,7 @@ 2009-04-21 Karl Berry Fix AC_CHECK_FT2. - + * builds/unix/freetype2.m4: Only check PATH for freetype-config if we did not already find it from a prefix option. @@ -1957,7 +2415,7 @@ Add #error to modules and files that do not support PIC yet. - When FT_CONFIG_OPTION_PIC is defined the following files will + When FT_CONFIG_OPTION_PIC is defined the following files will create #error: * src/bdf/bdfdrivr.h * src/cache/ftcmanag.c @@ -1977,15 +2435,15 @@ Position Independent Code (PIC) support in autofit module. - * include/freetype/internal/autohint.h add macros to init + * include/freetype/internal/autohint.h add macros to init instances of FT_AutoHinter_ServiceRec. - * src/autofit/afmodule.h declare autofit_module_class - using macros from ftmodapi.h, + * src/autofit/afmodule.h declare autofit_module_class + using macros from ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/autofit/afmodule.c when FT_CONFIG_OPTION_PIC is defined - af_autofitter_service and autofit_module_class structs + * src/autofit/afmodule.c when FT_CONFIG_OPTION_PIC is defined + af_autofitter_service and autofit_module_class structs will have functions to init or create and destroy them instead of being allocated in the global scope. And macros will be used from afpic.h in order to access them. @@ -1993,54 +2451,54 @@ * src/autofit/aftypes.h add macros to init and declare instances of AF_ScriptClassRec. - * src/autofit/afcjk.h declare af_cjk_script_class - using macros from aftypes.h, + * src/autofit/afcjk.h declare af_cjk_script_class + using macros from aftypes.h, when FT_CONFIG_OPTION_PIC is defined init function will be declared. - * src/autofit/afcjk.c when FT_CONFIG_OPTION_PIC is defined - af_cjk_script_class struct will have function to init it instead of + * src/autofit/afcjk.c when FT_CONFIG_OPTION_PIC is defined + af_cjk_script_class struct will have function to init it instead of being allocated in the global scope. - * src/autofit/afdummy.h declare af_dummy_script_class - using macros from aftypes.h, + * src/autofit/afdummy.h declare af_dummy_script_class + using macros from aftypes.h, when FT_CONFIG_OPTION_PIC is defined init function will be declared. - * src/autofit/afdummy.c when FT_CONFIG_OPTION_PIC is defined - af_dummy_script_class struct will have function to init it instead of + * src/autofit/afdummy.c when FT_CONFIG_OPTION_PIC is defined + af_dummy_script_class struct will have function to init it instead of being allocated in the global scope. - * src/autofit/afindic.h declare af_indic_script_class - using macros from aftypes.h, + * src/autofit/afindic.h declare af_indic_script_class + using macros from aftypes.h, when FT_CONFIG_OPTION_PIC is defined init function will be declared. - * src/autofit/afindic.c when FT_CONFIG_OPTION_PIC is defined - af_indic_script_class struct will have function to init it instead of + * src/autofit/afindic.c when FT_CONFIG_OPTION_PIC is defined + af_indic_script_class struct will have function to init it instead of being allocated in the global scope. - * src/autofit/aflatin.h declare af_latin_script_class - using macros from aftypes.h, + * src/autofit/aflatin.h declare af_latin_script_class + using macros from aftypes.h, when FT_CONFIG_OPTION_PIC is defined init function will be declared. - * src/autofit/aflatin.c when FT_CONFIG_OPTION_PIC is defined - af_latin_script_class struct will have function to init it instead of + * src/autofit/aflatin.c when FT_CONFIG_OPTION_PIC is defined + af_latin_script_class struct will have function to init it instead of being allocated in the global scope. - Change af_latin_blue_chars to be PIC-compatible by being a two + Change af_latin_blue_chars to be PIC-compatible by being a two dimentional array rather than array of pointers. - * src/autofit/aflatin2.h declare af_latin2_script_class - using macros from aftypes.h, + * src/autofit/aflatin2.h declare af_latin2_script_class + using macros from aftypes.h, when FT_CONFIG_OPTION_PIC is defined init function will be declared. - * src/autofit/aflatin2.c when FT_CONFIG_OPTION_PIC is defined - af_latin2_script_class struct will have function to init it instead of + * src/autofit/aflatin2.c when FT_CONFIG_OPTION_PIC is defined + af_latin2_script_class struct will have function to init it instead of being allocated in the global scope. - Change af_latin2_blue_chars to be PIC-compatible by being a two + Change af_latin2_blue_chars to be PIC-compatible by being a two dimentional array rather than array of pointers. - * src/autofit/afglobal.c when FT_CONFIG_OPTION_PIC is defined + * src/autofit/afglobal.c when FT_CONFIG_OPTION_PIC is defined af_script_classes array initialization was moved to afpic.c and is later refered using macros defeined in afpic.h. New Files: * src/autofit/afpic.h declare struct to hold PIC globals for autofit module and macros to access them. - * src/autofit/afpic.c implement functions to allocate, destroy and + * src/autofit/afpic.c implement functions to allocate, destroy and initialize PIC globals for autofit module. * src/autofit/autofit.c add new file to build: afpic.c. @@ -2050,15 +2508,15 @@ Position Independent Code (PIC) support in pshinter module. - * include/freetype/internal/pshints.h add macros to init + * include/freetype/internal/pshints.h add macros to init instances of PSHinter_Interface. - * src/pshinter/pshmod.h declare pshinter_module_class - using macros from ftmodapi.h, + * src/pshinter/pshmod.h declare pshinter_module_class + using macros from ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/pshinter/pshmod.c when FT_CONFIG_OPTION_PIC is defined - pshinter_interface and pshinter_module_class structs + * src/pshinter/pshmod.c when FT_CONFIG_OPTION_PIC is defined + pshinter_interface and pshinter_module_class structs will have functions to init or create and destroy them instead of being allocated in the global scope. And macros will be used from pshpic.h in order to access them. @@ -2066,7 +2524,7 @@ New Files: * src/pshinter/pshpic.h declare struct to hold PIC globals for pshinter module and macros to access them. - * src/pshinter/pshpic.c implement functions to allocate, destroy and + * src/pshinter/pshpic.c implement functions to allocate, destroy and initialize PIC globals for pshinter module. * src/pshinter/pshinter.c add new file to build: pshpic.c. @@ -2076,15 +2534,15 @@ Position Independent Code (PIC) support in psnames module. - * include/freetype/internal/services/svpscmap.h add macros to init + * include/freetype/internal/services/svpscmap.h add macros to init instances of FT_Service_PsCMapsRec. - * src/psnames/psmodule.h declare psnames_module_class - using macros from ftmodapi.h, + * src/psnames/psmodule.h declare psnames_module_class + using macros from ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/psnames/psmodule.c when FT_CONFIG_OPTION_PIC is defined - pscmaps_interface and pscmaps_services structs + * src/psnames/psmodule.c when FT_CONFIG_OPTION_PIC is defined + pscmaps_interface and pscmaps_services structs and psnames_module_class array will have functions to init or create and destroy them instead of being allocated in the global scope. @@ -2093,7 +2551,7 @@ New Files: * src/psnames/pspic.h declare struct to hold PIC globals for psnames module and macros to access them. - * src/psnames/pspic.c implement functions to allocate, destroy and + * src/psnames/pspic.c implement functions to allocate, destroy and initialize PIC globals for psnames module. * src/psnames/psnames.c add new file to build: pspic.c. @@ -2103,29 +2561,29 @@ Position Independent Code (PIC) support in raster renderer. - * src/raster/ftrend1.h declare ft_raster1_renderer_class - and ft_raster5_renderer_class - using macros from ftrender.h, + * src/raster/ftrend1.h declare ft_raster1_renderer_class + and ft_raster5_renderer_class + using macros from ftrender.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/smooth/ftrend1.c when FT_CONFIG_OPTION_PIC is defined + * src/smooth/ftrend1.c when FT_CONFIG_OPTION_PIC is defined ft_raster1_renderer_class and ft_raster5_renderer_class structs will have functions to init or create and destroy them instead of being allocated in the global scope. - Macros will be used from rastpic.h in order to access + Macros will be used from rastpic.h in order to access ft_standard_raster from the pic_container (allocated in ftraster.c). - In ft_raster1_render when PIC is enabled, the last letter of + In ft_raster1_render when PIC is enabled, the last letter of module_name is used to verfy the renderer class rather than the class pointer. - * src/raster/ftraster.c when FT_CONFIG_OPTION_PIC is defined + * src/raster/ftraster.c when FT_CONFIG_OPTION_PIC is defined ft_standard_raster struct will have function to init it instead of being allocated in the global scope. New Files: * src/raster/rastpic.h declare struct to hold PIC globals for raster renderer and macros to access them. - * src/raster/rastpic.c implement functions to allocate, destroy and + * src/raster/rastpic.c implement functions to allocate, destroy and initialize PIC globals for raster renderer. * src/raster/raster.c add new file to build: rastpic.c. @@ -2135,35 +2593,35 @@ Position Independent Code (PIC) support in smooth renderer. - * src/smooth/ftsmooth.h declare ft_smooth_renderer_class, - ft_smooth_lcd_renderer_class and ft_smooth_lcd_v_renderer_class - using macros from ftrender.h, + * src/smooth/ftsmooth.h declare ft_smooth_renderer_class, + ft_smooth_lcd_renderer_class and ft_smooth_lcd_v_renderer_class + using macros from ftrender.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/smooth/ftsmooth.c when FT_CONFIG_OPTION_PIC is defined - the following structs: - ft_smooth_renderer_class, ft_smooth_lcd_renderer_class - and ft_smooth_lcd_v_renderer_class + * src/smooth/ftsmooth.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + ft_smooth_renderer_class, ft_smooth_lcd_renderer_class + and ft_smooth_lcd_v_renderer_class will have functions to init or create and destroy them instead of being allocated in the global scope. - And macros will be used from ftspic.h in order to access + And macros will be used from ftspic.h in order to access ft_grays_raster from the pic_container (allocated in ftgrays.c). * src/smooth/ftgrays.h include FT_CONFIG_CONFIG_H - * src/smooth/ftgrays.c when FT_CONFIG_OPTION_PIC is NOT defined - func_interface was moved from gray_convert_glyph_inner function + * src/smooth/ftgrays.c when FT_CONFIG_OPTION_PIC is NOT defined + func_interface was moved from gray_convert_glyph_inner function to the global scope. - When FT_CONFIG_OPTION_PIC is defined + When FT_CONFIG_OPTION_PIC is defined func_interface and ft_grays_raster structs will have functions to init them instead of being allocated in the global scope. - And func_interface will be allocated on the stack of + And func_interface will be allocated on the stack of gray_convert_glyph_inner. New Files: * src/smooth/ftspic.h declare struct to hold PIC globals for smooth renderer and macros to access them. - * src/smooth/ftspic.c implement functions to allocate, destroy and + * src/smooth/ftspic.c implement functions to allocate, destroy and initialize PIC globals for smooth renderer. * src/smooth/smooth.c add new file to build: ftspic.c. @@ -2173,17 +2631,17 @@ Position Independent Code (PIC) support in cff driver. - * include/freetype/internal/services/svcid.h add macros to init + * include/freetype/internal/services/svcid.h add macros to init instances of FT_Service_CIDRec. - * include/freetype/internal/services/svpsinfo.h add macros to init + * include/freetype/internal/services/svpsinfo.h add macros to init instances of FT_Service_PsInfoRec. * src/cff/cffcmap.h declare cff_cmap_encoding_class_rec and cff_cmap_unicode_class_rec using macros from ftobjs.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/cff/cffcmap.c when FT_CONFIG_OPTION_PIC is defined - the following structs: + * src/cff/cffcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: cff_cmap_encoding_class_rec and cff_cmap_unicode_class_rec will have functions to init or create and destroy them instead of being allocated in the global scope. @@ -2191,10 +2649,10 @@ * src/cff/cffdrivr.h declare cff_driver_class using macros from ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/cff/cffdrivr.c when FT_CONFIG_OPTION_PIC is defined - the following structs: + * src/cff/cffdrivr.c when FT_CONFIG_OPTION_PIC is defined + the following structs: cff_service_glyph_dict, cff_service_ps_info, cff_service_ps_name - cff_service_get_cmap_info, cff_service_cid_info, cff_driver_class, + cff_service_get_cmap_info, cff_service_cid_info, cff_driver_class, and cff_services array will have functions to init or create and destroy them instead of being allocated in the global scope. @@ -2206,8 +2664,8 @@ * src/cff/cffobjs.c Use macros from cffpic.h in order to access the structs allocated in cffcmap.c - * src/cff/parser.c when FT_CONFIG_OPTION_PIC is defined - implement functions to create and destroy cff_field_handlers array + * src/cff/parser.c when FT_CONFIG_OPTION_PIC is defined + implement functions to create and destroy cff_field_handlers array instead of being allocated in the global scope. And macros will be used from cffpic.h in order to access it from the pic_container. @@ -2215,7 +2673,7 @@ New Files: * src/cff/cffpic.h declare struct to hold PIC globals for cff driver and macros to access them. - * src/cff/cffpic.c implement functions to allocate, destroy and + * src/cff/cffpic.c implement functions to allocate, destroy and initialize PIC globals for cff driver. * src/cff/cff.c add new file to build: cffpic.c. @@ -2225,38 +2683,38 @@ Position Independent Code (PIC) support in sfnt driver. - * include/freetype/internal/services/svbdf.h add macros to init + * include/freetype/internal/services/svbdf.h add macros to init instances of FT_Service_BDFRec. - * include/freetype/internal/services/svgldict.h add macros to init + * include/freetype/internal/services/svgldict.h add macros to init instances of FT_Service_GlyphDictRec. - * include/freetype/internal/services/svpostnm.h add macros to init + * include/freetype/internal/services/svpostnm.h add macros to init instances of FT_Service_PsFontNameRec. - * include/freetype/internal/services/svsfnt.h add macros to init + * include/freetype/internal/services/svsfnt.h add macros to init instances of FT_Service_SFNT_TableRec. - * include/freetype/internal/services/svttcmap.h add macros to init + * include/freetype/internal/services/svttcmap.h add macros to init instances of FT_Service_TTCMapsRec. - * include/freetype/internal/sfnt.h add macros to init + * include/freetype/internal/sfnt.h add macros to init instances of SFNT_Interface. * src/sfnt/sfdriver.h declare sfnt_module_class using macros from ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/sfnt/sfdriver.c when FT_CONFIG_OPTION_PIC is defined - the following structs: + * src/sfnt/sfdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: sfnt_service_sfnt_table, sfnt_service_glyph_dict, sfnt_service_ps_name - tt_service_get_cmap_info, sfnt_service_bdf, sfnt_interface, + tt_service_get_cmap_info, sfnt_service_bdf, sfnt_interface, sfnt_module_class, and sfnt_services array will have functions to init or create and destroy them instead of being allocated in the global scope. And macros will be used from sfntpic.h in order to access them from the pic_container. - * src/sfnt/ttcmap.h add macros to init + * src/sfnt/ttcmap.h add macros to init instances of TT_CMap_ClassRec. - * src/sfnt/ttcmap.c when FT_CONFIG_OPTION_PIC is defined - the following structs: + * src/sfnt/ttcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: tt_cmap0_class_rec, tt_cmap2_class_rec, tt_cmap4_class_rec - tt_cmap6_class_rec, tt_cmap8_class_rec, tt_cmap10_class_rec, + tt_cmap6_class_rec, tt_cmap8_class_rec, tt_cmap10_class_rec, tt_cmap12_class_rec, tt_cmap14_class_rec and tt_cmap_classes array will have functions to init or create and destroy them instead of being allocated in the global scope. @@ -2268,9 +2726,9 @@ New Files: * src/sfnt/sfntpic.h declare struct to hold PIC globals for sfnt driver and macros to access them. - * src/sfnt/sfntpic.c implement functions to allocate, destroy and + * src/sfnt/sfntpic.c implement functions to allocate, destroy and initialize PIC globals for sfnt driver. - * src/sfnt/ttcmapc.h describing the content of + * src/sfnt/ttcmapc.h describing the content of tt_cmap_classes allocated in ttcmap.c * src/sfnt/sfnt.c add new file to build: sfntpic.c. @@ -2280,30 +2738,30 @@ Position Independent Code (PIC) support in truetype driver. - * include/freetype/internal/services/svmm.h add macros to init + * include/freetype/internal/services/svmm.h add macros to init instances of FT_Service_MultiMastersRec. - * include/freetype/internal/services/svttglyf.h add macros to init + * include/freetype/internal/services/svttglyf.h add macros to init instances of FT_Service_TTGlyfRec. * src/truetype/ttdriver.h declare tt_driver_class using macros from ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy functions will be declared. - * src/truetype/ttdriver.c when FT_CONFIG_OPTION_PIC is defined - the following structs: + * src/truetype/ttdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: tt_service_gx_multi_masters, tt_service_truetype_glyf, tt_driver_class - and tt_services array, + and tt_services array, will have functions to init or create and destroy them instead of being allocated in the global scope. And macros will be used from ttpic.h in order to access them from the pic_container. * src/truetype/ttobjs.c change trick_names array to be - PIC-compatible by being a two dimentional array rather than array + PIC-compatible by being a two dimentional array rather than array of pointers. New Files: * src/truetype/ttpic.h declare struct to hold PIC globals for truetype driver and macros to access them. - * src/truetype/ttpic.c implement functions to allocate, destroy and + * src/truetype/ttpic.c implement functions to allocate, destroy and initialize PIC globals for truetype driver. * src/truetype/truetype.c add new file to build: ttpic.c. @@ -2314,50 +2772,50 @@ Position Independent Code (PIC) support and infrastructure in base. * include/freetype/config/ftoption.h add FT_CONFIG_OPTION_PIC - * include/freetype/internal/ftobjs.h Add pic_container member to + * include/freetype/internal/ftobjs.h Add pic_container member to FT_LibraryRec. Add macros to declare and init instances of FT_CMap_ClassRec. Add macros to init instances of FT_Outline_Funcs and FT_Raster_Funcs. - Add macros to declare, allocate and initialize modules + Add macros to declare, allocate and initialize modules (FT_Module_Class). - Add macros to declare, allocate and initialize renderers + Add macros to declare, allocate and initialize renderers (FT_Renderer_Class). Add macro to init instances of FT_Glyph_Class. - Add macros to declare, allocate and initialize drivers + Add macros to declare, allocate and initialize drivers (FT_Driver_ClassRec). - * include/freetype/internal/ftpic.h new file to declare the + * include/freetype/internal/ftpic.h new file to declare the FT_PIC_Container struct and the functions to allocate and detroy it. - * include/freetype/internal/ftserv.h add macros to allocate and + * include/freetype/internal/ftserv.h add macros to allocate and destory arrays of FT_ServiceDescRec. - * include/freetype/internal/internal.h define macro to include + * include/freetype/internal/internal.h define macro to include ftpic.h. New Files: - * src/base/ftpic.c implement functions to allocate and destory the + * src/base/ftpic.c implement functions to allocate and destory the global pic_container. - * src/base/basepic.h declare struct to hold PIC globals for base and + * src/base/basepic.h declare struct to hold PIC globals for base and macros to access them. - * src/base/basepic.c implement functions to allocate, destroy and + * src/base/basepic.c implement functions to allocate, destroy and initialize PIC globals for base. - * src/base/ftinit.c when FT_CONFIG_OPTION_PIC is defined implement - functions that allocate and destroy ft_default_modules according to + * src/base/ftinit.c when FT_CONFIG_OPTION_PIC is defined implement + functions that allocate and destroy ft_default_modules according to FT_CONFIG_MODULES_H in the pic_container instead of the global scope and use macro from basepic.h to access it. - * src/base/ftobjs.c add calls to the functions that allocate and - destroy the global pic_container when the library is created and + * src/base/ftobjs.c add calls to the functions that allocate and + destroy the global pic_container when the library is created and destroyed. - * src/base/jamfile add new files to FT2_MULTI build: + * src/base/jamfile add new files to FT2_MULTI build: ftpic.c and basepic.c. - * src/base/ftbase.c add new files to build: + * src/base/ftbase.c add new files to build: ftpic.c and basepic.c. - * src/base/ftglyph.c when FT_CONFIG_OPTION_PIC is defined + * src/base/ftglyph.c when FT_CONFIG_OPTION_PIC is defined ft_bitmap_glyph_class and ft_outline_glyph_class will be allocated in the pic_container instead of the global scope and use macros from basepic.h to access them. - * src/base/ftbbox.c allocate bbox_interface stract on the stack + * src/base/ftbbox.c allocate bbox_interface stract on the stack instead of the global scope when FT_CONFIG_OPTION_PIC is defined. * src/base/ftstroke.c access ft_outline_glyph_class allocated in ftglyph.c via macros from basepic.h @@ -2367,7 +2825,7 @@ Preparing changes in cff parser later needed for PIC version. * src/cff/cffload.c, src/cff/cffload.h, src/cff/cffobjs.c, - src/cff/cffparse.c, src/cff/cffparse.h: Add library pointer to + src/cff/cffparse.c, src/cff/cffparse.h: Add library pointer to 'CFF_ParserRec' set by `cff_parser_init'. Route library pointer from 'cff_face_init' to 'cff_subfont_load' for `cff_parser_init'. @@ -6442,8 +6900,8 @@ 2006-12-08 Vladimir Volovich - * src/tools/apinames (State): Remove final comma in structure -- xlc - v5 under AIX 4.3 doesn't like this. + * src/tools/apinames.c (State): Remove final comma in structure -- + xlc v5 under AIX 4.3 doesn't like this. 2006-12-07 David Turner @@ -7474,7 +7932,7 @@ ---------------------------------------------------------------------------- -Copyright 2006, 2007, 2008, 2009 by +Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/reactos/lib/3rdparty/freetype/Jamfile b/reactos/lib/3rdparty/freetype/Jamfile index ac327b812e0..d8c1bbada29 100644 --- a/reactos/lib/3rdparty/freetype/Jamfile +++ b/reactos/lib/3rdparty/freetype/Jamfile @@ -194,7 +194,7 @@ rule RefDoc actions RefDoc { - python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.11 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h + python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.12 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h } RefDoc refdoc ; diff --git a/reactos/lib/3rdparty/freetype/README b/reactos/lib/3rdparty/freetype/README index f63c8fc4602..282791ef087 100644 --- a/reactos/lib/3rdparty/freetype/README +++ b/reactos/lib/3rdparty/freetype/README @@ -9,7 +9,7 @@ is called `libttf'. They are *not* compatible! - FreeType 2.3.11 + FreeType 2.3.12 =============== Please read the docs/CHANGES file, it contains IMPORTANT @@ -26,9 +26,9 @@ and download one of the following files. - freetype-doc-2.3.11.tar.bz2 - freetype-doc-2.3.11.tar.gz - ftdoc2311.zip + freetype-doc-2.3.12.tar.bz2 + freetype-doc-2.3.12.tar.gz + ftdoc2312.zip Bugs @@ -51,7 +51,7 @@ ---------------------------------------------------------------------- -Copyright 2006, 2007, 2008, 2009 by +Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/reactos/lib/3rdparty/freetype/autogen.sh b/reactos/lib/3rdparty/freetype/autogen.sh index 16c335fd5c9..c28a51c1323 100644 --- a/reactos/lib/3rdparty/freetype/autogen.sh +++ b/reactos/lib/3rdparty/freetype/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright 2005, 2006, 2007, 2008, 2009 by +# Copyright 2005, 2006, 2007, 2008, 2009, 2010 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -95,10 +95,11 @@ compare_to_minimum_version () check_tool_version () { field=$5 + # assume the output of "[TOOL] --version" is "toolname (GNU toolname foo bar) version" if test "$field"x = x; then - field=4 # default to 4 for all GNU autotools + field=3 # default to 3 for all GNU autotools, after filtering enclosed string fi - version=`$1 --version | head -1 | cut -d ' ' -f $field` + version=`$1 --version | head -1 | sed 's/([^)]*)/()/g' | cut -d ' ' -f $field` version_check=`compare_to_minimum_version $version $4` if test "$version_check"x = 0x; then echo "ERROR: Your version of the \`$2' tool is too old." diff --git a/reactos/lib/3rdparty/freetype/devel/ftoption.h b/reactos/lib/3rdparty/freetype/devel/ftoption.h index d4fee59537b..9c6c2fe4594 100644 --- a/reactos/lib/3rdparty/freetype/devel/ftoption.h +++ b/reactos/lib/3rdparty/freetype/devel/ftoption.h @@ -4,7 +4,8 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +86,9 @@ FT_BEGIN_HEADER /* */ /* This macro has no impact on the FreeType API, only on its */ /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ - /* the original size; the difference will be that each triplet of */ - /* subpixels has R=G=B. */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ /* */ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ @@ -312,8 +313,9 @@ FT_BEGIN_HEADER /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ - /* This allows FreeType to be used with the PostScript language, using */ - /* the GhostScript interpreter. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ /* */ #define FT_CONFIG_OPTION_INCREMENTAL @@ -396,6 +398,20 @@ FT_BEGIN_HEADER #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + /*************************************************************************/ /*************************************************************************/ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h index 3c0b8b16412..43d587e02b9 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ /* */ /*************************************************************************/ - #ifndef __FTCONFIG_H__ #define __FTCONFIG_H__ @@ -306,9 +305,38 @@ FT_BEGIN_HEADER /* Provide assembler fragments for performance-critical functions. */ /* These must be defined `static __inline__' with GCC. */ +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + #ifdef __GNUC__ -#if defined( __arm__ ) && !defined( __thumb__ ) +#if defined( __arm__ ) && !defined( __thumb__ ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) #define FT_MULFIX_ASSEMBLER FT_MulFix_arm /* documentation is in freetype.h */ @@ -333,7 +361,7 @@ FT_BEGIN_HEADER return a; } -#endif /* __arm__ && !__thumb__ */ +#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ #if defined( i386 ) #define FT_MULFIX_ASSEMBLER FT_MulFix_i386 diff --git a/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h b/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h index f7250896681..443c0d8bf4d 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,8 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +86,9 @@ FT_BEGIN_HEADER /* */ /* This macro has no impact on the FreeType API, only on its */ /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ - /* the original size; the difference will be that each triplet of */ - /* subpixels has R=G=B. */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ /* */ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ @@ -312,8 +313,9 @@ FT_BEGIN_HEADER /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ - /* This allows FreeType to be used with the PostScript language, using */ - /* the GhostScript interpreter. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ /* */ /* #define FT_CONFIG_OPTION_INCREMENTAL */ @@ -401,7 +403,7 @@ FT_BEGIN_HEADER /* Position Independent Code */ /* */ /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ + /* avoid creating constants that require address fixups. Instead the */ /* constants will be moved into a struct and additional intialization */ /* code will be used. */ /* */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/freetype.h b/reactos/lib/3rdparty/freetype/include/freetype/freetype.h index 9e74f1158af..942a740f00a 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/freetype.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/freetype.h @@ -4,7 +4,8 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -231,6 +232,10 @@ FT_BEGIN_HEADER /* vertAdvance :: */ /* Advance height for vertical layout. */ /* */ + /* */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; @@ -1477,8 +1482,13 @@ FT_BEGIN_HEADER /* important to perform correct WYSIWYG layout. */ /* Only relevant for outline glyphs. */ /* */ - /* advance :: This is the transformed advance width for the */ - /* glyph (in 26.6 fractional pixel format). */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* advance width for the glyph (in 26.6 */ + /* fractional pixel format). As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ /* */ /* format :: This field indicates the format of the image */ /* contained in the glyph slot. Typically */ @@ -1743,7 +1753,8 @@ FT_BEGIN_HEADER /* data :: A pointer to the parameter data. */ /* */ /* */ - /* The ID and function of parameters are driver-specific. */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ /* */ typedef struct FT_Parameter_ { @@ -3763,7 +3774,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 3 -#define FREETYPE_PATCH 11 +#define FREETYPE_PATCH 12 /*************************************************************************/ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h b/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h index cacccf025e4..0b8f0c04444 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftglyph.h @@ -468,7 +468,7 @@ FT_BEGIN_HEADER /* // convert to a bitmap (default render mode + destroying old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ /* 0, 1 ); */ /* if ( error ) // `glyph' unchanged */ /* ... */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h b/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h index 2fcc113ad5d..0272e92d2b3 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftimage.h @@ -5,7 +5,8 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,10 +52,9 @@ FT_BEGIN_HEADER /* FT_Pos */ /* */ /* */ - /* The type FT_Pos is a 32-bit integer used to store vectorial */ - /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 16.16, or 26.6 fixed float */ - /* pixel coordinates. */ + /* The type FT_Pos is used to store vectorial coordinates. Depending */ + /* on the context, these can represent distances in integer font */ + /* units, or 16.16, or 26.6 fixed float pixel coordinates. */ /* */ typedef signed long FT_Pos; @@ -99,6 +99,20 @@ FT_BEGIN_HEADER /* */ /* yMax :: The vertical maximum (top-most). */ /* */ + /* */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ typedef struct FT_BBox_ { FT_Pos xMin, yMin; @@ -254,6 +268,9 @@ FT_BEGIN_HEADER /* flow. In all cases, the pitch is an offset to add */ /* to a bitmap pointer in order to go down one row. */ /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ /* buffer :: A typeless pointer to the bitmap buffer. This */ /* value should be aligned on 32-bit boundaries in */ /* most cases. */ @@ -563,8 +580,8 @@ FT_BEGIN_HEADER /* FT_Outline_ConicToFunc */ /* */ /* */ - /* A function pointer type use to describe the signature of a `conic */ - /* to' function during outline walking/decomposition. */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ /* */ /* A `conic to' is emitted to indicate a second-order Bézier arc in */ /* the outline. */ @@ -596,7 +613,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking/decomposition. */ + /* to' function during outline walking or decomposition. */ /* */ /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ /* */ @@ -629,8 +646,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Béziers, */ - /* as well as `move to' and `close to' operations. */ + /* decomposition in order to emit segments, conic, and cubic Béziers. */ /* */ /* */ /* move_to :: The `move to' emitter. */ @@ -657,7 +673,7 @@ FT_BEGIN_HEADER /* y' = (x << shift) - delta */ /* } */ /* */ - /* Set the value of `shift' and `delta' to~0 to get the original */ + /* Set the values of `shift' and `delta' to~0 to get the original */ /* point coordinates. */ /* */ typedef struct FT_Outline_Funcs_ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h b/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h index 96abedea7b6..aaf689ff16c 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2008 by */ +/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -101,7 +101,10 @@ FT_BEGIN_HEADER * Top bearing, in font units. * * advance :: - * Glyph advance, in font units. + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. * * @note: * These correspond to horizontal or vertical metrics depending on the @@ -114,6 +117,7 @@ FT_BEGIN_HEADER FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ } FT_Incremental_MetricsRec; diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h b/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h index d7d01e82706..2829a05ca30 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +85,8 @@ FT_BEGIN_HEADER /* */ /* */ /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ + /* segments and Bézier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ /* */ /* */ /* outline :: A pointer to the source target. */ diff --git a/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h b/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h index f20b4099dae..485e4e162e7 100644 --- a/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h +++ b/reactos/lib/3rdparty/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -160,6 +160,35 @@ FT_BEGIN_HEADER FT_SfntName *aname ); + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + /* */ diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c index 394fb9789ba..e6882d5e7b5 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin.c @@ -402,16 +402,16 @@ af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_UInt i; - FT_Bool started = 0, same_width = 1; + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; /* check whether all ASCII digits have the same advance width; */ /* digit `0' is 0x30 in all supported charmaps */ for ( i = 0x30; i <= 0x39; i++ ) { - FT_UInt glyph_index; - FT_Fixed advance, old_advance = 0; + FT_UInt glyph_index; glyph_index = FT_Get_Char_Index( face, i ); diff --git a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c index 5e2ad48c406..5cbeb296b58 100644 --- a/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c +++ b/reactos/lib/3rdparty/freetype/src/autofit/aflatin2.c @@ -407,16 +407,16 @@ af_latin2_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_UInt i; - FT_Bool started = 0, same_width = 1; + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; /* check whether all ASCII digits have the same advance width; */ /* digit `0' is 0x30 in all supported charmaps */ for ( i = 0x30; i <= 0x39; i++ ) { - FT_UInt glyph_index; - FT_Fixed advance, old_advance; + FT_UInt glyph_index; glyph_index = FT_Get_Char_Index( face, i ); diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbase.h b/reactos/lib/3rdparty/freetype/src/base/ftbase.h index 9cae85da9ef..1dc49f3bdf6 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftbase.h +++ b/reactos/lib/3rdparty/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008 by */ +/* Copyright 2008, 2010 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,7 @@ FT_BEGIN_HEADER /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ /* font, and try to load a face specified by the face_index. */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) open_face_PS_from_sfnt_stream( FT_Library library, FT_Stream stream, FT_Long face_index, @@ -40,7 +40,7 @@ FT_BEGIN_HEADER /* Create a new FT_Face given a buffer and a driver name. */ /* From ftmac.c. */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, FT_ULong size, diff --git a/reactos/lib/3rdparty/freetype/src/base/ftbbox.c b/reactos/lib/3rdparty/freetype/src/base/ftbbox.c index 8136ccc1e9f..4b8e9112fee 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftbbox.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -140,7 +140,7 @@ /* */ /* */ /* This function is used as a `conic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ @@ -507,7 +507,7 @@ /* */ /* */ /* This function is used as a `cubic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c b/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c index 677f242080c..160269d1929 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftdbgmem.c @@ -989,7 +989,7 @@ #else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ - static const FT_Byte _debug_mem_dummy = 0; + typedef int _debug_mem_dummy; #endif /* !FT_DEBUG_MEMORY */ diff --git a/reactos/lib/3rdparty/freetype/src/base/ftglyph.c b/reactos/lib/3rdparty/freetype/src/base/ftglyph.c index ef61d45df2b..3505d6dde9a 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftglyph.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftglyph.c @@ -372,7 +372,7 @@ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) clazz = FT_BITMAP_GLYPH_CLASS_GET; - /* it it is an outline too */ + /* if it is an outline */ else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) clazz = FT_OUTLINE_GLYPH_CLASS_GET; @@ -515,6 +515,10 @@ const FT_Glyph_Class* clazz; +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library = FT_GLYPH( glyph )->library; +#endif + /* check argument */ if ( !the_glyph ) diff --git a/reactos/lib/3rdparty/freetype/src/base/ftinit.c b/reactos/lib/3rdparty/freetype/src/base/ftinit.c index ef13503869f..f94f25a83c1 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftinit.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftinit.c @@ -115,7 +115,7 @@ FT_Module_Class** classes; FT_Memory memory; FT_UInt i; - BasePIC* pic_container = library->pic_container.base; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; if ( !pic_container->default_module_classes ) return; @@ -145,7 +145,7 @@ FT_Module_Class** classes; FT_Module_Class* clazz; FT_UInt i; - BasePIC* pic_container = library->pic_container.base; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; memory = library->memory; pic_container->default_module_classes = 0; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftobjs.c b/reactos/lib/3rdparty/freetype/src/base/ftobjs.c index 421540c8dc2..46bcd3bb8b2 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftobjs.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,8 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,7 +38,9 @@ #include FT_SERVICE_KERNING_H #include FT_SERVICE_TRUETYPE_ENGINE_H +#ifdef FT_CONFIG_OPTION_MAC_FONTS #include "ftbase.h" +#endif #define GRID_FIT_METRICS @@ -708,8 +711,8 @@ } /* compute the linear advance in 16.16 pixels */ - if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( FT_IS_SCALABLE( face ) ) ) + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && + ( FT_IS_SCALABLE( face ) ) ) { FT_Size_Metrics* metrics = &face->size->metrics; @@ -739,11 +742,30 @@ renderer, slot, &internal->transform_matrix, &internal->transform_delta ); + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* apply `standard' transformation if no renderer is available */ + if ( &internal->transform_matrix ) + FT_Outline_Transform( &slot->outline, + &internal->transform_matrix ); + + if ( &internal->transform_delta ) + FT_Outline_Translate( &slot->outline, + internal->transform_delta.x, + internal->transform_delta.y ); + } + /* transform advance */ FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); } } + FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); + FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); + + FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); + FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); + /* do we need to render the image now? */ if ( !error && slot->format != FT_GLYPH_FORMAT_BITMAP && diff --git a/reactos/lib/3rdparty/freetype/src/base/ftoutln.c b/reactos/lib/3rdparty/freetype/src/base/ftoutln.c index 49ef82e27d8..b69df84c04c 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftoutln.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -304,9 +304,9 @@ *anoutline = null_outline; - if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || - FT_NEW_ARRAY( anoutline->tags, numPoints ) || - FT_NEW_ARRAY( anoutline->contours, numContours ) ) + if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || + FT_NEW_ARRAY( anoutline->tags, numPoints ) || + FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; anoutline->n_points = (FT_UShort)numPoints; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftpatent.c b/reactos/lib/3rdparty/freetype/src/base/ftpatent.c index 236d9a674c4..501cab52cad 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftpatent.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftpatent.c @@ -5,7 +5,7 @@ /* FreeType API for checking patented TrueType bytecode instructions */ /* (body). */ /* */ -/* Copyright 2007, 2008 by David Turner. */ +/* Copyright 2007, 2008, 2010 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -114,7 +114,7 @@ FT_ULong tag ) { FT_Stream stream = face->stream; - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; FT_Service_SFNT_Table service; FT_Bool result = FALSE; @@ -124,13 +124,14 @@ if ( service ) { FT_UInt i = 0; - FT_ULong tag_i = 0, offset_i, length_i; + FT_ULong tag_i = 0, offset_i = 0, length_i = 0; + for ( i = 0; !error && tag_i != tag ; i++ ) error = service->table_info( face, i, &tag_i, &offset_i, &length_i ); - if ( error || + if ( error || FT_STREAM_SEEK( offset_i ) ) goto Exit; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftstroke.c b/reactos/lib/3rdparty/freetype/src/base/ftstroke.c index 0978b0ed947..75bcbded6a3 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftstroke.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -979,7 +979,8 @@ thcos = FT_Cos( theta ); sigma = FT_MulFix( stroker->miter_limit, thcos ); - if ( sigma >= 0x10000L ) + /* FT_Sin(x) = 0 for x <= 57 */ + if ( sigma >= 0x10000L || ft_pos_abs( theta ) <= 57 ) miter = FALSE; if ( miter ) /* this is a miter (broken angle) */ @@ -1360,7 +1361,7 @@ phi1 = (angle_mid + angle_in ) / 2; phi2 = (angle_mid + angle_out ) / 2; length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); - length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); + length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) ); for ( side = 0; side <= 1; side++ ) { @@ -1735,13 +1736,10 @@ } else { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ + /* if both first and last points are conic, */ + /* start at their middle */ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; } point--; tags--; diff --git a/reactos/lib/3rdparty/freetype/src/base/ftsynth.c b/reactos/lib/3rdparty/freetype/src/base/ftsynth.c index 326d8e73e47..ba3c633e28e 100644 --- a/reactos/lib/3rdparty/freetype/src/base/ftsynth.c +++ b/reactos/lib/3rdparty/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -100,8 +100,8 @@ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { - error = FT_Outline_Embolden( &slot->outline, xstr ); /* ignore error */ + (void)FT_Outline_Embolden( &slot->outline, xstr ); /* this is more than enough for most glyphs; if you need accurate */ /* values, you have to call FT_Outline_Get_CBox */ diff --git a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c index 2f462a2f645..a9ab0c319f7 100644 --- a/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c +++ b/reactos/lib/3rdparty/freetype/src/cache/ftcglyph.c @@ -71,8 +71,8 @@ FT_UNUSED( cache ); - return FT_BOOL( gnode->family == gquery->family && - gnode->gindex == gquery->gindex ); + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); } diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c index 217adf2f129..dad0b65d8b1 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffdrivr.c @@ -621,14 +621,15 @@ { FT_Module sfnt; FT_Module_Interface result; - FT_Library library = driver->library; - FT_UNUSED(library); result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( driver->library, "sfnt" ); diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffgload.c b/reactos/lib/3rdparty/freetype/src/cff/cffgload.c index 40fa20b426f..9330c058823 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffgload.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffgload.c @@ -4,7 +4,8 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -113,6 +114,9 @@ cff_op_closepath, cff_op_callothersubr, cff_op_pop, + cff_op_seac, + cff_op_sbw, + cff_op_setcurrentpoint, /* do not remove */ cff_op_max @@ -201,7 +205,10 @@ 2, /* hsbw */ 0, 0, - 0 + 0, + 5, /* seac */ + 4, /* sbw */ + 2 /* setcurrentpoint */ }; @@ -319,17 +326,23 @@ /* subroutines. */ /* */ /* */ - /* num_subrs :: The number of glyph subroutines. */ + /* in_charstring_type :: The `CharstringType' value of the top DICT */ + /* dictionary. */ + /* */ + /* num_subrs :: The number of glyph subroutines. */ /* */ /* */ /* The bias value. */ static FT_Int - cff_compute_bias( FT_UInt num_subrs ) + cff_compute_bias( FT_Int in_charstring_type, + FT_UInt num_subrs ) { FT_Int result; - if ( num_subrs < 1240 ) + if ( in_charstring_type == 1 ) + result = 0; + else if ( num_subrs < 1240 ) result = 107; else if ( num_subrs < 33900U ) result = 1131; @@ -380,9 +393,12 @@ cff_builder_init( &decoder->builder, face, size, slot, hinting ); /* initialize Type2 decoder */ + decoder->cff = cff; decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; - decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + decoder->globals_bias = cff_compute_bias( + cff->top_font.font_dict.charstring_type, + decoder->num_globals ); decoder->hint_mode = hint_mode; } @@ -434,7 +450,9 @@ decoder->num_locals = sub->num_local_subrs; decoder->locals = sub->local_subrs; - decoder->locals_bias = cff_compute_bias( decoder->num_locals ); + decoder->locals_bias = cff_compute_bias( + decoder->cff->top_font.font_dict.charstring_type, + decoder->num_locals ); decoder->glyph_width = sub->private_dict.default_width; decoder->nominal_width = sub->private_dict.nominal_width; @@ -677,7 +695,7 @@ data.length = length; face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object,&data ); + face->root.internal->incremental_interface->object, &data ); } else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -693,6 +711,7 @@ static FT_Error cff_operator_seac( CFF_Decoder* decoder, + FT_Pos asb, FT_Pos adx, FT_Pos ady, FT_Int bchar, @@ -705,6 +724,7 @@ FT_Vector left_bearing, advance; FT_Byte* charstring; FT_ULong charstring_len; + FT_Pos glyph_width; if ( decoder->seac ) @@ -713,6 +733,9 @@ return CFF_Err_Syntax_Error; } + adx += decoder->builder.left_bearing.x; + ady += decoder->builder.left_bearing.y; + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ /* They use the character code, not the glyph index, in this case. */ @@ -795,16 +818,17 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ + /* Save the left bearing, advance and glyph width of the base */ + /* character as they will be erased by the next load. */ left_bearing = builder->left_bearing; advance = builder->advance; + glyph_width = decoder->glyph_width; builder->left_bearing.x = 0; builder->left_bearing.y = 0; - builder->pos_x = adx; + builder->pos_x = adx - asb; builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ @@ -824,10 +848,11 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Restore the left side bearing and advance width */ - /* of the base character. */ + /* Restore the left side bearing, advance and glyph width */ + /* of the base character. */ builder->left_bearing = left_bearing; builder->advance = advance; + decoder->glyph_width = glyph_width; builder->pos_x = 0; builder->pos_y = 0; @@ -869,6 +894,8 @@ FT_Pos x, y; FT_Fixed seed; FT_Fixed* stack; + FT_Int charstring_type = + decoder->cff->top_font.font_dict.charstring_type; T2_Hints_Funcs hinter; @@ -958,7 +985,8 @@ ( (FT_Int32)ip[2] << 8 ) | ip[3]; ip += 4; - shift = 0; + if ( charstring_type == 2 ) + shift = 0; } if ( decoder->top - stack >= CFF_MAX_OPERANDS ) goto Stack_Overflow; @@ -1032,6 +1060,12 @@ case 0: op = cff_op_dotsection; break; + case 1: /* this is actually the Type1 vstem3 operator */ + op = cff_op_vstem; + break; + case 2: /* this is actually the Type1 hstem3 operator */ + op = cff_op_hstem; + break; case 3: op = cff_op_and; break; @@ -1041,6 +1075,12 @@ case 5: op = cff_op_not; break; + case 6: + op = cff_op_seac; + break; + case 7: + op = cff_op_sbw; + break; case 8: op = cff_op_store; break; @@ -1104,6 +1144,9 @@ case 30: op = cff_op_roll; break; + case 33: + op = cff_op_setcurrentpoint; + break; case 34: op = cff_op_hflex; break; @@ -1171,7 +1214,7 @@ op = cff_op_hvcurveto; break; default: - ; + break; } if ( op == cff_op_unknown ) @@ -1886,6 +1929,21 @@ } break; + case cff_op_seac: + FT_TRACE4(( " seac\n" )); + + error = cff_operator_seac( decoder, + args[0], args[1], args[2], + (FT_Int)( args[3] >> 16 ), + (FT_Int)( args[4] >> 16 ) ); + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + case cff_op_endchar: FT_TRACE4(( " endchar\n" )); @@ -1895,10 +1953,8 @@ /* Save glyph width so that the subglyphs don't overwrite it. */ FT_Pos glyph_width = decoder->glyph_width; - error = cff_operator_seac( decoder, - args[-4], - args[-3], + 0L, args[-4], args[-3], (FT_Int)( args[-2] >> 16 ), (FT_Int)( args[-1] >> 16 ) ); @@ -2106,7 +2162,7 @@ FT_TRACE4(( " dup\n" )); args[1] = args[0]; - args++; + args += 2; break; case cff_op_put: @@ -2117,7 +2173,7 @@ FT_TRACE4(( " put\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } break; @@ -2130,7 +2186,7 @@ FT_TRACE4(( " get\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) val = decoder->buildchar[idx]; args[0] = val; @@ -2170,10 +2226,42 @@ FT_TRACE4(( " hsbw (invalid op)\n" )); - decoder->glyph_width = decoder->nominal_width + - (args[1] >> 16); - x = args[0]; - y = 0; + decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = 0; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y; + args = stack; + break; + + case cff_op_sbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " sbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = args[1]; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_setcurrentpoint: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; args = stack; break; @@ -2184,8 +2272,10 @@ FT_TRACE4(( " callothersubr (invalid op)\n" )); - /* don't modify stack; handle the subr as `unknown' so that */ - /* following `pop' operands use the arguments on stack */ + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' other */ + /* subroutines in the Type1 spec. */ + args -= 2 + ( args[-2] >> 16 ); break; case cff_op_pop: @@ -2674,23 +2764,25 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && + if ( !error && + face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = decoder.builder.left_bearing.x; - metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.bearing_y = 0; metrics.advance = decoder.builder.advance.x; + metrics.advance_v = decoder.builder.advance.y; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); + decoder.builder.left_bearing.x = metrics.bearing_x; - decoder.builder.left_bearing.y = metrics.bearing_y; decoder.builder.advance.x = metrics.advance; - decoder.builder.advance.y = 0; + decoder.builder.advance.y = metrics.advance_v; } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -2827,9 +2919,12 @@ if ( has_vertical_info ) metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; - else - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + else + { + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } } diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffgload.h b/reactos/lib/3rdparty/freetype/src/cff/cffgload.h index 956817a0806..38937be5c11 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffgload.h +++ b/reactos/lib/3rdparty/freetype/src/cff/cffgload.h @@ -28,8 +28,9 @@ FT_BEGIN_HEADER -#define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_TRANS_ELEMENTS 32 /*************************************************************************/ @@ -137,8 +138,7 @@ FT_BEGIN_HEADER FT_Bool read_width; FT_Bool width_only; FT_Int num_hints; - FT_Fixed* buildchar; - FT_Int len_buildchar; + FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; FT_UInt num_locals; FT_UInt num_globals; diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c index e0966e0d38e..bd56c4ba11d 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffobjs.c @@ -657,10 +657,11 @@ cffface->num_glyphs = cff->charstrings_index.count; /* set global bbox, as well as EM size */ - cffface->bbox.xMin = dict->font_bbox.xMin >> 16; - cffface->bbox.yMin = dict->font_bbox.yMin >> 16; - cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; - cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; + cffface->bbox.xMin = dict->font_bbox.xMin >> 16; + cffface->bbox.yMin = dict->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; + cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); diff --git a/reactos/lib/3rdparty/freetype/src/cff/cffparse.c b/reactos/lib/3rdparty/freetype/src/cff/cffparse.c index 947ec9d343b..01266a193d2 100644 --- a/reactos/lib/3rdparty/freetype/src/cff/cffparse.c +++ b/reactos/lib/3rdparty/freetype/src/cff/cffparse.c @@ -745,8 +745,10 @@ p++; for (;;) { + /* An unterminated floating point number at the */ + /* end of a dictionary is invalid but harmless. */ if ( p >= limit ) - goto Syntax_Error; + goto Exit; v = p[0] >> 4; if ( v == 15 ) break; diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidgload.c b/reactos/lib/3rdparty/freetype/src/cid/cidgload.c index f59035ffa36..ea61b4e1283 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidgload.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,6 +58,8 @@ #endif + FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* For incremental fonts get the character data using */ @@ -171,16 +173,16 @@ metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); - metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.bearing_y = 0; metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); error = inc->funcs->get_glyph_metrics( inc->object, glyph_index, FALSE, &metrics ); decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); - decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); - decoder->builder.advance.y = 0; + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -425,9 +427,12 @@ metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } Exit: diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c b/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c index 9647d870161..82678af0d4b 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c +++ b/reactos/lib/3rdparty/freetype/src/cid/cidobjs.c @@ -413,10 +413,11 @@ cidface->num_fixed_sizes = 0; cidface->available_sizes = 0; - cidface->bbox.xMin = cid->font_bbox.xMin >> 16; - cidface->bbox.yMin = cid->font_bbox.yMin >> 16; - cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; - cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; + cidface->bbox.xMin = cid->font_bbox.xMin >> 16; + cidface->bbox.yMin = cid->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16; + cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16; if ( !cidface->units_per_EM ) cidface->units_per_EM = 1000; diff --git a/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h b/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h index 94a3657b025..904cb09cf4d 100644 --- a/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h +++ b/reactos/lib/3rdparty/freetype/src/cid/cidtoken.h @@ -22,7 +22,7 @@ #define T1CODE T1_FIELD_LOCATION_CID_INFO T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) - T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 ) + T1_FIELD_FIXED ( "CIDFontVersion", cid_version, 0 ) T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) T1_FIELD_STRING( "Registry", registry, 0 ) T1_FIELD_STRING( "Ordering", ordering, 0 ) diff --git a/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c b/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c index 4f601a16d28..6e57dedb971 100644 --- a/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c +++ b/reactos/lib/3rdparty/freetype/src/lzw/ftlzw.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2004, 2005, 2006, 2009 by */ +/* Copyright 2004, 2005, 2006, 2009, 2010 by */ /* Albert Chin-A-Young. */ /* */ /* Based on code in src/gzip/ftgzip.c, Copyright 2004 by */ @@ -122,13 +122,9 @@ zip->pos = 0; /* check and skip .Z header */ - { - stream = source; - - error = ft_lzw_check_header( source ); - if ( error ) - goto Exit; - } + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; /* initialize internal lzw variable */ ft_lzwstate_init( lzw, source ); diff --git a/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c b/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c index 8a38bec1d33..d2f17dc9ceb 100644 --- a/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c +++ b/reactos/lib/3rdparty/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -600,8 +600,8 @@ /* get the bitmap metrics */ { - FT_Long xpos, ypos, advance; - FT_UInt xsize, ysize, format; + FT_Long xpos = 0, ypos = 0, advance = 0; + FT_UInt xsize = 0, ysize = 0, format = 0; FT_Byte* p; diff --git a/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c b/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c index b3245a67889..31554ff1ba7 100644 --- a/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c +++ b/reactos/lib/3rdparty/freetype/src/psaux/t1decode.c @@ -4,7 +4,8 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -211,7 +212,12 @@ /* `glyph_names' is set to 0 for CID fonts which do not */ /* include an encoding. How can we deal with these? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( decoder->glyph_names == 0 && + !face->root.internal->incremental_interface ) +#else if ( decoder->glyph_names == 0 ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { FT_ERROR(( "t1operator_seac:" " glyph names table not available in this font\n" )); @@ -1453,12 +1459,20 @@ case op_setcurrentpoint: FT_TRACE4(( " setcurrentpoint" )); - /* From the T1 specs, section 6.4: */ + /* From the T1 specification, section 6.4: */ /* */ /* The setcurrentpoint command is used only in */ /* conjunction with results from OtherSubrs procedures. */ - /* known_othersubr_result_cnt != 0 is already handled above */ + /* known_othersubr_result_cnt != 0 is already handled */ + /* above. */ + + /* Note, however, that both Ghostscript and Adobe */ + /* Distiller handle this situation by silently ignoring */ + /* the inappropriate `setcurrentpoint' instruction. So */ + /* we do the same. */ +#if 0 + if ( decoder->flex_state != 1 ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -1466,6 +1480,7 @@ goto Syntax_Error; } else +#endif decoder->flex_state = 0; break; diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c index 1d157b7e9d6..1097efb86d7 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfdriver.c @@ -417,8 +417,6 @@ sfnt_get_interface( FT_Module module, const char* module_interface ) { - FT_Library library = module->library; - FT_UNUSED(library); FT_UNUSED( module ); return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c b/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c index cef3cd959e4..b74b1a93a9b 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/sfobjs.c @@ -26,6 +26,7 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SFNT_NAMES_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -527,13 +528,27 @@ #endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool ignore_preferred_family = FALSE; + FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); + /* Check parameters */ + + { + FT_Int i; + + + for ( i = 0; i < num_params; i++ ) + { + if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) + ignore_preferred_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) + ignore_preferred_subfamily = TRUE; + } + } /* Load tables */ @@ -722,26 +737,30 @@ /* Foundation (WPF). This flag has been introduced in version */ /* 1.5 of the OpenType specification (May 2008). */ + face->root.family_name = NULL; + face->root.style_name = NULL; if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) { - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } else { GET_NAME( WWS_FAMILY, &face->root.family_name ); - if ( !face->root.family_name ) + if ( !face->root.family_name && !ignore_preferred_family ) GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name ) + if ( !face->root.style_name && !ignore_preferred_subfamily ) GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c index 26ea83c16c8..b283f6d1621 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttcmap.c @@ -2574,10 +2574,7 @@ } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap13_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap13_class_rec, sizeof ( TT_CMap13Rec ), (FT_CMap_InitFunc) tt_cmap13_init, @@ -2586,11 +2583,11 @@ (FT_CMap_CharNextFunc) tt_cmap13_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 13, (TT_CMap_ValidateFunc) tt_cmap13_validate, (TT_CMap_Info_GetFunc) tt_cmap13_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_13 */ diff --git a/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c b/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c index f08f6403983..3ad33bd6d86 100644 --- a/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c +++ b/reactos/lib/3rdparty/freetype/src/sfnt/ttload.c @@ -168,10 +168,10 @@ check_table_dir( SFNT_Header sfnt, FT_Stream stream ) { - FT_Error error; - FT_UInt nn, valid_entries = 0; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; + FT_Error error; + FT_UShort nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; static const FT_Frame_Field table_dir_entry_fields[] = { diff --git a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c index 4a4d375c809..846e454e667 100644 --- a/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c +++ b/reactos/lib/3rdparty/freetype/src/smooth/ftgrays.c @@ -1426,7 +1426,7 @@ /* */ /* */ /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bzier arcs. This function is also able to emit */ + /* segments and Bézier arcs. This function is also able to emit */ /* `move to' and `close to' operations to indicate the start and end */ /* of new contours in the outline. */ /* */ diff --git a/reactos/lib/3rdparty/freetype/src/tools/apinames.c b/reactos/lib/3rdparty/freetype/src/tools/apinames.c index 19aec500bf2..7f191e19c91 100644 --- a/reactos/lib/3rdparty/freetype/src/tools/apinames.c +++ b/reactos/lib/3rdparty/freetype/src/tools/apinames.c @@ -10,7 +10,7 @@ * accepted if you are using GCC for compilation (and probably by * other compilers too). * - * Author: David Turner, 2005, 2006, 2008 + * Author: David Turner, 2005, 2006, 2008, 2009 * * This code is explicitly placed into the public domain. * @@ -265,7 +265,7 @@ read_header_file( FILE* file, int verbose ) if ( p > name ) { if ( verbose ) - fprintf( stderr, ">>> %.*s\n", p-name, name ); + fprintf( stderr, ">>> %.*s\n", (int)(p - name), name ); names_add( name, p ); } diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c index dca009a104d..d723b57ae9d 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,8 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -298,7 +299,15 @@ if ( !size ) return TT_Err_Invalid_Size_Handle; - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !face ) + return TT_Err_Invalid_Argument; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->num_glyphs && + !face->internal->incremental_interface ) +#else + if ( glyph_index >= (FT_UInt)face->num_glyphs ) +#endif return TT_Err_Invalid_Argument; if ( load_flags & FT_LOAD_NO_HINTING ) @@ -393,16 +402,17 @@ tt_get_interface( FT_Module driver, /* TT_Driver */ const char* tt_interface ) { - FT_Library library = driver->library; FT_Module_Interface result; FT_Module sfntd; SFNT_Service sfnt; - FT_UNUSED(library); result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* only return the default interface from the SFNT module */ sfntd = FT_Get_Module( driver->library, "sfnt" ); if ( sfntd ) diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c index 28ddb99553a..57ea0baa770 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,8 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,7 +70,7 @@ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ - FT_LOCAL_DEF(void) + FT_LOCAL_DEF( void ) TT_Get_HMetrics( TT_Face face, FT_UInt idx, FT_Bool check, @@ -80,6 +81,9 @@ if ( check && face->postscript.isFixedPitch ) *aw = face->horizontal.advance_Width_Max; + + FT_TRACE5(( " advance width (font units): %d\n", *aw )); + FT_TRACE5(( " left side bearing (font units): %d\n", *lsb )); } @@ -96,7 +100,7 @@ /* The monospace `check' is probably not meaningful here, but we leave */ /* it in for a consistent interface. */ /* */ - FT_LOCAL_DEF(void) + FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, FT_Bool check, @@ -131,6 +135,91 @@ #endif + FT_TRACE5(( " advance height (font units): %d\n", *ah )); + FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); + } + + + static void + tt_get_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; + + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font check whether there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; + metrics.advance_v = 0; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + +#if 0 + + /* GWW: Do I do the same for vertical metrics? */ + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + +#endif /* 0 */ + + } + + Exit: + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } } @@ -1102,9 +1191,10 @@ static FT_Error load_truetype_glyph( TT_Loader loader, FT_UInt glyph_index, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool header_only ) { - FT_Error error; + FT_Error error = TT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; TT_Face face = (TT_Face)loader->face; @@ -1151,75 +1241,7 @@ y_scale = 0x10000L; } - /* get metrics, horizontal and vertical */ - { - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; - - - TT_Get_HMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &left_bearing, - &advance_width ); - TT_Get_VMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &top_bearing, - &advance_height ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* If this is an incrementally loaded font see if there are */ - /* overriding metrics for this glyph. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = left_bearing; - metrics.bearing_y = 0; - metrics.advance = advance_width; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - if ( error ) - goto Exit; - left_bearing = (FT_Short)metrics.bearing_x; - advance_width = (FT_UShort)metrics.advance; - -#if 0 - - /* GWW: Do I do the same for vertical metrics? */ - metrics.bearing_x = 0; - metrics.bearing_y = top_bearing; - metrics.advance = advance_height; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, TRUE, &metrics ); - if ( error ) - goto Exit; - top_bearing = (FT_Short)metrics.bearing_y; - advance_height = (FT_UShort)metrics.advance; - -#endif /* 0 */ - - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } + tt_get_metrics( loader, glyph_index ); /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ @@ -1257,7 +1279,13 @@ if ( loader->byte_len > 0 ) { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* for the incremental interface, `glyf_offset' is always zero */ + if ( !loader->glyf_offset && + !face->root.internal->incremental_interface ) +#else if ( !loader->glyf_offset ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); error = TT_Err_Invalid_Table; @@ -1272,9 +1300,9 @@ opened_frame = 1; - /* read first glyph header */ + /* read glyph header first */ error = face->read_glyph_header( loader ); - if ( error ) + if ( error || header_only ) goto Exit; } @@ -1285,6 +1313,9 @@ loader->bbox.yMin = 0; loader->bbox.yMax = 0; + if ( header_only ) + goto Exit; + TT_LOADER_SET_PP( loader ); #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1474,7 +1505,7 @@ num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1 ); + recurse_count + 1, FALSE ); if ( error ) goto Exit; @@ -1697,7 +1728,7 @@ /* scale the metrics */ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - top = FT_MulFix( top, y_scale ); + top = FT_MulFix( top, y_scale ); advance = FT_MulFix( advance, y_scale ); } @@ -1757,6 +1788,7 @@ glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; glyph->format = FT_GLYPH_FORMAT_BITMAP; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { glyph->bitmap_left = metrics.vertBearingX; @@ -1779,7 +1811,8 @@ tt_loader_init( TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, - FT_Int32 load_flags ) + FT_Int32 load_flags, + FT_Bool glyf_table_only ) { TT_Face face; FT_Stream stream; @@ -1793,7 +1826,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER /* load execution context */ - if ( IS_HINTED( load_flags ) ) + if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; FT_Bool grayscale; @@ -1874,6 +1907,7 @@ } /* get face's glyph loader */ + if ( !glyf_table_only ) { FT_GlyphLoader gloader = glyph->internal->loader; @@ -1945,7 +1979,25 @@ { error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( !error ) + { + FT_Face root = &face->root; + + + if ( FT_IS_SCALABLE( root ) ) + { + /* for the bbox we need the header only */ + (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); + (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + glyph->linearHoriAdvance = loader.linear; + glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - + loader.vadvance; + if ( face->postscript.isFixedPitch && + ( load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) + glyph->linearHoriAdvance = face->horizontal.advance_Width_Max; + } + return TT_Err_Ok; + } } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ @@ -1957,7 +2009,7 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return TT_Err_Invalid_Argument; - error = tt_loader_init( &loader, size, glyph, load_flags ); + error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); if ( error ) return error; @@ -1966,7 +2018,7 @@ glyph->outline.flags = 0; /* main loading loop */ - error = load_truetype_glyph( &loader, glyph_index, 0 ); + error = load_truetype_glyph( &loader, glyph_index, 0, FALSE ); if ( !error ) { if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c index 1456a8cc0a6..ef25aafb5bf 100644 --- a/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/reactos/lib/3rdparty/freetype/src/truetype/ttgxvar.c @@ -94,11 +94,8 @@ #define ALL_POINTS (FT_UShort*)( -1 ) - enum - { - GX_PT_POINTS_ARE_WORDS = 0x80, - GX_PT_POINT_RUN_COUNT_MASK = 0x7F - }; +#define GX_PT_POINTS_ARE_WORDS 0x80 +#define GX_PT_POINT_RUN_COUNT_MASK 0x7F /*************************************************************************/ @@ -214,9 +211,9 @@ FT_Offset delta_cnt ) { FT_Short *deltas; - FT_Int runcnt; + FT_UInt runcnt; FT_Offset i; - FT_Offset j; + FT_UInt j; FT_Memory memory = stream->memory; FT_Error error = TT_Err_Ok; diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1afm.c b/reactos/lib/3rdparty/freetype/src/type1/t1afm.c index 16dc471c57f..ef343901a44 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1afm.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,7 @@ /* PS string/name length must be < 16-bit */ - if ( ( len - 0xFFFFU ) > 0 ) + if ( len > 0xFFFFU ) return 0; for ( n = 0; n < type1->num_glyphs; n++ ) @@ -285,13 +285,15 @@ { t1_font->font_bbox = fi->FontBBox; - t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; - t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; - t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFFU ) >> 16; - t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFFU ) >> 16; + t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; + t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16; + t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16; - t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000U ) >> 16 ); - t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000U ) >> 16 ); + /* no `U' suffix here to 0x8000! */ + t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); + t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); if ( fi->NumKernPair ) { diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1gload.c b/reactos/lib/3rdparty/freetype/src/type1/t1gload.c index 16586153fb8..f3fad4f5df7 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1gload.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -103,16 +103,16 @@ metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); - metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.bearing_y = 0; metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); error = inc->funcs->get_glyph_metrics( inc->object, glyph_index, FALSE, &metrics ); decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); - decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); - decoder->builder.advance.y = 0; + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -287,7 +287,12 @@ #endif +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->root.num_glyphs && + !face->root.internal->incremental_interface ) +#else if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { error = T1_Err_Invalid_Argument; goto Exit; @@ -396,10 +401,20 @@ FIXED_TO_INT( decoder.builder.advance.x ); glyph->root.internal->glyph_transformed = 0; - /* make up vertical ones */ - metrics->vertAdvance = ( face->type1.font_bbox.yMax - - face->type1.font_bbox.yMin ) >> 16; - glyph->root.linearVertAdvance = metrics->vertAdvance; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + metrics->vertAdvance = ( face->type1.font_bbox.yMax - + face->type1.font_bbox.yMin ) >> 16; + glyph->root.linearVertAdvance = metrics->vertAdvance; + } + else + { + metrics->vertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + glyph->root.linearVertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + } glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; @@ -459,9 +474,12 @@ metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } /* Set control data to the glyph charstrings. Note that this is */ diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1objs.c b/reactos/lib/3rdparty/freetype/src/type1/t1objs.c index e9357e6c573..b1de6871967 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1objs.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1objs.c @@ -441,10 +441,11 @@ root->num_fixed_sizes = 0; root->available_sizes = 0; - root->bbox.xMin = type1->font_bbox.xMin >> 16; - root->bbox.yMin = type1->font_bbox.yMin >> 16; - root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFFU ) >> 16; - root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFFU ) >> 16; + root->bbox.xMin = type1->font_bbox.xMin >> 16; + root->bbox.yMin = type1->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; + root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; /* Set units_per_EM if we didn't set it in parse_font_matrix. */ if ( !root->units_per_EM ) diff --git a/reactos/lib/3rdparty/freetype/src/type1/t1parse.c b/reactos/lib/3rdparty/freetype/src/type1/t1parse.c index 1bef56bcfac..2a762279fd3 100644 --- a/reactos/lib/3rdparty/freetype/src/type1/t1parse.c +++ b/reactos/lib/3rdparty/freetype/src/type1/t1parse.c @@ -397,15 +397,18 @@ T1_Skip_PS_Token( parser ); cur = parser->root.cursor; - if ( *cur == '\r' ) - { - cur++; - if ( *cur == '\n' ) - cur++; - } - else if ( *cur == '\n' ) - cur++; - else + + /* according to the Type1 spec, the first cipher byte must not be */ + /* an ASCII whitespace character code (blank, tab, carriage return */ + /* or line feed). We have seen Type 1 fonts with two line feed */ + /* characters... So skip now all whitespace character codes. */ + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + *cur == '\r' || + *cur == '\n' ) ) + ++cur; + if ( cur >= limit ) { FT_ERROR(( "T1_Get_Private_Dict:" " `eexec' not properly terminated\n" )); From 82c609eda0bbdcebdd7ba320de1f5e11408370fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 26 May 2010 19:56:07 +0000 Subject: [PATCH 048/292] [freeldr] Disable NTFS cache because it gives wrong results svn path=/trunk/; revision=47364 --- reactos/boot/freeldr/freeldr/fs/ntfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/fs/ntfs.c b/reactos/boot/freeldr/freeldr/fs/ntfs.c index 830e3ade042..123edf309cf 100644 --- a/reactos/boot/freeldr/freeldr/fs/ntfs.c +++ b/reactos/boot/freeldr/freeldr/fs/ntfs.c @@ -232,7 +232,9 @@ static ULONGLONG NtfsReadAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_CONTEXT AlreadyRead = 0; - if(Context->CacheRunOffset <= Offset && Offset < Context->CacheRunOffset + Context->CacheRunLength * Volume->ClusterSize) + // FIXME: Cache seems to be non-working. Disable it for now + //if(Context->CacheRunOffset <= Offset && Offset < Context->CacheRunOffset + Context->CacheRunLength * Volume->ClusterSize) + if (0) { DataRun = Context->CacheRun; LastLCN = Context->CacheRunLastLCN; From 24c7a108076b0da88585a7dda23d28dc01296b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 26 May 2010 19:58:54 +0000 Subject: [PATCH 049/292] [freeldr] Repair NTFS driver. ReactOS is now able to boot (again) from NTFS partitions svn path=/trunk/; revision=47365 --- reactos/boot/freeldr/freeldr/fs/ntfs.c | 28 +++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/fs/ntfs.c b/reactos/boot/freeldr/freeldr/fs/ntfs.c index 123edf309cf..aff3bfaa339 100644 --- a/reactos/boot/freeldr/freeldr/fs/ntfs.c +++ b/reactos/boot/freeldr/freeldr/fs/ntfs.c @@ -1,6 +1,7 @@ /* * FreeLoader NTFS support * Copyright (C) 2004 Filip Navara + * Copyright (C) 2009-2010 Hervé Poussineau * * 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 @@ -37,6 +38,7 @@ typedef struct _NTFS_VOLUME_INFO /* FIXME: MFTContext is never freed. */ PNTFS_ATTR_CONTEXT MFTContext; ULONG DeviceId; + PUCHAR TemporarySector; } NTFS_VOLUME_INFO; PNTFS_VOLUME_INFO NtfsVolumes[MAX_FDS]; @@ -147,10 +149,17 @@ static BOOLEAN NtfsDiskRead(PNTFS_VOLUME_INFO Volume, ULONGLONG Offset, ULONGLON ret = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) return FALSE; - ReadLength = min(Length, Volume->BootSector.BytesPerSector - (Offset % Volume->BootSector.BytesPerSector)); - ret = ArcRead(Volume->DeviceId, Buffer, ReadLength, &Count); - if (ret != ESUCCESS || Count != ReadLength) + ret = ArcRead(Volume->DeviceId, Volume->TemporarySector, Volume->BootSector.BytesPerSector, &Count); + if (ret != ESUCCESS || Count != Volume->BootSector.BytesPerSector) return FALSE; + ReadLength = min(Length, Volume->BootSector.BytesPerSector - (Offset % Volume->BootSector.BytesPerSector)); + + // + // Copy interesting data + // + RtlCopyMemory(Buffer, + &Volume->TemporarySector[Offset % Volume->BootSector.BytesPerSector], + ReadLength); // // Move to unfilled buffer part @@ -792,6 +801,7 @@ LONG NtfsOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) return ENOENT; } + FsSetDeviceSpecific(*FileId, FileHandle); return ESUCCESS; } @@ -932,6 +942,18 @@ const DEVVTBL* NtfsMount(ULONG DeviceId) return NULL; } + // + // Keep room to read partial sectors + // + Volume->TemporarySector = MmHeapAlloc(Volume->BootSector.BytesPerSector); + if (!Volume->TemporarySector) + { + FileSystemError("Failed to allocate memory."); + MmHeapFree(Volume->MasterFileTable); + MmHeapFree(Volume); + return NULL; + } + // // Keep device id // From 5faac2284481cfbcbe5a95795b5bfc9589d22dd9 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 26 May 2010 22:33:10 +0000 Subject: [PATCH 050/292] [WIN32K] GreGradientFill: don't forget to unlock the DC svn path=/trunk/; revision=47367 --- reactos/subsystems/win32/win32k/objects/fillshap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index 87304e3c729..327b628ed30 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -955,6 +955,8 @@ GreGradientFill( if (ppal) PALETTE_UnlockPalette(ppal); + DC_UnlockDc(pdc); + return bRet; } From 7c79933df4fed6c8fee4456771c20e0c971f06aa Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 27 May 2010 00:26:34 +0000 Subject: [PATCH 051/292] [NPFS] - Change the other side's to PIPE_STATUS_CLOSING_STATE in NpfsCleanup and NpfsClose so the reading/writing thread knows that the pipe is dead when we signal its event - Fixes iphlpapi_winetest hang and possibly bug #4689 svn path=/trunk/; revision=47370 --- reactos/drivers/filesystems/npfs/create.c | 10 +++++++--- reactos/drivers/filesystems/npfs/rw.c | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/create.c b/reactos/drivers/filesystems/npfs/create.c index 5236e2035ee..86209bdb8ab 100644 --- a/reactos/drivers/filesystems/npfs/create.c +++ b/reactos/drivers/filesystems/npfs/create.c @@ -619,7 +619,7 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject, ExAcquireFastMutex(&OtherSide->DataListLock); ExAcquireFastMutex(&Ccb->DataListLock); } - //OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE; + OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; OtherSide->OtherSide = NULL; /* * Signaling the write event. If is possible that an other @@ -743,8 +743,12 @@ NpfsClose(PDEVICE_OBJECT DeviceObject, } /* Disconnect the pipes */ - if (Ccb->OtherSide) Ccb->OtherSide->OtherSide = NULL; - if (Ccb) Ccb->OtherSide = NULL; + if (Ccb->OtherSide) + { + Ccb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; + Ccb->OtherSide->OtherSide = NULL; + Ccb->OtherSide = NULL; + } ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE); diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index 7b14449b308..4c83f5cec53 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -331,7 +331,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject, if ((Ccb->OtherSide == NULL) && (Ccb->ReadDataAvailable == 0)) { - if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE) + if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE) { DPRINT("File pipe broken\n"); Status = STATUS_PIPE_BROKEN; From 5989fa66ddfa15accc2e6712665734df9592f648 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 27 May 2010 10:25:14 +0000 Subject: [PATCH 052/292] - Sync wined3d, ddraw, d3d8, d3d9 with Wine svn path=/trunk/; revision=47371 --- reactos/dll/directx/wine/d3d8/device.c | 36 +- reactos/dll/directx/wine/d3d9/device.c | 30 + reactos/dll/directx/wine/ddraw/ddraw.c | 35 +- reactos/dll/directx/wine/ddraw/ddraw_thunks.c | 3 + reactos/dll/directx/wine/ddraw/device.c | 120 +- reactos/dll/directx/wine/ddraw/direct3d.c | 1 + .../dll/directx/wine/ddraw/executebuffer.c | 4 +- reactos/dll/directx/wine/ddraw/main.c | 2 +- reactos/dll/directx/wine/ddraw/material.c | 1 - reactos/dll/directx/wine/ddraw/utils.c | 6 +- .../directx/wine/wined3d/arb_program_shader.c | 791 +++-- .../wine/wined3d/ati_fragment_shader.c | 219 +- .../dll/directx/wine/wined3d/basetexture.c | 95 +- reactos/dll/directx/wine/wined3d/buffer.c | 370 ++- reactos/dll/directx/wine/wined3d/context.c | 1348 ++++---- .../dll/directx/wine/wined3d/cubetexture.c | 260 +- reactos/dll/directx/wine/wined3d/device.c | 1674 +++++----- reactos/dll/directx/wine/wined3d/directx.c | 1218 +++---- reactos/dll/directx/wine/wined3d/drawprim.c | 133 +- .../dll/directx/wine/wined3d/glsl_shader.c | 457 ++- .../wine/wined3d/nvidia_texture_shader.c | 192 +- reactos/dll/directx/wine/wined3d/palette.c | 35 +- reactos/dll/directx/wine/wined3d/query.c | 122 +- reactos/dll/directx/wine/wined3d/resource.c | 10 +- reactos/dll/directx/wine/wined3d/shader.c | 15 +- reactos/dll/directx/wine/wined3d/state.c | 761 +++-- reactos/dll/directx/wine/wined3d/stateblock.c | 71 +- reactos/dll/directx/wine/wined3d/surface.c | 2886 ++++++++--------- .../dll/directx/wine/wined3d/surface_base.c | 318 +- .../dll/directx/wine/wined3d/surface_gdi.c | 18 +- reactos/dll/directx/wine/wined3d/swapchain.c | 268 +- .../dll/directx/wine/wined3d/swapchain_base.c | 26 +- .../dll/directx/wine/wined3d/swapchain_gdi.c | 30 +- reactos/dll/directx/wine/wined3d/texture.c | 202 +- reactos/dll/directx/wine/wined3d/utils.c | 1100 ++++--- reactos/dll/directx/wine/wined3d/view.c | 12 +- reactos/dll/directx/wine/wined3d/volume.c | 11 +- .../dll/directx/wine/wined3d/volumetexture.c | 163 +- reactos/dll/directx/wine/wined3d/wined3d_gl.h | 60 +- .../dll/directx/wine/wined3d/wined3d_main.c | 56 +- .../directx/wine/wined3d/wined3d_private.h | 332 +- reactos/include/reactos/wine/wined3d.idl | 51 +- 42 files changed, 7375 insertions(+), 6167 deletions(-) diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 11697b2ff26..12ed0fbfd38 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -171,18 +171,19 @@ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enu if (t->free_entries) { + DWORD index = t->free_entries - t->entries; /* Use a free handle */ entry = t->free_entries; if (entry->type != D3D8_HANDLE_FREE) { - ERR("Handle %u(%p) is in the free list, but has type %#x.\n", (entry - t->entries), entry, entry->type); + ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type); return D3D8_INVALID_HANDLE; } t->free_entries = entry->object; entry->object = object; entry->type = type; - return entry - t->entries; + return index; } if (!(t->entry_count < t->table_size)) @@ -324,6 +325,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { HeapFree(GetProcessHeap(), 0, This->decls); IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This->handle_table.entries); HeapFree(GetProcessHeap(), 0, This); @@ -2762,6 +2764,19 @@ static const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl = device_parent_CreateSwapChain, }; +static void setup_fpu(void) +{ + WORD cw; + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ volatile ("fnstcw %0" : "=m" (cw)); + cw = (cw & ~0xf3f) | 0x3f; + __asm__ volatile ("fldcw %0" : : "m" (cw)); +#else + FIXME("FPU setup not implemented for this platform.\n"); +#endif +} + HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) { @@ -2780,6 +2795,8 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte } device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE; + if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); + wined3d_mutex_lock(); hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device, (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice); @@ -2791,6 +2808,19 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte return hr; } + if (!parameters->Windowed) + { + if (!focus_window) focus_window = parameters->hDeviceWindow; + if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + IWineD3DDevice_Release(device->WineD3DDevice); + wined3d_mutex_unlock(); + HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + return hr; + } + } + if (flags & D3DCREATE_MULTITHREADED) IWineD3DDevice_SetMultithreaded(device->WineD3DDevice); wined3d_parameters.BackBufferWidth = parameters->BackBufferWidth; @@ -2813,6 +2843,7 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte if (FAILED(hr)) { WARN("Failed to initialize 3D, hr %#x.\n", hr); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, device->handle_table.entries); @@ -2855,6 +2886,7 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte err: wined3d_mutex_lock(); IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D8CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, device->handle_table.entries); diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index 79a9ba01834..b9f539e0b28 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -271,6 +271,7 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(LPDIRECT3DDEV HeapFree(GetProcessHeap(), 0, This->convertedDecls); IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice); wined3d_mutex_unlock(); @@ -2821,6 +2822,19 @@ static const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl = device_parent_CreateSwapChain, }; +static void setup_fpu(void) +{ + WORD cw; + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ volatile ("fnstcw %0" : "=m" (cw)); + cw = (cw & ~0xf3f) | 0x3f; + __asm__ volatile ("fldcw %0" : : "m" (cw)); +#else + FIXME("FPU setup not implemented for this platform.\n"); +#endif +} + HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) { @@ -2832,6 +2846,8 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte device->device_parent_vtbl = &d3d9_wined3d_device_parent_vtbl; device->ref = 1; + if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); + wined3d_mutex_lock(); hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device, (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice); @@ -2842,6 +2858,18 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte return hr; } + if (!parameters->Windowed) + { + if (!focus_window) focus_window = parameters->hDeviceWindow; + if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + IWineD3DDevice_Release(device->WineD3DDevice); + wined3d_mutex_unlock(); + return hr; + } + } + if (flags & D3DCREATE_ADAPTERGROUP_DEVICE) { WINED3DCAPS caps; @@ -2885,6 +2913,7 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte if (FAILED(hr)) { WARN("Failed to initialize 3D, hr %#x.\n", hr); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); HeapFree(GetProcessHeap(), 0, wined3d_parameters); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); @@ -2921,6 +2950,7 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte ERR("Failed to allocate FVF vertex declaration map memory.\n"); wined3d_mutex_lock(); IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D9CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); return E_OUTOFMEMORY; diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c index 122c31b8cb8..a7522f91789 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.c +++ b/reactos/dll/directx/wine/ddraw/ddraw.c @@ -264,8 +264,8 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface) void IDirectDrawImpl_Destroy(IDirectDrawImpl *This) { - /* Clear the cooplevel to restore window and display mode */ IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)This, NULL, DDSCL_NORMAL); + IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)This); /* Destroy the device window if we created one */ if(This->devicewindow != 0) @@ -441,12 +441,11 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface, /* Switching from fullscreen? */ if(This->cooperative_level & DDSCL_FULLSCREEN) { - /* Restore the display mode */ - IDirectDraw7_RestoreDisplayMode(iface); - This->cooperative_level &= ~DDSCL_FULLSCREEN; This->cooperative_level &= ~DDSCL_EXCLUSIVE; This->cooperative_level &= ~DDSCL_ALLOWMODEX; + + IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice); } /* Don't override focus windows or private device windows */ @@ -483,6 +482,13 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface, !(This->devicewindow) && (hwnd != window) ) { + HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd); + if (FAILED(hr)) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return hr; + } This->dest_window = hwnd; } } @@ -1514,11 +1520,24 @@ IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface, IDirectDrawSurface7 **Surface) { IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface); + IWineD3DSurface *wined3d_surface; + HRESULT hr; - /* Implementation idea if needed: Loop through all surfaces and compare - * their hdc with hdc. Implement it in WineD3D! */ - return DDERR_NOTFOUND; + TRACE("iface %p, dc %p, surface %p.\n", iface, hdc, Surface); + + if (!Surface) return E_INVALIDARG; + + hr = IWineD3DDevice_GetSurfaceFromDC(This->wineD3DDevice, hdc, &wined3d_surface); + if (FAILED(hr)) + { + TRACE("No surface found for dc %p.\n", hdc); + *Surface = NULL; + return DDERR_NOTFOUND; + } + + IWineD3DSurface_GetParent(wined3d_surface, (IUnknown **)Surface); + TRACE("Returning surface %p.\n", Surface); + return DD_OK; } /***************************************************************************** diff --git a/reactos/dll/directx/wine/ddraw/ddraw_thunks.c b/reactos/dll/directx/wine/ddraw/ddraw_thunks.c index dc71bf55a9c..9d606245272 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_thunks.c +++ b/reactos/dll/directx/wine/ddraw/ddraw_thunks.c @@ -290,6 +290,7 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc, set_surf_version(impl, 1); IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This)); impl->ifaceToRelease = NULL; + return hr; } @@ -309,11 +310,13 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc, *ppSurface = NULL; return hr; } + impl = (IDirectDrawSurfaceImpl *)pSurface7; *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl; set_surf_version(impl, 2); IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This)); impl->ifaceToRelease = NULL; + return hr; } diff --git a/reactos/dll/directx/wine/ddraw/device.c b/reactos/dll/directx/wine/ddraw/device.c index 13ecfa133ac..9a4e5c73204 100644 --- a/reactos/dll/directx/wine/ddraw/device.c +++ b/reactos/dll/directx/wine/ddraw/device.c @@ -2409,22 +2409,60 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, case D3DRENDERSTATE_TEXTUREMIN: { WINED3DTEXTUREFILTERTYPE tex_min; + WINED3DTEXTUREFILTERTYPE tex_mip; hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, - 0, WINED3DSAMP_MINFILTER, - &tex_min); + 0, WINED3DSAMP_MINFILTER, &tex_min); + if (FAILED(hr)) + { + LeaveCriticalSection(&ddraw_cs); + return hr; + } + hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MIPFILTER, &tex_mip); switch (tex_min) { case WINED3DTEXF_POINT: - *Value = D3DFILTER_NEAREST; + switch (tex_mip) + { + case WINED3DTEXF_NONE: + *Value = D3DFILTER_NEAREST; + break; + case WINED3DTEXF_POINT: + *Value = D3DFILTER_MIPNEAREST; + break; + case WINED3DTEXF_LINEAR: + *Value = D3DFILTER_LINEARMIPNEAREST; + break; + default: + ERR("Unhandled mip filter %#x.\n", tex_mip); + *Value = D3DFILTER_NEAREST; + break; + } break; case WINED3DTEXF_LINEAR: - *Value = D3DFILTER_LINEAR; + switch (tex_mip) + { + case WINED3DTEXF_NONE: + *Value = D3DFILTER_LINEAR; + break; + case WINED3DTEXF_POINT: + *Value = D3DFILTER_MIPLINEAR; + break; + case WINED3DTEXF_LINEAR: + *Value = D3DFILTER_LINEARMIPLINEAR; + break; + default: + ERR("Unhandled mip filter %#x.\n", tex_mip); + *Value = D3DFILTER_LINEAR; + break; + } break; default: - ERR("Unhandled texture mag %d !\n",tex_min); - *Value = 0; + ERR("Unhandled texture min filter %#x.\n",tex_min); + *Value = D3DFILTER_NEAREST; + break; } break; } @@ -2441,8 +2479,20 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, Value); break; + case D3DRENDERSTATE_BORDERCOLOR: + FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); + hr = E_NOTIMPL; + break; + default: - /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */ + if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 + && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) + { + FIXME("Unhandled stipple pattern render state (%#x).\n", + RenderStateType); + hr = E_NOTIMPL; + break; + } hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice, RenderStateType, Value); @@ -2640,22 +2690,39 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, /* Some render states need special care */ switch(RenderStateType) { + /* + * The ddraw texture filter mapping works like this: + * D3DFILTER_NEAREST Point min/mag, no mip + * D3DFILTER_MIPNEAREST Point min/mag, point mip + * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip + * + * D3DFILTER_LINEAR Linear min/mag, no mip + * D3DFILTER_MIPLINEAR Linear min/mag, point mip + * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip + * + * This is the opposite of the GL naming convention, + * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR. + */ case D3DRENDERSTATE_TEXTUREMAG: { - WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT; + WINED3DTEXTUREFILTERTYPE tex_mag; - switch ((D3DTEXTUREFILTER) Value) + switch (Value) { case D3DFILTER_NEAREST: + case D3DFILTER_MIPNEAREST: case D3DFILTER_LINEARMIPNEAREST: tex_mag = WINED3DTEXF_POINT; break; case D3DFILTER_LINEAR: + case D3DFILTER_MIPLINEAR: case D3DFILTER_LINEARMIPLINEAR: tex_mag = WINED3DTEXF_LINEAR; break; default: + tex_mag = WINED3DTEXF_POINT; ERR("Unhandled texture mag %d !\n",Value); + break; } hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, @@ -2666,24 +2733,26 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, case D3DRENDERSTATE_TEXTUREMIN: { - WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT; - WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE; + WINED3DTEXTUREFILTERTYPE tex_min; + WINED3DTEXTUREFILTERTYPE tex_mip; switch ((D3DTEXTUREFILTER) Value) { case D3DFILTER_NEAREST: tex_min = WINED3DTEXF_POINT; + tex_mip = WINED3DTEXF_NONE; break; case D3DFILTER_LINEAR: tex_min = WINED3DTEXF_LINEAR; + tex_mip = WINED3DTEXF_NONE; break; case D3DFILTER_MIPNEAREST: tex_min = WINED3DTEXF_POINT; tex_mip = WINED3DTEXF_POINT; break; case D3DFILTER_MIPLINEAR: - tex_min = WINED3DTEXF_POINT; - tex_mip = WINED3DTEXF_LINEAR; + tex_min = WINED3DTEXF_LINEAR; + tex_mip = WINED3DTEXF_POINT; break; case D3DFILTER_LINEARMIPNEAREST: tex_min = WINED3DTEXF_POINT; @@ -2696,11 +2765,13 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, default: ERR("Unhandled texture min %d !\n",Value); + tex_min = WINED3DTEXF_POINT; + tex_mip = WINED3DTEXF_NONE; + break; } - IWineD3DDevice_SetSamplerState(This->wineD3DDevice, - 0, WINED3DSAMP_MIPFILTER, - tex_mip); + IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MIPFILTER, tex_mip); hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, 0, WINED3DSAMP_MINFILTER, tex_min); @@ -2723,9 +2794,22 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, Value); break; - default: + case D3DRENDERSTATE_BORDERCOLOR: + /* This should probably just forward to the corresponding sampler + * state. Needs tests. */ + FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); + hr = E_NOTIMPL; + break; - /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */ + default: + if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 + && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) + { + FIXME("Unhandled stipple pattern render state (%#x).\n", + RenderStateType); + hr = E_NOTIMPL; + break; + } hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice, RenderStateType, diff --git a/reactos/dll/directx/wine/ddraw/direct3d.c b/reactos/dll/directx/wine/ddraw/direct3d.c index 80052adb83f..3f2410fe8a7 100644 --- a/reactos/dll/directx/wine/ddraw/direct3d.c +++ b/reactos/dll/directx/wine/ddraw/direct3d.c @@ -1273,6 +1273,7 @@ IDirect3DImpl_GetCaps(IWineD3D *WineD3D, /* Copy the results into the d3d7 and d3d3 structures */ Desc7->dwDevCaps = WCaps.DevCaps; + Desc7->dpcLineCaps.dwMiscCaps = WCaps.PrimitiveMiscCaps; Desc7->dpcLineCaps.dwRasterCaps = WCaps.RasterCaps; Desc7->dpcLineCaps.dwZCmpCaps = WCaps.ZCmpCaps; Desc7->dpcLineCaps.dwSrcBlendCaps = WCaps.SrcBlendCaps; diff --git a/reactos/dll/directx/wine/ddraw/executebuffer.c b/reactos/dll/directx/wine/ddraw/executebuffer.c index 2f426881cba..29fd65e25a9 100644 --- a/reactos/dll/directx/wine/ddraw/executebuffer.c +++ b/reactos/dll/directx/wine/ddraw/executebuffer.c @@ -489,7 +489,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX)); } else { - ERR("Unhandled vertex processing !\n"); + ERR("Unhandled vertex processing flag %#x.\n", ci->dwFlags); } instr += size; @@ -703,7 +703,6 @@ IDirect3DExecuteBufferImpl_Lock(IDirect3DExecuteBuffer *iface, TRACE("(%p)->(%p)\n", This, lpDesc); dwSize = lpDesc->dwSize; - memset(lpDesc, 0, dwSize); memcpy(lpDesc, &This->desc, dwSize); if (TRACE_ON(d3d7)) { @@ -789,7 +788,6 @@ IDirect3DExecuteBufferImpl_GetExecuteData(IDirect3DExecuteBuffer *iface, TRACE("(%p)->(%p): stub!\n", This, lpData); dwSize = lpData->dwSize; - memset(lpData, 0, dwSize); memcpy(lpData, &This->data, dwSize); if (TRACE_ON(d3d7)) { diff --git a/reactos/dll/directx/wine/ddraw/main.c b/reactos/dll/directx/wine/ddraw/main.c index bc23987ed81..72426cdf26c 100644 --- a/reactos/dll/directx/wine/ddraw/main.c +++ b/reactos/dll/directx/wine/ddraw/main.c @@ -288,7 +288,7 @@ err_out: /* Let's hope we never need this ;) */ if(wineD3DDevice) IWineD3DDevice_Release(wineD3DDevice); if(wineD3D) IWineD3D_Release(wineD3D); - if(This) HeapFree(GetProcessHeap(), 0, This->decls); + HeapFree(GetProcessHeap(), 0, This->decls); HeapFree(GetProcessHeap(), 0, This); return hr; } diff --git a/reactos/dll/directx/wine/ddraw/material.c b/reactos/dll/directx/wine/ddraw/material.c index 6f162f7c828..d75501ecd95 100644 --- a/reactos/dll/directx/wine/ddraw/material.c +++ b/reactos/dll/directx/wine/ddraw/material.c @@ -294,7 +294,6 @@ IDirect3DMaterialImpl_GetMaterial(IDirect3DMaterial3 *iface, /* Copies the material structure */ EnterCriticalSection(&ddraw_cs); dwSize = lpMat->dwSize; - memset(lpMat, 0, dwSize); memcpy(lpMat, &This->mat, dwSize); LeaveCriticalSection(&ddraw_cs); diff --git a/reactos/dll/directx/wine/ddraw/utils.c b/reactos/dll/directx/wine/ddraw/utils.c index cfb04049770..5166b167b4a 100644 --- a/reactos/dll/directx/wine/ddraw/utils.c +++ b/reactos/dll/directx/wine/ddraw/utils.c @@ -171,7 +171,7 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u2.dwRBitMask = 0x00E0; DDPixelFormat->u3.dwGBitMask = 0x001C; DDPixelFormat->u4.dwBBitMask = 0x0003; - DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0xFF00; break; case WINED3DFMT_B4G4R4X4_UNORM: @@ -182,7 +182,7 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u3.dwGBitMask = 0x00F0; DDPixelFormat->u4.dwBBitMask = 0x000F; DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; - return; + break; /* How are Z buffer bit depth and Stencil buffer bit depth related? */ @@ -236,8 +236,8 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u3.dwZBitMask = 0x00FFFFFFFF; DDPixelFormat->u4.dwStencilBitMask = 0x00000000; DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; - break; + case WINED3DFMT_S1_UINT_D15_UNORM: DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER; DDPixelFormat->dwFourCC = 0; diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index cf7638605eb..0824fedb571 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -39,8 +39,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - /* Extract a line. Note that this modifies the source string. */ static char *get_line(char **ptr) { @@ -61,14 +59,14 @@ static char *get_line(char **ptr) static void shader_arb_dump_program_source(const char *source) { - unsigned long source_size; + ULONG source_size; char *ptr, *line, *tmp; source_size = strlen(source) + 1; tmp = HeapAlloc(GetProcessHeap(), 0, source_size); if (!tmp) { - ERR("Failed to allocate %lu bytes for shader source.\n", source_size); + ERR("Failed to allocate %u bytes for shader source.\n", source_size); return; } memcpy(tmp, source, source_size); @@ -81,10 +79,13 @@ static void shader_arb_dump_program_source(const char *source) } /* GL locking for state handlers is done by the caller. */ -static BOOL need_mova_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info) +static BOOL need_rel_addr_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { - IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) shader; - if(!This->baseShader.reg_maps.usesmova) return FALSE; + if (shader->baseShader.reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX) + { + if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) return TRUE; + } + if (!shader->baseShader.reg_maps.usesmova) return FALSE; return !gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]; } @@ -95,29 +96,85 @@ static inline BOOL use_nv_clip(const struct wined3d_gl_info *gl_info) && !(gl_info->quirks & WINED3D_QUIRK_NV_CLIP_BROKEN); } -static BOOL need_helper_const(const struct wined3d_gl_info *gl_info) +static BOOL need_helper_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { - if (!gl_info->supported[NV_VERTEX_PROGRAM] /* Need to init colors. */ - || gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT /* Load the immval offset. */ - || gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W /* Have to init texcoords. */ - || (!use_nv_clip(gl_info)) /* Init the clip texcoord */) - { - return TRUE; - } + if (need_rel_addr_const(shader, gl_info)) return TRUE; + if (!gl_info->supported[NV_VERTEX_PROGRAM]) return TRUE; /* Need to init colors. */ + if (gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT) return TRUE; /* Load the immval offset. */ + if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) return TRUE; /* Have to init texcoords. */ + if (!use_nv_clip(gl_info)) return TRUE; /* Init the clip texcoord */ + if (shader->baseShader.reg_maps.usesnrm) return TRUE; /* 0.0 */ + if (shader->baseShader.reg_maps.usesrcp) return TRUE; /* EPS */ return FALSE; } -static unsigned int reserved_vs_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info) +static unsigned int reserved_vs_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { unsigned int ret = 1; /* We use one PARAM for the pos fixup, and in some cases one to load * some immediate values into the shader */ - if(need_helper_const(gl_info)) ret++; - if(need_mova_const(shader, gl_info)) ret++; + if(need_helper_const(shader, gl_info)) ret++; + if(need_rel_addr_const(shader, gl_info)) ret++; return ret; } +enum arb_helper_value +{ + ARB_ZERO, + ARB_ONE, + ARB_TWO, + ARB_0001, + ARB_EPS, + + ARB_VS_REL_OFFSET +}; + +static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum arb_helper_value value) +{ + if (shader == WINED3D_SHADER_TYPE_GEOMETRY) + { + ERR("Geometry shaders are unsupported\n"); + return "bad"; + } + + if (shader == WINED3D_SHADER_TYPE_PIXEL) + { + switch (value) + { + case ARB_ZERO: return "ps_helper_const.x"; + case ARB_ONE: return "ps_helper_const.y"; + case ARB_TWO: return "coefmul.x"; + case ARB_0001: return "helper_const.xxxy"; + case ARB_EPS: return "ps_helper_const.z"; + default: break; + } + } + else + { + switch (value) + { + case ARB_ZERO: return "helper_const.x"; + case ARB_ONE: return "helper_const.y"; + case ARB_TWO: return "helper_const.z"; + case ARB_EPS: return "helper_const.w"; + case ARB_0001: return "helper_const.xxxy"; + case ARB_VS_REL_OFFSET: return "rel_addr_const.y"; + } + } + FIXME("Unmanaged %s shader helper constant requested: %u\n", + shader == WINED3D_SHADER_TYPE_PIXEL ? "pixel" : "vertex", value); + switch (value) + { + case ARB_ZERO: return "0.0"; + case ARB_ONE: return "1.0"; + case ARB_TWO: return "2.0"; + case ARB_0001: return "{0.0, 0.0, 0.0, 1.0}"; + case ARB_EPS: return "1e-8"; + default: return "bad"; + } +} + static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock) { return stateblock->lowest_disabled_stage < 7; @@ -287,7 +344,8 @@ struct shader_arb_priv const struct arb_ps_compiled_shader *compiled_fprog; const struct arb_vs_compiled_shader *compiled_vprog; GLuint depth_blt_vprogram_id; - GLuint depth_blt_fprogram_id[tex_type_count]; + GLuint depth_blt_fprogram_id_full[tex_type_count]; + GLuint depth_blt_fprogram_id_masked[tex_type_count]; BOOL use_arbfp_fixed_func; struct wine_rb_tree fragment_shaders; BOOL last_ps_const_clamped; @@ -509,7 +567,7 @@ static inline void shader_arb_ps_local_constants(IWineD3DDeviceImpl* deviceImpl) */ float val[4]; val[0] = context->render_offscreen ? 0.0f - : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height; + : deviceImpl->render_targets[0]->currentDesc.Height; val[1] = context->render_offscreen ? 1.0f : -1.0f; val[2] = 1.0f; val[3] = 0.0f; @@ -576,7 +634,7 @@ static inline void shader_arb_vs_local_constants(IWineD3DDeviceImpl* deviceImpl) /* GL locking is done by the caller (state handler) */ static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; + IWineD3DDeviceImpl *device = context->swapchain->device; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -606,7 +664,7 @@ static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; + if (!context || context->swapchain->device != This) return; memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count); This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count); @@ -619,7 +677,7 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; + if (!context || context->swapchain->device != This) return; memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count); This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count); @@ -670,12 +728,23 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s if (pshader) { max_constantsF = gl_info->limits.arb_ps_native_constants; + /* 24 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. */ + if (max_constantsF < 24) + max_constantsF = gl_info->limits.arb_ps_float_constants; } else { + max_constantsF = gl_info->limits.arb_vs_native_constants; + /* 96 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. + * Also prevents max_constantsF from becoming less than 0 and + * wrapping . */ + if (max_constantsF < 96) + max_constantsF = gl_info->limits.arb_vs_float_constants; + if(This->baseShader.reg_maps.usesrelconstF) { DWORD highest_constf = 0, clip_limit; - max_constantsF = gl_info->limits.arb_vs_native_constants - reserved_vs_const(iface, gl_info); + + max_constantsF -= reserved_vs_const(This, gl_info); max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants); for(i = 0; i < This->baseShader.limits.constant_float; i++) @@ -708,7 +777,6 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s { if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes; else *num_clipplanes = min(gl_info->limits.clipplanes, 4); - max_constantsF = gl_info->limits.arb_vs_native_constants; } } @@ -1355,7 +1423,9 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD if (pshader) { gen_color_correction(buffer, dst_str, ins->dst[0].write_mask, - "one", "coefmul.x", priv->cur_ps_args->super.color_fixup[sampler_idx]); + arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE), + arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO), + priv->cur_ps_args->super.color_fixup[sampler_idx]); } } @@ -1369,6 +1439,8 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in int insert_line; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); + const char *two = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_TWO); /* Assume a new line will be added */ insert_line = 1; @@ -1394,13 +1466,13 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in shader_addline(buffer, "ADD T%c, -%s, coefdiv.x;\n", 'A' + tmpreg, regstr); break; case WINED3DSPSM_SIGN: - shader_addline(buffer, "MAD T%c, %s, coefmul.x, -one.x;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "MAD T%c, %s, %s, -%s;\n", 'A' + tmpreg, regstr, two, one); break; case WINED3DSPSM_SIGNNEG: - shader_addline(buffer, "MAD T%c, %s, -coefmul.x, one.x;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "MAD T%c, %s, %s, %s;\n", 'A' + tmpreg, regstr, two, one); break; case WINED3DSPSM_COMP: - shader_addline(buffer, "SUB T%c, one.x, %s;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "SUB T%c, %s, %s;\n", 'A' + tmpreg, one, regstr); break; case WINED3DSPSM_X2: shader_addline(buffer, "ADD T%c, %s, %s;\n", 'A' + tmpreg, regstr, regstr); @@ -1671,12 +1743,16 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; BOOL pshader = shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type); struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; + const char *zero = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ONE); + const char *two = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_TWO); struct wined3d_shader_buffer *buffer = ins->ctx->buffer; char src0_param[256]; if(ins->handler_idx == WINED3DSIH_MOVA) { char write_mask[6]; + const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET); if(ctx->target_version >= NV2) { shader_hw_map2gl(ins); @@ -1695,15 +1771,15 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) * The ARL is performed when A0 is used - the requested component is read from A0_SHADOW into * A0.x. We can use the overwritten component of A0_shadow as temporary storage for the sign. */ - shader_addline(buffer, "SGE A0_SHADOW%s, %s, mova_const.y;\n", write_mask, src0_param); - shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, mova_const.z, -mova_const.w;\n", write_mask); + shader_addline(buffer, "SGE A0_SHADOW%s, %s, %s;\n", write_mask, src0_param, zero); + shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, %s, -%s;\n", write_mask, two, one); shader_addline(buffer, "ABS TA%s, %s;\n", write_mask, src0_param); - shader_addline(buffer, "ADD TA%s, TA, mova_const.x;\n", write_mask); + shader_addline(buffer, "ADD TA%s, TA, rel_addr_const.x;\n", write_mask); shader_addline(buffer, "FLR TA%s, TA;\n", write_mask); if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { - shader_addline(buffer, "ADD TA%s, TA, helper_const.z;\n", write_mask); + shader_addline(buffer, "ADD TA%s, TA, %s;\n", write_mask, offset); } shader_addline(buffer, "MUL A0_SHADOW%s, TA, A0_SHADOW;\n", write_mask); @@ -1715,8 +1791,9 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) src0_param[0] = '\0'; if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { + const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET); shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param); - shader_addline(buffer, "ADD TA.x, %s, helper_const.z;\n", src0_param); + shader_addline(buffer, "ADD TA.x, %s, %s;\n", src0_param, offset); shader_addline(buffer, "ARL A0.x, TA.x;\n"); } else @@ -2170,6 +2247,8 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; char dst_name[50]; + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); /* texdepth has an implicit destination, the fragment depth value. It's only parameter, * which is essentially an input, is the destination register because it is the first @@ -2181,7 +2260,7 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) /* According to the msdn, the source register(must be r5) is unusable after * the texdepth instruction, so we're free to modify it */ - shader_addline(buffer, "MIN %s.y, %s.y, one.y;\n", dst_name, dst_name); + shader_addline(buffer, "MIN %s.y, %s.y, %s;\n", dst_name, dst_name, one); /* How to deal with the special case dst_name.g == 0? if r != 0, then * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct @@ -2189,8 +2268,8 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) */ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name); shader_addline(buffer, "MUL TA.x, %s.x, %s.y;\n", dst_name, dst_name); - shader_addline(buffer, "MIN TA.x, TA.x, one.x;\n"); - shader_addline(buffer, "MAX result.depth, TA.x, 0.0;\n"); + shader_addline(buffer, "MIN TA.x, TA.x, %s;\n", one); + shader_addline(buffer, "MAX result.depth, TA.x, %s;\n", zero); } /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB: @@ -2254,6 +2333,8 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins const struct wined3d_shader_dst_param *dst = &ins->dst[0]; char src0[50], dst_name[50]; BOOL is_color; + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); shader_arb_get_src_param(ins, &ins->src[0], 0, src0); shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color); @@ -2265,8 +2346,8 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins */ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name); shader_addline(buffer, "MUL %s.x, %s.x, %s.y;\n", dst_name, dst_name, dst_name); - shader_addline(buffer, "MIN %s.x, %s.x, one.x;\n", dst_name, dst_name); - shader_addline(buffer, "MAX result.depth, %s.x, 0.0;\n", dst_name); + shader_addline(buffer, "MIN %s.x, %s.x, %s;\n", dst_name, dst_name, one); + shader_addline(buffer, "MAX result.depth, %s.x, %s;\n", dst_name, zero); } /** Handles transforming all WINED3DSIO_M?x? opcodes for @@ -2325,6 +2406,44 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) } } +static void shader_hw_rcp(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_shader_buffer *buffer = ins->ctx->buffer; + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; + const char *flt_eps = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_EPS); + + char dst[50]; + char src[50]; + + shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */ + shader_arb_get_src_param(ins, &ins->src[0], 0, src); + if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE) + { + /* Dx sdk says .x is used if no swizzle is given, but our test shows that + * .w is used + */ + strcat(src, ".w"); + } + + /* TODO: If the destination is readable, and not the same as the source, the destination + * can be used instead of TA + */ + if (priv->target_version >= NV2) + { + shader_addline(buffer, "MOVC TA.x, %s;\n", src); + shader_addline(buffer, "MOV TA.x (EQ.x), %s;\n", flt_eps); + shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst); + } + else + { + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + shader_addline(buffer, "ABS TA.x, %s;\n", src); + shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero); + shader_addline(buffer, "MAD TA.x, TA.y, %s, %s;\n", flt_eps, src); + shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst); + } +} + static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_buffer *buffer = ins->ctx->buffer; @@ -2364,20 +2483,44 @@ static void shader_hw_nrm(const struct wined3d_shader_instruction *ins) char src_name[50]; struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); shader_arb_get_dst_param(ins, &ins->dst[0], dst_name); shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, src_name); + /* In D3D, NRM of a vector with length zero returns zero. Catch this situation, as + * otherwise NRM or RSQ would return NaN */ if(pshader && priv->target_version >= NV3) { + /* GL_NV_fragment_program2's NRM needs protection against length zero vectors too + * + * TODO: Find out if DP3+NRM+MOV is really faster than DP3+RSQ+MUL + */ + shader_addline(buffer, "DP3C TA, %s, %s;\n", src_name, src_name); shader_addline(buffer, "NRM%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name); + shader_addline(buffer, "MOV %s (EQ), %s;\n", dst_name, zero); + } + else if(priv->target_version >= NV2) + { + shader_addline(buffer, "DP3C TA.x, %s, %s;\n", src_name, src_name); + shader_addline(buffer, "RSQ TA.x (NE), TA.x;\n"); + shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name, + src_name); } else { - shader_addline(buffer, "DP3 TA, %s, %s;\n", src_name, src_name); - shader_addline(buffer, "RSQ TA, TA.x;\n"); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); + + shader_addline(buffer, "DP3 TA.x, %s, %s;\n", src_name, src_name); + /* Pass any non-zero value to RSQ if the input vector has a length of zero. The + * RSQ result doesn't matter, as long as multiplying it by 0 returns 0. + */ + shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero); + shader_addline(buffer, "MAD TA.x, %s, TA.y, TA.x;\n", one); + + shader_addline(buffer, "RSQ TA.x, TA.x;\n"); /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/ - shader_addline(buffer, "MUL%s %s, %s, TA;\n", shader_arb_get_modifier(ins), dst_name, + shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name, src_name); } } @@ -2997,6 +3140,7 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh { unsigned int cur_clip = 0; char component[4] = {'x', 'y', 'z', 'w'}; + const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO); for (i = 0; i < gl_info->limits.clipplanes; ++i) { @@ -3009,16 +3153,16 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh switch(cur_clip) { case 0: - shader_addline(buffer, "MOV TA, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA, %s;\n", zero); break; case 1: - shader_addline(buffer, "MOV TA.yzw, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.yzw, %s;\n", zero); break; case 2: - shader_addline(buffer, "MOV TA.zw, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.zw, %s;\n", zero); break; case 3: - shader_addline(buffer, "MOV TA.w, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.w, %s;\n", zero); break; } shader_addline(buffer, "MOV result.texcoord[%u], TA;\n", @@ -3028,8 +3172,9 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c * and the glsl equivalent */ - if(need_helper_const(gl_info)) { - shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n"); + if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); + shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); } else { shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); @@ -3103,12 +3248,14 @@ static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_inf } /* GL locking is done by the caller */ -static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, + enum tex_types tex_type, BOOL masked) { GLuint program_id = 0; + const char *fprogram; GLint pos; - static const char * const blt_fprograms[tex_type_count] = + static const char * const blt_fprograms_full[tex_type_count] = { /* tex_1d */ NULL, @@ -3134,16 +3281,55 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i "END\n", }; - if (!blt_fprograms[tex_type]) + static const char * const blt_fprograms_masked[tex_type_count] = { - FIXME("tex_type %#x not supported\n", tex_type); + /* tex_1d */ + NULL, + /* tex_2d */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_rect */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + }; + + fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; + if (!fprogram) + { + FIXME("tex_type %#x not supported, falling back to tex_2d\n", tex_type); tex_type = tex_2d; + fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; } GL_EXTCALL(glGenProgramsARB(1, &program_id)); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type])); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fprogram), fprogram)); checkGLcall("glProgramStringARB()"); glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); @@ -3151,7 +3337,7 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i { FIXME("Fragment program error at position %d: %s\n\n", pos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - shader_arb_dump_program_source(blt_fprograms[tex_type]); + shader_arb_dump_program_source(fprogram); } else { @@ -3309,7 +3495,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct char fragcolor[16]; DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This), next_local, cur; struct shader_arb_ctx_priv priv_ctx; - BOOL dcl_tmp = args->super.srgb_correction, dcl_td = FALSE; + BOOL dcl_td = FALSE; BOOL want_nv_prog = FALSE; struct arb_pshader_private *shader_priv = This->baseShader.backend_data; GLint errPos; @@ -3331,7 +3517,6 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct } switch(found) { - case 4: dcl_tmp = FALSE; break; case 0: sprintf(srgbtmp[0], "TA"); sprintf(srgbtmp[1], "TB"); @@ -3351,6 +3536,8 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct case 3: sprintf(srgbtmp[3], "TA"); break; + case 4: + break; } /* Create the hw ARB shader */ @@ -3432,7 +3619,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */ shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n"); shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n"); - shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n"); + shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps); if (reg_maps->shader_version.major < 2) { @@ -3927,11 +4114,11 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct } shader_addline(buffer, "TEMP TMP_OUT;\n"); - if(need_helper_const(gl_info)) { - shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset); + if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps); } - if(need_mova_const((IWineD3DBaseShader *) This, gl_info)) { - shader_addline(buffer, "PARAM mova_const = { 0.5, 0.0, 2.0, 1.0 };\n"); + if(need_rel_addr_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + shader_addline(buffer, "PARAM rel_addr_const = { 0.5, %d.0, 0.0, 0.0 };\n", This->rel_offset); shader_addline(buffer, "TEMP A0_SHADOW;\n"); } @@ -3979,15 +4166,18 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct */ if (!gl_info->supported[NV_VERTEX_PROGRAM]) { - shader_addline(buffer, "MOV result.color.secondary, -helper_const.wwwy;\n"); + const char *color_init = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_0001); + shader_addline(buffer, "MOV result.color.secondary, %s;\n", color_init); if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W && !device->frag_pipe->ffp_proj_control) { int i; - for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) { - if(This->baseShader.reg_maps.texcoord_mask[i] != 0 && + const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE); + for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) + { + if (This->baseShader.reg_maps.texcoord_mask[i] != 0 && This->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) { - shader_addline(buffer, "MOV result.texcoord[%u].w, -helper_const.y;\n", i); + shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one); } } } @@ -4339,7 +4529,7 @@ static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IW /* GL locking is done by the caller */ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; + IWineD3DDeviceImpl *This = context->swapchain->device; struct shader_arb_priv *priv = This->shader_priv; const struct wined3d_gl_info *gl_info = context->gl_info; int i; @@ -4443,18 +4633,23 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, } /* GL locking is done by the caller */ -static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) +{ + const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy}; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_arb_priv *priv = This->shader_priv; - GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type]; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + GLuint *blt_fprogram; if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id)); glEnable(GL_VERTEX_PROGRAM_ARB); - if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type); + blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type]; + if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram)); + if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask)); glEnable(GL_FRAGMENT_PROGRAM_ARB); } @@ -4499,7 +4694,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); for (i = 0; i < shader_data->num_gl_shaders; ++i) @@ -4525,7 +4720,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); for (i = 0; i < shader_data->num_gl_shaders; ++i) @@ -4594,9 +4789,15 @@ static void shader_arb_free(IWineD3DDevice *iface) { if(priv->depth_blt_vprogram_id) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); } - for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_fprogram_id[i]) { - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i])); + for (i = 0; i < tex_type_count; ++i) + { + if (priv->depth_blt_fprogram_id_full[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i])); + } + if (priv->depth_blt_fprogram_id_masked[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i])); } } LEAVE_GL(); @@ -4611,16 +4812,19 @@ static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) { static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps) { - DWORD vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants); - DWORD ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants); - - /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps, - * then overwrite the shader specific ones - */ - none_shader_backend.shader_get_caps(gl_info, pCaps); - if (gl_info->supported[ARB_VERTEX_PROGRAM]) { + DWORD vs_consts; + + /* 96 is the minimum allowed value of MAX_PROGRAM_ENV_PARAMETERS_ARB + * for vertex programs. If the native limit is less than that it's + * not very useful, and e.g. Mesa swrast returns 0, probably to + * indicate it's a software implementation. */ + if (gl_info->limits.arb_vs_native_constants < 96) + vs_consts = gl_info->limits.arb_vs_float_constants; + else + vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants); + if (gl_info->supported[NV_VERTEX_PROGRAM3]) { pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0); @@ -4639,9 +4843,23 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh } pCaps->MaxVertexShaderConst = vs_consts; } + else + { + pCaps->VertexShaderVersion = 0; + pCaps->MaxVertexShaderConst = 0; + } if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { + DWORD ps_consts; + + /* Similar as above for vertex programs, but the minimum for fragment + * programs is 24. */ + if (gl_info->limits.arb_ps_native_constants < 24) + ps_consts = gl_info->limits.arb_ps_float_constants; + else + ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants); + if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) { pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0); @@ -4661,6 +4879,12 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh pCaps->PixelShader1xMaxValue = 8.0f; pCaps->MaxPixelShaderConst = ps_consts; } + else + { + pCaps->PixelShaderVersion = 0; + pCaps->PixelShader1xMaxValue = 0.0f; + pCaps->MaxPixelShaderConst = 0; + } pCaps->VSClipping = use_nv_clip(gl_info); } @@ -4766,7 +4990,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL /* WINED3DSIH_NRM */ shader_hw_nrm, /* WINED3DSIH_PHASE */ NULL, /* WINED3DSIH_POW */ shader_hw_log_pow, - /* WINED3DSIH_RCP */ shader_hw_scalar_op, + /* WINED3DSIH_RCP */ shader_hw_rcp, /* WINED3DSIH_REP */ shader_hw_rep, /* WINED3DSIH_RET */ shader_hw_ret, /* WINED3DSIH_RSQ */ shader_hw_scalar_op, @@ -5279,6 +5503,7 @@ static void arbfp_free(IWineD3DDevice *iface) { static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { + caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE | WINED3DTEXOPCAPS_SELECTARG1 | WINED3DTEXOPCAPS_SELECTARG2 | @@ -5309,14 +5534,11 @@ static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen caps->MaxTextureBlendStages = 8; caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); - - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; } -#undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float col[4]; @@ -5338,6 +5560,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float col[4]; @@ -5366,6 +5589,7 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float mat[2][2]; @@ -5377,9 +5601,8 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled * anyway */ - if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) + stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } if(device->shader_backend == &arb_program_shader_backend) { @@ -5403,6 +5626,7 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float param[4]; @@ -5414,9 +5638,8 @@ static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock /* The pixel shader has to know the luminance offset. Do a constants update if it * isn't scheduled anyway */ - if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) + stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } if(device->shader_backend == &arb_program_shader_backend) { @@ -5648,9 +5871,9 @@ static void gen_ffp_instr(struct wined3d_shader_buffer *buffer, unsigned int sta } } -/* The stateblock is passed for GLINFO_LOCATION */ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock) { + const struct wined3d_gl_info *gl_info = &stateblock->device->adapter->gl_info; unsigned int stage; struct wined3d_shader_buffer buffer; BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; @@ -5925,6 +6148,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(stateblock); @@ -5961,7 +6185,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, return; } new_desc->num_textures_used = 0; - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { if(settings.op[i].cop == WINED3DTOP_DISABLE) break; new_desc->num_textures_used = i; @@ -6007,13 +6231,10 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) { device->shader_backend->shader_select(context, use_pshader, use_vshader); - if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) { - device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context); - } - } - if(use_pshader) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) + stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context); } + if (use_pshader) stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } /* We can't link the fog states to the fragment state directly since the vertex pipeline links them @@ -6060,130 +6281,128 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } } -#undef GLINFO_LOCATION - static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { {STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -6194,11 +6413,11 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { {STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_PIXELSHADER, { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, WINED3D_GL_EXT_NONE }, @@ -6223,13 +6442,12 @@ const struct fragment_pipeline arbfp_fragment_pipeline = { TRUE /* We can disable projected textures */ }; -#define GLINFO_LOCATION device->adapter->gl_info - struct arbfp_blit_priv { GLenum yuy2_rect_shader, yuy2_2d_shader; GLenum uyvy_rect_shader, uyvy_2d_shader; GLenum yv12_rect_shader, yv12_2d_shader; GLenum p8_rect_shader, p8_2d_shader; + GLuint palette_texture; }; static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) { @@ -6245,6 +6463,7 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) { /* Context activation is done by the caller. */ static void arbfp_blit_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct arbfp_blit_priv *priv = device->blit_priv; ENTER_GL(); @@ -6257,6 +6476,8 @@ static void arbfp_blit_free(IWineD3DDevice *iface) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader)); GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader)); checkGLcall("Delete yuv and p8 programs"); + + if(priv->palette_texture) glDeleteTextures(1, &priv->palette_texture); LEAVE_GL(); HeapFree(GetProcessHeap(), 0, device->blit_priv); @@ -6499,6 +6720,7 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype) { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; GLenum shader; struct wined3d_shader_buffer buffer; struct arbfp_blit_priv *priv = device->blit_priv; @@ -6563,9 +6785,43 @@ static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype) return shader; } +/* Context activation is done by the caller. */ +static void upload_palette(IWineD3DSurfaceImpl *surface) +{ + BYTE table[256][4]; + IWineD3DDeviceImpl *device = surface->resource.device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct arbfp_blit_priv *priv = device->blit_priv; + BOOL colorkey = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE; + + d3dfmt_p8_init_palette(surface, table, colorkey); + + ENTER_GL(); + if (!priv->palette_texture) + glGenTextures(1, &priv->palette_texture); + + GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1)); + glBindTexture(GL_TEXTURE_1D, priv->palette_texture); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + /* Make sure we have discrete color levels. */ + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + /* Upload the palette */ + /* TODO: avoid unneeed uploads in the future by adding some SFLAG_PALETTE_DIRTY mechanism */ + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); + + /* Switch back to unit 0 in which the 2D texture will be stored. */ + GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0)); + LEAVE_GL(); +} + /* Context activation is done by the caller. */ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_fixup, GLenum textype) { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; GLenum shader; struct wined3d_shader_buffer buffer; char luminance_component; @@ -6720,19 +6976,20 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_ } /* Context activation is done by the caller. */ -static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height) +static HRESULT arbfp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) { GLenum shader; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; - float size[4] = {width, height, 1, 1}; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + float size[4] = {surface->pow2Width, surface->pow2Height, 1, 1}; struct arbfp_blit_priv *priv = device->blit_priv; enum complex_fixup fixup; + GLenum textype = surface->texture_target; - if (!is_complex_fixup(format_desc->color_fixup)) + if (!is_complex_fixup(surface->resource.format_desc->color_fixup)) { TRACE("Fixup:\n"); - dump_color_fixup_desc(format_desc->color_fixup); + dump_color_fixup_desc(surface->resource.format_desc->color_fixup); /* Don't bother setting up a shader for unconverted formats */ ENTER_GL(); glEnable(textype); @@ -6741,7 +6998,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD return WINED3D_OK; } - fixup = get_complex_fixup(format_desc->color_fixup); + fixup = get_complex_fixup(surface->resource.format_desc->color_fixup); switch(fixup) { @@ -6760,6 +7017,8 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD case COMPLEX_FIXUP_P8: shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader; if (!shader) shader = gen_p8_shader(device, textype); + + upload_palette(surface); break; default: @@ -6808,31 +7067,47 @@ static void arbfp_blit_unset(IWineD3DDevice *iface) { LEAVE_GL(); } -static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup) +static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) { - enum complex_fixup complex_fixup; + enum complex_fixup src_fixup; + if (blit_op != BLIT_OP_BLIT) + { + TRACE("Unsupported blit_op=%d\n", blit_op); + return FALSE; + } + + src_fixup = get_complex_fixup(src_format_desc->color_fixup); if (TRACE_ON(d3d_shader) && TRACE_ON(d3d)) { TRACE("Checking support for fixup:\n"); - dump_color_fixup_desc(fixup); + dump_color_fixup_desc(src_format_desc->color_fixup); } - if (is_identity_fixup(fixup)) + if (!is_identity_fixup(dst_format_desc->color_fixup)) + { + TRACE("Destination fixups are not supported\n"); + return FALSE; + } + + if (is_identity_fixup(src_format_desc->color_fixup)) { TRACE("[OK]\n"); return TRUE; } - /* We only support YUV conversions. */ - if (!is_complex_fixup(fixup)) + /* We only support YUV conversions. */ + if (!is_complex_fixup(src_format_desc->color_fixup)) { TRACE("[FAILED]\n"); return FALSE; } - complex_fixup = get_complex_fixup(fixup); - switch(complex_fixup) + switch(src_fixup) { case COMPLEX_FIXUP_YUY2: case COMPLEX_FIXUP_UYVY: @@ -6842,18 +7117,70 @@ static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup) return TRUE; default: - FIXME("Unsupported YUV fixup %#x\n", complex_fixup); + FIXME("Unsupported YUV fixup %#x\n", src_fixup); TRACE("[FAILED]\n"); return FALSE; } } +HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) +{ + IWineD3DSwapChainImpl *dst_swapchain; + struct wined3d_context *context; + RECT dst_rect = *dst_rect_in; + + /* Now load the surface */ + surface_internal_preload(src_surface, SRGB_RGB); + + /* Activate the destination context, set it up for blitting */ + context = context_acquire(device, dst_surface); + context_apply_blit_state(context, device); + + /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', + * while OpenGL coordinates are window relative. + * Also beware of the origin difference(top left vs bottom left). + * Also beware that the front buffer's surface size is screen width x screen height, + * whereas the real gl drawable size is the size of the window. */ + dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL; + if (dst_swapchain && dst_surface == dst_swapchain->front_buffer) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); + + arbfp_blit_set((IWineD3DDevice *)device, src_surface); + + ENTER_GL(); + + /* Draw a textured quad */ + draw_textured_quad(src_surface, src_rect, &dst_rect, Filter); + + LEAVE_GL(); + + /* Leave the opengl state valid for blitting */ + arbfp_blit_unset((IWineD3DDevice *)device); + + if (wined3d_settings.strict_draw_ordering || (dst_swapchain + && (dst_surface == dst_swapchain->front_buffer + || dst_swapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); + return WINED3D_OK; +} + +static HRESULT arbfp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + FIXME("Color filling not implemented by arbfp_blit\n"); + return WINED3DERR_INVALIDCALL; +} + const struct blit_shader arbfp_blit = { arbfp_blit_alloc, arbfp_blit_free, arbfp_blit_set, arbfp_blit_unset, - arbfp_blit_color_fixup_supported, + arbfp_blit_supported, + arbfp_blit_color_fill }; - -#undef GLINFO_LOCATION diff --git a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c index 0f911e9dc15..993ece0be8d 100644 --- a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -190,7 +190,6 @@ static const char *debug_mask(GLuint mask) { default: return "Unexpected writemask"; } } -#define GLINFO_LOCATION (*gl_info) static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) @@ -796,11 +795,10 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con checkGLcall("GL_EXTCALL(glEndFragmentShaderATI())"); return ret; } -#undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *This = stateblock->device; const struct atifs_ffp_desc *desc; struct ffp_frag_settings settings; @@ -818,14 +816,14 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st return; } new_desc->num_textures_used = 0; - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { if(settings.op[i].cop == WINED3DTOP_DISABLE) break; new_desc->num_textures_used = i; } memcpy(&new_desc->parent.settings, &settings, sizeof(settings)); - new_desc->shader = gen_ati_shader(settings.op, context->gl_info); + new_desc->shader = gen_ati_shader(settings.op, gl_info); add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent); TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc); desc = new_desc; @@ -849,6 +847,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); @@ -859,6 +858,7 @@ static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *statebloc static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; float mat[2][2]; mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]); @@ -907,127 +907,124 @@ static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *statebl if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) { device->shader_backend->shader_select(context, FALSE, use_vshader); - if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) { - device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) + stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context); } } -#undef GLINFO_LOCATION - static const struct StateEntryTemplate atifs_fragmentstate_template[] = { {STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_atifs }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -1063,6 +1060,7 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) { static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { + caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE | WINED3DTEXOPCAPS_SELECTARG1 | WINED3DTEXOPCAPS_SELECTARG2 | @@ -1105,8 +1103,6 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen */ caps->MaxTextureBlendStages = 8; caps->MaxSimultaneousTextures = 6; - - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; } static HRESULT atifs_alloc(IWineD3DDevice *iface) { @@ -1128,11 +1124,11 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } -#define GLINFO_LOCATION This->adapter->gl_info /* Context activation is done by the caller. */ static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context) { IWineD3DDeviceImpl *This = context; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry); ENTER_GL(); @@ -1152,7 +1148,6 @@ static void atifs_free(IWineD3DDevice *iface) { HeapFree(GetProcessHeap(), 0, priv); This->fragment_priv = NULL; } -#undef GLINFO_LOCATION static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup) { diff --git a/reactos/dll/directx/wine/wined3d/basetexture.c b/reactos/dll/directx/wine/wined3d/basetexture.c index f3c3fe74e1b..deab4fb2362 100644 --- a/reactos/dll/directx/wine/wined3d/basetexture.c +++ b/reactos/dll/directx/wine/wined3d/basetexture.c @@ -27,9 +27,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture); -HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, - WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) +HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count, + WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage, + const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) { HRESULT hr; @@ -41,7 +42,17 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DR return hr; } - texture->baseTexture.levels = levels; + texture->baseTexture.sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + level_count * layer_count * sizeof(*texture->baseTexture.sub_resources)); + if (!texture->baseTexture.sub_resources) + { + ERR("Failed to allocate sub-resource array.\n"); + resource_cleanup((IWineD3DResource *)texture); + return E_OUTOFMEMORY; + } + + texture->baseTexture.layer_count = layer_count; + texture->baseTexture.level_count = level_count; texture->baseTexture.filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; texture->baseTexture.LOD = 0; texture->baseTexture.texture_rgb.dirty = TRUE; @@ -66,9 +77,27 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DR void basetexture_cleanup(IWineD3DBaseTexture *iface) { basetexture_unload(iface); + HeapFree(GetProcessHeap(), 0, ((IWineD3DBaseTextureImpl *)iface)->baseTexture.sub_resources); resource_cleanup((IWineD3DResource *)iface); } +IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT layer, UINT level) +{ + if (layer >= texture->baseTexture.layer_count) + { + WARN("layer %u >= layer_count %u.\n", layer, texture->baseTexture.layer_count); + return NULL; + } + + if (level >= texture->baseTexture.level_count) + { + WARN("level %u >= level_count %u.\n", level, texture->baseTexture.level_count); + return NULL; + } + + return texture->baseTexture.sub_resources[layer * texture->baseTexture.level_count + level]; +} + /* A GL context is provided by the caller */ static void gltexture_delete(struct gl_texture *tex) { @@ -86,7 +115,7 @@ void basetexture_unload(IWineD3DBaseTexture *iface) if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name) { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if(This->baseTexture.texture_rgb.name) { @@ -115,8 +144,8 @@ DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew) return 0; } - if(LODNew >= This->baseTexture.levels) - LODNew = This->baseTexture.levels - 1; + if (LODNew >= This->baseTexture.level_count) + LODNew = This->baseTexture.level_count - 1; if(This->baseTexture.LOD != LODNew) { This->baseTexture.LOD = LODNew; @@ -145,8 +174,8 @@ DWORD basetexture_get_lod(IWineD3DBaseTexture *iface) DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - TRACE("(%p) : returning %d\n", This, This->baseTexture.levels); - return This->baseTexture.levels; + TRACE("iface %p, returning %u.\n", iface, This->baseTexture.level_count); + return This->baseTexture.level_count; } HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) @@ -164,7 +193,7 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT * Or should we delay the applying until the texture is used for drawing? For now, apply * immediately. */ - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name); @@ -270,9 +299,7 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0; gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1; gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = 0; - gl_tex->states[WINED3DTEXSTA_ELEMENTINDEX] = 0; - gl_tex->states[WINED3DTEXSTA_DMAPOFFSET] = 0; - gl_tex->states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP; + gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; IWineD3DBaseTexture_SetDirty(iface, TRUE); isNewTexture = TRUE; @@ -301,10 +328,11 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac * relying on the partial GL_ARB_texture_non_power_of_two emulation with texture rectangles * (ie, do not care for cond_np2 here, just look for GL_TEXTURE_RECTANGLE_ARB) */ - if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB) { - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); - glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); - checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)"); + if (textureDimensions != GL_TEXTURE_RECTANGLE_ARB) + { + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", This->baseTexture.level_count - 1); + glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count - 1); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count)"); } if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) { /* Cubemaps are always set to clamp, regardless of the sampler state. */ @@ -444,17 +472,18 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue); checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ..."); - if(!cond_np2) { - if(gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) { + if (!cond_np2) + { + if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) glValue = This->baseTexture.LOD; - } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) { - glValue = This->baseTexture.levels - 1; - } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) { + else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.level_count) + glValue = This->baseTexture.level_count - 1; + else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) /* baseTexture.LOD is already clamped in the setter */ glValue = This->baseTexture.LOD; - } else { + else glValue = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL]; - } + /* Note that D3DSAMP_MAXMIPLEVEL specifies the biggest mipmap(default 0), while * GL_TEXTURE_MAX_LEVEL specifies the smallest mimap used(default 1000). * So D3DSAMP_MAXMIPLEVEL is the same as GL_TEXTURE_BASE_LEVEL. @@ -488,4 +517,22 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, } gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso; } + + if (!(This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + != !gl_tex->states[WINED3DTEXSTA_SHADOW]) + { + if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + { + glTexParameteri(textureDimensions, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); + glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)"); + gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE; + } + else + { + glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)"); + gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; + } + } } diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index e22d311beb9..daece20c33d 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -29,8 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->resource.device->adapter->gl_info - #define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ #define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ @@ -97,11 +95,29 @@ static inline BOOL buffer_is_fully_dirty(struct wined3d_buffer *This) return FALSE; } +/* Context activation is done by the caller */ +static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +{ + if(!This->buffer_object) return; + + ENTER_GL(); + GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); + checkGLcall("glDeleteBuffersARB"); + LEAVE_GL(); + This->buffer_object = 0; + + if(This->query) + { + wined3d_event_query_destroy(This->query); + This->query = NULL; + } + This->flags &= ~WINED3D_BUFFER_APPLESYNC; +} + /* Context activation is done by the caller. */ -static void buffer_create_buffer_object(struct wined3d_buffer *This) +static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { GLenum error, gl_usage; - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n", This, debug_d3dusage(This->resource.usage)); @@ -157,6 +173,10 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); This->flags |= WINED3D_BUFFER_FLUSH; + + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); + This->flags |= WINED3D_BUFFER_APPLESYNC; } /* No setup is needed here for GL_ARB_map_buffer_range */ } @@ -203,13 +223,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) fail: /* Clean up all vbo init, but continue because we can work without a vbo :-) */ ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n"); - if (This->buffer_object) - { - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); - LEAVE_GL(); - } - This->buffer_object = 0; + delete_gl_buffer(This, gl_info); buffer_clear_dirty_areas(This); } @@ -258,12 +272,13 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, attrib_size = attrib->format_desc->component_count * attrib->format_desc->component_size; for (i = 0; i < attrib_size; ++i) { - if (This->conversion_map[data + i] != conversion_type) + DWORD_PTR idx = (data + i) % This->stride; + if (This->conversion_map[idx] != conversion_type) { - TRACE("Byte %ld in vertex changed\n", i + data); - TRACE("It was type %d, is %d now\n", This->conversion_map[data + i], conversion_type); + TRACE("Byte %ld in vertex changed\n", idx); + TRACE("It was type %d, is %d now\n", This->conversion_map[idx], conversion_type); ret = TRUE; - This->conversion_map[data + i] = conversion_type; + This->conversion_map[idx] = conversion_type; } } @@ -534,7 +549,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) } /* Context activation is done by the caller. */ -static void buffer_check_buffer_object_size(struct wined3d_buffer *This) +static void buffer_check_buffer_object_size(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { UINT size = This->conversion_stride ? This->conversion_stride * (This->resource.size / This->stride) : This->resource.size; @@ -550,7 +565,7 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This) /* Rescue the data before resizing the buffer object if we do not have our backup copy */ if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, gl_info); } ENTER_GL(); @@ -595,7 +610,7 @@ static inline void fixup_transformed_pos(float *p) } /* Context activation is done by the caller. */ -const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info, GLuint *buffer_object) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; @@ -604,19 +619,19 @@ const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer { if (This->flags & WINED3D_BUFFER_CREATEBO) { - buffer_create_buffer_object(This); + buffer_create_buffer_object(This, gl_info); This->flags &= ~WINED3D_BUFFER_CREATEBO; if (This->buffer_object) { *buffer_object = This->buffer_object; - return (const BYTE *)offset; + return NULL; } } - return This->resource.allocatedMemory + offset; + return This->resource.allocatedMemory; } else { - return (const BYTE *)offset; + return NULL; } } @@ -655,7 +670,7 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) } /* Context activation is done by the caller. */ -BYTE *buffer_get_sysmem(struct wined3d_buffer *This) +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */ if(This->resource.allocatedMemory) return This->resource.allocatedMemory; @@ -682,20 +697,16 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); /* Download the buffer, but don't permanently enable double buffering */ if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, context->gl_info); This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; } - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - This->buffer_object = 0; + delete_gl_buffer(This, context->gl_info); This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */ buffer_clear_dirty_areas(This); @@ -766,26 +777,171 @@ static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) return resource_get_priority((IWineD3DResource *)iface); } +/* The caller provides a context and binds the buffer */ +static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const struct wined3d_gl_info *gl_info) +{ + enum wined3d_event_query_result ret; + + /* No fencing needs to be done if the app promises not to overwrite + * existing data */ + if(flags & WINED3DLOCK_NOOVERWRITE) return; + if(flags & WINED3DLOCK_DISCARD) + { + ENTER_GL(); + GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage)); + checkGLcall("glBufferDataARB\n"); + LEAVE_GL(); + return; + } + + if(!This->query) + { + TRACE("Creating event query for buffer %p\n", This); + + if (!wined3d_event_query_supported(gl_info)) + { + FIXME("Event queries not supported, dropping async buffer locks.\n"); + goto drop_query; + } + + This->query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->query)); + if (!This->query) + { + ERR("Failed to allocate event query memory, dropping async buffer locks.\n"); + goto drop_query; + } + + /* Since we don't know about old draws a glFinish is needed once */ + wglFinish(); + return; + } + TRACE("Synchronizing buffer %p\n", This); + ret = wined3d_event_query_finish(This->query, This->resource.device); + switch(ret) + { + case WINED3D_EVENT_QUERY_NOT_STARTED: + case WINED3D_EVENT_QUERY_OK: + /* All done */ + return; + + case WINED3D_EVENT_QUERY_WRONG_THREAD: + WARN("Cannot synchronize buffer lock due to a thread conflict\n"); + goto drop_query; + + default: + ERR("wined3d_event_query_finish returned %u, dropping async buffer locks\n", ret); + goto drop_query; + } + +drop_query: + if(This->query) + { + wined3d_event_query_destroy(This->query); + This->query = NULL; + } + + wglFinish(); + ENTER_GL(); + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); + LEAVE_GL(); + This->flags &= ~WINED3D_BUFFER_APPLESYNC; +} + +/* The caller provides a GL context */ +static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) +{ + BYTE *map; + UINT start = 0, len = 0; + + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + checkGLcall("glBindBufferARB"); + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield mapflags; + mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; + if (flags & WINED3D_BUFFER_DISCARD) + { + mapflags |= GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + } + else if (flags & WINED3D_BUFFER_NOSYNC) + { + mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; + } + map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, + This->resource.size, mapflags)); + checkGLcall("glMapBufferRange"); + } + else + { + if (This->flags & WINED3D_BUFFER_APPLESYNC) + { + DWORD syncflags = 0; + if (flags & WINED3D_BUFFER_DISCARD) syncflags |= WINED3DLOCK_DISCARD; + if (flags & WINED3D_BUFFER_NOSYNC) syncflags |= WINED3DLOCK_NOOVERWRITE; + LEAVE_GL(); + buffer_sync_apple(This, syncflags, gl_info); + ENTER_GL(); + } + map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB)); + checkGLcall("glMapBufferARB"); + } + if (!map) + { + LEAVE_GL(); + ERR("Failed to map opengl buffer\n"); + return; + } + + while(This->modified_areas) + { + This->modified_areas--; + start = This->maps[This->modified_areas].offset; + len = This->maps[This->modified_areas].size; + + memcpy(map + start, This->resource.allocatedMemory + start, len); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRange"); + } + else if (This->flags & WINED3D_BUFFER_FLUSH) + { + GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRangeAPPLE"); + } + } + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + checkGLcall("glUnmapBufferARB"); + LEAVE_GL(); +} + static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; IWineD3DDeviceImpl *device = This->resource.device; UINT start = 0, end = 0, len = 0, vertices; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BOOL decl_changed = FALSE; unsigned int i, j; BYTE *data; + DWORD flags = This->flags & (WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD); TRACE("iface %p\n", iface); + This->flags &= ~(WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; if (!This->buffer_object) { /* TODO: Make converting independent from VBOs */ if (This->flags & WINED3D_BUFFER_CREATEBO) { - buffer_create_buffer_object(This); + buffer_create_buffer_object(This, gl_info); This->flags &= ~WINED3D_BUFFER_CREATEBO; } else @@ -836,7 +992,20 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC); goto end; } - buffer_check_buffer_object_size(This); + buffer_check_buffer_object_size(This, gl_info); + + /* The declaration changed, reload the whole buffer */ + WARN("Reloading buffer because of decl change\n"); + buffer_clear_dirty_areas(This); + if(!buffer_add_dirty_area(This, 0, 0)) + { + ERR("buffer_add_dirty_area failed, this is not expected\n"); + return; + } + /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application + * cleared for unsynchronized updates + */ + flags = 0; } else { @@ -864,18 +1033,6 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) } } - if (decl_changed) - { - /* The declaration changed, reload the whole buffer */ - WARN("Reloading buffer because of decl change\n"); - buffer_clear_dirty_areas(This); - if(!buffer_add_dirty_area(This, 0, 0)) - { - ERR("buffer_add_dirty_area failed, this is not expected\n"); - return; - } - } - if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); @@ -896,18 +1053,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) return; } - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBufferARB"); - while(This->modified_areas) - { - This->modified_areas--; - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; - GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, len, This->resource.allocatedMemory + start)); - checkGLcall("glBufferSubDataARB"); - } - LEAVE_GL(); + buffer_direct_upload(This, context->gl_info, flags); context_release(context); return; @@ -915,7 +1061,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, gl_info); } /* Now for each vertex in the buffer that needs conversion */ @@ -1033,7 +1179,7 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac /* IWineD3DBuffer methods */ -static DWORD buffer_sanitize_flags(DWORD flags) +static DWORD buffer_sanitize_flags(struct wined3d_buffer *buffer, DWORD flags) { /* Not all flags make sense together, but Windows never returns an error. Catch the * cases that could cause issues */ @@ -1055,6 +1201,11 @@ static DWORD buffer_sanitize_flags(DWORD flags) WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n"); return 0; } + else if (flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE) && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) + { + WARN("DISCARD or NOOVERWRITE lock on non-dynamic buffer, ignoring\n"); + return 0; + } return flags; } @@ -1082,10 +1233,11 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; LONG count; + BOOL dirty = buffer_is_dirty(This); TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags); - flags = buffer_sanitize_flags(flags); + flags = buffer_sanitize_flags(This, flags); if (!(flags & WINED3DLOCK_READONLY)) { if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY; @@ -1093,36 +1245,81 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, count = InterlockedIncrement(&This->lock_count); - if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) + if (This->buffer_object) { - if(count == 1) + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - IWineD3DDeviceImpl *device = This->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - - if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + if(count == 1) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); + IWineD3DDeviceImpl *device = This->resource.device; + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); + } + + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield mapflags = buffer_gl_map_flags(flags); + This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, + This->resource.size, mapflags)); + checkGLcall("glMapBufferRange"); + } + else + { + if(This->flags & WINED3D_BUFFER_APPLESYNC) + { + LEAVE_GL(); + buffer_sync_apple(This, flags, gl_info); + ENTER_GL(); + } + This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); + checkGLcall("glMapBufferARB"); + } + LEAVE_GL(); + + if (((DWORD_PTR) This->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1)) + { + WARN("Pointer %p is not %u byte aligned, falling back to double buffered operation\n", + This->resource.allocatedMemory, RESOURCE_ALIGNMENT); + + ENTER_GL(); + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + checkGLcall("glUnmapBufferARB"); + LEAVE_GL(); + This->resource.allocatedMemory = NULL; + + buffer_get_sysmem(This, gl_info); + TRACE("New pointer is %p\n", This->resource.allocatedMemory); + } + context_release(context); + } + } + else + { + if (dirty) + { + if (This->flags & WINED3D_BUFFER_NOSYNC && !(flags & WINED3DLOCK_NOOVERWRITE)) + { + This->flags &= ~WINED3D_BUFFER_NOSYNC; + } + } + else if(flags & WINED3DLOCK_NOOVERWRITE) + { + This->flags |= WINED3D_BUFFER_NOSYNC; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - gl_info = context->gl_info; - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + if (flags & WINED3DLOCK_DISCARD) { - GLbitfield mapflags = buffer_gl_map_flags(flags); - This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, - This->resource.size, mapflags)); + This->flags |= WINED3D_BUFFER_DISCARD; } - else - { - This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); - } - LEAVE_GL(); - context_release(context); } } @@ -1169,7 +1366,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; ENTER_GL(); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); @@ -1251,7 +1448,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info); HRESULT hr; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; BOOL dynamic_buffer_ok; @@ -1276,7 +1473,8 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format_desc->format), buffer->resource.allocatedMemory, buffer); - dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; + /* GL_ARB_map_buffer_range is disabled for now due to numerous bugs and no gains */ + dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]; /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + * drawStridedFast (half-life 2 and others). diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index 08789855812..5304af2f408 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -28,8 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - static DWORD wined3d_context_tls_idx; /* FBO helper functions */ @@ -84,19 +82,19 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb } /* GL locking is done by the caller */ -static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info) +static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, GLenum target) { unsigned int i; for (i = 0; i < gl_info->limits.buffers; ++i) { - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } @@ -106,7 +104,7 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) const struct wined3d_gl_info *gl_info = context->gl_info; context_bind_fbo(context, GL_FRAMEBUFFER, fbo); - context_clean_fbo_attachments(gl_info); + context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER); context_bind_fbo(context, GL_FRAMEBUFFER, NULL); gl_info->fbo_ops.glDeleteFramebuffers(1, fbo); @@ -114,17 +112,18 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) } /* GL locking is done by the caller */ -static void context_apply_attachment_filter_states(IWineD3DSurface *surface) +static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface) { - const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; - IWineD3DDeviceImpl *device = surface_impl->resource.device; IWineD3DBaseTextureImpl *texture_impl; - BOOL update_minfilter = FALSE; - BOOL update_magfilter = FALSE; /* Update base texture states array */ - if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&texture_impl))) { + IWineD3DDeviceImpl *device = surface->resource.device; + BOOL update_minfilter = FALSE; + BOOL update_magfilter = FALSE; + if (texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] != WINED3DTEXF_POINT || texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] != WINED3DTEXF_NONE) { @@ -146,82 +145,85 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface) } IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl); - } - if (update_minfilter || update_magfilter) - { - GLenum target, bind_target; - GLint old_binding; - - target = surface_impl->texture_target; - if (target == GL_TEXTURE_2D) + if (update_minfilter || update_magfilter) { - bind_target = GL_TEXTURE_2D; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); - } else if (target == GL_TEXTURE_RECTANGLE_ARB) { - bind_target = GL_TEXTURE_RECTANGLE_ARB; - glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); - } else { - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + GLenum target, bind_target; + GLint old_binding; + + target = surface->texture_target; + if (target == GL_TEXTURE_2D) + { + bind_target = GL_TEXTURE_2D; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + } + else if (target == GL_TEXTURE_RECTANGLE_ARB) + { + bind_target = GL_TEXTURE_RECTANGLE_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + } + else + { + bind_target = GL_TEXTURE_CUBE_MAP_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + } + + glBindTexture(bind_target, surface->texture_name); + if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(bind_target, old_binding); } - glBindTexture(bind_target, surface_impl->texture_name); - if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(bind_target, old_binding); + checkGLcall("apply_attachment_filter_states()"); } - - checkGLcall("apply_attachment_filter_states()"); } /* GL locking is done by the caller */ void context_attach_depth_stencil_fbo(struct wined3d_context *context, - GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) + GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) { - IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Attach depth stencil %p\n", depth_stencil); if (depth_stencil) { - DWORD format_flags = depth_stencil_impl->resource.format_desc->Flags; + DWORD format_flags = depth_stencil->resource.format_desc->Flags; - if (use_render_buffer && depth_stencil_impl->current_renderbuffer) + if (use_render_buffer && depth_stencil->current_renderbuffer) { if (format_flags & WINED3DFMT_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id); checkGLcall("glFramebufferRenderbuffer()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id); checkGLcall("glFramebufferRenderbuffer()"); } } else { - surface_prepare_texture(depth_stencil_impl, FALSE); + surface_prepare_texture(depth_stencil, gl_info, FALSE); context_apply_attachment_filter_states(depth_stencil); if (format_flags & WINED3DFMT_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, - depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level); + depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, - depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level); + depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } } @@ -249,21 +251,20 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context, } /* GL locking is done by the caller */ -void context_attach_surface_fbo(const struct wined3d_context *context, - GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) +static void context_attach_surface_fbo(const struct wined3d_context *context, + GLenum fbo_target, DWORD idx, IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Attach surface %p to %u\n", surface, idx); if (surface) { - surface_prepare_texture(surface_impl, FALSE); + surface_prepare_texture(surface, gl_info, FALSE); context_apply_attachment_filter_states(surface); - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target, - surface_impl->texture_name, surface_impl->texture_level); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface->texture_target, + surface->texture_name, surface->texture_level); checkGLcall("glFramebufferTexture2D()"); } else @@ -274,12 +275,12 @@ void context_attach_surface_fbo(const struct wined3d_context *context, } /* GL locking is done by the caller */ -static void context_check_fbo_status(struct wined3d_context *context) +static void context_check_fbo_status(struct wined3d_context *context, GLenum target) { const struct wined3d_gl_info *gl_info = context->gl_info; GLenum status; - status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + status = gl_info->fbo_ops.glCheckFramebufferStatus(target); if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("FBO complete\n"); @@ -297,7 +298,7 @@ static void context_check_fbo_status(struct wined3d_context *context) /* Dump the FBO attachments */ for (i = 0; i < gl_info->limits.buffers; ++i) { - attachment = (IWineD3DSurfaceImpl *)context->current_fbo->render_targets[i]; + attachment = context->current_fbo->render_targets[i]; if (attachment) { FIXME("\tColor attachment %d: (%p) %s %ux%u\n", @@ -305,7 +306,7 @@ static void context_check_fbo_status(struct wined3d_context *context) attachment->pow2Width, attachment->pow2Height); } } - attachment = (IWineD3DSurfaceImpl *)context->current_fbo->depth_stencil; + attachment = context->current_fbo->depth_stencil; if (attachment) { FIXME("\tDepth attachment: (%p) %s %ux%u\n", @@ -315,16 +316,16 @@ static void context_check_fbo_status(struct wined3d_context *context) } } -static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context) +static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets)); - memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = device->stencilBufferTarget; + memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); + entry->depth_stencil = depth_stencil; entry->attached = FALSE; entry->id = 0; @@ -332,16 +333,17 @@ static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *contex } /* GL locking is done by the caller */ -static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil, + struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; - context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); - context_clean_fbo_attachments(gl_info); + context_bind_fbo(context, target, &entry->id); + context_clean_fbo_attachments(gl_info, target); - memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = device->stencilBufferTarget; + memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); + entry->depth_stencil = depth_stencil; entry->attached = FALSE; } @@ -361,17 +363,17 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb /* GL locking is done by the caller */ -static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) +static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry) { if (!memcmp(entry->render_targets, - device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) - && entry->depth_stencil == device->stencilBufferTarget) + render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) + && entry->depth_stencil == depth_stencil) { list_remove(&entry->entry); list_add_head(&context->fbo_list, &entry->entry); @@ -381,14 +383,14 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) { - entry = context_create_fbo_entry(context); + entry = context_create_fbo_entry(context, render_targets, depth_stencil); list_add_head(&context->fbo_list, &entry->entry); ++context->fbo_entry_count; } else { entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry); - context_reuse_fbo_entry(context, entry); + context_reuse_fbo_entry(context, target, render_targets, depth_stencil, entry); list_remove(&entry->entry); list_add_head(&context->fbo_list, &entry->entry); } @@ -397,32 +399,28 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) } /* GL locking is done by the caller */ -static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; - context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); + context_bind_fbo(context, target, &entry->id); if (!entry->attached) { /* Apply render targets */ for (i = 0; i < gl_info->limits.buffers; ++i) { - IWineD3DSurface *render_target = device->render_targets[i]; - context_attach_surface_fbo(context, GL_FRAMEBUFFER, i, render_target); + context_attach_surface_fbo(context, target, i, entry->render_targets[i]); } /* Apply depth targets */ - if (device->stencilBufferTarget) + if (entry->depth_stencil) { - unsigned int w = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Width; - unsigned int h = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Height; - - surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h); + surface_set_compatible_renderbuffer(entry->depth_stencil, + entry->render_targets[0]->pow2Width, entry->render_targets[0]->pow2Height); } - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->stencilBufferTarget, TRUE); + context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, TRUE); entry->attached = TRUE; } @@ -430,24 +428,17 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ { for (i = 0; i < gl_info->limits.buffers; ++i) { - if (device->render_targets[i]) - context_apply_attachment_filter_states(device->render_targets[i]); + if (entry->render_targets[i]) + context_apply_attachment_filter_states(entry->render_targets[i]); } - if (device->stencilBufferTarget) - context_apply_attachment_filter_states(device->stencilBufferTarget); - } - - for (i = 0; i < gl_info->limits.buffers; ++i) - { - if (device->render_targets[i]) - device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; - else - device->draw_buffers[i] = GL_NONE; + if (entry->depth_stencil) + context_apply_attachment_filter_states(entry->depth_stencil); } } /* GL locking is done by the caller */ -static void context_apply_fbo_state(struct wined3d_context *context) +static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { struct fbo_entry *entry, *entry2; @@ -456,16 +447,39 @@ static void context_apply_fbo_state(struct wined3d_context *context) context_destroy_fbo_entry(context, entry); } - if (context->render_offscreen) + if (context->rebind_fbo) { - context->current_fbo = context_find_fbo_entry(context); - context_apply_fbo_entry(context, context->current_fbo); - } else { - context->current_fbo = NULL; context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + context->rebind_fbo = FALSE; } - context_check_fbo_status(context); + if (render_targets) + { + context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil); + context_apply_fbo_entry(context, target, context->current_fbo); + } + else + { + context->current_fbo = NULL; + context_bind_fbo(context, target, NULL); + } + + context_check_fbo_status(context, target); +} + +/* GL locking is done by the caller */ +void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) +{ + if (surface_is_offscreen(render_target)) + { + context->blit_targets[0] = render_target; + context_apply_fbo_state(context, target, context->blit_targets, depth_stencil); + } + else + { + context_apply_fbo_state(context, target, NULL, NULL); + } } /* Context activation is done by the caller. */ @@ -614,13 +628,13 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry, *entry2; - if (context->current_rt == (IWineD3DSurface *)resource) context->current_rt = NULL; + if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL; LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) { UINT j; - if (entry->depth_stencil == (IWineD3DSurface *)resource) + if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource) { list_remove(&entry->entry); list_add_head(&context->fbo_destroy_list, &entry->entry); @@ -629,7 +643,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource for (j = 0; j < gl_info->limits.buffers; ++j) { - if (entry->render_targets[j] == (IWineD3DSurface *)resource) + if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource) { list_remove(&entry->entry); list_add_head(&context->fbo_destroy_list, &entry->entry); @@ -647,6 +661,115 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource } } +void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct fbo_entry *entry = context->current_fbo; + unsigned int i; + + if (!entry || context->rebind_fbo) return; + + for (i = 0; i < gl_info->limits.buffers; ++i) + { + if (surface == entry->render_targets[i]) + { + TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i); + context->rebind_fbo = TRUE; + return; + } + } + + if (surface == entry->depth_stencil) + { + TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface); + context->rebind_fbo = TRUE; + } +} + +static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format) +{ + int current = GetPixelFormat(dc); + + if (current == format) return TRUE; + + if (!current) + { + if (!SetPixelFormat(dc, format, NULL)) + { + ERR("Failed to set pixel format %d on device context %p, last error %#x.\n", + format, dc, GetLastError()); + return FALSE; + } + return TRUE; + } + + /* By default WGL doesn't allow pixel format adjustments but we need it + * here. For this reason there's a Wine specific wglSetPixelFormat() + * which allows us to set the pixel format multiple times. Only use it + * when really needed. */ + if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) + { + if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format, NULL))) + { + ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n", + format, dc); + return FALSE; + } + return TRUE; + } + + /* OpenGL doesn't allow pixel format adjustments. Print an error and + * continue using the old format. There's a big chance that the old + * format works although with a performance hit and perhaps rendering + * errors. */ + ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n", + format, dc, current); + return TRUE; +} + +static void context_update_window(struct wined3d_context *context) +{ + TRACE("Updating context %p window from %p to %p.\n", + context, context->win_handle, context->swapchain->win_handle); + + if (context->valid) + { + if (!ReleaseDC(context->win_handle, context->hdc)) + { + ERR("Failed to release device context %p, last error %#x.\n", + context->hdc, GetLastError()); + } + } + else context->valid = 1; + + context->win_handle = context->swapchain->win_handle; + + if (!(context->hdc = GetDC(context->win_handle))) + { + ERR("Failed to get a device context for window %p.\n", context->win_handle); + goto err; + } + + if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format)) + { + ERR("Failed to set pixel format %d on device context %p.\n", + context->pixel_format, context->hdc); + goto err; + } + + if (!pwglMakeCurrent(context->hdc, context->glCtx)) + { + ERR("Failed to make GL context %p current on device context %p, last error %#x.\n", + context->glCtx, context->hdc, GetLastError()); + goto err; + } + + return; + +err: + context->valid = 0; +} + static void context_validate(struct wined3d_context *context) { HWND wnd = WindowFromDC(context->hdc); @@ -657,6 +780,9 @@ static void context_validate(struct wined3d_context *context) context->hdc, wnd, context->win_handle); context->valid = 0; } + + if (context->win_handle != context->swapchain->win_handle) + context_update_window(context); } static void context_destroy_gl_resources(struct wined3d_context *context) @@ -713,11 +839,6 @@ static void context_destroy_gl_resources(struct wined3d_context *context) if (context->valid) { - if (context->src_fbo) - { - TRACE("Destroy src FBO %d\n", context->src_fbo); - context_destroy_fbo(context, &context->src_fbo); - } if (context->dst_fbo) { TRACE("Destroy dst FBO %d\n", context->dst_fbo); @@ -772,15 +893,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context) ERR("Failed to disable GL context.\n"); } - if (context->pbuffer) - { - GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc)); - GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer)); - } - else - { - ReleaseDC(context->win_handle, context->hdc); - } + ReleaseDC(context->win_handle, context->hdc); if (!pwglDeleteContext(context->glCtx)) { @@ -928,68 +1041,10 @@ static void Context_MarkStateDirty(struct wined3d_context *context, DWORD state, context->isStateDirty[idx] |= (1 << shift); } -/***************************************************************************** - * AddContextToArray - * - * Adds a context to the context array. Helper function for context_create(). - * - * This method is not called in performance-critical code paths, only when a - * new render target or swapchain is created. Thus performance is not an issue - * here. - * - * Params: - * This: Device to add the context for - * hdc: device context - * glCtx: WGL context to add - * pbuffer: optional pbuffer used with this context - * - *****************************************************************************/ -static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This, - HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) -{ - struct wined3d_context **oldArray = This->contexts; - DWORD state; - - This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1)); - if(This->contexts == NULL) { - ERR("Unable to grow the context array\n"); - This->contexts = oldArray; - return NULL; - } - if(oldArray) { - memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts); - } - - This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This->contexts)); - if(This->contexts[This->numContexts] == NULL) { - ERR("Unable to allocate a new context\n"); - HeapFree(GetProcessHeap(), 0, This->contexts); - This->contexts = oldArray; - return NULL; - } - - This->contexts[This->numContexts]->hdc = hdc; - This->contexts[This->numContexts]->glCtx = glCtx; - This->contexts[This->numContexts]->pbuffer = pbuffer; - This->contexts[This->numContexts]->win_handle = win_handle; - HeapFree(GetProcessHeap(), 0, oldArray); - - /* Mark all states dirty to force a proper initialization of the states on the first use of the context - */ - for(state = 0; state <= STATE_HIGHEST; state++) { - if (This->StateTable[state].representative) - Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable); - } - - This->numContexts++; - TRACE("Created context %p\n", This->contexts[This->numContexts - 1]); - return This->contexts[This->numContexts - 1]; -} - /* This function takes care of WineD3D pixel format selection. */ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, - const struct GlPixelFormatDesc *color_format_desc, const struct GlPixelFormatDesc *ds_format_desc, - BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible) + const struct wined3d_format_desc *color_format_desc, const struct wined3d_format_desc *ds_format_desc, + BOOL auxBuffers, int numSamples, BOOL findCompatible) { int iPixelFormat=0; unsigned int matchtry; @@ -1019,9 +1074,9 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, int i = 0; int nCfgs = This->adapter->nCfgs; - TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, pbuffer=%d, findCompatible=%d\n", + TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, findCompatible=%d\n", debug_d3dformat(color_format_desc->format), debug_d3dformat(ds_format_desc->format), - auxBuffers, numSamples, pbuffer, findCompatible); + auxBuffers, numSamples, findCompatible); if (!getColorBits(color_format_desc, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) { @@ -1030,23 +1085,6 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, return 0; } - /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. - * You are able to add a depth + stencil surface at a later stage when you need it. - * In order to support this properly in WineD3D we need the ability to recreate the opengl context and - * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new - * context, need torecreate shaders, textures and other resources. - * - * The context manager already takes care of the state problem and for the other tasks code from Reset - * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. - * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the - * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this - * issue needs to be fixed. */ - if (ds_format_desc->format != WINED3DFMT_D24_UNORM_S8_UINT) - { - FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n"); - ds_format_desc = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, &This->adapter->gl_info); - } - getDepthStencilBits(ds_format_desc, &depthBits, &stencilBits); for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])) && !iPixelFormat; matchtry++) { @@ -1059,18 +1097,14 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, if(cfg->iPixelType != WGL_TYPE_RGBA_ARB) continue; - /* In window mode (!pbuffer) we need a window drawable format and double buffering. */ - if(!pbuffer && !(cfg->windowDrawable && cfg->doubleBuffer)) + /* In window mode we need a window drawable format and double buffering. */ + if(!(cfg->windowDrawable && cfg->doubleBuffer)) continue; /* We like to have aux buffers in backbuffer mode */ if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux) continue; - /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */ - if(pbuffer && (!cfg->pbufferDrawable || cfg->doubleBuffer)) - continue; - if(matches[matchtry].exact_color) { if(cfg->redSize != redBits) continue; @@ -1167,227 +1201,174 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, /***************************************************************************** * context_create * - * Creates a new context for a window, or a pbuffer context. + * Creates a new context. * * * Params: * This: Device to activate the context for * target: Surface this context will render to * win_handle: handle to the window which we are drawing to - * create_pbuffer: tells whether to create a pbuffer or not * pPresentParameters: contains the pixelformats to use for onscreen rendering * *****************************************************************************/ -struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, - HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) +struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target, + const struct wined3d_format_desc *ds_format_desc) { - const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; - struct wined3d_context *ret = NULL; - HPBUFFERARB pbuffer = NULL; + IWineD3DDeviceImpl *device = swapchain->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_format_desc *color_format_desc; + struct wined3d_context *ret; + PIXELFORMATDESCRIPTOR pfd; + BOOL auxBuffers = FALSE; + int numSamples = 0; + int pixel_format; unsigned int s; + DWORD state; HGLRC ctx; HDC hdc; - TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target); + TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); - if(create_pbuffer) { - HDC hdc_parent = GetDC(win_handle); - int iPixelFormat = 0; + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); + if (!ret) + { + ERR("Failed to allocate context memory.\n"); + return NULL; + } - IWineD3DSurface *StencilSurface = This->stencilBufferTarget; - const struct GlPixelFormatDesc *ds_format_desc = StencilSurface - ? ((IWineD3DSurfaceImpl *)StencilSurface)->resource.format_desc - : getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info); + if (!(hdc = GetDC(swapchain->win_handle))) + { + ERR("Failed to retrieve a device context.\n"); + goto out; + } - /* Try to find a pixel format with pbuffer support. */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc, - ds_format_desc, FALSE /* auxBuffers */, 0 /* numSamples */, TRUE /* PBUFFER */, - FALSE /* findCompatible */); - if(!iPixelFormat) { - TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); + color_format_desc = target->resource.format_desc; - /* For some reason we weren't able to find a format, try to find something instead of crashing. - * A reason for failure could have been wglChoosePixelFormatARB strictness. */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc, - ds_format_desc, FALSE /* auxBuffer */, 0 /* numSamples */, TRUE /* PBUFFER */, - TRUE /* findCompatible */); - } + /* In case of ORM_BACKBUFFER, make sure to request an alpha component for + * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + { + auxBuffers = TRUE; - /* This shouldn't happen as ChoosePixelFormat always returns something */ - if(!iPixelFormat) { - ERR("Unable to locate a pixel format for a pbuffer\n"); - ReleaseDC(win_handle, hdc_parent); - goto out; - } + if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM) + color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, gl_info); + else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) + color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); + } - TRACE("Creating a pBuffer drawable for the new context\n"); - pbuffer = GL_EXTCALL(wglCreatePbufferARB(hdc_parent, iPixelFormat, target->currentDesc.Width, target->currentDesc.Height, 0)); - if(!pbuffer) { - ERR("Cannot create a pbuffer\n"); - ReleaseDC(win_handle, hdc_parent); - goto out; - } + /* DirectDraw supports 8bit paletted render targets and these are used by + * old games like Starcraft and C&C. Most modern hardware doesn't support + * 8bit natively so we perform some form of 8bit -> 32bit conversion. The + * conversion (ab)uses the alpha component for storing the palette index. + * For this reason we require a format with 8bit alpha, so request + * A8R8G8B8. */ + if (color_format_desc->format == WINED3DFMT_P8_UINT) + color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); - /* In WGL a pbuffer is 'wrapped' inside a HDC to 'fool' wglMakeCurrent */ - hdc = GL_EXTCALL(wglGetPbufferDCARB(pbuffer)); - if(!hdc) { - ERR("Cannot get a HDC for pbuffer (%p)\n", pbuffer); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - ReleaseDC(win_handle, hdc_parent); - goto out; - } - ReleaseDC(win_handle, hdc_parent); - } else { - PIXELFORMATDESCRIPTOR pfd; - int iPixelFormat; - int res; - const struct GlPixelFormatDesc *color_format_desc = target->resource.format_desc; - const struct GlPixelFormatDesc *ds_format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, - &This->adapter->gl_info); - BOOL auxBuffers = FALSE; - int numSamples = 0; - - hdc = GetDC(win_handle); - if(hdc == NULL) { - ERR("Cannot retrieve a device context!\n"); - goto out; - } - - /* In case of ORM_BACKBUFFER, make sure to request an alpha component for X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ - if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { - auxBuffers = TRUE; - - if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM) - color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, &This->adapter->gl_info); - else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) - color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info); - } - - /* DirectDraw supports 8bit paletted render targets and these are used by old games like Starcraft and C&C. - * Most modern hardware doesn't support 8bit natively so we perform some form of 8bit -> 32bit conversion. - * The conversion (ab)uses the alpha component for storing the palette index. For this reason we require - * a format with 8bit alpha, so request A8R8G8B8. */ - if (color_format_desc->format == WINED3DFMT_P8_UINT) - color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info); - - /* Retrieve the depth stencil format from the present parameters. - * The choice of the proper format can give a nice performance boost - * in case of GPU limited programs. */ - if(pPresentParms->EnableAutoDepthStencil) { - TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat)); - ds_format_desc = getFormatDescEntry(pPresentParms->AutoDepthStencilFormat, &This->adapter->gl_info); - } - - /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD */ - if(pPresentParms->MultiSampleType && (pPresentParms->SwapEffect == WINED3DSWAPEFFECT_DISCARD)) { - if (!gl_info->supported[ARB_MULTISAMPLE]) - ERR("The program is requesting multisampling without support!\n"); - else - { - TRACE("Requesting multisample type %#x.\n", pPresentParms->MultiSampleType); - numSamples = pPresentParms->MultiSampleType; - } - } - - /* Try to find a pixel format which matches our requirements */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc, - auxBuffers, numSamples, FALSE /* PBUFFER */, FALSE /* findCompatible */); - - /* Try to locate a compatible format if we weren't able to find anything */ - if(!iPixelFormat) { - TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc, - auxBuffers, 0 /* numSamples */, FALSE /* PBUFFER */, TRUE /* findCompatible */ ); - } - - /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */ - if(!iPixelFormat) { - ERR("Can't find a suitable iPixelFormat\n"); - return NULL; - } - - DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd); - res = SetPixelFormat(hdc, iPixelFormat, NULL); - if(!res) { - int oldPixelFormat = GetPixelFormat(hdc); - - /* By default WGL doesn't allow pixel format adjustments but we need it here. - * For this reason there is a WINE-specific wglSetPixelFormat which allows you to - * set the pixel format multiple times. Only use it when it is really needed. */ - - if(oldPixelFormat == iPixelFormat) { - /* We don't have to do anything as the formats are the same :) */ - } - else if (oldPixelFormat && gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) - { - res = GL_EXTCALL(wglSetPixelFormatWINE(hdc, iPixelFormat, NULL)); - - if(!res) { - ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat); - return NULL; - } - } else if(oldPixelFormat) { - /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format. - * There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */ - ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat); - } else { - ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat); - return NULL; - } + /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD. */ + if (swapchain->presentParms.MultiSampleType && (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD)) + { + if (!gl_info->supported[ARB_MULTISAMPLE]) + WARN("The application is requesting multisampling without support.\n"); + else + { + TRACE("Requesting multisample type %#x.\n", swapchain->presentParms.MultiSampleType); + numSamples = swapchain->presentParms.MultiSampleType; } } - ctx = pwglCreateContext(hdc); - if (This->numContexts) + /* Try to find a pixel format which matches our requirements. */ + pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc, + auxBuffers, numSamples, FALSE /* findCompatible */); + + /* Try to locate a compatible format if we weren't able to find anything. */ + if (!pixel_format) { - if (!pwglShareLists(This->contexts[0]->glCtx, ctx)) + TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); + pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc, + auxBuffers, 0 /* numSamples */, TRUE /* findCompatible */); + } + + /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */ + if (!pixel_format) + { + ERR("Can't find a suitable pixel format.\n"); + goto out; + } + + DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd); + if (!context_set_pixel_format(gl_info, hdc, pixel_format)) + { + ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc); + goto out; + } + + ctx = pwglCreateContext(hdc); + if (device->numContexts) + { + if (!pwglShareLists(device->contexts[0]->glCtx, ctx)) { DWORD err = GetLastError(); ERR("wglShareLists(%p, %p) failed, last error %#x.\n", - This->contexts[0]->glCtx, ctx, err); + device->contexts[0]->glCtx, ctx, err); } } if(!ctx) { ERR("Failed to create a WGL context\n"); - if(create_pbuffer) { - GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc)); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - } goto out; } - ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer); - if(!ret) { + + if (!device_context_add(device, ret)) + { ERR("Failed to add the newly created context to the context list\n"); if (!pwglDeleteContext(ctx)) { DWORD err = GetLastError(); ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err); } - if(create_pbuffer) { - GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc)); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - } goto out; } - ret->valid = 1; - ret->gl_info = &This->adapter->gl_info; - ret->surface = (IWineD3DSurface *) target; - ret->current_rt = (IWineD3DSurface *)target; - ret->render_offscreen = surface_is_offscreen((IWineD3DSurface *) target); - ret->draw_buffer_dirty = TRUE; + + ret->gl_info = gl_info; + + /* Mark all states dirty to force a proper initialization of the states + * on the first use of the context. */ + for (state = 0; state <= STATE_HIGHEST; ++state) + { + if (device->StateTable[state].representative) + Context_MarkStateDirty(ret, state, device->StateTable); + } + + ret->swapchain = swapchain; + ret->current_rt = target; ret->tid = GetCurrentThreadId(); - if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) { + + ret->render_offscreen = surface_is_offscreen(target); + ret->draw_buffer_dirty = TRUE; + ret->valid = 1; + + ret->glCtx = ctx; + ret->win_handle = swapchain->win_handle; + ret->hdc = hdc; + ret->pixel_format = pixel_format; + + if (device->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *)device)) + { /* Create the dirty constants array and initialize them to dirty */ ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF); + sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF); ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF); + sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF); memset(ret->vshader_const_dirty, 1, - sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF); + sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF); memset(ret->pshader_const_dirty, 1, - sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF); + sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF); } + ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + gl_info->limits.buffers * sizeof(*ret->blit_targets)); + if (!ret->blit_targets) goto out; + ret->free_occlusion_query_size = 4; ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0, ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries)); @@ -1440,10 +1421,10 @@ struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurface glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); - glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment); - checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);"); - glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment); - checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);"); + glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment); + checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);"); + glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment); + checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);"); if (gl_info->supported[APPLE_CLIENT_STORAGE]) { @@ -1512,83 +1493,22 @@ struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurface LEAVE_GL(); - This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE); + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + + TRACE("Created context %p.\n", ret); return ret; out: - if (ret) - { - HeapFree(GetProcessHeap(), 0, ret->free_event_queries); - HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); - HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty); - HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty); - HeapFree(GetProcessHeap(), 0, ret); - } + HeapFree(GetProcessHeap(), 0, ret->free_event_queries); + HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); + HeapFree(GetProcessHeap(), 0, ret->blit_targets); + HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty); + HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty); + HeapFree(GetProcessHeap(), 0, ret); return NULL; } -/***************************************************************************** - * RemoveContextFromArray - * - * Removes a context from the context manager. The opengl context is not - * destroyed or unset. context is not a valid pointer after that call. - * - * Similar to the former call this isn't a performance critical function. A - * helper function for context_destroy(). - * - * Params: - * This: Device to activate the context for - * context: Context to remove - * - *****************************************************************************/ -static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_context *context) -{ - struct wined3d_context **new_array; - BOOL found = FALSE; - UINT i; - - TRACE("Removing ctx %p\n", context); - - for (i = 0; i < This->numContexts; ++i) - { - if (This->contexts[i] == context) - { - found = TRUE; - break; - } - } - - if (!found) - { - ERR("Context %p doesn't exist in context array\n", context); - return; - } - - while (i < This->numContexts - 1) - { - This->contexts[i] = This->contexts[i + 1]; - ++i; - } - - --This->numContexts; - if (!This->numContexts) - { - HeapFree(GetProcessHeap(), 0, This->contexts); - This->contexts = NULL; - return; - } - - new_array = HeapReAlloc(GetProcessHeap(), 0, This->contexts, This->numContexts * sizeof(*This->contexts)); - if (!new_array) - { - ERR("Failed to shrink context array. Oh well.\n"); - return; - } - - This->contexts = new_array; -} - /***************************************************************************** * context_destroy * @@ -1617,9 +1537,10 @@ void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) destroy = FALSE; } + HeapFree(GetProcessHeap(), 0, context->blit_targets); HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty); - RemoveContextFromArray(This, context); + device_context_remove(This, context); if (destroy) HeapFree(GetProcessHeap(), 0, context); } @@ -1657,8 +1578,8 @@ static void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *conte int i; const struct StateEntry *StateTable = This->StateTable; const struct wined3d_gl_info *gl_info = context->gl_info; - UINT width = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Width; - UINT height = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height; + UINT width = context->current_rt->currentDesc.Width; + UINT height = context->current_rt->currentDesc.Height; DWORD sampler; TRACE("Setting up context %p for blitting\n", context); @@ -1811,6 +1732,9 @@ static void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *conte glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); checkGLcall("glColorMask"); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), StateTable); if (gl_info->supported[EXT_SECONDARY_COLOR]) { glDisable(GL_COLOR_SUM_EXT); @@ -1882,14 +1806,12 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain * * Returns: The needed context * *****************************************************************************/ -static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target) +static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) { IWineD3DSwapChain *swapchain = NULL; struct wined3d_context *current_context = context_get_current(); - const struct StateEntry *StateTable = This->StateTable; DWORD tid = GetCurrentThreadId(); struct wined3d_context *context; - BOOL old_render_offscreen; if (current_context && current_context->destroyed) current_context = NULL; @@ -1897,15 +1819,15 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur { if (current_context && current_context->current_rt - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) + && current_context->swapchain->device == This) { target = current_context->current_rt; } else { IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0]; - if (swapchain->backBuffer) target = swapchain->backBuffer[0]; - else target = swapchain->frontBuffer; + if (swapchain->back_buffers) target = swapchain->back_buffers[0]; + else target = swapchain->front_buffer; } } @@ -1915,165 +1837,36 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur return current_context; } - if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) { + if (target->Flags & SFLAG_SWAPCHAIN) + { TRACE("Rendering onscreen\n"); + swapchain = (IWineD3DSwapChain *)target->container; context = findThreadContextForSwapChain(swapchain, tid); - - old_render_offscreen = context->render_offscreen; - context->render_offscreen = surface_is_offscreen(target); - /* The context != This->activeContext will catch a NOP context change. This can occur - * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen - * rendering. No context change is needed in that case - */ - - if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) { - if(This->pbufferContext && tid == This->pbufferContext->tid) { - This->pbufferContext->tid = 0; - } - } - IWineD3DSwapChain_Release(swapchain); } else { TRACE("Rendering offscreen\n"); -retry: - if (wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) + /* Stay with the currently active context. */ + if (current_context && current_context->swapchain->device == This) { - IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *)target; - if (!This->pbufferContext - || This->pbufferWidth < targetimpl->currentDesc.Width - || This->pbufferHeight < targetimpl->currentDesc.Height) - { - if (This->pbufferContext) context_destroy(This, This->pbufferContext); - - /* The display is irrelevant here, the window is 0. But - * context_create() needs a valid X connection. Create the context - * on the same server as the primary swapchain. The primary - * swapchain is exists at this point. */ - This->pbufferContext = context_create(This, targetimpl, - ((IWineD3DSwapChainImpl *)This->swapchains[0])->context[0]->win_handle, - TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms); - This->pbufferWidth = targetimpl->currentDesc.Width; - This->pbufferHeight = targetimpl->currentDesc.Height; - if (This->pbufferContext) context_release(This->pbufferContext); - } - - if (This->pbufferContext) - { - if (This->pbufferContext->tid && This->pbufferContext->tid != tid) - { - FIXME("The PBuffer context is only supported for one thread for now!\n"); - } - This->pbufferContext->tid = tid; - context = This->pbufferContext; - } - else - { - ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering.\n"); - wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; - goto retry; - } + context = current_context; } else { - /* Stay with the currently active context. */ - if (current_context - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) - { - context = current_context; - } - else - { - /* This may happen if the app jumps straight into offscreen rendering - * Start using the context of the primary swapchain. tid == 0 is no problem - * for findThreadContextForSwapChain. - * - * Can also happen on thread switches - in that case findThreadContextForSwapChain - * is perfect to call. */ - context = findThreadContextForSwapChain(This->swapchains[0], tid); - } + /* This may happen if the app jumps straight into offscreen rendering + * Start using the context of the primary swapchain. tid == 0 is no problem + * for findThreadContextForSwapChain. + * + * Can also happen on thread switches - in that case findThreadContextForSwapChain + * is perfect to call. */ + context = findThreadContextForSwapChain(This->swapchains[0], tid); } - - old_render_offscreen = context->render_offscreen; - context->render_offscreen = TRUE; } context_validate(context); - if (context->render_offscreen != old_render_offscreen) - { - Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); - Context_MarkStateDirty(context, STATE_VDECL, StateTable); - Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); - Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); - Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); - } - - /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers - * the alpha blend state changes with different render target formats. */ - if (!context->current_rt) - { - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); - } - else - { - const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.format_desc; - const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc; - - if (old->format != new->format) - { - /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ - if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask) - || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) - { - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); - } - } - - /* When switching away from an offscreen render target, and we're not - * using FBOs, we have to read the drawable into the texture. This is - * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There - * are some things that need care though. PreLoad needs a GL context, - * and FindContext is called before the context is activated. It also - * has to be called with the old rendertarget active, otherwise a - * wrong drawable is read. */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && old_render_offscreen && context->current_rt != target) - { - BOOL oldInDraw = This->isInDraw; - - /* surface_internal_preload() requires a context to load the - * texture, so it will call context_acquire(). Set isInDraw to true - * to signal surface_internal_preload() that it has a context. */ - - /* FIXME: This is just broken. There's no guarantee whatsoever - * that the currently active context, if any, is appropriate for - * reading back the render target. We should probably call - * context_set_current(context) here and then rely on - * context_acquire() doing the right thing. */ - This->isInDraw = TRUE; - - /* Read the back buffer of the old drawable into the destination texture. */ - if (((IWineD3DSurfaceImpl *)context->current_rt)->texture_name_srgb) - { - surface_internal_preload(context->current_rt, SRGB_BOTH); - } - else - { - surface_internal_preload(context->current_rt, SRGB_RGB); - } - - IWineD3DSurface_ModifyLocation(context->current_rt, SFLAG_INDRAWABLE, FALSE); - - This->isInDraw = oldInDraw; - } - } - - context->draw_buffer_dirty = TRUE; - context->current_rt = target; - return context; } @@ -2081,10 +1874,10 @@ retry: static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit) { const struct wined3d_gl_info *gl_info = context->gl_info; - IWineD3DSurface *rt = context->current_rt; + IWineD3DSurfaceImpl *rt = context->current_rt; IWineD3DDeviceImpl *device; - device = ((IWineD3DSurfaceImpl *)rt)->resource.device; + device = rt->resource.device; if (!surface_is_offscreen(rt)) { ENTER_GL(); @@ -2099,6 +1892,16 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit { if (!blit) { + unsigned int i; + + for (i = 0; i < gl_info->limits.buffers; ++i) + { + if (device->render_targets[i]) + device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; + else + device->draw_buffers[i] = GL_NONE; + } + if (gl_info->supported[ARB_DRAW_BUFFERS]) { GL_EXTCALL(glDrawBuffersARB(gl_info->limits.buffers, device->draw_buffers)); @@ -2131,116 +1934,268 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) context->draw_buffer_dirty = TRUE; } +static inline void context_set_render_offscreen(struct wined3d_context *context, const struct StateEntry *StateTable, + BOOL offscreen) +{ + if (context->render_offscreen == offscreen) return; + + Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); + Context_MarkStateDirty(context, STATE_VDECL, StateTable); + Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); + Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); + Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); + context->render_offscreen = offscreen; +} + +static BOOL match_depth_stencil_format(const struct wined3d_format_desc *existing, + const struct wined3d_format_desc *required) +{ + short existing_depth, existing_stencil, required_depth, required_stencil; + + if(existing == required) return TRUE; + if((existing->Flags & WINED3DFMT_FLAG_FLOAT) != (required->Flags & WINED3DFMT_FLAG_FLOAT)) return FALSE; + + getDepthStencilBits(existing, &existing_depth, &existing_stencil); + getDepthStencilBits(required, &required_depth, &required_stencil); + + if(existing_depth < required_depth) return FALSE; + /* If stencil bits are used the exact amount is required - otherwise wrapping + * won't work correctly */ + if(required_stencil && required_stencil != existing_stencil) return FALSE; + return TRUE; +} +/* The caller provides a context */ +static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) +{ + /* Onscreen surfaces are always in a swapchain */ + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container; + + if (context->render_offscreen || !depth_stencil) return; + if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return; + + /* TODO: If the requested format would satisfy the needs of the existing one(reverse match), + * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new + * format. */ + WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); + + /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)context->current_rt, SFLAG_INTEXTURE, NULL); + swapchain->render_to_fbo = TRUE; + context_set_render_offscreen(context, device->StateTable, TRUE); +} + /* Context activation is done by the caller. */ -static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage) +void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) +{ + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, NULL); + + if (context->render_offscreen) + { + FIXME("Applying blit state for an offscreen target with ORM_FBO. This should be avoided.\n"); + surface_internal_preload(context->current_rt, SRGB_RGB); + + ENTER_GL(); + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, context->current_rt, NULL); + LEAVE_GL(); + } + else + { + ENTER_GL(); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + LEAVE_GL(); + } + + context->draw_buffer_dirty = TRUE; + } + + if (context->draw_buffer_dirty) + { + context_apply_draw_buffer(context, TRUE); + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + context->draw_buffer_dirty = FALSE; + } + + SetupForBlit(device, context); +} + +/* Context activation is done by the caller. */ +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) +{ + const struct StateEntry *state_table = device->StateTable; + GLenum buffer; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, depth_stencil); + + ENTER_GL(); + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil); + LEAVE_GL(); + } + + if (!surface_is_offscreen(render_target)) + buffer = surface_get_gl_buffer(render_target); + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + buffer = GL_COLOR_ATTACHMENT0; + else + buffer = device->offscreenBuffer; + + ENTER_GL(); + context_set_draw_buffer(context, buffer); + LEAVE_GL(); + + if (context->last_was_blit) + { + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + } + + /* Blending and clearing should be orthogonal, but tests on the nvidia + * driver show that disabling blending when clearing improves the clearing + * performance incredibly. */ + ENTER_GL(); + glDisable(GL_BLEND); + glEnable(GL_SCISSOR_TEST); + checkGLcall("glEnable GL_SCISSOR_TEST"); + LEAVE_GL(); + + context->last_was_blit = FALSE; + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); + Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); +} + +/* Context activation is done by the caller. */ +void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) { const struct StateEntry *state_table = device->StateTable; unsigned int i; - switch (usage) { - case CTXUSAGE_CLEAR: - case CTXUSAGE_DRAWPRIM: - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - ENTER_GL(); - context_apply_fbo_state(context); - LEAVE_GL(); - } - if (context->draw_buffer_dirty) { - context_apply_draw_buffer(context, FALSE); - context->draw_buffer_dirty = FALSE; - } - break; + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, device->depth_stencil); - case CTXUSAGE_BLIT: - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (context->render_offscreen) - { - FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n"); - surface_internal_preload(context->current_rt, SRGB_RGB); - - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); - LEAVE_GL(); - } else { - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - LEAVE_GL(); - } - context->draw_buffer_dirty = TRUE; - } - if (context->draw_buffer_dirty) { - context_apply_draw_buffer(context, TRUE); - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) { - context->draw_buffer_dirty = FALSE; - } - } - break; - - default: - break; + if (!context->render_offscreen) + { + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL); + LEAVE_GL(); + } + else + { + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil); + LEAVE_GL(); + } } - switch(usage) { - case CTXUSAGE_RESOURCELOAD: - /* This does not require any special states to be set up */ - break; + if (context->draw_buffer_dirty) + { + context_apply_draw_buffer(context, FALSE); + context->draw_buffer_dirty = FALSE; + } - case CTXUSAGE_CLEAR: - if(context->last_was_blit) { - device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); - } + if (context->last_was_blit) + { + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + } - /* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling - * blending when clearing improves the clearing performance incredibly. - */ - ENTER_GL(); - glDisable(GL_BLEND); - LEAVE_GL(); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table); + IWineD3DDeviceImpl_FindTexUnitMap(device); + device_preload_textures(device); + if (isStateDirty(context, STATE_VDECL)) + device_update_stream_info(device, context->gl_info); - ENTER_GL(); - glEnable(GL_SCISSOR_TEST); - checkGLcall("glEnable GL_SCISSOR_TEST"); - LEAVE_GL(); - context->last_was_blit = FALSE; - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); - Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); - break; + ENTER_GL(); + for (i = 0; i < context->numDirtyEntries; ++i) + { + DWORD rep = context->dirtyArray[i]; + DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); + BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); + context->isStateDirty[idx] &= ~(1 << shift); + state_table[rep].apply(rep, device->stateBlock, context); + } + LEAVE_GL(); + context->numDirtyEntries = 0; /* This makes the whole list clean */ + context->last_was_blit = FALSE; +} - case CTXUSAGE_DRAWPRIM: - /* This needs all dirty states applied */ - if(context->last_was_blit) { - device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); - } +static void context_setup_target(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *target) +{ + BOOL old_render_offscreen = context->render_offscreen, render_offscreen; + const struct StateEntry *StateTable = device->StateTable; - IWineD3DDeviceImpl_FindTexUnitMap(device); - device_preload_textures(device); - if (isStateDirty(context, STATE_VDECL)) - device_update_stream_info(device, context->gl_info); + if (!target) return; + else if (context->current_rt == target) return; + render_offscreen = surface_is_offscreen(target); - ENTER_GL(); - for (i = 0; i < context->numDirtyEntries; ++i) + context_set_render_offscreen(context, StateTable, render_offscreen); + + /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers + * the alpha blend state changes with different render target formats. */ + if (!context->current_rt) + { + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); + } + else + { + const struct wined3d_format_desc *old = context->current_rt->resource.format_desc; + const struct wined3d_format_desc *new = target->resource.format_desc; + + if (old->format != new->format) + { + /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ + if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask) + || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) { - DWORD rep = context->dirtyArray[i]; - DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] &= ~(1 << shift); - state_table[rep].apply(rep, device->stateBlock, context); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); } - LEAVE_GL(); - context->numDirtyEntries = 0; /* This makes the whole list clean */ - context->last_was_blit = FALSE; - break; + } - case CTXUSAGE_BLIT: - SetupForBlit(device, context); - break; + /* When switching away from an offscreen render target, and we're not + * using FBOs, we have to read the drawable into the texture. This is + * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There + * are some things that need care though. PreLoad needs a GL context, + * and FindContext is called before the context is activated. It also + * has to be called with the old rendertarget active, otherwise a + * wrong drawable is read. */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && old_render_offscreen && context->current_rt != target) + { + BOOL oldInDraw = device->isInDraw; - default: - FIXME("Unexpected context usage requested\n"); + /* surface_internal_preload() requires a context to load the + * texture, so it will call context_acquire(). Set isInDraw to true + * to signal surface_internal_preload() that it has a context. */ + + /* FIXME: This is just broken. There's no guarantee whatsoever + * that the currently active context, if any, is appropriate for + * reading back the render target. We should probably call + * context_set_current(context) here and then rely on + * context_acquire() doing the right thing. */ + device->isInDraw = TRUE; + + /* Read the back buffer of the old drawable into the destination texture. */ + if (context->current_rt->texture_name_srgb) + { + surface_internal_preload(context->current_rt, SRGB_BOTH); + } + else + { + surface_internal_preload(context->current_rt, SRGB_RGB); + } + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)context->current_rt, SFLAG_INDRAWABLE, FALSE); + + device->isInDraw = oldInDraw; + } } + + context->draw_buffer_dirty = TRUE; + context->current_rt = target; } /***************************************************************************** @@ -2256,14 +2211,15 @@ static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceI * usage: Prepares the context for blitting, drawing or other actions * *****************************************************************************/ -struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurface *target, enum ContextUsage usage) +struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *target) { struct wined3d_context *current_context = context_get_current(); struct wined3d_context *context; - TRACE("device %p, target %p, usage %#x.\n", device, target, usage); + TRACE("device %p, target %p.\n", device, target); context = FindContext(device, target); + context_setup_target(device, context, target); context_enter(context); if (!context->valid) return context; @@ -2295,7 +2251,5 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurf } } - context_apply_state(context, device, usage); - return context; } diff --git a/reactos/dll/directx/wine/wined3d/cubetexture.c b/reactos/dll/directx/wine/wined3d/cubetexture.c index c5fa6ba280f..12acee26573 100644 --- a/reactos/dll/directx/wine/wined3d/cubetexture.c +++ b/reactos/dll/directx/wine/wined3d/cubetexture.c @@ -31,11 +31,12 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 { /* Override the IWineD3DResource Preload method. */ IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context = NULL; - unsigned int i, j; BOOL srgb_mode; BOOL *dirty; + UINT i; switch (srgb) { @@ -66,25 +67,24 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 { /* No danger of recursive calls, context_acquire() sets isInDraw to true * when loading offscreen render targets into their texture. */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + if (palette9_changed(surface)) { - if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[j][i])) - { - TRACE("Reloading surface because the d3d8/9 palette was changed.\n"); - /* TODO: This is not necessarily needed with hw palettized texture support. */ - IWineD3DSurface_LoadLocation(This->surfaces[j][i], SFLAG_INSYSMEM, NULL); - /* Make sure the texture is reloaded because of the palette change, - * this kills performance though :( */ - IWineD3DSurface_ModifyLocation(This->surfaces[j][i], SFLAG_INTEXTURE, FALSE); - } + TRACE("Reloading surface %p because the d3d8/9 palette was changed.\n", surface); + /* TODO: This is not necessarily needed with hw palettized texture support. */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); + /* Make sure the texture is reloaded because of the palette change, + * this kills performance though :( */ + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } } @@ -93,12 +93,9 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 * since the last load then reload the surfaces. */ if (*dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) - { - IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode); - } + IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode); } } else @@ -114,26 +111,24 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This) { - unsigned int i, j; + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; TRACE("(%p) : Cleaning up.\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = 0; j < 6; ++j) - { - IWineD3DSurface *surface = This->surfaces[j][i]; + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; - if (surface) - { - /* Clean out the texture name we gave to the surface so that the - * surface doesn't try and release it. */ - surface_set_texture_name(surface, 0, TRUE); - surface_set_texture_name(surface, 0, FALSE); - surface_set_texture_target(surface, 0); - IWineD3DSurface_SetContainer(surface, NULL); - IWineD3DSurface_Release(surface); - } + if (surface) + { + /* Clean out the texture name we gave to the surface so that the + * surface doesn't try and release it. */ + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); + surface_set_texture_target(surface, 0); + IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL); + IWineD3DSurface_Release((IWineD3DSurface *)surface); } } basetexture_cleanup((IWineD3DBaseTexture *)This); @@ -207,21 +202,25 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY); } -static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) { - unsigned int i, j; +static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) +{ IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - TRACE("(%p)\n", This); + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; + + TRACE("iface %p.\n", iface); /* Unload all the surfaces and reset the texture name. If UnLoad was called on the * surface before, this one will be a NOP and vice versa. Unloading an unloaded - * surface is fine - */ - for (i = 0; i < This->baseTexture.levels; i++) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) { - IWineD3DSurface_UnLoad(This->surfaces[j][i]); - surface_set_texture_name(This->surfaces[j][i], 0, TRUE); - surface_set_texture_name(This->surfaces[j][i], 0, FALSE); - } + * surface is fine. */ + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + IWineD3DSurface_UnLoad((IWineD3DSurface *)surface); + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -281,16 +280,19 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *i TRACE("(%p) : relay to BaseTexture\n", This); hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc); - if (set_gl_texture_desc && SUCCEEDED(hr)) { - UINT i, j; - for (i = 0; i < This->baseTexture.levels; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) { - if(This->baseTexture.is_srgb) { - surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_srgb.name, TRUE); - } else { - surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_rgb.name, FALSE); - } - } + if (set_gl_texture_desc && SUCCEEDED(hr)) + { + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + if (This->baseTexture.is_srgb) + surface_set_texture_name(surface, This->baseTexture.texture_srgb.name, TRUE); + else + surface_set_texture_name(surface, This->baseTexture.texture_rgb.name, FALSE); } } @@ -314,82 +316,102 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface) /* ******************************************* IWineD3DCubeTexture IWineD3DCubeTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) { - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, + UINT level, WINED3DSURFACE_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) level (%d)\n", This, Level); - return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc); + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + + return IWineD3DSurface_GetDesc(surface, desc); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, IWineD3DSurface** ppCubeMapSurface) { - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level, IWineD3DSurface **surface) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *s; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - *ppCubeMapSurface = This->surfaces[FaceType][Level]; - IWineD3DSurface_AddRef(*ppCubeMapSurface); + TRACE("iface %p, face %u, level %u, surface %p.\n", + iface, face, level, surface); - hr = WINED3D_OK; - } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) returning surface@%p\n", This, FaceType, Level, This->surfaces[FaceType][Level]); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); + if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + IWineD3DSurface_AddRef(s); + *surface = s; + + TRACE("Returning surface %p.\n", *surface); + + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - hr = IWineD3DSurface_LockRect(This->surfaces[FaceType][Level], pLockedRect, pRect, Flags); + TRACE("iface %p, face %u, level %u, locked_rect %p, rect %s, flags %#x.\n", + iface, face, level, locked_rect, wine_dbgstr_rect(rect), flags); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) returning memory@%p success(%u)\n", This, FaceType, Level, pLockedRect->pBits, hr); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); - } - - return hr; + return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - hr = IWineD3DSurface_UnlockRect(This->surfaces[FaceType][Level]); + TRACE("iface %p, face %u, level %u.\n", + iface, face, level); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) success(%u)\n", This, FaceType, Level, hr); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); - } - return hr; + return IWineD3DSurface_UnlockRect(surface); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType); - if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect); - hr = WINED3D_OK; - } else { - WARN("(%p) overflow FaceType(%d)\n", This, FaceType); +static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, const RECT *dirty_rect) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurfaceImpl *surface; + + TRACE("iface %p, face %u, dirty_rect %s.\n", + iface, face, wine_dbgstr_rect(dirty_rect)); + + if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, face, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + surface_add_dirty_rect(surface, dirty_rect); + + return WINED3D_OK; } static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = @@ -433,7 +455,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT pow2_edge_length; unsigned int i, j; UINT tmp_w; @@ -478,8 +500,8 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN texture->lpVtbl = &IWineD3DCubeTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_CUBETEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 6, levels, + WINED3DRTYPE_CUBETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x\n", hr); @@ -510,7 +532,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN /* Generate all the surfaces. */ tmp_w = edge_length; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { /* Create the 6 faces. */ for (j = 0; j < 6; ++j) @@ -524,20 +546,22 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, }; + UINT idx = j * texture->baseTexture.level_count + i; + IWineD3DSurface *surface; hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_w, - format, usage, pool, i /* Level */, j, &texture->surfaces[j][i]); + format, usage, pool, i /* Level */, j, &surface); if (FAILED(hr)) { FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr); - texture->surfaces[j][i] = NULL; cubetexture_cleanup(texture); return hr; } - IWineD3DSurface_SetContainer(texture->surfaces[j][i], (IWineD3DBase *)texture); - TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[j][i]); - surface_set_texture_target(texture->surfaces[j][i], cube_targets[j]); + IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture); + surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]); + texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface; + TRACE("Created surface level %u @ %p.\n", i, surface); } tmp_w = max(1, tmp_w >> 1); } diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index 6682aa4635e..7eb9153fca9 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -34,7 +34,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->adapter->gl_info /* Define the default light parameters as specified by MSDN */ const WINED3DLIGHT WINED3D_default_light = { @@ -213,7 +212,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, else { TRACE("Stream %u isn't UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]); - data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], 0, &buffer_object); + data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], + &This->adapter->gl_info, &buffer_object); /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory @@ -224,7 +224,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); buffer_object = 0; - data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]); + data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot], + &This->adapter->gl_info); if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { FIXME("System memory vertex data load offset is negative!\n"); @@ -305,6 +306,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, } } + This->num_buffer_queries = 0; if (!This->stateBlock->streamIsUP) { WORD map = stream_info->use_map; @@ -314,6 +316,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { struct wined3d_stream_info_element *element; struct wined3d_buffer *buffer; + struct wined3d_event_query *query; if (!(map & 1)) continue; @@ -325,7 +328,13 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, if (buffer->buffer_object != element->buffer_object) { element->buffer_object = 0; - element->data = buffer_get_sysmem(buffer) + (ptrdiff_t)element->data; + element->data = buffer_get_sysmem(buffer, &This->adapter->gl_info) + (ptrdiff_t)element->data; + } + + query = ((struct wined3d_buffer *) buffer)->query; + if(query) + { + This->buffer_queries[This->num_buffer_queries++] = query; } } } @@ -334,7 +343,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, static void stream_info_element_from_strided(const struct wined3d_gl_info *gl_info, const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(strided->format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(strided->format, gl_info); e->format_desc = format_desc; e->stride = strided->dwStride; e->data = strided->lpData; @@ -494,6 +503,95 @@ void device_preload_textures(IWineD3DDeviceImpl *device) } } +BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) +{ + struct wined3d_context **new_array; + + TRACE("Adding context %p.\n", context); + + if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, sizeof(*new_array) * (device->numContexts + 1)); + + if (!new_array) + { + ERR("Failed to grow the context array.\n"); + return FALSE; + } + + new_array[device->numContexts++] = context; + device->contexts = new_array; + return TRUE; +} + +void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) +{ + struct wined3d_context **new_array; + BOOL found = FALSE; + UINT i; + + TRACE("Removing context %p.\n", context); + + for (i = 0; i < device->numContexts; ++i) + { + if (device->contexts[i] == context) + { + found = TRUE; + break; + } + } + + if (!found) + { + ERR("Context %p doesn't exist in context array.\n", context); + return; + } + + if (!--device->numContexts) + { + HeapFree(GetProcessHeap(), 0, device->contexts); + device->contexts = NULL; + return; + } + + memmove(&device->contexts[i], &device->contexts[i + 1], (device->numContexts - i) * sizeof(*device->contexts)); + new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->numContexts * sizeof(*device->contexts)); + if (!new_array) + { + ERR("Failed to shrink context array. Oh well.\n"); + return; + } + + device->contexts = new_array; +} + +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) +{ + IWineD3DStateBlockImpl *stateblock = device->stateBlock; + WINED3DVIEWPORT *vp = &stateblock->viewport; + + SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height); + + if (stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) + { + IntersectRect(rect, rect, &stateblock->scissorRect); + } +} + +void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) +{ + if (device->onscreen_depth_stencil) + { + surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_DS_OFFSCREEN); + surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN, + device->onscreen_depth_stencil->ds_current_size.cx, + device->onscreen_depth_stencil->ds_current_size.cy); + IWineD3DSurface_Release((IWineD3DSurface *)device->onscreen_depth_stencil); + } + device->onscreen_depth_stencil = depth_stencil; + IWineD3DSurface_AddRef((IWineD3DSurface *)device->onscreen_depth_stencil); +} + /********************************************************** * IUnknown parts follows **********************************************************/ @@ -540,9 +638,17 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { /* NOTE: You must release the parent if the object was created via a callback ** ***************************/ - if (!list_empty(&This->resources)) { + if (!list_empty(&This->resources)) + { + IWineD3DResourceImpl *resource; FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This); - dumpResources(&This->resources); + + LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) + { + WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource); + FIXME("Leftover resource %p with type %s (%#x).\n", + resource, debug_d3dresourcetype(type), type); + } } if(This->contexts) ERR("Context array not freed!\n"); @@ -760,6 +866,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice * { struct wined3d_rendertarget_view *object; + TRACE("iface %p, resource %p, parent %p, rendertarget_view %p.\n", + iface, resource, parent, rendertarget_view); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { @@ -767,12 +876,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice * return E_OUTOFMEMORY; } - object->vtbl = &wined3d_rendertarget_view_vtbl; - object->refcount = 1; - IWineD3DResource_AddRef(resource); - object->resource = resource; - object->parent = parent; + wined3d_rendertarget_view_init(object, resource, parent); + TRACE("Created render target view %p.\n", object); *rendertarget_view = (IWineD3DRendertargetView *)object; return WINED3D_OK; @@ -1030,11 +1136,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice return WINED3D_OK; } -static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */ - DWORD fvf, WINED3DVERTEXELEMENT** ppVertexElements) { +struct wined3d_fvf_convert_state +{ + const struct wined3d_gl_info *gl_info; + WINED3DVERTEXELEMENT *elements; + UINT offset; + UINT idx; +}; - unsigned int idx, idx2; - unsigned int offset; +static void append_decl_element(struct wined3d_fvf_convert_state *state, + WINED3DFORMAT format, WINED3DDECLUSAGE usage, UINT usage_idx) +{ + WINED3DVERTEXELEMENT *elements = state->elements; + const struct wined3d_format_desc *format_desc; + UINT offset = state->offset; + UINT idx = state->idx; + + elements[idx].format = format; + elements[idx].input_slot = 0; + elements[idx].offset = offset; + elements[idx].output_slot = 0; + elements[idx].method = WINED3DDECLMETHOD_DEFAULT; + elements[idx].usage = usage; + elements[idx].usage_idx = usage_idx; + + format_desc = getFormatDescEntry(format, state->gl_info); + state->offset += format_desc->component_count * format_desc->component_size; + ++state->idx; +} + +static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */ + DWORD fvf, WINED3DVERTEXELEMENT **ppVertexElements) +{ + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; BOOL has_pos = (fvf & WINED3DFVF_POSITION_MASK) != 0; BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW; BOOL has_blend_idx = has_blend && @@ -1048,9 +1182,9 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; DWORD texcoords = (fvf & 0xFFFF0000) >> 16; - WINED3DVERTEXELEMENT *elements = NULL; - + struct wined3d_fvf_convert_state state; unsigned int size; + unsigned int idx; DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1); if (has_blend_idx) num_blends--; @@ -1058,112 +1192,84 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal + has_psize + has_diffuse + has_specular + num_textures; - /* convert the declaration */ - elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WINED3DVERTEXELEMENT)); - if (!elements) return ~0U; + state.gl_info = gl_info; + state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements)); + if (!state.elements) return ~0U; + state.offset = 0; + state.idx = 0; - idx = 0; - if (has_pos) { - if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) { - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITIONT; - } - else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) { - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITION; - } - else { - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITION; - } - elements[idx].usage_idx = 0; - idx++; + if (has_pos) + { + if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITIONT, 0); + else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITION, 0); + else + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_POSITION, 0); } - if (has_blend && (num_blends > 0)) { - if (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)) - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - else { - switch(num_blends) { - case 1: elements[idx].format = WINED3DFMT_R32_FLOAT; break; - case 2: elements[idx].format = WINED3DFMT_R32G32_FLOAT; break; - case 3: elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; break; - case 4: elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; break; + + if (has_blend && (num_blends > 0)) + { + if ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)) + append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + else + { + switch (num_blends) + { + case 1: + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 2: + append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 3: + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 4: + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; default: ERR("Unexpected amount of blend values: %u\n", num_blends); } } - elements[idx].usage = WINED3DDECLUSAGE_BLENDWEIGHT; - elements[idx].usage_idx = 0; - idx++; } - if (has_blend_idx) { - if (fvf & WINED3DFVF_LASTBETA_UBYTE4 || - (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))) - elements[idx].format = WINED3DFMT_R8G8B8A8_UINT; + + if (has_blend_idx) + { + if ((fvf & WINED3DFVF_LASTBETA_UBYTE4) + || ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))) + append_decl_element(&state, WINED3DFMT_R8G8B8A8_UINT, WINED3DDECLUSAGE_BLENDINDICES, 0); else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR) - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; + append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDINDICES, 0); else - elements[idx].format = WINED3DFMT_R32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_BLENDINDICES; - elements[idx].usage_idx = 0; - idx++; + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDINDICES, 0); } - if (has_normal) { - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_NORMAL; - elements[idx].usage_idx = 0; - idx++; - } - if (has_psize) { - elements[idx].format = WINED3DFMT_R32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_PSIZE; - elements[idx].usage_idx = 0; - idx++; - } - if (has_diffuse) { - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - elements[idx].usage = WINED3DDECLUSAGE_COLOR; - elements[idx].usage_idx = 0; - idx++; - } - if (has_specular) { - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - elements[idx].usage = WINED3DDECLUSAGE_COLOR; - elements[idx].usage_idx = 1; - idx++; - } - for (idx2 = 0; idx2 < num_textures; idx2++) { - unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03; - switch (numcoords) { + + if (has_normal) append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_NORMAL, 0); + if (has_psize) append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_PSIZE, 0); + if (has_diffuse) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 0); + if (has_specular) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 1); + + for (idx = 0; idx < num_textures; ++idx) + { + switch ((texcoords >> (idx * 2)) & 0x03) + { case WINED3DFVF_TEXTUREFORMAT1: - elements[idx].format = WINED3DFMT_R32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT2: - elements[idx].format = WINED3DFMT_R32G32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT3: - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT4: - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; } - elements[idx].usage = WINED3DDECLUSAGE_TEXCOORD; - elements[idx].usage_idx = idx2; - idx++; } - /* Now compute offsets, and initialize the rest of the fields */ - for (idx = 0, offset = 0; idx < size; ++idx) - { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(elements[idx].format, &This->adapter->gl_info); - elements[idx].input_slot = 0; - elements[idx].method = WINED3DDECLMETHOD_DEFAULT; - elements[idx].offset = offset; - offset += format_desc->component_count * format_desc->component_size; - } - - *ppVertexElements = elements; + *ppVertexElements = state.elements; return size; } @@ -1282,35 +1388,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DW IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DPaletteImpl *object; HRESULT hr; - TRACE("(%p)->(%x, %p, %p, %p)\n", This, Flags, PalEnt, Palette, Parent); - /* Create the new object */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DPaletteImpl)); - if(!object) { - ERR("Out of memory when allocating memory for a IWineD3DPalette implementation\n"); + TRACE("iface %p, flags %#x, entries %p, palette %p, parent %p.\n", + iface, Flags, PalEnt, Palette, Parent); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate palette memory.\n"); return E_OUTOFMEMORY; } - object->lpVtbl = &IWineD3DPalette_Vtbl; - object->ref = 1; - object->Flags = Flags; - object->parent = Parent; - object->device = This; - object->palNumEntries = IWineD3DPaletteImpl_Size(Flags); - object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion)); - - if(!object->hpal) { - HeapFree( GetProcessHeap(), 0, object); - return E_OUTOFMEMORY; - } - - hr = IWineD3DPalette_SetEntries((IWineD3DPalette *) object, 0, 0, IWineD3DPaletteImpl_Size(Flags), PalEnt); - if(FAILED(hr)) { - IWineD3DPalette_Release((IWineD3DPalette *) object); + hr = wined3d_palette_init(object, This, Flags, PalEnt, Parent); + if (FAILED(hr)) + { + WARN("Failed to initialize palette, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); return hr; } - *Palette = (IWineD3DPalette *) object; + TRACE("Created palette %p.\n", object); + *Palette = (IWineD3DPalette *)object; return WINED3D_OK; } @@ -1429,6 +1527,30 @@ static void destroy_dummy_textures(IWineD3DDeviceImpl *device, const struct wine memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName)); } +static HRESULT WINAPI IWineD3DDeviceImpl_AcquireFocusWindow(IWineD3DDevice *iface, HWND window) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface; + + if (!wined3d_register_window(window, device)) + { + ERR("Failed to register window %p.\n", window); + return E_FAIL; + } + + device->focus_window = window; + SetForegroundWindow(window); + + return WINED3D_OK; +} + +static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow(IWineD3DDevice *iface) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface; + + if (device->focus_window) wined3d_unregister_window(device->focus_window); + device->focus_window = NULL; +} + static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) { @@ -1445,17 +1567,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, if(This->d3d_initialized) return WINED3DERR_INVALIDCALL; if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL; - if (!pPresentationParameters->Windowed) - { - This->focus_window = This->createParms.hFocusWindow; - if (!This->focus_window) This->focus_window = pPresentationParameters->hDeviceWindow; - if (!wined3d_register_window(This->focus_window, This)) - { - ERR("Failed to register window %p.\n", This->focus_window); - return E_FAIL; - } - } - TRACE("(%p) : Creating stateblock\n", This); /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */ hr = IWineD3DDevice_CreateStateBlock(iface, @@ -1471,7 +1582,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock); This->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IWineD3DSurface *) * gl_info->limits.buffers); + sizeof(*This->render_targets) * gl_info->limits.buffers); This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * gl_info->limits.buffers); @@ -1509,8 +1620,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, } } - if (This->focus_window) SetFocus(This->focus_window); - /* Setup the implicit swapchain. This also initializes a context. */ TRACE("Creating implicit swapchain\n"); hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent, @@ -1529,21 +1638,22 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, } This->swapchains[0] = (IWineD3DSwapChain *) swapchain; - if(swapchain->backBuffer && swapchain->backBuffer[0]) { - TRACE("Setting rendertarget to %p\n", swapchain->backBuffer); - This->render_targets[0] = swapchain->backBuffer[0]; + if (swapchain->back_buffers && swapchain->back_buffers[0]) + { + TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers); + This->render_targets[0] = swapchain->back_buffers[0]; } - else { - TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer); - This->render_targets[0] = swapchain->frontBuffer; + else + { + TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer); + This->render_targets[0] = swapchain->front_buffer; } - IWineD3DSurface_AddRef(This->render_targets[0]); + IWineD3DSurface_AddRef((IWineD3DSurface *)This->render_targets[0]); /* Depth Stencil support */ - This->stencilBufferTarget = This->auto_depth_stencil_buffer; - if (NULL != This->stencilBufferTarget) { - IWineD3DSurface_AddRef(This->stencilBufferTarget); - } + This->depth_stencil = This->auto_depth_stencil; + if (This->depth_stencil) + IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); hr = This->shader_backend->shader_alloc_private(iface); if(FAILED(hr)) { @@ -1566,7 +1676,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, /* Setup all the devices defaults */ IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock); - context = context_acquire(This, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, swapchain->front_buffer); create_dummy_textures(This); @@ -1583,10 +1693,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, This->offscreenBuffer = GL_COLOR_ATTACHMENT0; break; - case ORM_PBUFFER: - This->offscreenBuffer = GL_BACK; - break; - case ORM_BACKBUFFER: { if (context_get_current()->aux_buffers > 0) @@ -1645,7 +1751,6 @@ err_out: if (This->shader_priv) { This->shader_backend->shader_free_private(iface); } - if (This->focus_window) wined3d_unregister_window(This->focus_window); return hr; } @@ -1702,7 +1807,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, /* I don't think that the interface guarantees that the device is destroyed from the same thread * it was created. Thus make sure a context is active for the glDelete* calls */ - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); gl_info = context->gl_info; if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface); @@ -1720,9 +1825,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, } } - /* Delete the pbuffer context if there is any */ - if(This->pbufferContext) context_destroy(This, This->pbufferContext); - /* Delete the mouse cursor texture */ if(This->cursorTexture) { ENTER_GL(); @@ -1781,26 +1883,33 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, This->shader_backend->shader_free_private(iface); /* Release the buffers (with sanity checks)*/ - TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); - if(This->stencilBufferTarget != NULL && (IWineD3DSurface_Release(This->stencilBufferTarget) >0)){ - if(This->auto_depth_stencil_buffer != This->stencilBufferTarget) - FIXME("(%p) Something's still holding the stencilBufferTarget\n",This); + if (This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; } - This->stencilBufferTarget = NULL; + + TRACE("Releasing the depth stencil buffer at %p\n", This->depth_stencil); + if (This->depth_stencil && IWineD3DSurface_Release((IWineD3DSurface *)This->depth_stencil)) + { + if (This->auto_depth_stencil != This->depth_stencil) + FIXME("(%p) Something is still holding the depth/stencil buffer.\n",This); + } + This->depth_stencil = NULL; TRACE("Releasing the render target at %p\n", This->render_targets[0]); - if(IWineD3DSurface_Release(This->render_targets[0]) >0){ - /* This check is a bit silly, it should be in swapchain_release FIXME("(%p) Something's still holding the renderTarget\n",This); */ - } + IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[0]); + TRACE("Setting rendertarget to NULL\n"); This->render_targets[0] = NULL; - if (This->auto_depth_stencil_buffer) { - if (IWineD3DSurface_Release(This->auto_depth_stencil_buffer) > 0) + if (This->auto_depth_stencil) + { + if (IWineD3DSurface_Release((IWineD3DSurface *)This->auto_depth_stencil)) { FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This); } - This->auto_depth_stencil_buffer = NULL; + This->auto_depth_stencil = NULL; } context_release(context); @@ -1828,8 +1937,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, This->d3d_initialized = FALSE; - if (This->focus_window) wined3d_unregister_window(This->focus_window); - return WINED3D_OK; } @@ -1867,8 +1974,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, U const WINED3DDISPLAYMODE* pMode) { DEVMODEW devmode; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + const struct wined3d_format_desc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info); LONG ret; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info); RECT clip_rc; TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format)); @@ -2982,7 +3089,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI( TRACE("(iface %p, dstData %p, start %d, count %d)\n", iface, dstData, start, count); - if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0) + if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= 0) return WINED3DERR_INVALIDCALL; memcpy(dstData, &This->stateBlock->vertexShaderConstantI[start * 4], cnt * sizeof(int) * 4); @@ -3469,9 +3576,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn /* We might access VBOs from this code, so hold the lock */ ENTER_GL(); - if (dest->resource.allocatedMemory == NULL) { - buffer_get_sysmem(dest); - } + if (!dest->resource.allocatedMemory) + buffer_get_sysmem(dest, gl_info); /* Get a pointer into the destination vbo(create one if none exists) and * write correct opengl data into it. It's cheap and allows us to run drawStridedFast @@ -3518,7 +3624,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn FIXME("Clipping is broken and disabled for now\n"); } } else doClip = FALSE; - dest_ptr = ((char *) buffer_get_sysmem(dest)) + dwDestIndex * get_flexible_vertex_size(DestFVF); + dest_ptr = ((char *)buffer_get_sysmem(dest, gl_info)) + dwDestIndex * get_flexible_vertex_size(DestFVF); IWineD3DDevice_GetTransform( (IWineD3DDevice *) This, WINED3DTS_VIEW, @@ -3794,6 +3900,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct wined3d_stream_info stream_info; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP; HRESULT hr; @@ -3805,7 +3912,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, } /* Need any context to write to the vbo. */ - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); + gl_info = context->gl_info; /* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP * control the streamIsUP flag, thus restore it afterwards. @@ -3832,7 +3940,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); ENTER_GL(); GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); vb->buffer_object = 0; @@ -4218,7 +4326,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) return WINED3DERR_INVALIDCALL; } - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ wglFlush(); /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever @@ -4250,18 +4358,81 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface, return WINED3D_OK; } +static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, const RECT *clear_rect) +{ + /* partial draw rect */ + if (draw_rect->left || draw_rect->top + || draw_rect->right < target->currentDesc.Width + || draw_rect->bottom < target->currentDesc.Height) + return FALSE; + + /* partial clear rect */ + if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0 + || clear_rect->right < target->currentDesc.Width + || clear_rect->bottom < target->currentDesc.Height)) + return FALSE; + + return TRUE; +} + +static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context, + DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect) +{ + RECT current_rect, r; + + if (ds->Flags & location) + SetRect(¤t_rect, 0, 0, + ds->ds_current_size.cx, + ds->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + IntersectRect(&r, draw_rect, ¤t_rect); + if (EqualRect(&r, draw_rect)) + { + /* current_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); + return; + } + + if (EqualRect(&r, ¤t_rect)) + { + /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ + + if (!clear_rect) + { + /* Full clear, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + + IntersectRect(&r, draw_rect, clear_rect); + if (EqualRect(&r, draw_rect)) + { + /* clear_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + } + + /* Full load. */ + surface_load_ds_location(ds, context, location); + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +} + /* Not called from the VTable (internal subroutine) */ -HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, - CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color, - float Z, DWORD Stencil) { +HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, + const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) +{ + const RECT *clear_rect = (Count > 0 && pRects) ? (const RECT *)pRects : NULL; + IWineD3DSurfaceImpl *depth_stencil = This->depth_stencil; GLbitfield glMask = 0; unsigned int i; - WINED3DRECT curRect; - RECT vp_rect; - const WINED3DVIEWPORT *vp = &This->stateBlock->viewport; UINT drawable_width, drawable_height; - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget; struct wined3d_context *context; + RECT draw_rect; + + device_get_draw_rect(This, &draw_rect); /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true @@ -4272,132 +4443,119 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa * the drawable up to date. We have to check all settings that limit the clear area though. Do not bother * checking all this if the dest surface is in the drawable anyway. */ - if((Flags & WINED3DCLEAR_TARGET) && !(target->Flags & SFLAG_INDRAWABLE)) { - while(1) { - if(vp->X != 0 || vp->Y != 0 || - vp->Width < target->currentDesc.Width || vp->Height < target->currentDesc.Height) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && ( - This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 || - This->stateBlock->scissorRect.right < target->currentDesc.Width || - This->stateBlock->scissorRect.bottom < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(Count > 0 && pRects && ( - pRects[0].x1 > 0 || pRects[0].y1 > 0 || - pRects[0].x2 < target->currentDesc.Width || - pRects[0].y2 < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - break; - } + if (Flags & WINED3DCLEAR_TARGET && !(target->Flags & SFLAG_INDRAWABLE)) + { + if (!is_full_clear(target, &draw_rect, clear_rect)) + IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL); } - context = context_acquire(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR); + context = context_acquire(This, target); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping clear.\n"); + return WINED3D_OK; + } + + context_apply_clear_state(context, This, target, depth_stencil); target->get_drawable_size(context, &drawable_width, &drawable_height); ENTER_GL(); /* Only set the values up once, as they are not changing */ - if (Flags & WINED3DCLEAR_STENCIL) { + if (Flags & WINED3DCLEAR_STENCIL) + { + if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE]) + { + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE)); + } + glStencilMask(~0U); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); glClearStencil(Stencil); checkGLcall("glClearStencil"); glMask = glMask | GL_STENCIL_BUFFER_BIT; - glStencilMask(0xFFFFFFFF); } - if (Flags & WINED3DCLEAR_ZBUFFER) { + if (Flags & WINED3DCLEAR_ZBUFFER) + { DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; + + if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil) + device_switch_onscreen_ds(This, context, depth_stencil); + prepare_ds_clear(depth_stencil, context, location, &draw_rect, Count, clear_rect); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)depth_stencil, SFLAG_INDRAWABLE, TRUE); + glDepthMask(GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); glClearDepth(Z); checkGLcall("glClearDepth"); glMask = glMask | GL_DEPTH_BUFFER_BIT; - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); - - if (vp->X != 0 || vp->Y != 0 || - vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } - else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && ( - This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 || - This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width || - This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } - else if (Count > 0 && pRects && ( - pRects[0].x1 > 0 || pRects[0].y1 > 0 || - pRects[0].x2 < depth_stencil->currentDesc.Width || - pRects[0].y2 < depth_stencil->currentDesc.Height)) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } } - if (Flags & WINED3DCLEAR_TARGET) { - TRACE("Clearing screen with glClear to color %x\n", Color); - glClearColor(D3DCOLOR_R(Color), - D3DCOLOR_G(Color), - D3DCOLOR_B(Color), - D3DCOLOR_A(Color)); - checkGLcall("glClearColor"); + if (Flags & WINED3DCLEAR_TARGET) + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); - /* Clear ALL colors! */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); + glClearColor(D3DCOLOR_R(Color), D3DCOLOR_G(Color), D3DCOLOR_B(Color), D3DCOLOR_A(Color)); + checkGLcall("glClearColor"); glMask = glMask | GL_COLOR_BUFFER_BIT; } - vp_rect.left = vp->X; - vp_rect.top = vp->Y; - vp_rect.right = vp->X + vp->Width; - vp_rect.bottom = vp->Y + vp->Height; - if (!(Count > 0 && pRects)) { - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect); - } + if (!clear_rect) + { if (context->render_offscreen) { - glScissor(vp_rect.left, vp_rect.top, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); - } else { - glScissor(vp_rect.left, drawable_height - vp_rect.bottom, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); + glScissor(draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); + } + else + { + glScissor(draw_rect.left, drawable_height - draw_rect.bottom, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); } checkGLcall("glScissor"); glClear(glMask); checkGLcall("glClear"); - } else { - /* Now process each rect in turn */ - for (i = 0; i < Count; i++) { + } + else + { + RECT current_rect; + + /* Now process each rect in turn. */ + for (i = 0; i < Count; ++i) + { /* Note gl uses lower left, width/height */ - IntersectRect((RECT *)&curRect, &vp_rect, (const RECT *)&pRects[i]); - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect((RECT *) &curRect, (RECT *) &curRect, &This->stateBlock->scissorRect); - } - TRACE("(%p) Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This, - pRects[i].x1, pRects[i].y1, pRects[i].x2, pRects[i].y2, - curRect.x1, (target->currentDesc.Height - curRect.y2), - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); + IntersectRect(¤t_rect, &draw_rect, &clear_rect[i]); + + TRACE("clear_rect[%u] %s, current_rect %s.\n", i, + wine_dbgstr_rect(&clear_rect[i]), + wine_dbgstr_rect(¤t_rect)); /* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently. * The rectangle is not cleared, no error is returned, but further rectanlges are - * still cleared if they are valid - */ - if(curRect.x1 > curRect.x2 || curRect.y1 > curRect.y2) { - TRACE("Rectangle with negative dimensions, ignoring\n"); + * still cleared if they are valid. */ + if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom) + { + TRACE("Rectangle with negative dimensions, ignoring.\n"); continue; } if (context->render_offscreen) { - glScissor(curRect.x1, curRect.y1, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); - } else { - glScissor(curRect.x1, drawable_height - curRect.y2, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); + glScissor(current_rect.left, current_rect.top, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); + } + else + { + glScissor(current_rect.left, drawable_height - current_rect.bottom, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); } checkGLcall("glScissor"); @@ -4406,52 +4564,33 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa } } - /* Restore the old values (why..?) */ - if (Flags & WINED3DCLEAR_STENCIL) { - glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]); - } - if (Flags & WINED3DCLEAR_TARGET) { - DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE]; - glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - - /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists, - * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it - */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); - } - if (Flags & WINED3DCLEAR_ZBUFFER) { - /* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */ - DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; - surface_modify_ds_location(This->stencilBufferTarget, location); - } - LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN) + && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target)) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, CONST WINED3DRECT* pRects, - DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) { +static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, + const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)This->render_targets[0]; TRACE("(%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d)\n", This, Count, pRects, Flags, Color, Z, Stencil); - if(Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && This->stencilBufferTarget == NULL) { + if (Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && !This->depth_stencil) + { WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); /* TODO: What about depth stencil buffers without stencil bits? */ return WINED3DERR_INVALIDCALL; } - return IWineD3DDeviceImpl_ClearSurface(This, target, Count, pRects, Flags, Color, Z, Stencil); + return IWineD3DDeviceImpl_ClearSurface(This, This->render_targets[0], Count, pRects, Flags, Color, Z, Stencil); } /***** @@ -5083,71 +5222,58 @@ static float WINAPI IWineD3DDeviceImpl_GetNPatchMode(IWineD3DDevice *iface) return 0.0f; } -static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, IWineD3DSurface *pSourceSurface, CONST RECT* pSourceRect, IWineD3DSurface *pDestinationSurface, CONST POINT* pDestPoint) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - /** TODO: remove casts to IWineD3DSurfaceImpl - * NOTE: move code to surface to accomplish this - ****************************************/ - IWineD3DSurfaceImpl *pSrcSurface = (IWineD3DSurfaceImpl *)pSourceSurface; - IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)pDestinationSurface; - int srcWidth, srcHeight; - unsigned int srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight; - WINED3DFORMAT destFormat, srcFormat; - UINT destSize; - int srcLeft, destLeft, destTop; - WINED3DPOOL srcPool, destPool; - int offset = 0; - int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */ - const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc; - GLenum dummy; - DWORD sampler; - int bpp; - CONVERT_TYPES convert = NO_CONVERSION; +static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, + IWineD3DSurface *src_surface, const RECT *src_rect, + IWineD3DSurface *dst_surface, const POINT *dst_point) +{ + IWineD3DSurfaceImpl *src_impl = (IWineD3DSurfaceImpl *)src_surface; + IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)dst_surface; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + const struct wined3d_format_desc *src_format; + const struct wined3d_format_desc *dst_format; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; + const unsigned char *data; + UINT update_w, update_h; + CONVERT_TYPES convert; + UINT src_w, src_h; + UINT dst_x, dst_y; + DWORD sampler; + struct wined3d_format_desc desc; - WINED3DSURFACE_DESC winedesc; + TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", + iface, src_surface, wine_dbgstr_rect(src_rect), + dst_surface, wine_dbgstr_point(dst_point)); - TRACE("(%p) : Source (%p) Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); - - IWineD3DSurface_GetDesc(pSourceSurface, &winedesc); - srcSurfaceWidth = winedesc.width; - srcSurfaceHeight = winedesc.height; - srcPool = winedesc.pool; - srcFormat = winedesc.format; - - IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc); - destSurfaceWidth = winedesc.width; - destSurfaceHeight = winedesc.height; - destPool = winedesc.pool; - destFormat = winedesc.format; - destSize = winedesc.size; - - if(srcPool != WINED3DPOOL_SYSTEMMEM || destPool != WINED3DPOOL_DEFAULT){ - WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface); + if (src_impl->resource.pool != WINED3DPOOL_SYSTEMMEM || dst_impl->resource.pool != WINED3DPOOL_DEFAULT) + { + WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", + src_surface, dst_surface); return WINED3DERR_INVALIDCALL; } - /* This call loads the opengl surface directly, instead of copying the surface to the - * destination's sysmem copy. If surface conversion is needed, use BltFast instead to - * copy in sysmem and use regular surface loading. - */ - d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE); - if(convert != NO_CONVERSION) { - return IWineD3DSurface_BltFast(pDestinationSurface, - pDestPoint ? pDestPoint->x : 0, - pDestPoint ? pDestPoint->y : 0, - pSourceSurface, pSourceRect, 0); + src_format = src_impl->resource.format_desc; + dst_format = dst_impl->resource.format_desc; + + if (src_format->format != dst_format->format) + { + WARN("Source and destination surfaces should have the same format.\n"); + return WINED3DERR_INVALIDCALL; } - if (destFormat == WINED3DFMT_UNKNOWN) { - TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", This); - IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat); + dst_x = dst_point ? dst_point->x : 0; + dst_y = dst_point ? dst_point->y : 0; - /* Get the update surface description */ - IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc); - } + /* This call loads the OpenGL surface directly, instead of copying the + * surface to the destination's sysmem copy. If surface conversion is + * needed, use BltFast instead to copy in sysmem and use regular surface + * loading. */ + d3dfmt_get_conv(dst_impl, FALSE, TRUE, &desc, &convert); + if (convert != NO_CONVERSION || desc.convert) + return IWineD3DSurface_BltFast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0); - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); + gl_info = context->gl_info; ENTER_GL(); GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB)); @@ -5155,92 +5281,79 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, LEAVE_GL(); /* Make sure the surface is loaded and up to date */ - surface_internal_preload(pDestinationSurface, SRGB_RGB); - IWineD3DSurface_BindTexture(pDestinationSurface, FALSE); + surface_internal_preload(dst_impl, SRGB_RGB); + IWineD3DSurface_BindTexture(dst_surface, FALSE); - src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc; - dst_format_desc = dst_impl->resource.format_desc; + src_w = src_impl->currentDesc.Width; + src_h = src_impl->currentDesc.Height; + update_w = src_rect ? src_rect->right - src_rect->left : src_w; + update_h = src_rect ? src_rect->bottom - src_rect->top : src_h; - /* this needs to be done in lines if the sourceRect != the sourceWidth */ - srcWidth = pSourceRect ? pSourceRect->right - pSourceRect->left : srcSurfaceWidth; - srcHeight = pSourceRect ? pSourceRect->bottom - pSourceRect->top : srcSurfaceHeight; - srcLeft = pSourceRect ? pSourceRect->left : 0; - destLeft = pDestPoint ? pDestPoint->x : 0; - destTop = pDestPoint ? pDestPoint->y : 0; - - - /* This function doesn't support compressed textures - the pitch is just bytesPerPixel * width */ - if(srcWidth != srcSurfaceWidth || srcLeft ){ - rowoffset = srcSurfaceWidth * src_format_desc->byte_count; - offset += srcLeft * src_format_desc->byte_count; - /* TODO: do we ever get 3bpp?, would a shift and an add be quicker than a mul (well maybe a cycle or two) */ - } - /* TODO DXT formats */ - - if(pSourceRect != NULL && pSourceRect->top != 0){ - offset += pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count; - } - TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n", - This, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat, - dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset); - - /* Sanity check */ - if (IWineD3DSurface_GetData(pSourceSurface) == NULL) { - - /* need to lock the surface to get the data */ - FIXME("Surfaces has no allocated memory, but should be an in memory only surface\n"); - } + data = IWineD3DSurface_GetData(src_surface); + if (!data) ERR("Source surface has no allocated memory, but should be a sysmem surface.\n"); ENTER_GL(); - /* TODO: Cube and volume support */ - if(rowoffset != 0){ - /* not a whole row so we have to do it a line at a time */ - int j; + if (dst_format->Flags & WINED3DFMT_FLAG_COMPRESSED) + { + UINT row_length = (update_w / src_format->block_width) * src_format->block_byte_count; + UINT row_count = update_h / src_format->block_height; + UINT src_pitch = IWineD3DSurface_GetPitch(src_surface); - /* hopefully using pointer addition will be quicker than using a point + j * rowoffset */ - const unsigned char* data =((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset; - - for (j = destTop; j < (srcHeight + destTop); ++j) + if (src_rect) { - glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j, - srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data); - data += rowoffset; + data += (src_rect->top / src_format->block_height) * src_pitch; + data += (src_rect->left / src_format->block_width) * src_format->block_byte_count; } - } else { /* Full width, so just write out the whole texture */ - const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset; + TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, " + "format %#x, image_size %#x, data %p.\n", dst_impl->texture_target, dst_impl->texture_level, + dst_x, dst_y, update_w, update_h, dst_format->glFormat, row_count * row_length, data); - if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED) + if (row_length == src_pitch) { - if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth) - { - /* FIXME: The easy way to do this is to lock the destination, and copy the bits across. */ - FIXME("Updating part of a compressed texture is not supported.\n"); - } - if (destFormat != srcFormat) - { - FIXME("Updating mixed format compressed textures is not supported.\n"); - } - else - { - GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level, - dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data)); - } + GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level, + dst_x, dst_y, update_w, update_h, dst_format->glInternal, row_count * row_length, data)); } else { - glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop, - srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data); + UINT row, y; + + /* glCompressedTexSubImage2DARB() ignores pixel store state, so we + * can't use the unpack row length like below. */ + for (row = 0, y = dst_y; row < row_count; ++row) + { + GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level, + dst_x, y, update_w, src_format->block_height, dst_format->glInternal, row_length, data)); + y += src_format->block_height; + data += src_pitch; + } } - } - checkGLcall("glTexSubImage2D"); + checkGLcall("glCompressedTexSubImage2DARB"); + } + else + { + if (src_rect) + { + data += src_rect->top * src_w * src_format->byte_count; + data += src_rect->left * src_format->byte_count; + } + + TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p.\n", + dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y, + update_w, update_h, dst_format->glFormat, dst_format->glType, data); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w); + glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y, + update_w, update_h, dst_format->glFormat, dst_format->glType, data); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + checkGLcall("glTexSubImage2D"); + } LEAVE_GL(); context_release(context); - IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INTEXTURE, TRUE); sampler = This->rev_tex_unit_map[0]; if (sampler != WINED3D_UNMAPPED_STAGE) { @@ -5370,68 +5483,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DeletePatch(IWineD3DDevice *iface, UINT return WINED3DERR_INVALIDCALL; } -static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) { - HRESULT hr; - IWineD3DSwapChain *swapchain; - - hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain); - if (SUCCEEDED(hr)) { - IWineD3DSwapChain_Release((IUnknown *)swapchain); - return swapchain; - } - - return NULL; -} - -static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, +static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface, const WINED3DRECT *rect, const float color[4]) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; struct wined3d_context *context; - if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE); + if (rect) IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, TRUE); - if (!surface_is_offscreen(surface)) + context = context_acquire(This, surface); + context_apply_clear_state(context, This, surface, NULL); + + ENTER_GL(); + + if (rect) { - TRACE("Surface %p is onscreen\n", surface); - - context = context_acquire(This, surface, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - context_set_draw_buffer(context, surface_get_gl_buffer(surface)); + if (surface_is_offscreen(surface)) + glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); + else + glScissor(rect->x1, surface->currentDesc.Height - rect->y2, + rect->x2 - rect->x1, rect->y2 - rect->y1); + checkGLcall("glScissor"); } else { - TRACE("Surface %p is offscreen\n", surface); - - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); - } - - if (rect) { - glEnable(GL_SCISSOR_TEST); - if(surface_is_offscreen(surface)) { - glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); - } else { - glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2, - rect->x2 - rect->x1, rect->y2 - rect->y1); - } - checkGLcall("glScissor"); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SCISSORRECT); - } else { glDisable(GL_SCISSOR_TEST); } - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); - - glDisable(GL_BLEND); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE)); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); glClearColor(color[0], color[1], color[2], color[3]); glClear(GL_COLOR_BUFFER_BIT); @@ -5439,119 +5523,11 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); } -static inline DWORD argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) { - unsigned int r, g, b, a; - DWORD ret; - - if (destfmt == WINED3DFMT_B8G8R8A8_UNORM - || destfmt == WINED3DFMT_B8G8R8X8_UNORM - || destfmt == WINED3DFMT_B8G8R8_UNORM) - return color; - - TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt)); - - a = (color & 0xff000000) >> 24; - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - - switch(destfmt) - { - case WINED3DFMT_B5G6R5_UNORM: - if(r == 0xff && g == 0xff && b == 0xff) return 0xffff; - r = (r * 32) / 256; - g = (g * 64) / 256; - b = (b * 32) / 256; - ret = r << 11; - ret |= g << 5; - ret |= b; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B5G5R5X1_UNORM: - case WINED3DFMT_B5G5R5A1_UNORM: - a = (a * 2) / 256; - r = (r * 32) / 256; - g = (g * 32) / 256; - b = (b * 32) / 256; - ret = a << 15; - ret |= r << 10; - ret |= g << 5; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_A8_UNORM: - TRACE("Returning %08x\n", a); - return a; - - case WINED3DFMT_B4G4R4X4_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - a = (a * 16) / 256; - r = (r * 16) / 256; - g = (g * 16) / 256; - b = (b * 16) / 256; - ret = a << 12; - ret |= r << 8; - ret |= g << 4; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B2G3R3_UNORM: - r = (r * 8) / 256; - g = (g * 8) / 256; - b = (b * 4) / 256; - ret = r << 5; - ret |= g << 2; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_R8G8B8X8_UNORM: - case WINED3DFMT_R8G8B8A8_UNORM: - ret = a << 24; - ret |= b << 16; - ret |= g << 8; - ret |= r << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B10G10R10A2_UNORM: - a = (a * 4) / 256; - r = (r * 1024) / 256; - g = (g * 1024) / 256; - b = (b * 1024) / 256; - ret = a << 30; - ret |= r << 20; - ret |= g << 10; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_R10G10B10A2_UNORM: - a = (a * 4) / 256; - r = (r * 1024) / 256; - g = (g * 1024) / 256; - b = (b * 1024) / 256; - ret = a << 30; - ret |= b << 20; - ret |= g << 10; - ret |= r << 0; - TRACE("Returning %08x\n", ret); - return ret; - - default: - FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt)); - return 0; - } -} - static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD3DSurface *pSurface, const WINED3DRECT *pRect, WINED3DCOLOR color) { @@ -5567,13 +5543,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { const float c[4] = {D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color)}; - color_fill_fbo(iface, pSurface, pRect, c); + color_fill_fbo(iface, surface, pRect, c); return WINED3D_OK; } else { /* Just forward this to the DirectDraw blitting engine */ memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); - BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(color, surface->resource.format_desc->format); return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); } @@ -5583,7 +5559,7 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac IWineD3DRendertargetView *rendertarget_view, const float color[4]) { IWineD3DResource *resource; - IWineD3DSurface *surface; + IWineD3DSurfaceImpl *surface; HRESULT hr; hr = IWineD3DRendertargetView_GetResource(rendertarget_view, &resource); @@ -5600,7 +5576,7 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac return; } - surface = (IWineD3DSurface *)resource; + surface = (IWineD3DSurfaceImpl *)resource; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -5621,8 +5597,9 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac /* Just forward this to the DirectDraw blitting engine */ memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); - BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format); - hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(c, surface->resource.format_desc->format); + hr = IWineD3DSurface_Blt((IWineD3DSurface *)surface, NULL, NULL, NULL, + WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); if (FAILED(hr)) { ERR("Blt failed, hr %#x\n", hr); @@ -5643,7 +5620,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface return WINED3DERR_INVALIDCALL; } - *ppRenderTarget = This->render_targets[RenderTargetIndex]; + *ppRenderTarget = (IWineD3DSurface *)This->render_targets[RenderTargetIndex]; TRACE("(%p) : RenderTarget %d Index returning %p\n", This, RenderTargetIndex, *ppRenderTarget); /* Note inc ref on returned surface */ if(*ppRenderTarget != NULL) @@ -5652,110 +5629,103 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface } static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *iface, - IWineD3DSurface *Front, IWineD3DSurface *Back) + IWineD3DSurface *front, IWineD3DSurface *back) { - IWineD3DSurfaceImpl *FrontImpl = (IWineD3DSurfaceImpl *) Front; - IWineD3DSurfaceImpl *BackImpl = (IWineD3DSurfaceImpl *) Back; - IWineD3DSwapChainImpl *Swapchain; + IWineD3DSurfaceImpl *front_impl = (IWineD3DSurfaceImpl *)front; + IWineD3DSurfaceImpl *back_impl = (IWineD3DSurfaceImpl *)back; + IWineD3DSwapChainImpl *swapchain; HRESULT hr; - TRACE("iface %p, front %p, back %p.\n", iface, Front, Back); + TRACE("iface %p, front %p, back %p.\n", iface, front, back); - hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &Swapchain); - if(hr != WINED3D_OK) { - ERR("Can't get the swapchain\n"); + if (FAILED(hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&swapchain))) + { + ERR("Failed to get the swapchain, hr %#x.\n", hr); return hr; } - /* Make sure to release the swapchain */ - IWineD3DSwapChain_Release((IWineD3DSwapChain *) Swapchain); - - if(FrontImpl && !(FrontImpl->resource.usage & WINED3DUSAGE_RENDERTARGET) ) { - ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n"); - return WINED3DERR_INVALIDCALL; - } - else if(BackImpl && !(BackImpl->resource.usage & WINED3DUSAGE_RENDERTARGET)) { - ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n"); + if (front_impl && !(front_impl->resource.usage & WINED3DUSAGE_RENDERTARGET)) + { + ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); return WINED3DERR_INVALIDCALL; } - if(Swapchain->frontBuffer != Front) { - TRACE("Changing the front buffer from %p to %p\n", Swapchain->frontBuffer, Front); - - if(Swapchain->frontBuffer) + if (back_impl) + { + if (!(back_impl->resource.usage & WINED3DUSAGE_RENDERTARGET)) { - IWineD3DSurface_SetContainer(Swapchain->frontBuffer, NULL); - ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN; + ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); + return WINED3DERR_INVALIDCALL; } - Swapchain->frontBuffer = Front; - if(Swapchain->frontBuffer) { - IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain); - ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; - } - } - - if(Back && !Swapchain->backBuffer) { - /* We need memory for the back buffer array - only one back buffer this way */ - Swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *)); - if(!Swapchain->backBuffer) { - ERR("Out of memory\n"); - return E_OUTOFMEMORY; - } - } - - if(Swapchain->backBuffer[0] != Back) { - TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back); - - /* What to do about the context here in the case of multithreading? Not sure. - * This function is called by IDirect3D7::CreateDevice so in theory its initialization code - */ - WARN("No active context?\n"); - - ENTER_GL(); - if(!Swapchain->backBuffer[0]) { - /* GL was told to draw to the front buffer at creation, - * undo that - */ - glDrawBuffer(GL_BACK); - checkGLcall("glDrawBuffer(GL_BACK)"); - /* Set the backbuffer count to 1 because other code uses it to fing the back buffers */ - Swapchain->presentParms.BackBufferCount = 1; - } else if (!Back) { - /* That makes problems - disable for now */ - /* glDrawBuffer(GL_FRONT); */ - checkGLcall("glDrawBuffer(GL_FRONT)"); - /* We have lost our back buffer, set this to 0 to avoid confusing other code */ - Swapchain->presentParms.BackBufferCount = 0; - } - LEAVE_GL(); - - if(Swapchain->backBuffer[0]) + if (!swapchain->back_buffers) { - IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL); - ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN; + swapchain->back_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->back_buffers)); + if (!swapchain->back_buffers) + { + ERR("Failed to allocate back buffer array memory.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); + return E_OUTOFMEMORY; + } } - Swapchain->backBuffer[0] = Back; - - if(Swapchain->backBuffer[0]) { - IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain); - ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN; - Swapchain->presentParms.BackBufferWidth = BackImpl->currentDesc.Width; - Swapchain->presentParms.BackBufferHeight = BackImpl->currentDesc.Height; - Swapchain->presentParms.BackBufferFormat = BackImpl->resource.format_desc->format; - } else { - HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer); - Swapchain->backBuffer = NULL; - } - } + if (swapchain->front_buffer != front_impl) + { + TRACE("Changing the front buffer from %p to %p.\n", swapchain->front_buffer, front_impl); + + if (swapchain->front_buffer) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, NULL); + swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN; + } + swapchain->front_buffer = front_impl; + + if (front) + { + IWineD3DSurface_SetContainer(front, (IWineD3DBase *)swapchain); + front_impl->Flags |= SFLAG_SWAPCHAIN; + } + } + + if (swapchain->back_buffers[0] != back_impl) + { + TRACE("Changing the back buffer from %p to %p.\n", swapchain->back_buffers[0], back_impl); + + if (swapchain->back_buffers[0]) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[0], NULL); + swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN; + } + swapchain->back_buffers[0] = back_impl; + + if (back) + { + swapchain->presentParms.BackBufferWidth = back_impl->currentDesc.Width; + swapchain->presentParms.BackBufferHeight = back_impl->currentDesc.Height; + swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format; + swapchain->presentParms.BackBufferCount = 1; + + IWineD3DSurface_SetContainer(back, (IWineD3DBase *)swapchain); + back_impl->Flags |= SFLAG_SWAPCHAIN; + } + else + { + swapchain->presentParms.BackBufferCount = 0; + HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); + swapchain->back_buffers = NULL; + } + } + + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppZStencilSurface = This->stencilBufferTarget; + *ppZStencilSurface = (IWineD3DSurface *)This->depth_stencil; TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface); if(*ppZStencilSurface != NULL) { @@ -5767,21 +5737,21 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice } } -void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect, - IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) +void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect_in, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ - IWineD3DSwapChain *src_swapchain, *dst_swapchain; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; GLenum gl_filter; - POINT offset = {0, 0}; + RECT src_rect, dst_rect; - TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n", - This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip); - TRACE("src_rect [%u, %u]->[%u, %u]\n", src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2); - TRACE("dst_rect [%u, %u]->[%u, %u]\n", dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2); + TRACE("device %p, src_surface %p, src_rect_in %s, dst_surface %p, dst_rect_in %s, filter %s (0x%08x).\n", + device, src_surface, wine_dbgstr_rect(src_rect_in), dst_surface, + wine_dbgstr_rect(dst_rect_in), debug_d3dtexturefiltertype(filter), filter); + + src_rect = *src_rect_in; + dst_rect = *dst_rect_in; switch (filter) { case WINED3DTEXF_LINEAR: @@ -5799,16 +5769,19 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED /* Make sure the drawables are up-to-date. Note that loading the * destination surface isn't strictly required if we overwrite the * entire surface. */ - IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)src_surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, NULL); - /* Attach src surface to src fbo */ - src_swapchain = get_swapchain(src_surface); - dst_swapchain = get_swapchain(dst_surface); + if (!surface_is_offscreen(src_surface)) context = context_acquire(device, src_surface); + else if (!surface_is_offscreen(dst_surface)) context = context_acquire(device, dst_surface); + else context = context_acquire(device, NULL); - if (src_swapchain) context = context_acquire(This, src_surface, CTXUSAGE_RESOURCELOAD); - else if (dst_swapchain) context = context_acquire(This, dst_surface, CTXUSAGE_RESOURCELOAD); - else context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping blit.\n"); + return; + } gl_info = context->gl_info; @@ -5818,19 +5791,11 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Source surface %p is onscreen\n", src_surface); - if(buffer == GL_FRONT) { - RECT windowsize; - UINT h; - ClientToScreen(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &offset); - GetClientRect(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - src_rect->x1 -= offset.x; src_rect->x2 -=offset.x; - src_rect->y1 = offset.y + h - src_rect->y1; - src_rect->y2 = offset.y + h - src_rect->y2; - } else { - src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1; - src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2; - } + if (buffer == GL_FRONT) + surface_translate_frontbuffer_coords(src_surface, context->win_handle, &src_rect); + + src_rect.top = src_surface->currentDesc.Height - src_rect.top; + src_rect.bottom = src_surface->currentDesc.Height - src_rect.bottom; ENTER_GL(); context_bind_fbo(context, GL_READ_FRAMEBUFFER, NULL); @@ -5839,11 +5804,9 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED } else { TRACE("Source surface %p is offscreen\n", src_surface); ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); - context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL); glReadBuffer(GL_COLOR_ATTACHMENT0); checkGLcall("glReadBuffer()"); - context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); } LEAVE_GL(); @@ -5854,20 +5817,11 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Destination surface %p is onscreen\n", dst_surface); - if(buffer == GL_FRONT) { - RECT windowsize; - UINT h; - ClientToScreen(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &offset); - GetClientRect(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - dst_rect->x1 -= offset.x; dst_rect->x2 -=offset.x; - dst_rect->y1 = offset.y + h - dst_rect->y1; - dst_rect->y2 = offset.y + h - dst_rect->y2; - } else { - /* Screen coords = window coords, surface height = window height */ - dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1; - dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2; - } + if (buffer == GL_FRONT) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); + + dst_rect.top = dst_surface->currentDesc.Height - dst_rect.top; + dst_rect.bottom = dst_surface->currentDesc.Height - dst_rect.bottom; ENTER_GL(); context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); @@ -5878,31 +5832,23 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Destination surface %p is offscreen\n", dst_surface); ENTER_GL(); - context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL); context_set_draw_buffer(context, GL_COLOR_ATTACHMENT0); - context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE); } glDisable(GL_SCISSOR_TEST); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); - if (flip) { - gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2, - dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter); - checkGLcall("glBlitFramebuffer()"); - } else { - gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2, - dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter); - checkGLcall("glBlitFramebuffer()"); - } + gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter); + checkGLcall("glBlitFramebuffer()"); LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); - IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); } static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget, @@ -5932,13 +5878,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, } /* If we are trying to set what we already have, don't bother */ - if (pRenderTarget == This->render_targets[RenderTargetIndex]) { + if (pRenderTarget == (IWineD3DSurface *)This->render_targets[RenderTargetIndex]) + { TRACE("Trying to do a NOP SetRenderTarget operation\n"); return WINED3D_OK; } - if(pRenderTarget) IWineD3DSurface_AddRef(pRenderTarget); - if(This->render_targets[RenderTargetIndex]) IWineD3DSurface_Release(This->render_targets[RenderTargetIndex]); - This->render_targets[RenderTargetIndex] = pRenderTarget; + if (pRenderTarget) + IWineD3DSurface_AddRef(pRenderTarget); + if (This->render_targets[RenderTargetIndex]) + IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[RenderTargetIndex]); + This->render_targets[RenderTargetIndex] = (IWineD3DSurfaceImpl *)pRenderTarget; /* Render target 0 is special */ if(RenderTargetIndex == 0 && set_viewport) { @@ -5946,8 +5895,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, * Tests show that stateblock recording is ignored, the change goes * directly into the primary stateblock. */ - This->stateBlock->viewport.Height = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height; - This->stateBlock->viewport.Width = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Width; + This->stateBlock->viewport.Height = This->render_targets[0]->currentDesc.Height; + This->stateBlock->viewport.Width = This->render_targets[0]->currentDesc.Width; This->stateBlock->viewport.X = 0; This->stateBlock->viewport.Y = 0; This->stateBlock->viewport.MaxZ = 1.0f; @@ -5965,49 +5914,46 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *iface, IWineD3DSurface *pNewZStencil) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - HRESULT hr = WINED3D_OK; - IWineD3DSurface *tmp; + IWineD3DSurfaceImpl *tmp; - TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil); + TRACE("device %p, depth_stencil %p, old depth_stencil %p.\n", This, pNewZStencil, This->depth_stencil); - if (pNewZStencil == This->stencilBufferTarget) { - TRACE("Trying to do a NOP SetRenderTarget operation\n"); - } else { - /** OpenGL doesn't support 'sharing' of the stencilBuffer so we may incur an extra memory overhead - * depending on the renter target implementation being used. - * A shared context implementation will share all buffers between all rendertargets (including swapchains), - * implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the - * stencil buffer and incur an extra memory overhead - ******************************************************/ + if (This->depth_stencil == (IWineD3DSurfaceImpl *)pNewZStencil) + { + TRACE("Trying to do a NOP SetRenderTarget operation.\n"); + return WINED3D_OK; + } - if (This->stencilBufferTarget) { - if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED); - } else { - struct wined3d_context *context = context_acquire(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD); - surface_load_ds_location(This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN); - surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); - context_release(context); + if (This->depth_stencil) + { + if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || This->depth_stencil->Flags & SFLAG_DISCARD) + { + surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED, + This->depth_stencil->currentDesc.Width, + This->depth_stencil->currentDesc.Height); + if (This->depth_stencil == This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; } } - - tmp = This->stencilBufferTarget; - This->stencilBufferTarget = pNewZStencil; - /* should we be calling the parent or the wined3d surface? */ - if (NULL != This->stencilBufferTarget) IWineD3DSurface_AddRef(This->stencilBufferTarget); - if (NULL != tmp) IWineD3DSurface_Release(tmp); - hr = WINED3D_OK; - - if((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) { - /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); - } } - return hr; + tmp = This->depth_stencil; + This->depth_stencil = (IWineD3DSurfaceImpl *)pNewZStencil; + if (This->depth_stencil) IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); + if (tmp) IWineD3DSurface_Release((IWineD3DSurface *)tmp); + + if ((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) + { + /* Swapping NULL / non NULL depth stencil affects the depth and tests */ + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); + } + + return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot, @@ -6020,8 +5966,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot); /* some basic validation checks */ - if(This->cursorTexture) { - struct wined3d_context *context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + if (This->cursorTexture) + { + struct wined3d_context *context = context_acquire(This, NULL); ENTER_GL(); glDeleteTextures(1, &This->cursorTexture); LEAVE_GL(); @@ -6065,15 +6012,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i if (SUCCEEDED(IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY))) { const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; - const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); struct wined3d_context *context; char *mem, *bits = rect.pBits; - GLint intfmt = glDesc->glInternal; - GLint format = glDesc->glFormat; - GLint type = glDesc->glType; + GLint intfmt = format_desc->glInternal; + GLint format = format_desc->glFormat; + GLint type = format_desc->glType; INT height = This->cursorHeight; INT width = This->cursorWidth; - INT bpp = glDesc->byte_count; + INT bpp = format_desc->byte_count; DWORD sampler; INT i; @@ -6084,7 +6031,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp); IWineD3DSurface_UnlockRect(pCursorBitmap); - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); ENTER_GL(); @@ -6258,14 +6205,10 @@ static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRES while (surface->pow2Width < pPresentationParameters->BackBufferWidth) surface->pow2Width <<= 1; while (surface->pow2Height < pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1; } - surface->glRect.left = 0; - surface->glRect.top = 0; - surface->glRect.right = surface->pow2Width; - surface->glRect.bottom = surface->pow2Height; if (surface->texture_name) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); glDeleteTextures(1, &surface->texture_name); LEAVE_GL(); @@ -6286,7 +6229,7 @@ static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRES /* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered * to a FBO */ - if(!surface_init_sysmem((IWineD3DSurface *) surface)) + if (!surface_init_sysmem(surface)) { return E_OUTOFMEMORY; } @@ -6327,14 +6270,14 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRE return FALSE; } -void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { +static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; IWineD3DBaseShaderImpl *shader; - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); gl_info = context->gl_info; IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL); @@ -6371,9 +6314,9 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_ swapchain->num_contexts = 0; } -HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { +static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface; struct wined3d_context *context; HRESULT hr; IWineD3DSurfaceImpl *target; @@ -6386,9 +6329,8 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain * return E_OUTOFMEMORY; } - target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer); - context = context_create(This, target, swapchain->win_handle, FALSE, &swapchain->presentParms); - if (!context) + target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer; + if (!(context = context_create(swapchain, target, swapchain->ds_format))) { WARN("Failed to create context.\n"); HeapFree(GetProcessHeap(), 0, swapchain->context); @@ -6427,7 +6369,7 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain * return WINED3D_OK; err: - context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context_acquire(This, NULL); destroy_dummy_textures(This, context->gl_info); context_release(context); context_destroy(This, context); @@ -6499,7 +6441,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE pPresentationParameters->hDeviceWindow != swapchain->presentParms.hDeviceWindow) { ERR("Cannot change the device window yet\n"); } - if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) { + if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil) + { HRESULT hrc; TRACE("Creating the depth stencil buffer\n"); @@ -6512,7 +6455,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE pPresentationParameters->MultiSampleType, pPresentationParameters->MultiSampleQuality, FALSE, - &This->auto_depth_stencil_buffer); + (IWineD3DSurface **)&This->auto_depth_stencil); if (FAILED(hrc)) { ERR("Failed to create the depth stencil buffer\n"); @@ -6521,9 +6464,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } + if (This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; + } + /* Reset the depth stencil */ if (pPresentationParameters->EnableAutoDepthStencil) - IWineD3DDevice_SetDepthStencilSurface(iface, This->auto_depth_stencil_buffer); + IWineD3DDevice_SetDepthStencilSurface(iface, (IWineD3DSurface *)This->auto_depth_stencil); else IWineD3DDevice_SetDepthStencilSurface(iface, NULL); @@ -6531,7 +6480,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock); IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock); - delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain); + delete_opengl_contexts(iface, swapchain); if(pPresentationParameters->Windowed) { mode.Width = swapchain->orig_width; @@ -6558,23 +6507,25 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth; swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight; - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters); + hr = updateSurfaceDesc(swapchain->front_buffer, pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } - for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) { - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters); + for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) + { + hr = updateSurfaceDesc(swapchain->back_buffers[i], pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } } - if(This->auto_depth_stencil_buffer) { - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters); + if (This->auto_depth_stencil) + { + hr = updateSurfaceDesc(This->auto_depth_stencil, pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); @@ -6583,24 +6534,26 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } - if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) || - (swapchain->presentParms.Windowed && !pPresentationParameters->Windowed) || - DisplayModeChanged) { - + if (!pPresentationParameters->Windowed != !swapchain->presentParms.Windowed + || DisplayModeChanged) + { IWineD3DDevice_SetDisplayMode(iface, 0, &mode); - if(swapchain->win_handle && !pPresentationParameters->Windowed) { + if (!pPresentationParameters->Windowed) + { if(swapchain->presentParms.Windowed) { /* switch from windowed to fs */ swapchain_setup_fullscreen_window(swapchain, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); } else { /* Fullscreen -> fullscreen mode change */ - MoveWindow(swapchain->win_handle, 0, 0, + MoveWindow(swapchain->device_window, 0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight, TRUE); } - } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) { + } + else if (!swapchain->presentParms.Windowed) + { /* Fullscreen -> windowed switch */ swapchain_restore_fullscreen_window(swapchain); } @@ -6657,7 +6610,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } - hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain); + hr = create_primary_opengl_context(iface, swapchain); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); /* All done. There is no need to reload resources or shaders, this will happen automatically on the @@ -6747,13 +6700,11 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour { for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i) { - if (This->render_targets[i] == (IWineD3DSurface *)resource) { + if (This->render_targets[i] == (IWineD3DSurfaceImpl *)resource) This->render_targets[i] = NULL; - } - } - if (This->stencilBufferTarget == (IWineD3DSurface *)resource) { - This->stencilBufferTarget = NULL; } + if (This->depth_stencil == (IWineD3DSurfaceImpl *)resource) + This->depth_stencil = NULL; } break; @@ -6845,6 +6796,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources(IWineD3DDevice *iface, D3 return WINED3D_OK; } +static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + IWineD3DResourceImpl *resource; + + LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) + { + WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource); + if (type == WINED3DRTYPE_SURFACE) + { + if (((IWineD3DSurfaceImpl *)resource)->hDC == dc) + { + TRACE("Found surface %p for dc %p.\n", resource, dc); + *surface = (IWineD3DSurface *)resource; + return WINED3D_OK; + } + } + } + + return WINED3DERR_INVALIDCALL; +} + /********************************************************** * IWineD3DDevice VTbl follows **********************************************************/ @@ -6993,7 +6966,10 @@ static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_UpdateSurface, IWineD3DDeviceImpl_GetFrontBufferData, /*** object tracking ***/ - IWineD3DDeviceImpl_EnumResources + IWineD3DDeviceImpl_EnumResources, + IWineD3DDeviceImpl_GetSurfaceFromDC, + IWineD3DDeviceImpl_AcquireFocusWindow, + IWineD3DDeviceImpl_ReleaseFocusWindow, }; HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, @@ -7045,27 +7021,29 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, select_shader_mode(&adapter->gl_info, &device->ps_selected_mode, &device->vs_selected_mode); device->shader_backend = adapter->shader_backend; - memset(&shader_caps, 0, sizeof(shader_caps)); - device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); - device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; - device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; - device->vs_clipping = shader_caps.VSClipping; - - memset(&ffp_caps, 0, sizeof(ffp_caps)); + if (device->shader_backend) + { + device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); + device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; + device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; + device->vs_clipping = shader_caps.VSClipping; + } fragment_pipeline = adapter->fragment_pipe; device->frag_pipe = fragment_pipeline; - fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps); - device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; - - hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info, - ffp_vertexstate_template, fragment_pipeline, misc_state_template); - if (FAILED(hr)) + if (fragment_pipeline) { - ERR("Failed to compile state table, hr %#x.\n", hr); - IWineD3D_Release(device->wined3d); - return hr; - } + fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps); + device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; + hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info, + ffp_vertexstate_template, fragment_pipeline, misc_state_template); + if (FAILED(hr)) + { + ERR("Failed to compile state table, hr %#x.\n", hr); + IWineD3D_Release(device->wined3d); + return hr; + } + } device->blitter = adapter->blitter; return WINED3D_OK; @@ -7090,31 +7068,21 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { } } -void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) -{ - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.device; - /* The drawable size of a pbuffer render target is the current pbuffer size. */ - *width = device->pbufferWidth; - *height = device->pbufferHeight; -} - void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt; /* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */ - *width = surface->pow2Width; - *height = surface->pow2Height; + *width = context->current_rt->pow2Width; + *height = context->current_rt->pow2Height; } void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface; + IWineD3DSwapChainImpl *swapchain = context->swapchain; /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the * current context's drawable, which is the size of the back buffer of the swapchain - * the active context belongs to. The back buffer of the swapchain is stored as the - * surface the context belongs to. */ - *width = surface->currentDesc.Width; - *height = surface->currentDesc.Height; + * the active context belongs to. */ + *width = swapchain->presentParms.BackBufferWidth; + *height = swapchain->presentParms.BackBufferHeight; } LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window, diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 812e5ccc9e8..29061476ddd 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -24,14 +24,13 @@ */ #include "config.h" +#include #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); -#define GLINFO_LOCATION (*gl_info) #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024) -#define MAKEDWORD_VERSION(maj, min) ((maj & 0xffff) << 16) | (min & 0xffff) /* The d3d device ID */ static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } }; @@ -74,6 +73,7 @@ static const struct { {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 }, {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 }, {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100, 0 }, + {"GL_ARB_shadow", ARB_SHADOW, 0 }, {"GL_ARB_sync", ARB_SYNC, 0 }, {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 }, {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 }, @@ -104,6 +104,7 @@ static const struct { {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 }, {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 }, {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 }, + {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 }, {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 }, {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 }, {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 }, @@ -325,12 +326,12 @@ fail: } /* Adjust the amount of used texture memory */ -long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram) +unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *device, unsigned int glram) { - struct wined3d_adapter *adapter = D3DDevice->adapter; + struct wined3d_adapter *adapter = device->adapter; adapter->UsedTextureRam += glram; - TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam); + TRACE("Adjusted gl ram by %d to %d\n", glram, adapter->UsedTextureRam); return adapter->UsedTextureRam; } @@ -528,9 +529,12 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info) checkGLcall("Loading the PBO test texture"); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + LEAVE_GL(); + wglFinish(); /* just to be sure */ memset(check, 0, sizeof(check)); + ENTER_GL(); glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check); checkGLcall("Reading back the PBO test texture"); @@ -570,7 +574,7 @@ static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { - return (gl_vendor == GL_VENDOR_ATI); + return gl_vendor == GL_VENDOR_FGLRX; } @@ -669,6 +673,61 @@ static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const ch return ret; } +/* Context activation is done by the caller. */ +static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer, + enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + char data[4 * 4 * 4]; + GLuint tex, fbo; + GLenum status; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE; + + memset(data, 0xcc, sizeof(data)); + + ENTER_GL(); + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + checkGLcall("glTexImage2D"); + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + checkGLcall("glFramebufferTexture2D"); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); + checkGLcall("glCheckFramebufferStatus"); + + memset(data, 0x11, sizeof(data)); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glTexSubImage2D"); + + glClearColor(0.996, 0.729, 0.745, 0.792); + glClear(GL_COLOR_BUFFER_BIT); + checkGLcall("glClear"); + + glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glGetTexImage"); + + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + checkGLcall("glBindTexture"); + + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); + checkGLcall("glDeleteTextures"); + + LEAVE_GL(); + + return *(DWORD *)data == 0x11111111; +} + static void quirk_arb_constants(struct wined3d_gl_info *gl_info) { TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants); @@ -797,6 +856,11 @@ static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info) gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN; } +static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE; +} + struct driver_quirk { BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, @@ -876,6 +940,11 @@ static const struct driver_quirk quirk_table[] = quirk_disable_nvvp_clip, "Apple NV_vertex_program clip bug quirk" }, + { + match_fbo_tex_update, + quirk_fbo_tex_update, + "FBO rebind for attachment updates" + }, }; /* Certain applications (Steam) complain if we report an outdated driver version. In general, @@ -955,7 +1024,7 @@ static const struct driver_version_information driver_version_table[] = {HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 14, 10, 6764 }, - {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 14, 10, 6764 }, + {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", 14, 10, 6764 }, @@ -1131,10 +1200,11 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl return GL_VENDOR_NVIDIA; if (strstr(gl_vendor_string, "ATI")) - return GL_VENDOR_ATI; + return GL_VENDOR_FGLRX; if (strstr(gl_vendor_string, "Intel(R)") - || strstr(gl_renderer, "Intel(R)") + /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ + || strstr(gl_renderer, "Intel") || strstr(gl_vendor_string, "Intel Inc.")) return GL_VENDOR_INTEL; @@ -1148,9 +1218,10 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl || strstr(gl_renderer, "Gallium")) return GL_VENDOR_MESA; - FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_WINE.\n", debugstr_a(gl_vendor_string)); + FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n", + debugstr_a(gl_vendor_string)); - return GL_VENDOR_WINE; + return GL_VENDOR_UNKNOWN; } static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer) @@ -1165,14 +1236,15 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s return HW_VENDOR_ATI; if (strstr(gl_vendor_string, "Intel(R)") - || strstr(gl_renderer, "Intel(R)") + /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ + || strstr(gl_renderer, "Intel") || strstr(gl_vendor_string, "Intel Inc.")) return HW_VENDOR_INTEL; if (strstr(gl_vendor_string, "Mesa") || strstr(gl_vendor_string, "Tungsten Graphics, Inc") || strstr(gl_vendor_string, "VMware, Inc.")) - return HW_VENDOR_WINE; + return HW_VENDOR_SOFTWARE; FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string)); @@ -1181,13 +1253,10 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s -enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { - /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more - * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. - */ - if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3]) + if (WINE_D3D10_CAPABLE(gl_info)) { /* Geforce 200 - highend */ if (strstr(gl_renderer, "GTX 280") @@ -1293,6 +1362,16 @@ enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info * return CARD_NVIDIA_GEFORCE_8300GS; } + /* Geforce8-compatible fall back if the GPU is not in the list yet */ + *vidmem = 128; + return CARD_NVIDIA_GEFORCE_8300GS; + } + + /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more + * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. + */ + if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3]) + { /* Geforce7 - highend */ if (strstr(gl_renderer, "7800") || strstr(gl_renderer, "7900") @@ -1425,14 +1504,14 @@ enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info * } -enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx * * Beware: renderer string do not match exact card model, * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */ - if (WINE_D3D9_CAPABLE(gl_info)) + if (WINE_D3D10_CAPABLE(gl_info)) { /* Radeon EG CYPRESS XT / PRO HD5800 - highend */ if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */ @@ -1507,16 +1586,17 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD2600; } - /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */ - if (strstr(gl_renderer, "HD 2300") + /* Radeon R6xx HD2350/HD2400/HD3400 - lowend + * Note HD2300=DX9, HD2350=DX10 */ + if (strstr(gl_renderer, "HD 2350") || strstr(gl_renderer, "HD 2400") || strstr(gl_renderer, "HD 3470") || strstr(gl_renderer, "HD 3450") || strstr(gl_renderer, "HD 3430") || strstr(gl_renderer, "HD 3400")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1528,6 +1608,13 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD3200; } + /* Default for when no GPU has been found */ + *vidmem = 128; /* 128MB */ + return CARD_ATI_RADEON_HD3200; + } + + if (WINE_D3D8_CAPABLE(gl_info)) + { /* Radeon R5xx */ if (strstr(gl_renderer, "X1600") || strstr(gl_renderer, "X1650") @@ -1539,14 +1626,19 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_X1600; } - /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */ + /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx) + * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */ if (strstr(gl_renderer, "X700") || strstr(gl_renderer, "X800") || strstr(gl_renderer, "X850") || strstr(gl_renderer, "X1300") || strstr(gl_renderer, "X1400") || strstr(gl_renderer, "X1450") - || strstr(gl_renderer, "X1550")) + || strstr(gl_renderer, "X1550") + || strstr(gl_renderer, "X2300") + || strstr(gl_renderer, "X2500") + || strstr(gl_renderer, "HD 2300") + ) { *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */ return CARD_ATI_RADEON_X700; @@ -1581,8 +1673,8 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ } -enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { if (strstr(gl_renderer, "X3100")) { @@ -1607,8 +1699,8 @@ enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *g } -enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx * @@ -1663,12 +1755,12 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD2600; } - /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */ + /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */ if (strstr(gl_renderer, "RV610") || strstr(gl_renderer, "RV620")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1786,8 +1878,8 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ if (strstr(gl_renderer, "(RV610") || strstr(gl_renderer, "(RV620")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1816,8 +1908,8 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ } -enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n"); if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600; @@ -1827,8 +1919,8 @@ enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info * return CARD_NVIDIA_RIVA_128; } -enum wined3d_pci_device (select_card_intel_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_intel_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n"); return CARD_INTEL_I915G; @@ -1850,10 +1942,11 @@ static const struct vendor_card_selection vendor_card_select_table[] = {GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary}, {GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary}, {GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel_binary}, - {GL_VENDOR_ATI, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary}, + {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary}, {GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa}, {GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa}, - {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa} + {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}, + {GL_VENDOR_INTEL, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa} }; @@ -2034,6 +2127,7 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) * with Default values */ memset(gl_info->supported, 0, sizeof(gl_info->supported)); + gl_info->limits.blends = 1; gl_info->limits.buffers = 1; gl_info->limits.textures = 1; gl_info->limits.fragment_samplers = 1; @@ -2347,7 +2441,13 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) if (gl_info->supported[ARB_SHADING_LANGUAGE_100]) { const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); + unsigned int major, minor; + TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str)); + + /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */ + sscanf(str, "%u.%u", &major, &minor); + gl_info->glsl_version = MAKEDWORD_VERSION(major, minor); } if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) { @@ -2522,10 +2622,6 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) ThisExtn[len] = '\0'; TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn)); - if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) { - gl_info->supported[WGL_ARB_PBUFFER] = TRUE; - TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n"); - } if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) { gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE; TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n"); @@ -2590,7 +2686,7 @@ static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { /* Display */ - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); UINT format_bits = format_desc->byte_count * CHAR_BIT; unsigned int i = 0; unsigned int j = 0; @@ -2637,7 +2733,7 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); UINT format_bits = format_desc->byte_count * CHAR_BIT; DEVMODEW DevModeW; int ModeIdx = 0; @@ -2802,13 +2898,16 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad } static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info, - const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc) + const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc) { short redSize, greenSize, blueSize, alphaSize, colorBits; if(!cfg) return FALSE; + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE; + if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */ if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) { @@ -2829,29 +2928,14 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined return FALSE; return TRUE; - } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */ - if (format_desc->format == WINED3DFMT_R16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R16G16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16); - if (format_desc->format == WINED3DFMT_R32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R32G32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32); - } else { - /* Probably a color index mode */ - return FALSE; } + /* Probably a RGBA_float or color index mode */ return FALSE; } static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info, - const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc) + const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc) { short depthSize, stencilSize; BOOL lockable = FALSE; @@ -2865,6 +2949,9 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3 return FALSE; } + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE; + if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT)) lockable = TRUE; @@ -2890,8 +2977,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT int nCfgs; const WineD3D_PixelFormat *cfgs; const struct wined3d_adapter *adapter; - const struct GlPixelFormatDesc *rt_format_desc; - const struct GlPixelFormatDesc *ds_format_desc; + const struct wined3d_format_desc *rt_format_desc; + const struct wined3d_format_desc *ds_format_desc; int it; WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n", @@ -2909,15 +2996,26 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT adapter = &This->adapters[Adapter]; rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info); ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info); - cfgs = adapter->cfgs; - nCfgs = adapter->nCfgs; - for (it = 0; it < nCfgs; ++it) { - if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc)) - { - if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc)) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if ((rt_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET) && + (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) { + TRACE_(d3d_caps)("(%p) : Formats matched\n", This); + return WINED3D_OK; + } + } + else + { + cfgs = adapter->cfgs; + nCfgs = adapter->nCfgs; + for (it = 0; it < nCfgs; ++it) { + if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc)) { - TRACE_(d3d_caps)("(%p) : Formats matched\n", This); - return WINED3D_OK; + if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc)) + { + TRACE_(d3d_caps)("(%p) : Formats matched\n", This); + return WINED3D_OK; + } } } } @@ -2930,7 +3028,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels) { IWineD3DImpl *This = (IWineD3DImpl *)iface; - const struct GlPixelFormatDesc *glDesc; + const struct wined3d_format_desc *glDesc; const struct wined3d_adapter *adapter; TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n", @@ -3109,51 +3207,41 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter /* Check if we support bumpmapping for a format */ -static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { - switch(format_desc->format) - { - case WINED3DFMT_R8G8_SNORM: - case WINED3DFMT_R16G16_SNORM: - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - case WINED3DFMT_R8G8B8A8_SNORM: - /* Ask the fixed function pipeline implementation if it can deal - * with the conversion. If we've got a GL extension giving native - * support this will be an identity conversion. */ - if (adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup)) - { - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - } - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } + /* Ask the fixed function pipeline implementation if it can deal + * with the conversion. If we've got a GL extension giving native + * support this will be an identity conversion. */ + return (format_desc->Flags & WINED3DFMT_FLAG_BUMPMAP) + && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup); } /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */ static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *display_format_desc, const struct GlPixelFormatDesc *ds_format_desc) + const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc) { int it=0; /* Only allow depth/stencil formats */ if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE; - /* Walk through all WGL pixel formats to find a match */ - for (it = 0; it < adapter->nCfgs; ++it) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - WineD3D_PixelFormat *cfg = &adapter->cfgs[it]; - if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc)) + /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */ + if (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE; + } + else + { + /* Walk through all WGL pixel formats to find a match */ + for (it = 0; it < adapter->nCfgs; ++it) { - if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc)) + WineD3D_PixelFormat *cfg = &adapter->cfgs[it]; + if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc)) { - return TRUE; + if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc)) + { + return TRUE; + } } } } @@ -3161,7 +3249,7 @@ static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* The flags entry of a format contains the filtering capability */ if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE; @@ -3171,11 +3259,10 @@ static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct /* Check the render target capabilities of a format */ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *adapter_format_desc, const struct GlPixelFormatDesc *check_format_desc) + const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc) { /* Filter out non-RT formats */ if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE; - if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { WineD3D_PixelFormat *cfgs = adapter->cfgs; int it; @@ -3204,23 +3291,9 @@ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, return TRUE; } } - } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) { - /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */ - WineD3D_PixelFormat *cfgs = adapter->cfgs; - int it; - - /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */ - for (it = 0; it < adapter->nCfgs; ++it) - { - if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, - &cfgs[it], check_format_desc)) - { - TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", - cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format)); - return TRUE; - } - } - } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){ + } + else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { /* For now return TRUE for FBOs until we have some proper checks. * Note that this function will only be called when the format is around for texturing. */ return TRUE; @@ -3228,46 +3301,18 @@ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - - /* Check for supported sRGB formats (Texture loading and framebuffer) */ - if (!gl_info->supported[EXT_TEXTURE_SRGB]) - { - TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n"); - return FALSE; - } - - switch (format_desc->format) - { - case WINED3DFMT_B8G8R8A8_UNORM: - case WINED3DFMT_B8G8R8X8_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - case WINED3DFMT_L8_UNORM: - case WINED3DFMT_L8A8_UNORM: - case WINED3DFMT_DXT1: - case WINED3DFMT_DXT2: - case WINED3DFMT_DXT3: - case WINED3DFMT_DXT4: - case WINED3DFMT_DXT5: - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - - default: - TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format)); - return FALSE; - } - return FALSE; + return adapter->gl_info.supported[EXT_TEXTURE_SRGB] + && (format_desc->Flags & WINED3DFMT_FLAG_SRGB_READ); } -static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are * doing the color fixup in shaders. * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */ - if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)) + if (format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) { int vs_selected_mode; int ps_selected_mode; @@ -3285,7 +3330,7 @@ static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, /* Check if a format support blending in combination with pixel shaders */ static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *format_desc) + const struct wined3d_format_desc *format_desc) { /* The flags entry of a format contains the post pixel shader blending capability */ if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE; @@ -3293,7 +3338,7 @@ static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapt return FALSE; } -static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported, * but we have to report mipmapping so we cannot reject this flag. Tests show that @@ -3308,8 +3353,7 @@ static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const str } /* Check if a texture format is supported on the given adapter */ -static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { const struct wined3d_gl_info *gl_info = &adapter->gl_info; @@ -3340,12 +3384,12 @@ static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, return FALSE; /***** - * supported: Palettized + * Not supported: Palettized + * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7. + * Since it is not widely available, don't offer it. Further no Windows driver offers + * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either. */ case WINED3DFMT_P8_UINT: - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - /* No Windows driver offers WINED3DFMT_P8_UINT_A8_UNORM, so don't offer it either */ case WINED3DFMT_P8_UINT_A8_UNORM: return FALSE; @@ -3539,8 +3583,10 @@ static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *adapter_format_desc, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *check_format_desc, WINED3DSURFTYPE SurfaceType) +static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, + const struct wined3d_format_desc *adapter_format_desc, + const struct wined3d_format_desc *check_format_desc, + WINED3DSURFTYPE SurfaceType) { if(SurfaceType == SURFACE_GDI) { switch(check_format_desc->format) @@ -3572,12 +3618,14 @@ static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct } /* All format that are supported for textures are supported for surfaces as well */ - if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE; + if (CheckTextureCapability(adapter, check_format_desc)) return TRUE; /* All depth stencil formats are supported on surfaces */ if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE; /* If opengl can't process the format natively, the blitter may be able to convert it */ - if (adapter->blitter->color_fixup_supported(check_format_desc->color_fixup)) + if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT, + NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc, + NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc)) { TRACE_(d3d_caps)("[OK]\n"); return TRUE; @@ -3588,32 +3636,11 @@ static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct return FALSE; } -static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, + const struct wined3d_format_desc *format_desc) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - - if (!gl_info->limits.vertex_samplers) - { - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - - switch (format_desc->format) - { - case WINED3DFMT_R32G32B32A32_FLOAT: - if (!gl_info->supported[ARB_TEXTURE_FLOAT]) - { - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - return FALSE; + return adapter->gl_info.limits.vertex_samplers + && (format_desc->Flags & WINED3DFMT_FLAG_VTF); } static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, @@ -3623,8 +3650,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt IWineD3DImpl *This = (IWineD3DImpl *)iface; struct wined3d_adapter *adapter = &This->adapters[Adapter]; const struct wined3d_gl_info *gl_info = &adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info); - const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info); + const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info); DWORD UsageCaps = 0; TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n", @@ -3640,484 +3667,476 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt return WINED3DERR_INVALIDCALL; } - if(RType == WINED3DRTYPE_CUBETEXTURE) { - - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } - - /* Cubetexture allows: - * - D3DUSAGE_AUTOGENMIPMAP - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_QUERY_WRAPANDMIP - */ - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - /* Check if the texture format is around */ - if (CheckTextureCapability(adapter, DeviceType, format_desc)) + switch (RType) + { + case WINED3DRTYPE_CUBETEXTURE: + /* Cubetexture allows: + * - WINED3DUSAGE_AUTOGENMIPMAP + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_DYNAMIC + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + * - WINED3DUSAGE_SOFTWAREPROCESSING + * - WINED3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) { - if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { - /* Check for automatic mipmap generation support */ - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; - } else { - /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */ - TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); - } - } + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) - UsageCaps |= WINED3DUSAGE_DYNAMIC; + if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + TRACE_(d3d_caps)("[FAILED] - No cube texture support\n"); + return WINED3DERR_NOTAVAILABLE; + } - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { - TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) - UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { - TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { - TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { - TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { - TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { - TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { - TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - } else { + if (!CheckTextureCapability(adapter, format_desc)) + { TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n"); return WINED3DERR_NOTAVAILABLE; } - } else { - TRACE_(d3d_caps)("[FAILED] - No cube texture support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } else if(RType == WINED3DRTYPE_SURFACE) { - /* Surface allows: - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - */ - if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType)) - { - if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { - if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; - } else { - TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { - TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { - TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - } else { - TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n"); - return WINED3DERR_NOTAVAILABLE; - } - - } else if(RType == WINED3DRTYPE_TEXTURE) { - /* Texture allows: - * - D3DUSAGE_AUTOGENMIPMAP - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_DMAP - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_TEXTAPI (d3d9ex) - * - D3DUSAGE_QUERY_WRAPANDMIP - */ - - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } - - /* Check if the texture format is around */ - if (CheckTextureCapability(adapter, DeviceType, format_desc)) - { - if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { - /* Check for automatic mipmap generation support */ - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; - } else { - /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */ + if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + /* When autogenmipmap isn't around continue and return + * WINED3DOK_NOAUTOGEN instead of D3D_OK. */ TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); - } + else + UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) UsageCaps |= WINED3DUSAGE_DYNAMIC; - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; } - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; } - /* Check QUERY_LEGACYBUMPMAP support */ - if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) { - if (CheckBumpMapCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP; - } else { - TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; } - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; } - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; } - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; } - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; + } + break; + + case WINED3DRTYPE_SURFACE: + /* Surface allows: + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + */ + if (!CheckSurfaceCapability(adapter, adapter_format_desc, format_desc, SurfaceType)) + { + TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n"); + return WINED3DERR_NOTAVAILABLE; } - if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { - if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) + if (Usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; + } + + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; + } + + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + break; + + case WINED3DRTYPE_TEXTURE: + /* Texture allows: + * - WINED3DUSAGE_AUTOGENMIPMAP + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_DMAP + * - WINED3DUSAGE_DYNAMIC + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + * - WINED3DUSAGE_SOFTWAREPROCESSING + * - WINED3DUSAGE_TEXTAPI (d3d9ex) + * - WINED3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) + { + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!CheckTextureCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + /* When autogenmipmap isn't around continue and return + * WINED3DOK_NOAUTOGEN instead of D3D_OK. */ + TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); + else + UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; + } + + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) + UsageCaps |= WINED3DUSAGE_DYNAMIC; + + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; + } + + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; + + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; + } + + if (Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) + { + if (!CheckBumpMapCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP; + } + + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; + } + + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; + } + + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; + } + + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; + } + + if (Usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) { - UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; - } else { TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n"); return WINED3DERR_NOTAVAILABLE; } + if ((format_desc->Flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW]) + { + TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; } - } else { - TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n"); - return WINED3DERR_NOTAVAILABLE; - } - } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) { - /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented. - * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too. - * - * Volumetexture allows: - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_QUERY_WRAPANDMIP - */ + break; - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } + case WINED3DRTYPE_VOLUMETEXTURE: + case WINED3DRTYPE_VOLUME: + /* Volume is to VolumeTexture what Surface is to Texture, but its + * usage caps are not documented. Most driver seem to offer + * (nearly) the same on Volume and VolumeTexture, so do that too. + * + * Volumetexture allows: + * - D3DUSAGE_DYNAMIC + * - D3DUSAGE_NONSECURE (d3d9ex) + * - D3DUSAGE_SOFTWAREPROCESSING + * - D3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) + { + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } - /* Check volume texture and volume usage caps */ - if (gl_info->supported[EXT_TEXTURE3D]) - { - if (!CheckTextureCapability(adapter, DeviceType, format_desc)) + if (!gl_info->supported[EXT_TEXTURE3D]) + { + TRACE_(d3d_caps)("[FAILED] - No volume texture support\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!CheckTextureCapability(adapter, format_desc)) { TRACE_(d3d_caps)("[FAILED] - Format not supported\n"); return WINED3DERR_NOTAVAILABLE; } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) + /* Filter formats that need conversion; For one part, this + * conversion is unimplemented, and volume textures are huge, so + * it would be a big performance hit. Unless we hit an application + * needing one of those formats, don't advertize them to avoid + * leading applications into temptation. The windows drivers don't + * support most of those formats on volumes anyway, except for + * WINED3DFMT_R32_FLOAT. */ + switch (CheckFormat) + { + case WINED3DFMT_P8_UINT: + case WINED3DFMT_L4A4_UNORM: + case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R16_FLOAT: + case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: + case WINED3DFMT_R5G5_SNORM_L6_UNORM: + case WINED3DFMT_R16G16_UNORM: + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + + case WINED3DFMT_R8G8B8A8_SNORM: + case WINED3DFMT_R16G16_SNORM: + if (!gl_info->supported[NV_TEXTURE_SHADER]) + { + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + } + break; + + case WINED3DFMT_R8G8_SNORM: + if (!gl_info->supported[NV_TEXTURE_SHADER]) + { + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + } + break; + + case WINED3DFMT_DXT1: + case WINED3DFMT_DXT2: + case WINED3DFMT_DXT3: + case WINED3DFMT_DXT4: + case WINED3DFMT_DXT5: + /* The GL_EXT_texture_compression_s3tc spec requires that + * loading an s3tc compressed texture results in an error. + * While the D3D refrast does support s3tc volumes, at + * least the nvidia windows driver does not, so we're free + * not to support this format. */ + TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n"); + return WINED3DERR_NOTAVAILABLE; + + default: + /* Do nothing, continue with checking the format below */ + break; + } + + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) UsageCaps |= WINED3DUSAGE_DYNAMIC; - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; } - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; } - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; } - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; } - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; } - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; } - } else { - TRACE_(d3d_caps)("[FAILED] - No volume texture support\n"); + break; + + default: + FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType)); return WINED3DERR_NOTAVAILABLE; - } - - /* Filter formats that need conversion; For one part, this conversion is unimplemented, - * and volume textures are huge, so it would be a big performance hit. Unless we hit an - * app needing one of those formats, don't advertize them to avoid leading apps into - * temptation. The windows drivers don't support most of those formats on volumes anyway, - * except of R32F. - */ - switch(CheckFormat) { - case WINED3DFMT_P8_UINT: - case WINED3DFMT_L4A4_UNORM: - case WINED3DFMT_R32_FLOAT: - case WINED3DFMT_R16_FLOAT: - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - case WINED3DFMT_R16G16_UNORM: - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - - case WINED3DFMT_R8G8B8A8_SNORM: - case WINED3DFMT_R16G16_SNORM: - if (!gl_info->supported[NV_TEXTURE_SHADER]) - { - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - } - break; - - case WINED3DFMT_R8G8_SNORM: - if (!gl_info->supported[NV_TEXTURE_SHADER]) - { - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - } - break; - - case WINED3DFMT_DXT1: - case WINED3DFMT_DXT2: - case WINED3DFMT_DXT3: - case WINED3DFMT_DXT4: - case WINED3DFMT_DXT5: - /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc - * compressed texture results in an error. While the D3D refrast does - * support s3tc volumes, at least the nvidia windows driver does not, so - * we're free not to support this format. - */ - TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n"); - return WINED3DERR_NOTAVAILABLE; - - default: - /* Do nothing, continue with checking the format below */ - break; - } - } else if(RType == WINED3DRTYPE_BUFFER){ - /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */ - TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n"); - return WINED3DERR_NOTAVAILABLE; } - /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which - * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other - * usage flags match. */ - if(UsageCaps == Usage) { + /* When the UsageCaps exactly matches Usage return WINED3D_OK except for + * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then + * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */ + if (UsageCaps == Usage) return WINED3D_OK; - } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){ + if (UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) return WINED3DOK_NOAUTOGEN; - } else { - TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps); - return WINED3DERR_NOTAVAILABLE; - } + + TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n", + Usage, debug_d3dformat(CheckFormat), debug_d3dresourcetype(RType), UsageCaps); + + return WINED3DERR_NOTAVAILABLE; } static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx, @@ -4204,13 +4223,14 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING; /* TODO: WINED3DPMISCCAPS_NULLREFERENCE - WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS WINED3DPMISCCAPS_FOGANDSPECULARALPHA WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS WINED3DPMISCCAPS_FOGVERTEXCLAMPED */ if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND; + if (gl_info->supported[EXT_DRAW_BUFFERS2]) + pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS; pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER | WINED3DPRASTERCAPS_PAT | @@ -4517,10 +4537,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DPTFILTERCAPS_MAGFLINEAR; pCaps->VertexTextureFilterCaps = 0; - memset(&shader_caps, 0, sizeof(shader_caps)); adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); - - memset(&fragment_caps, 0, sizeof(fragment_caps)); adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps); /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */ @@ -4551,13 +4568,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages; pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures; - pCaps->VS20Caps = shader_caps.VS20Caps; - pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted; - pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots; - pCaps->PS20Caps = shader_caps.PS20Caps; - pCaps->MaxPShaderInstructionsExecuted = shader_caps.MaxPShaderInstructionsExecuted; - pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots; - /* The following caps are shader specific, but they are things we cannot detect, or which * are the same among all shader models. So to avoid code duplication set the shader version * specific, but otherwise constant caps here @@ -4959,7 +4969,7 @@ static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info) } } -BOOL InitAdapters(IWineD3DImpl *This) +static BOOL InitAdapters(IWineD3DImpl *This) { static HMODULE mod_gl; BOOL ret; @@ -5120,17 +5130,6 @@ BOOL InitAdapters(IWineD3DImpl *This) cfgs->doubleBuffer = values[9]; cfgs->auxBuffers = values[10]; - cfgs->pbufferDrawable = FALSE; - /* Check for pbuffer support when it is around as - * wglGetPixelFormatAttribiv fails for unknown attributes. */ - if (gl_info->supported[WGL_ARB_PBUFFER]) - { - int attrib = WGL_DRAW_TO_PBUFFER_ARB; - int value; - if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value))) - cfgs->pbufferDrawable = value; - } - cfgs->numSamples = 0; /* Check multisample support */ if (gl_info->supported[ARB_MULTISAMPLE]) @@ -5145,7 +5144,11 @@ BOOL InitAdapters(IWineD3DImpl *This) } } - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, samples=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable, cfgs->pbufferDrawable); + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n", + cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, + cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, + cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable); cfgs++; } } @@ -5182,14 +5185,17 @@ BOOL InitAdapters(IWineD3DImpl *This) cfgs->colorSize = ppfd.cColorBits; cfgs->depthSize = ppfd.cDepthBits; cfgs->stencilSize = ppfd.cStencilBits; - cfgs->pbufferDrawable = 0; cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0; cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB; cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0; cfgs->auxBuffers = ppfd.cAuxBuffers; cfgs->numSamples = 0; - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable); + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, windowDrawable=%d\n", + cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, + cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, + cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable); cfgs++; adapter->nCfgs++; } @@ -5261,7 +5267,7 @@ nogl_adapter: * IWineD3D VTbl follows **********************************************************/ -const IWineD3DVtbl IWineD3D_Vtbl = +static const struct IWineD3DVtbl IWineD3D_Vtbl = { /* IUnknown */ IWineD3DImpl_QueryInterface, @@ -5291,3 +5297,23 @@ const struct wined3d_parent_ops wined3d_null_parent_ops = { wined3d_null_wined3d_object_destroyed, }; + +HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) +{ + wined3d->lpVtbl = &IWineD3D_Vtbl; + wined3d->dxVersion = version; + wined3d->ref = 1; + wined3d->parent = parent; + + if (!InitAdapters(wined3d)) + { + WARN("Failed to initialize adapters.\n"); + if (version > 7) + { + MESSAGE("Direct3D%u is not available without OpenGL.\n", version); + return E_FAIL; + } + } + + return WINED3D_OK; +} diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index b29d012b9d1..b36ef5b49ae 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -28,7 +28,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); -#define GLINFO_LOCATION This->adapter->gl_info #include #include @@ -71,7 +70,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context UINT vx_index; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const UINT *streamOffset = This->stateBlock->streamOffset; - long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; + LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; BOOL pixelShader = use_ps(This->stateBlock); BOOL specular_fog = FALSE; const BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; @@ -85,14 +84,14 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context TRACE("Using slow vertex array code\n"); /* Variable Initialization */ - if (idxSize != 0) { - /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer. - * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing - * idxData will be != NULL - */ - if(idxData == NULL) { - idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); - } + if (idxSize) + { + /* Immediate mode drawing can't make use of indices in a vbo - get the + * data from the index buffer. If the index buffer has no vbo (not + * supported or other reason), or with user pointer drawing idxData + * will be non-NULL. */ + if (!idxData) + idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -102,7 +101,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context } /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimType)); glBegin(glPrimType); if (si->use_map & (1 << WINED3D_FFP_POSITION)) @@ -226,13 +224,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context if (idxData != NULL) { /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufS[startIdx+vx_index])); + if (idxSize == 2) SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex; - } else { - VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufL[startIdx+vx_index])); + else SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex; - } } tmp_tex_mask = tex_mask; @@ -426,7 +421,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT startIdx) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; UINT vx_index; @@ -434,14 +430,14 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream IWineD3DStateBlockImpl *stateblock = This->stateBlock; const BYTE *ptr; - if (idxSize != 0) { - /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer. - * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing - * idxData will be != NULL - */ - if(idxData == NULL) { - idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); - } + if (idxSize) + { + /* Immediate mode drawing can't make use of indices in a vbo - get the + * data from the index buffer. If the index buffer has no vbo (not + * supported or other reason), or with user pointer drawing idxData + * will be non-NULL. */ + if (!idxData) + idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -451,20 +447,16 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream } /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimitiveType)); glBegin(glPrimitiveType); for (vx_index = 0; vx_index < numberOfVertices; ++vx_index) { if (idxData != NULL) { /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index])); + if (idxSize == 2) SkipnStrides = pIdxBufS[startIdx + vx_index] + stateblock->loadBaseVertexIndex; - } else { - VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index])); + else SkipnStrides = pIdxBufL[startIdx + vx_index] + stateblock->loadBaseVertexIndex; - } } for (i = MAX_ATTRIBS - 1; i >= 0; i--) @@ -543,7 +535,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine { struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx]; - ptr += (long) buffer_get_sysmem(vb); + ptr += (ULONG_PTR)buffer_get_sysmem(vb, &This->adapter->gl_info); } send_attribute(This, si->elements[instancedData[j]].format_desc->format, instancedData[j], ptr); @@ -555,7 +547,8 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine } } -static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_info *s) +static inline void remove_vbos(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info, + struct wined3d_stream_info *s) { unsigned int i; @@ -570,7 +563,7 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_i { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); } } } @@ -580,7 +573,6 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *target; struct wined3d_context *context; unsigned int i; @@ -591,11 +583,11 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Invalidate the back buffer memory so LockRect will read it the next time */ for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i) { - target = (IWineD3DSurfaceImpl *)This->render_targets[i]; + IWineD3DSurface *target = (IWineD3DSurface *)This->render_targets[i]; if (target) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_LoadLocation(target, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_ModifyLocation(target, SFLAG_INDRAWABLE, TRUE); } } } @@ -603,9 +595,18 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Signals other modules that a drawing is in progress and the stateblock finalized */ This->isInDraw = TRUE; - context = context_acquire(This, This->render_targets[0], CTXUSAGE_DRAWPRIM); + context = context_acquire(This, This->render_targets[0]); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping draw.\n"); + return; + } - if (This->stencilBufferTarget) { + context_apply_draw_state(context, This); + + if (This->depth_stencil) + { /* Note that this depends on the context_acquire() call above to set * This->render_offscreen properly. We don't currently take the * Z-compare function into account, but we could skip loading the @@ -614,9 +615,33 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE] || This->stateBlock->renderState[WINED3DRS_ZENABLE]) - surface_load_ds_location(This->stencilBufferTarget, context, location); - if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) - surface_modify_ds_location(This->stencilBufferTarget, location); + { + RECT current_rect, draw_rect, r; + + if (location == SFLAG_DS_ONSCREEN && This->depth_stencil != This->onscreen_depth_stencil) + device_switch_onscreen_ds(This, context, This->depth_stencil); + + if (This->depth_stencil->Flags & location) + SetRect(¤t_rect, 0, 0, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + device_get_draw_rect(This, &draw_rect); + + IntersectRect(&r, &draw_rect, ¤t_rect); + if (!EqualRect(&r, &draw_rect)) + surface_load_ds_location(This->depth_stencil, context, location); + + if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) + { + surface_modify_ds_location(This->depth_stencil, location, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->depth_stencil, SFLAG_INDRAWABLE, TRUE); + } + } } /* Ok, we will be updating the screen from here onwards so grab the lock */ @@ -659,7 +684,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT if(emulation) { stream_info = &stridedlcl; memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl)); - remove_vbos(This, &stridedlcl); + remove_vbos(This, context->gl_info, &stridedlcl); } } @@ -691,7 +716,12 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Finished updating the screen, restore lock */ LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + for(i = 0; i < This->num_buffer_queries; i++) + { + wined3d_event_query_issue(This->buffer_queries[i], This); + } + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -700,14 +730,14 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Diagnostics */ #ifdef SHOW_FRAME_MAKEUP { - static long int primCounter = 0; + static LONG primCounter = 0; /* NOTE: set primCounter to the value reported by drawprim before you want to to write frame makeup to /tmp */ if (primCounter >= 0) { WINED3DLOCKED_RECT r; char buffer[80]; IWineD3DSurface_LockRect(This->render_targets[0], &r, NULL, WINED3DLOCK_READONLY); - sprintf(buffer, "/tmp/backbuffer_%ld.tga", primCounter); + sprintf(buffer, "/tmp/backbuffer_%d.tga", primCounter); TRACE("Saving screenshot %s\n", buffer); IWineD3DSurface_SaveSnapshot(This->render_targets[0], buffer); IWineD3DSurface_UnlockRect(This->render_targets[0]); @@ -718,7 +748,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT int textureNo; for (textureNo = 0; textureNo < MAX_COMBINED_SAMPLERS; ++textureNo) { if (This->stateBlock->textures[textureNo] != NULL) { - sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo); + sprintf(buffer, "/tmp/texture_%p_%d_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo); TRACE("Saving texture %s\n", buffer); if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) { IWineD3DTexture_GetSurfaceLevel(This->stateBlock->textures[textureNo], 0, &pSur); @@ -732,7 +762,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT } #endif } - TRACE("drawprim #%ld\n", primCounter); + TRACE("drawprim #%d\n", primCounter); ++primCounter; } #endif @@ -788,7 +818,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, /* Simply activate the context for blitting. This disables all the things we don't want and * takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the * patch (as opposed to normal draws) will most likely need different changes anyway. */ - context = context_acquire(This, NULL, CTXUSAGE_BLIT); + context = context_acquire(This, NULL); + context_apply_blit_state(context, This); /* First, locate the position data. This is provided in a vertex buffer in the stateblock. * Beware of vbos @@ -800,7 +831,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, { struct wined3d_buffer *vb; vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, context->gl_info)); } vtxStride = e->stride; data = e->data + diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index cb23ee6aa0e..056e9adb45a 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -39,8 +39,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - #define WINED3D_GLSL_SAMPLE_PROJECTED 0x1 #define WINED3D_GLSL_SAMPLE_RECT 0x2 #define WINED3D_GLSL_SAMPLE_LOD 0x4 @@ -89,7 +87,8 @@ struct shader_glsl_priv { struct constant_heap vconst_heap; struct constant_heap pconst_heap; unsigned char *stack; - GLhandleARB depth_blt_program[tex_type_count]; + GLhandleARB depth_blt_program_full[tex_type_count]; + GLhandleARB depth_blt_program_masked[tex_type_count]; UINT next_constant_version; }; @@ -255,7 +254,7 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA /* GL locking is done by the caller. */ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program) { - GLint i, object_count, source_size; + GLint i, object_count, source_size = -1; GLhandleARB *objects; char *source = NULL; @@ -275,7 +274,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp)); - if (!source || source_size < tmp) + if (source_size < tmp) { HeapFree(GetProcessHeap(), 0, source); @@ -719,8 +718,8 @@ static void shader_glsl_load_np2fixup_constants( static void shader_glsl_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; + IWineD3DDeviceImpl *device = context->swapchain->device; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; struct shader_glsl_priv *priv = device->shader_priv; @@ -807,7 +806,7 @@ static void shader_glsl_load_constants(const struct wined3d_context *context, correction_params[1] = 1.0f; } else { /* position is window relative, not viewport relative */ - correction_params[0] = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height; + correction_params[0] = context->current_rt->currentDesc.Height; correction_params[1] = -1.0f; } GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params)); @@ -1034,7 +1033,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont */ FIXME("Cannot find a free uniform for vpos correction params\n"); shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n", - context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height, + context->render_offscreen ? 0.0f : device->render_targets[0]->currentDesc.Height, context->render_offscreen ? 1.0f : -1.0f); } shader_addline(buffer, "vec4 vpos;\n"); @@ -1048,20 +1047,37 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont switch (reg_maps->sampler_type[i]) { case WINED3DSTT_1D: - shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); + if (pshader && ps_args->shadow & (1 << i)) + shader_addline(buffer, "uniform sampler1DShadow %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); break; case WINED3DSTT_2D: - if(device->stateBlock->textures[i] && - IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) == GL_TEXTURE_RECTANGLE_ARB) { - shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i); - } else { - shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); + if (pshader && ps_args->shadow & (1 << i)) + { + if (device->stateBlock->textures[i] + && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) + == GL_TEXTURE_RECTANGLE_ARB) + shader_addline(buffer, "uniform sampler2DRectShadow %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler2DShadow %csampler%u;\n", prefix, i); + } + else + { + if (device->stateBlock->textures[i] + && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) + == GL_TEXTURE_RECTANGLE_ARB) + shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); } break; case WINED3DSTT_CUBE: + if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported Cube shadow sampler.\n"); shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i); break; case WINED3DSTT_VOLUME: + if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported 3D shadow sampler.\n"); shader_addline(buffer, "uniform sampler3D %csampler%u;\n", prefix, i); break; default: @@ -1642,9 +1658,13 @@ static inline const char *shader_get_comp_op(DWORD op) } } -static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_info, - DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function) +static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, + DWORD sampler_idx, DWORD flags, glsl_sample_function_t *sample_function) { + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ctx->reg_maps->sampler_type[sampler_idx]; + const struct wined3d_gl_info *gl_info = ctx->gl_info; + BOOL shadow = shader_is_pshader_version(ctx->reg_maps->shader_version.type) + && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx)); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT; BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; @@ -1653,115 +1673,225 @@ static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_inf /* Note that there's no such thing as a projected cube texture. */ switch(sampler_type) { case WINED3DSTT_1D: - if(lod) { - sample_function->name = projected ? "texture1DProjLod" : "texture1DLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow1DProjLod" : "shadow1DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow1DProjGrad" : "shadow1DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow1DProjGradARB" : "shadow1DGradARB"; + else + { + FIXME("Unsupported 1D shadow grad function.\n"); + sample_function->name = "unsupported1DGrad"; + } + } else { - FIXME("Unsupported 1D grad function.\n"); - sample_function->name = "unsupported1DGrad"; + sample_function->name = projected ? "shadow1DProj" : "shadow1D"; } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; } else { - sample_function->name = projected ? "texture1DProj" : "texture1D"; + if (lod) + { + sample_function->name = projected ? "texture1DProjLod" : "texture1DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB"; + else + { + FIXME("Unsupported 1D grad function.\n"); + sample_function->name = "unsupported1DGrad"; + } + } + else + { + sample_function->name = projected ? "texture1DProj" : "texture1D"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0; break; + case WINED3DSTT_2D: - if(texrect) { - if(lod) { - sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod"; - } - else if (grad) + if (shadow) + { + if (texrect) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow2DRectProjLod" : "shadow2DRectLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow2DRectProjGrad" : "shadow2DRectGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB"; + else + { + FIXME("Unsupported RECT shadow grad function.\n"); + sample_function->name = "unsupported2DRectGrad"; + } + } else { - FIXME("Unsupported RECT grad function.\n"); - sample_function->name = "unsupported2DRectGrad"; + sample_function->name = projected ? "shadow2DRectProj" : "shadow2DRect"; } } else { - sample_function->name = projected ? "texture2DRectProj" : "texture2DRect"; - } - } else { - if(lod) { - sample_function->name = projected ? "texture2DProjLod" : "texture2DLod"; - } - else if (grad) - { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow2DProjLod" : "shadow2DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow2DProjGrad" : "shadow2DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow2DProjGradARB" : "shadow2DGradARB"; + else + { + FIXME("Unsupported 2D shadow grad function.\n"); + sample_function->name = "unsupported2DGrad"; + } + } else { - FIXME("Unsupported 2D grad function.\n"); - sample_function->name = "unsupported2DGrad"; + sample_function->name = projected ? "shadow2DProj" : "shadow2D"; } } - else - { - sample_function->name = projected ? "texture2DProj" : "texture2D"; - } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; + } + else + { + if (texrect) + { + if (lod) + { + sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB"; + else + { + FIXME("Unsupported RECT grad function.\n"); + sample_function->name = "unsupported2DRectGrad"; + } + } + else + { + sample_function->name = projected ? "texture2DRectProj" : "texture2DRect"; + } + } + else + { + if (lod) + { + sample_function->name = projected ? "texture2DProjLod" : "texture2DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB"; + else + { + FIXME("Unsupported 2D grad function.\n"); + sample_function->name = "unsupported2DGrad"; + } + } + else + { + sample_function->name = projected ? "texture2DProj" : "texture2D"; + } + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; break; + case WINED3DSTT_CUBE: - if(lod) { - sample_function->name = "textureCubeLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = "textureCubeGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = "textureCubeGradARB"; - else - { - FIXME("Unsupported Cube grad function.\n"); - sample_function->name = "unsupportedCubeGrad"; - } + FIXME("Unsupported Cube shadow function.\n "); + sample_function->name = "unsupportedCubeShadow"; + sample_function->coord_mask = 0; } else { - sample_function->name = "textureCube"; + if (lod) + { + sample_function->name = "textureCubeLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = "textureCubeGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = "textureCubeGradARB"; + else + { + FIXME("Unsupported Cube grad function.\n"); + sample_function->name = "unsupportedCubeGrad"; + } + } + else + { + sample_function->name = "textureCube"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; break; + case WINED3DSTT_VOLUME: - if(lod) { - sample_function->name = projected ? "texture3DProjLod" : "texture3DLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB"; - else - { - FIXME("Unsupported 3D grad function.\n"); - sample_function->name = "unsupported3DGrad"; - } + FIXME("Unsupported 3D shadow function.\n "); + sample_function->name = "unsupported3DShadow"; + sample_function->coord_mask = 0; } else { - sample_function->name = projected ? "texture3DProj" : "texture3D"; + if (lod) + { + sample_function->name = projected ? "texture3DProjLod" : "texture3DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB"; + else + { + FIXME("Unsupported 3D grad function.\n"); + sample_function->name = "unsupported3DGrad"; + } + } + else + { + sample_function->name = projected ? "texture3DProj" : "texture3D"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; break; + default: sample_function->name = ""; sample_function->coord_mask = 0; @@ -2164,16 +2294,26 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_buffer *buffer = ins->ctx->buffer; glsl_src_param_t src_param; + unsigned int mask_size; DWORD write_mask; char dst_mask[6]; write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask); + mask_size = shader_glsl_get_write_mask_size(write_mask); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); shader_addline(buffer, "tmp0.x = length(%s);\n", src_param.param_str); shader_glsl_append_dst(buffer, ins); - shader_addline(buffer, "tmp0.x == 0.0 ? (%s * FLT_MAX) : (%s / tmp0.x));", - src_param.param_str, src_param.param_str); + if (mask_size > 1) + { + shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s / tmp0.x));\n", + mask_size, src_param.param_str); + } + else + { + shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s / tmp0.x));\n", + src_param.param_str); + } } /** Process the WINED3DSIO_EXPP instruction in GLSL: @@ -2868,10 +3008,8 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_sample_function_t sample_function; DWORD sample_flags = 0; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask = 0, swizzle; @@ -2879,11 +3017,11 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) * 2.0+: Use provided sampler source. */ if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx; else sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if (shader_version < WINED3D_SHADER_VERSION(1,4)) { DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) { @@ -2922,7 +3060,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); mask |= sample_function.coord_mask; if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE; @@ -2960,7 +3098,6 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) glsl_sample_function_t sample_function; glsl_src_param_t coord_param, dx_param, dy_param; DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD; - DWORD sampler_type; DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; @@ -2971,13 +3108,12 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) } sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param); shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param); @@ -2994,17 +3130,15 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) glsl_sample_function_t sample_function; glsl_src_param_t coord_param, lod_param; DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD; - DWORD sampler_type; DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param); @@ -3071,12 +3205,10 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins) * then perform a 1D texture lookup from stage dstregnum, place into dst. */ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; glsl_sample_function_t sample_function; DWORD sampler_idx = ins->dst[0].reg.idx; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; UINT mask_size; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -3086,7 +3218,7 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) * * It is a dependent read - not valid with conditional NP2 textures */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask); switch(mask_size) @@ -3199,18 +3331,16 @@ static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins) static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD reg = ins->dst[0].reg.idx; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; glsl_src_param_t src0_param; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy"); @@ -3223,17 +3353,15 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins) DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD reg = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3266,13 +3394,11 @@ static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins) static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD reg = ins->dst[0].reg.idx; glsl_src_param_t src0_param; glsl_src_param_t src1_param; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; - WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg]; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_sample_function_t sample_function; @@ -3285,7 +3411,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, stype, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3298,13 +3424,11 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD reg = ins->dst[0].reg.idx; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; glsl_src_param_t src0_param; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -3318,7 +3442,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n"); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3334,10 +3458,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_sample_function_t sample_function; glsl_src_param_t coord_param; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask; DWORD flags; @@ -3346,9 +3468,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) sampler_idx = ins->dst[0].reg.idx; flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); mask = sample_function.coord_mask; shader_glsl_write_mask_to_str(mask, coord_mask); @@ -3407,15 +3528,13 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins) * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "%s.wx", src0_param.reg_name); } @@ -3424,15 +3543,13 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "%s.yz", src0_param.reg_name); } @@ -3441,14 +3558,12 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */ static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, @@ -4453,10 +4568,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, } /* GL locking is done by the caller */ -static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked) { GLhandleARB program_id; GLhandleARB vshader_id, pshader_id; + const char *blt_pshader; + static const char *blt_vshader[] = { "#version 120\n" @@ -4468,7 +4585,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n" }; - static const char *blt_pshaders[tex_type_count] = + static const char *blt_pshaders_full[tex_type_count] = { /* tex_1d */ NULL, @@ -4498,7 +4615,44 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n", }; - if (!blt_pshaders[tex_type]) + static const char *blt_pshaders_masked[tex_type_count] = + { + /* tex_1d */ + NULL, + /* tex_2d */ + "#version 120\n" + "uniform sampler2D sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "#version 120\n" + "uniform samplerCube sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n" + "}\n", + /* tex_rect */ + "#version 120\n" + "#extension GL_ARB_texture_rectangle : enable\n" + "uniform sampler2DRect sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + }; + + blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type]; + if (!blt_pshader) { FIXME("tex_type %#x not supported\n", tex_type); tex_type = tex_2d; @@ -4509,7 +4663,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, GL_EXTCALL(glCompileShaderARB(vshader_id)); pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); - GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshaders[tex_type], NULL)); + GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshader, NULL)); GL_EXTCALL(glCompileShaderARB(pshader_id)); program_id = GL_EXTCALL(glCreateProgramObjectARB()); @@ -4530,8 +4684,8 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, /* GL locking is done by the caller */ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; + IWineD3DDeviceImpl *device = context->swapchain->device; struct shader_glsl_priv *priv = device->shader_priv; GLhandleARB program_id = 0; GLenum old_vertex_color_clamp, current_vertex_color_clamp; @@ -4571,21 +4725,34 @@ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS } /* GL locking is done by the caller */ -static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, + enum tex_types tex_type, const SIZE *ds_mask_size) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_glsl_priv *priv = This->shader_priv; - GLhandleARB *blt_program = &priv->depth_blt_program[tex_type]; + GLhandleARB *blt_program; + GLint loc; - if (!*blt_program) { - GLint loc; - *blt_program = create_glsl_blt_shader(gl_info, tex_type); + blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type]; + if (!*blt_program) + { + *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked); loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler")); GL_EXTCALL(glUseProgramObjectARB(*blt_program)); GL_EXTCALL(glUniform1iARB(loc, 0)); - } else { + } + else + { GL_EXTCALL(glUseProgramObjectARB(*blt_program)); } + + if (masked) + { + loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask")); + GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); + } } /* GL locking is done by the caller */ @@ -4625,7 +4792,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { return; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface) @@ -4644,7 +4811,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { return; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface) @@ -4821,9 +4988,13 @@ static void shader_glsl_free(IWineD3DDevice *iface) { ENTER_GL(); for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_program[i]) + if (priv->depth_blt_program_full[i]) { - GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i])); + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i])); + } + if (priv->depth_blt_program_masked[i]) + { + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i])); } } LEAVE_GL(); diff --git a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c index 64bb883d6c8..24cba329f20 100644 --- a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -28,8 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION stateblock->device->adapter->gl_info - /* GL locking for state handlers is done by the caller. */ static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -137,7 +135,6 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; GLenum target = GL_COMBINER0_NV + stage; GLenum output; - IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */ TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); @@ -579,6 +576,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[stage + 1]; + const struct wined3d_gl_info *gl_info = context->gl_info; float mat[2][2]; /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to @@ -587,7 +585,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix * for stage + 1. Keep the nvrc tex unit mapping in mind too */ - if (mapped_stage < context->gl_info->limits.textures) + if (mapped_stage < gl_info->limits.textures) { GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))"); @@ -606,6 +604,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0])); @@ -629,6 +628,15 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) { static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps) { + pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; + + /* The caps below can be supported but aren't handled yet in utils.c + * 'd3dta_to_combiner_input', disable them until support is fixed */ +#if 0 + if (gl_info->supported[NV_REGISTER_COMBINERS2]) + pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT; +#endif + pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD | WINED3DTEXOPCAPS_ADDSIGNED | WINED3DTEXOPCAPS_ADDSIGNED2X | @@ -672,14 +680,6 @@ static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct pCaps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners); pCaps->MaxSimultaneousTextures = gl_info->limits.textures; - - pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; - - /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */ -#if 0 - if (gl_info->supported[NV_REGISTER_COMBINERS2]) - pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT; -#endif } static HRESULT nvrc_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } @@ -713,119 +713,119 @@ static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup) static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), nvrc_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 }, diff --git a/reactos/dll/directx/wine/wined3d/palette.c b/reactos/dll/directx/wine/wined3d/palette.c index 553a08a787b..3fd8be9dd10 100644 --- a/reactos/dll/directx/wine/wined3d/palette.c +++ b/reactos/dll/directx/wine/wined3d/palette.c @@ -74,7 +74,8 @@ static ULONG WINAPI IWineD3DPaletteImpl_Release(IWineD3DPalette *iface) { } /* Not called from the vtable */ -DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) { +static DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) +{ switch (dwFlags & SIZE_BITS) { case WINEDDPCAPS_1BIT: return 2; case WINEDDPCAPS_2BIT: return 4; @@ -183,7 +184,7 @@ static HRESULT WINAPI IWineD3DPaletteImpl_GetParent(IWineD3DPalette *iface, IUn return WINED3D_OK; } -const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = +static const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = { /*** IUnknown ***/ IWineD3DPaletteImpl_QueryInterface, @@ -195,3 +196,33 @@ const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = IWineD3DPaletteImpl_GetCaps, IWineD3DPaletteImpl_SetEntries }; + +HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device, + DWORD flags, const PALETTEENTRY *entries, IUnknown *parent) +{ + HRESULT hr; + + palette->lpVtbl = &IWineD3DPalette_Vtbl; + palette->ref = 1; + palette->parent = parent; + palette->device = device; + palette->Flags = flags; + + palette->palNumEntries = IWineD3DPaletteImpl_Size(flags); + palette->hpal = CreatePalette((const LOGPALETTE *)&palette->palVersion); + if (!palette->hpal) + { + WARN("Failed to create palette.\n"); + return E_FAIL; + } + + hr = IWineD3DPalette_SetEntries((IWineD3DPalette *)palette, 0, 0, IWineD3DPaletteImpl_Size(flags), entries); + if (FAILED(hr)) + { + WARN("Failed to set palette entries, hr %#x.\n", hr); + DeleteObject(palette->hpal); + return hr; + } + + return WINED3D_OK; +} diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index 3860e2c95b5..b3c77eae692 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -25,33 +25,19 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) -static HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, struct wined3d_event_query **query) +BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) { - struct wined3d_event_query *ret; - *query = NULL; - if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE] - && !gl_info->supported[APPLE_FENCE]) return E_NOTIMPL; - - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); - if (!ret) - { - ERR("Failed to allocate a wined3d event query structure.\n"); - return E_OUTOFMEMORY; - } - ret->context = NULL; - *query = ret; - return WINED3D_OK; + return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE]; } -static void wined3d_event_query_destroy(struct wined3d_event_query *query) +void wined3d_event_query_destroy(struct wined3d_event_query *query) { if (query->context) context_free_event_query(query); HeapFree(GetProcessHeap(), 0, query); } -static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) { struct wined3d_context *context; const struct wined3d_gl_info *gl_info; @@ -72,7 +58,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_e return WINED3D_EVENT_QUERY_WRONG_THREAD; } - context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, query->context->current_rt); gl_info = context->gl_info; ENTER_GL(); @@ -125,7 +111,75 @@ static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_e return ret; } -static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +{ + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + enum wined3d_event_query_result ret; + + TRACE("(%p)\n", query); + + if (!query->context) + { + TRACE("Query not started\n"); + return WINED3D_EVENT_QUERY_NOT_STARTED; + } + gl_info = query->context->gl_info; + + if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC]) + { + /* A glFinish does not reliably wait for draws in other contexts. The caller has + * to find its own way to cope with the thread switch + */ + WARN("Event query finished from wrong thread\n"); + return WINED3D_EVENT_QUERY_WRONG_THREAD; + } + + context = context_acquire(device, query->context->current_rt); + + ENTER_GL(); + if (gl_info->supported[ARB_SYNC]) + { + GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, ~(GLuint64)0)); + checkGLcall("glClientWaitSync"); + + switch (gl_ret) + { + case GL_ALREADY_SIGNALED: + case GL_CONDITION_SATISFIED: + ret = WINED3D_EVENT_QUERY_OK; + break; + + /* We don't expect a timeout for a ~584 year wait */ + default: + ERR("glClientWaitSync returned %#x.\n", gl_ret); + ret = WINED3D_EVENT_QUERY_ERROR; + } + } + else if (context->gl_info->supported[APPLE_FENCE]) + { + GL_EXTCALL(glFinishFenceAPPLE(query->object.id)); + checkGLcall("glFinishFenceAPPLE"); + ret = WINED3D_EVENT_QUERY_OK; + } + else if (context->gl_info->supported[NV_FENCE]) + { + GL_EXTCALL(glFinishFenceNV(query->object.id)); + checkGLcall("glFinishFenceNV"); + ret = WINED3D_EVENT_QUERY_OK; + } + else + { + ERR("Event query created without GL support\n"); + ret = WINED3D_EVENT_QUERY_ERROR; + } + LEAVE_GL(); + + context_release(context); + return ret; +} + +void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; @@ -135,17 +189,17 @@ static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3 if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) { context_free_event_query(query); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); context_alloc_event_query(context, query); } else { - context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, query->context->current_rt); } } else { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); context_alloc_event_query(context, query); } @@ -293,7 +347,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, return S_OK; } - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); @@ -430,12 +484,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D FIXME("Wrong thread, can't restart query.\n"); context_free_occlusion_query(query); - context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL); context_alloc_occlusion_query(context, query); } else { - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -446,7 +500,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D else { if (query->context) context_free_occlusion_query(query); - context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL); context_alloc_occlusion_query(context, query); } @@ -470,7 +524,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D } else { - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -525,7 +579,6 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type, IUnknown *parent) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - HRESULT hr; switch (type) { @@ -548,9 +601,7 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, case WINED3DQUERYTYPE_EVENT: TRACE("Event query.\n"); - query->lpVtbl = &IWineD3DEventQuery_Vtbl; - hr = wined3d_event_query_init(gl_info, (struct wined3d_event_query **) &query->extendedData); - if (hr == E_NOTIMPL) + if (!wined3d_event_query_supported(gl_info)) { /* Half-Life 2 needs this query. It does not render the main * menu correctly otherwise. Pretend to support it, faking @@ -558,9 +609,12 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, * lowering performance. */ FIXME("Event query: Unimplemented, but pretending to be supported.\n"); } - else if(FAILED(hr)) + query->lpVtbl = &IWineD3DEventQuery_Vtbl; + query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query)); + if (!query->extendedData) { - return hr; + ERR("Failed to allocate event query memory.\n"); + return E_OUTOFMEMORY; } break; diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index b867586096d..67622a38942 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -28,7 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, + IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { struct IWineD3DResourceClass *resource = &((IWineD3DResourceImpl *)iface)->resource; @@ -247,11 +247,3 @@ HRESULT resource_get_parent(IWineD3DResource *iface, IUnknown **pParent) *pParent = This->resource.parent; return WINED3D_OK; } - -void dumpResources(struct list *list) { - IWineD3DResourceImpl *resource; - - LIST_FOR_EACH_ENTRY(resource, list, IWineD3DResourceImpl, resource.resource_list_entry) { - FIXME("Leftover resource %p with type %d,%s\n", resource, IWineD3DResource_GetType((IWineD3DResource *) resource), debug_d3dresourcetype(IWineD3DResource_GetType((IWineD3DResource *) resource))); - } -} diff --git a/reactos/dll/directx/wine/wined3d/shader.c b/reactos/dll/directx/wine/wined3d/shader.c index 307cadf804c..f26122af869 100644 --- a/reactos/dll/directx/wine/wined3d/shader.c +++ b/reactos/dll/directx/wine/wined3d/shader.c @@ -721,6 +721,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1; else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1; else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1; + else if (ins.handler_idx == WINED3DSIH_RCP) reg_maps->usesrcp = 1; limit = ins.src_count + (ins.predicate ? 1 : 0); for (i = 0; i < limit; ++i) @@ -1150,7 +1151,11 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe if (ins.dst_count) fe->shader_read_dst_param(fe_data, &ptr, &dst_param, &dst_rel_addr); /* Predication token */ - if (ins.predicate) ins.predicate = *ptr++; + if (ins.predicate) + { + FIXME("Predicates not implemented.\n"); + ins.predicate = *ptr++; + } /* Other source tokens */ for (i = 0; i < ins.src_count; ++i) @@ -1399,7 +1404,7 @@ static void shader_cleanup(IWineD3DBaseShader *iface) static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {} static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {} -static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {} +static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) {} static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {} static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {} static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {} @@ -1414,8 +1419,11 @@ static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct s { /* Set the shader caps to 0 for the none shader backend */ caps->VertexShaderVersion = 0; + caps->MaxVertexShaderConst = 0; caps->PixelShaderVersion = 0; caps->PixelShader1xMaxValue = 0.0f; + caps->MaxPixelShaderConst = 0; + caps->VSClipping = FALSE; } static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup) @@ -2017,6 +2025,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, } args->color_fixup[i] = texture->resource.format_desc->color_fixup; + if (texture->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + args->shadow |= 1 << i; + /* Flag samplers that need NP2 texcoord fixup. */ if (!texture->baseTexture.pow2Matrix_identity) { diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 5efe069bb19..4c6d5bfe025 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -35,31 +35,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); -#define GLINFO_LOCATION (*context->gl_info) - /* GL locking for state handlers is done by the caller. */ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context); -static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) -{ - /* Used for states which are not mapped to a gl state as-is, but used somehow different, - * e.g as a parameter for drawing, or which are unimplemented in windows d3d - */ - if(STATE_IS_RENDER(state)) { - WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0); - TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]); - } else { - /* Shouldn't have an unknown type here */ - FIXME("%d no direct mapping to gl of state with unknown type\n", state); - } -} - static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { ERR("Undefined state.\n"); } +static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state)); +} + static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE]; @@ -108,7 +97,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { /* No z test without depth stencil buffers */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ @@ -242,7 +231,8 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; + const struct wined3d_gl_info *gl_info = context->gl_info; int srcBlend = GL_ZERO; int dstBlend = GL_ZERO; @@ -450,10 +440,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state, so it may need updating */ if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -463,6 +450,7 @@ static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]); @@ -491,9 +479,8 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT) { @@ -506,10 +493,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } if (enable_ckey || context->last_was_ckey) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); context->last_was_ckey = enable_ckey; if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] || @@ -621,12 +605,13 @@ static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; int blendEquation = GL_FUNC_ADD; int blendEquationAlpha = GL_FUNC_ADD; /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */ if (stateblock->renderState[WINED3DRS_BLENDOPALPHA] - && !context->gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) + && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) { WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n"); return; @@ -779,6 +764,7 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; /* Note the texture color applies to all textures whereas @@ -788,7 +774,7 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); /* And now the default texture color as well */ - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { /* Note the WINED3DRS value applies to all textures, but GL has one * per texture, so apply it now ready to be used! @@ -804,6 +790,8 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass) { + const struct wined3d_gl_info *gl_info = context->gl_info; + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)"); GL_EXTCALL(glActiveStencilFaceEXT(face)); @@ -831,7 +819,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc GLint stencilPass_ccw = GL_KEEP; /* No stencil test without a stencil buffer. */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); @@ -914,7 +902,8 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -927,7 +916,7 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; glStencilMask(mask); checkGLcall("glStencilMask"); @@ -1402,7 +1391,9 @@ static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, st static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; @@ -1423,7 +1414,9 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; @@ -1525,30 +1518,60 @@ static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE]; + DWORD mask0 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE]; + DWORD mask1 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]; + DWORD mask2 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]; + DWORD mask3 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]; TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", - Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); - glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); + glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); checkGLcall("glColorMask(...)"); - /* depends on WINED3DRS_COLORWRITEENABLE. */ - if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) { - ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n", - stateblock->renderState[WINED3DRS_COLORWRITEENABLE1], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]); + if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) + || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) + { + FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", + mask0, mask1, mask2, mask3); + FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); } } +static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +{ + GL_EXTCALL(glColorMaskIndexedEXT(index, + mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE)); +} + +static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 0, stateblock->renderState[WINED3DRS_COLORWRITEENABLE]); +} + +static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 1, stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]); +} + +static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 2, stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]); +} + +static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 3, stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]); +} + static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) { @@ -1706,6 +1729,12 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str } } +static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + if (stateblock->renderState[WINED3DRS_ZVISIBLE]) + FIXME("WINED3DRS_ZVISIBLE not implemented.\n"); +} + static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) { @@ -1843,13 +1872,6 @@ static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, } } -static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) -{ - if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) { - FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n"); - } -} - static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) { @@ -3083,9 +3105,8 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask) { @@ -3157,6 +3178,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s { DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[texUnit]; + const struct wined3d_gl_info *gl_info = context->gl_info; BOOL generated; int coordIdx; @@ -3168,7 +3190,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s } if (mapped_stage == WINED3D_UNMAPPED_STAGE) return; - if (mapped_stage >= context->gl_info->limits.textures) return; + if (mapped_stage >= gl_info->limits.textures) return; GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glActiveTextureARB"); @@ -3197,21 +3219,20 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void unloadTexCoords(const struct wined3d_context *context) +static void unloadTexCoords(const struct wined3d_gl_info *gl_info) { unsigned int texture_idx; - for (texture_idx = 0; texture_idx < context->gl_info->limits.texture_stages; ++texture_idx) + for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx) { GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } -static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock, +static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si, GLuint *curVBO) { - const struct wined3d_gl_info *gl_info = context->gl_info; const UINT *offset = stateblock->streamOffset; unsigned int mapped_stage = 0; unsigned int textureNo = 0; @@ -3431,8 +3452,8 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru */ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - unloadTexCoords(context); - loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO); + unloadTexCoords(gl_info); + loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO); } } @@ -3603,10 +3624,8 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w * while it was enabled, so re-apply them. */ for (i = 0; i < context->gl_info->limits.texture_stages; ++i) { - if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) { - device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply - (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); - } + if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) + stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); } context->last_was_pshader = FALSE; } @@ -3750,27 +3769,20 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - static BOOL once = FALSE; + WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND]; + static unsigned int once; - switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) { - case WINED3DVBF_1WEIGHTS: - case WINED3DVBF_2WEIGHTS: - case WINED3DVBF_3WEIGHTS: - if(!once) { - once = TRUE; - /* TODO: Implement vertex blending in drawStridedSlow */ - FIXME("Vertex blending enabled, but not supported by hardware\n"); - } - break; + if (f == WINED3DVBF_DISABLE) return; - case WINED3DVBF_TWEENING: - WARN("Tweening not supported yet\n"); - } + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f); + else WARN("Vertex blend flags %#x not supported.\n", f); } static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND]; + const struct wined3d_gl_info *gl_info = context->gl_info; + static unsigned int once; switch(val) { case WINED3DVBF_1WEIGHTS: @@ -3787,7 +3799,7 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s if (!stateblock->device->vertexBlendUsed) { unsigned int i; - for (i = 1; i < context->gl_info->limits.blends; ++i) + for (i = 1; i < gl_info->limits.blends; ++i) { if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) { @@ -3798,19 +3810,15 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s } break; + case WINED3DVBF_TWEENING: + case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */ + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val); + else WARN("Vertex blend flags %#x not supported.\n", val); + /* Fall through. */ case WINED3DVBF_DISABLE: - case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */ glDisable(GL_VERTEX_BLEND_ARB); checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)"); break; - - case WINED3DVBF_TWEENING: - /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have - * vertex weights in the vertices? - * For now we don't report that as supported, so a warn should suffice - */ - WARN("Tweening not supported yet\n"); - break; } } @@ -3975,10 +3983,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock /* This should match any arrays loaded in loadVertexData. * TODO: Only load / unload arrays if we have to. */ -static inline void unloadVertexData(const struct wined3d_context *context) +static inline void unloadVertexData(const struct wined3d_gl_info *gl_info) { - const struct wined3d_gl_info *gl_info = context->gl_info; - glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -3990,11 +3996,13 @@ static inline void unloadVertexData(const struct wined3d_context *context) { glDisableClientState(GL_WEIGHT_ARRAY_ARB); } - unloadTexCoords(context); + unloadTexCoords(gl_info); } -static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i) +static inline void unload_numbered_array(struct wined3d_context *context, int i) { + const struct wined3d_gl_info *gl_info = context->gl_info; + GL_EXTCALL(glDisableVertexAttribArrayARB(i)); checkGLcall("glDisableVertexAttribArrayARB(reg)"); @@ -4004,7 +4012,7 @@ static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, str /* This should match any arrays loaded in loadNumberedArrays * TODO: Only load / unload arrays if we have to. */ -static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static inline void unloadNumberedArrays(struct wined3d_context *context) { /* disable any attribs (this is the same for both GLSL and ARB modes) */ GLint maxAttribs = 16; @@ -4016,7 +4024,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, stru if (glGetError() != GL_NO_ERROR) maxAttribs = 16; for (i = 0; i < maxAttribs; ++i) { - unload_numbered_array(stateblock, context, i); + unload_numbered_array(context, i); } } @@ -4036,14 +4044,14 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, for (i = 0; i < MAX_ATTRIBS; i++) { if (!(stream_info->use_map & (1 << i))) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); continue; } /* Do not load instance data. It will be specified using glTexCoord by drawprim */ if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); stateblock->device->instancedDraw = TRUE; continue; } @@ -4102,10 +4110,10 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, if (stream_info->elements[i].buffer_object) { vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; - ptr += (long) buffer_get_sysmem(vb); + ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info); } - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); switch (stream_info->elements[i].format_desc->format) { @@ -4225,11 +4233,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1)); - VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n", - WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) , - sd->u.s.blendWeights.dwStride, - sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); - if (curVBO != e->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); @@ -4237,8 +4240,13 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } - GL_EXTCALL(glWeightPointerARB)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n", + e->format_desc->gl_vtx_format, + e->format_desc->gl_vtx_type, + e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glWeightPointerARB(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glWeightPointerARB"); @@ -4279,8 +4287,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Vertex Pointers -----------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_POSITION)) { - VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data)); - e = &si->elements[WINED3D_FFP_POSITION]; if (curVBO != e->buffer_object) { @@ -4299,9 +4305,16 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB */ if (!e->buffer_object) { + TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); - } else { + } + else + { + TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", + e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); } @@ -4313,8 +4326,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Normals -------------------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_NORMAL)) { - VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_NORMAL]; if (curVBO != e->buffer_object) { @@ -4322,6 +4333,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB checkGLcall("glBindBufferARB"); curVBO = e->buffer_object; } + + TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glNormalPointer(e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glNormalPointer(...)"); @@ -4344,8 +4358,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_DIFFUSE)) { - VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_DIFFUSE]; if (curVBO != e->buffer_object) { @@ -4354,6 +4366,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } + TRACE("glColorPointer(%#x, %#x %#x, %p);\n", + e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); @@ -4369,7 +4384,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_SPECULAR)) { TRACE("setting specular colour\n"); - VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); e = &si->elements[WINED3D_FFP_SPECULAR]; if (gl_info->supported[EXT_SECONDARY_COLOR]) @@ -4391,8 +4405,10 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts * 4 component secondary colors use it */ - GL_EXTCALL(glSecondaryColorPointerEXT)(format, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); } else @@ -4400,25 +4416,29 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB switch(type) { case GL_UNSIGNED_BYTE: - GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); break; default: FIXME("Add 4 component specular color pointers for type %x\n", type); /* Make sure that the right color component is dropped */ - GL_EXTCALL(glSecondaryColorPointerEXT)(3, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); } } glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } else @@ -4427,15 +4447,15 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB { GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } /* Texture coords -------------------------------------------*/ - loadTexCoords(context, stateblock, si, &curVBO); + loadTexCoords(gl_info, stateblock, si, &curVBO); } static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -4446,13 +4466,13 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi if (context->numberedArraysLoaded && !load_numbered) { - unloadNumberedArrays(stateblock, context); + unloadNumberedArrays(context); context->numberedArraysLoaded = FALSE; context->numbered_array_mask = 0; } else if (context->namedArraysLoaded) { - unloadVertexData(context); + unloadVertexData(context->gl_info); context->namedArraysLoaded = FALSE; } @@ -4618,9 +4638,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s context->last_was_vshader = useVertexShaderFunction; - if(updateFog) { - device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); - } + if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); + if(!useVertexShaderFunction) { int i; for(i = 0; i < MAX_TEXTURES; i++) { @@ -4633,7 +4652,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; UINT width, height; WINED3DVIEWPORT vp = stateblock->viewport; @@ -4671,6 +4690,8 @@ static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) { state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context); } + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) + shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context); } static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -4789,7 +4810,7 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; RECT *pRect = &stateblock->scissorRect; UINT height; UINT width; @@ -4812,6 +4833,8 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; + if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) { GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); } else { @@ -4833,17 +4856,17 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi } const struct StateEntryTemplate misc_state_template[] = { - { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_STREAMSRC, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, @@ -4851,58 +4874,59 @@ const struct StateEntryTemplate misc_state_template[] = { * vshader loadings are untied from each other */ { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, + { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, + { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE }, @@ -4916,9 +4940,9 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE }, @@ -4933,35 +4957,35 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE }, @@ -4969,28 +4993,33 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE }, @@ -5017,8 +5046,8 @@ const struct StateEntryTemplate misc_state_template[] = { const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_VSHADER, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, + { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, /* Clip planes */ { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE }, @@ -5067,14 +5096,14 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { /* Transform states follow */ { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE }, @@ -5349,36 +5378,39 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE }, /* Fog */ { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported, * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states. * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix @@ -5412,96 +5444,95 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BORDERCOLOR), { STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -5512,13 +5543,13 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; -#undef GLINFO_LOCATION /* Context activation is done by the caller. */ static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { } static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps) { + pCaps->PrimitiveMiscCaps = 0; pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD | WINED3DTEXOPCAPS_ADDSIGNED | WINED3DTEXOPCAPS_ADDSIGNED2X | @@ -5626,20 +5657,94 @@ static void prune_invalid_states(struct StateEntry *state_table, const struct wi state_table[i].representative = 0; state_table[i].apply = state_undefined; } + + start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends)); + last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)); + for (i = start; i <= last; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; + } } static void validate_state_table(struct StateEntry *state_table) { - unsigned int i; + static const struct + { + DWORD first; + DWORD last; + } + rs_holes[] = + { + { 1, 1}, + { 3, 3}, + { 17, 18}, + { 21, 21}, + { 42, 45}, + { 61, 127}, + {149, 150}, + {169, 169}, + {177, 177}, + {196, 197}, + { 0, 0}, + }; + static const DWORD simple_states[] = + { + STATE_MATERIAL, + STATE_VDECL, + STATE_STREAMSRC, + STATE_INDEXBUFFER, + STATE_VERTEXSHADERCONSTANT, + STATE_PIXELSHADERCONSTANT, + STATE_VSHADER, + STATE_PIXELSHADER, + STATE_VIEWPORT, + STATE_SCISSORRECT, + STATE_FRONTFACE, + }; + unsigned int i, current; + + for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i) + { + if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first)) + { + if (!state_table[i].representative) + ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i); + } + else if (state_table[i].representative) + ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i); + + if (i == STATE_RENDER(rs_holes[current].last)) ++current; + } + + for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i) + { + if (!state_table[simple_states[i]].representative) + ERR("State %s (%#x) should have a representative.\n", + debug_d3dstate(simple_states[i]), simple_states[i]); + } for (i = 0; i < STATE_HIGHEST + 1; ++i) { DWORD rep = state_table[i].representative; - if (rep && !state_table[rep].representative) + if (rep) { - ERR("State %s (%#x) has invalid representative %s (%#x).\n", - debug_d3dstate(i), i, debug_d3dstate(rep), rep); - state_table[i].representative = 0; + if (state_table[rep].representative != rep) + { + ERR("State %s (%#x) has invalid representative %s (%#x).\n", + debug_d3dstate(i), i, debug_d3dstate(rep), rep); + state_table[i].representative = 0; + } + + if (rep != i) + { + if (state_table[i].apply) + ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i); + } + else if (!state_table[i].apply) + { + ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i); + } } } } @@ -5696,7 +5801,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ * applying later lines, but do not record anything in the state * table */ - if(!cur[i].content.apply) continue; + if (!cur[i].content.representative) continue; handlers = num_handlers(multistate_funcs[cur[i].state]); multistate_funcs[cur[i].state][handlers] = cur[i].content.apply; diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 48f9eacc453..1696646849e 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -757,7 +757,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) { TRACE("Updating scissor rect.\n"); - targetStateBlock->scissorRect = This->scissorRect; + This->scissorRect = targetStateBlock->scissorRect; } map = This->changed.streamSource; @@ -866,7 +866,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) return WINED3D_OK; } -static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl *This) +static void apply_lights(IWineD3DDevice *device, const IWineD3DStateBlockImpl *This) { UINT i; for(i = 0; i < LIGHTMAP_SIZE; i++) { @@ -876,8 +876,8 @@ static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl * { const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry); - IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms); - IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1); + IWineD3DDevice_SetLight(device, light->OriginalIndex, &light->OriginalParms); + IWineD3DDevice_SetLightEnable(device, light->OriginalIndex, light->glIndex != -1); } } } @@ -885,58 +885,58 @@ static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl * static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - IWineD3DDevice *pDevice = (IWineD3DDevice *)This->device; + IWineD3DDevice *device = (IWineD3DDevice *)This->device; unsigned int i; DWORD map; - TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice); + TRACE("(%p) : Applying state block %p ------------------v\n", This, device); TRACE("Blocktype: %d\n", This->blockType); - if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader); + if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(device, This->vertexShader); /* Vertex Shader Constants */ for (i = 0; i < This->num_contained_vs_consts_f; ++i) { - IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i], + IWineD3DDevice_SetVertexShaderConstantF(device, This->contained_vs_consts_f[i], This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1); } for (i = 0; i < This->num_contained_vs_consts_i; ++i) { - IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i], + IWineD3DDevice_SetVertexShaderConstantI(device, This->contained_vs_consts_i[i], This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1); } for (i = 0; i < This->num_contained_vs_consts_b; ++i) { - IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i], + IWineD3DDevice_SetVertexShaderConstantB(device, This->contained_vs_consts_b[i], This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1); } - apply_lights(pDevice, This); + apply_lights(device, This); - if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader); + if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(device, This->pixelShader); /* Pixel Shader Constants */ for (i = 0; i < This->num_contained_ps_consts_f; ++i) { - IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i], + IWineD3DDevice_SetPixelShaderConstantF(device, This->contained_ps_consts_f[i], This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1); } for (i = 0; i < This->num_contained_ps_consts_i; ++i) { - IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i], + IWineD3DDevice_SetPixelShaderConstantI(device, This->contained_ps_consts_i[i], This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1); } for (i = 0; i < This->num_contained_ps_consts_b; ++i) { - IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i], + IWineD3DDevice_SetPixelShaderConstantB(device, This->contained_ps_consts_b[i], This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1); } /* Render */ for (i = 0; i < This->num_contained_render_states; ++i) { - IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i], + IWineD3DDevice_SetRenderState(device, This->contained_render_states[i], This->renderState[This->contained_render_states[i]]); } @@ -946,7 +946,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) DWORD stage = This->contained_tss_states[i].stage; DWORD state = This->contained_tss_states[i].state; - IWineD3DDevice_SetTextureStageState(pDevice, stage, state, This->textureState[stage][state]); + IWineD3DDevice_SetTextureStageState(device, stage, state, This->textureState[stage][state]); } /* Sampler states */ @@ -957,12 +957,12 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) DWORD value = This->samplerState[stage][state]; if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS; - IWineD3DDevice_SetSamplerState(pDevice, stage, state, value); + IWineD3DDevice_SetSamplerState(device, stage, state, value); } for (i = 0; i < This->num_contained_transform_states; ++i) { - IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i], + IWineD3DDevice_SetTransform(device, This->contained_transform_states[i], &This->transforms[This->contained_transform_states[i]]); } @@ -974,40 +974,40 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) if (This->changed.indices) { - IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt); - IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); + IWineD3DDevice_SetIndexBuffer(device, This->pIndexData, This->IndexFmt); + IWineD3DDevice_SetBaseVertexIndex(device, This->baseVertexIndex); } if (This->changed.vertexDecl && This->vertexDecl) { - IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl); + IWineD3DDevice_SetVertexDeclaration(device, This->vertexDecl); } if (This->changed.material) { - IWineD3DDevice_SetMaterial(pDevice, &This->material); + IWineD3DDevice_SetMaterial(device, &This->material); } if (This->changed.viewport) { - IWineD3DDevice_SetViewport(pDevice, &This->viewport); + IWineD3DDevice_SetViewport(device, &This->viewport); } if (This->changed.scissorRect) { - IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect); + IWineD3DDevice_SetScissorRect(device, &This->scissorRect); } map = This->changed.streamSource; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]); + if (map & 1) IWineD3DDevice_SetStreamSource(device, i, This->streamSource[i], 0, This->streamStride[i]); } map = This->changed.streamFreq; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]); + if (map & 1) IWineD3DDevice_SetStreamSourceFreq(device, i, This->streamFreq[i] | This->streamFlags[i]); } map = This->changed.textures; @@ -1018,7 +1018,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) if (!(map & 1)) continue; stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS; - IWineD3DDevice_SetTexture(pDevice, stage, This->textures[i]); + IWineD3DDevice_SetTexture(device, stage, This->textures[i]); } map = This->changed.clipplane; @@ -1032,7 +1032,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) clip[1] = This->clipplane[i][1]; clip[2] = This->clipplane[i][2]; clip[3] = This->clipplane[i][3]; - IWineD3DDevice_SetClipPlane(pDevice, i, clip); + IWineD3DDevice_SetClipPlane(device, i, clip); } This->device->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1; @@ -1044,7 +1044,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) break; } } - TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice); + TRACE("(%p) : Applied state block %p ------------------^\n", This, device); return WINED3D_OK; } @@ -1052,8 +1052,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; IWineD3DDevice *device = (IWineD3DDevice *)This->device; - IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)device; - const struct wined3d_gl_info *gl_info = &ThisDevice->adapter->gl_info; + IWineD3DDeviceImpl *device_impl = (IWineD3DDeviceImpl *)device; + const struct wined3d_gl_info *gl_info = &device_impl->adapter->gl_info; union { WINED3DLINEPATTERN lp; DWORD d; @@ -1070,7 +1070,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat /* Note this may have a large overhead but it should only be executed once, in order to initialize the complete state of the device and all opengl equivalents */ - TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, ThisDevice); + TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, device); /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */ This->blockType = WINED3DSBT_INIT; @@ -1083,11 +1083,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat TRACE("Render states\n"); /* Render states: */ - if (ThisDevice->auto_depth_stencil_buffer != NULL) { + if (device_impl->auto_depth_stencil) IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE); - } else { + else IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE); - } IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE, WINED3DFILL_SOLID); IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE, WINED3DSHADE_GOURAUD); lp.lp.wRepeatFactor = 0; diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index d17d35cc16d..0903f6eecaf 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -34,8 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - static void surface_cleanup(IWineD3DSurfaceImpl *This) { IWineD3DDeviceImpl *device = This->resource.device; @@ -51,7 +49,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) * target, Uninit3D() will activate a context before doing anything. */ if (device->render_targets && device->render_targets[0]) { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } ENTER_GL(); @@ -98,7 +96,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) if (context) context_release(context); } -UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height) +UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height) { UINT size; @@ -123,13 +121,233 @@ UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT al return size; } +struct blt_info +{ + GLenum binding; + GLenum bind_target; + enum tex_types tex_type; + GLfloat coords[4][3]; +}; + +struct float_rect +{ + float l; + float t; + float r; + float b; +}; + +static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) +{ + f->l = ((r->left * 2.0f) / w) - 1.0f; + f->t = ((r->top * 2.0f) / h) - 1.0f; + f->r = ((r->right * 2.0f) / w) - 1.0f; + f->b = ((r->bottom * 2.0f) / h) - 1.0f; +} + +static void surface_get_blt_info(GLenum target, const RECT *rect_in, GLsizei w, GLsizei h, struct blt_info *info) +{ + GLfloat (*coords)[3] = info->coords; + RECT rect; + struct float_rect f; + + if (rect_in) + rect = *rect_in; + else + { + rect.left = 0; + rect.top = h; + rect.right = w; + rect.bottom = 0; + } + + switch (target) + { + default: + FIXME("Unsupported texture target %#x\n", target); + /* Fall back to GL_TEXTURE_2D */ + case GL_TEXTURE_2D: + info->binding = GL_TEXTURE_BINDING_2D; + info->bind_target = GL_TEXTURE_2D; + info->tex_type = tex_2d; + coords[0][0] = (float)rect.left / w; + coords[0][1] = (float)rect.top / h; + coords[0][2] = 0.0f; + + coords[1][0] = (float)rect.right / w; + coords[1][1] = (float)rect.top / h; + coords[1][2] = 0.0f; + + coords[2][0] = (float)rect.left / w; + coords[2][1] = (float)rect.bottom / h; + coords[2][2] = 0.0f; + + coords[3][0] = (float)rect.right / w; + coords[3][1] = (float)rect.bottom / h; + coords[3][2] = 0.0f; + break; + + case GL_TEXTURE_RECTANGLE_ARB: + info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + info->bind_target = GL_TEXTURE_RECTANGLE_ARB; + info->tex_type = tex_rect; + coords[0][0] = rect.left; coords[0][1] = rect.top; coords[0][2] = 0.0f; + coords[1][0] = rect.right; coords[1][1] = rect.top; coords[1][2] = 0.0f; + coords[2][0] = rect.left; coords[2][1] = rect.bottom; coords[2][2] = 0.0f; + coords[3][0] = rect.right; coords[3][1] = rect.bottom; coords[3][2] = 0.0f; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l; + coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r; + coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l; + coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l; + coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r; + coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l; + coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t; + coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t; + coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b; + coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t; + coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t; + coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b; + coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f; + coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f; + coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f; + coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f; + coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f; + coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f; + coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f; + break; + } +} + +static inline void surface_get_rect(IWineD3DSurfaceImpl *This, const RECT *rect_in, RECT *rect_out) +{ + if (rect_in) + *rect_out = *rect_in; + else + { + rect_out->left = 0; + rect_out->top = 0; + rect_out->right = This->currentDesc.Width; + rect_out->bottom = This->currentDesc.Height; + } +} + +/* GL locking and context activation is done by the caller */ +void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) +{ + IWineD3DBaseTextureImpl *texture; + struct blt_info info; + + surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info); + + glEnable(info.bind_target); + checkGLcall("glEnable(bind_target)"); + + /* Bind the texture */ + glBindTexture(info.bind_target, src_surface->texture_name); + checkGLcall("glBindTexture"); + + /* Filtering for StretchRect */ + glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, + wined3d_gl_mag_filter(magLookup, Filter)); + checkGLcall("glTexParameteri"); + glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER, + wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); + checkGLcall("glTexParameteri"); + glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGLcall("glTexEnvi"); + + /* Draw a quad */ + glBegin(GL_TRIANGLE_STRIP); + glTexCoord3fv(info.coords[0]); + glVertex2i(dst_rect->left, dst_rect->top); + + glTexCoord3fv(info.coords[1]); + glVertex2i(dst_rect->right, dst_rect->top); + + glTexCoord3fv(info.coords[2]); + glVertex2i(dst_rect->left, dst_rect->bottom); + + glTexCoord3fv(info.coords[3]); + glVertex2i(dst_rect->right, dst_rect->bottom); + glEnd(); + + /* Unbind the texture */ + glBindTexture(info.bind_target, 0); + checkGLcall("glBindTexture(info->bind_target, 0)"); + + /* We changed the filtering settings on the texture. Inform the + * container about this to get the filters reset properly next draw. */ + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DBaseTexture, (void **)&texture))) + { + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; + IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); + } +} + HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment, UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); void (*cleanup)(IWineD3DSurfaceImpl *This); unsigned int resource_size; HRESULT hr; @@ -226,7 +444,7 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, } /* Mark the texture as dirty so that it gets loaded first time around. */ - surface_add_dirty_rect((IWineD3DSurface *)surface, NULL); + surface_add_dirty_rect(surface, NULL); list_init(&surface->renderbuffers); TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size); @@ -243,64 +461,59 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, return hr; } -static void surface_force_reload(IWineD3DSurface *iface) +static void surface_force_reload(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - - This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); + surface->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); } -void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb) +void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint new_name, BOOL srgb) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; GLuint *name; DWORD flag; + TRACE("surface %p, new_name %u, srgb %#x.\n", surface, new_name, srgb); + if(srgb) { - name = &This->texture_name_srgb; + name = &surface->texture_name_srgb; flag = SFLAG_INSRGBTEX; } else { - name = &This->texture_name; + name = &surface->texture_name; flag = SFLAG_INTEXTURE; } - TRACE("(%p) : setting texture name %u\n", This, new_name); - if (!*name && new_name) { /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the * surface has no texture name yet. See if we can get rid of this. */ - if (This->Flags & flag) + if (surface->Flags & flag) ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n"); - IWineD3DSurface_ModifyLocation(iface, flag, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, flag, FALSE); } *name = new_name; - surface_force_reload(iface); + surface_force_reload(surface); } -void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) +void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + TRACE("surface %p, target %#x.\n", surface, target); - TRACE("(%p) : setting target %#x\n", This, target); - - if (This->texture_target != target) + if (surface->texture_target != target) { if (target == GL_TEXTURE_RECTANGLE_ARB) { - This->Flags &= ~SFLAG_NORMCOORD; + surface->Flags &= ~SFLAG_NORMCOORD; } - else if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) + else if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) { - This->Flags |= SFLAG_NORMCOORD; + surface->Flags |= SFLAG_NORMCOORD; } } - This->texture_target = target; - surface_force_reload(iface); + surface->texture_target = target; + surface_force_reload(surface); } /* Context activation is done by the caller. */ @@ -334,8 +547,9 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) { /* This function checks if the primary render target uses the 8bit paletted format. */ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) { - if (device->render_targets && device->render_targets[0]) { - IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0]; + if (device->render_targets && device->render_targets[0]) + { + IWineD3DSurfaceImpl *render_target = device->render_targets[0]; if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) && (render_target->resource.format_desc->format == WINED3DFMT_P8_UINT)) return TRUE; @@ -343,15 +557,12 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) return FALSE; } -#undef GLINFO_LOCATION - -#define GLINFO_LOCATION This->resource.device->adapter->gl_info - /* This call just downloads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_download_data(IWineD3DSurfaceImpl *This) { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_download_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info) +{ + const struct wined3d_format_desc *format_desc = This->resource.format_desc; /* Only support read back of converted P8 surfaces */ if (This->Flags & SFLAG_CONVERTED && format_desc->format != WINED3DFMT_P8_UINT) @@ -502,11 +713,28 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { /* This call just uploads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_upload_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + const struct wined3d_format_desc *format_desc, BOOL srgb, const GLvoid *data) +{ + GLsizei width = This->currentDesc.Width; + GLsizei height = This->currentDesc.Height; + GLenum internal; + + if (srgb) + { + internal = format_desc->glGammaInternal; + } + else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This)) + { + internal = format_desc->rtInternal; + } + else + { + internal = format_desc->glInternal; + } TRACE("This %p, internal %#x, width %d, height %d, format %#x, type %#x, data %p.\n", - This, internal, width, height, format, type, data); + This, internal, width, height, format_desc->glFormat, format_desc->glType, data); TRACE("target %#x, level %u, resource size %u.\n", This->texture_target, This->texture_level, This->resource.size); @@ -536,7 +764,7 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi TRACE("Calling glTexSubImage2D.\n"); glTexSubImage2D(This->texture_target, This->texture_level, - 0, 0, width, height, format, type, data); + 0, 0, width, height, format_desc->glFormat, format_desc->glType, data); checkGLcall("glTexSubImage2D"); } @@ -547,32 +775,58 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi } LEAVE_GL(); + + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + { + IWineD3DDeviceImpl *device = This->resource.device; + unsigned int i; + + for (i = 0; i < device->numContexts; ++i) + { + context_surface_update(device->contexts[i], This); + } + } } /* This call just allocates the texture, the caller is responsible for binding * the correct texture. */ /* Context activation is done by the caller. */ -static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) { - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_allocate_surface(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + const struct wined3d_format_desc *format_desc, BOOL srgb) +{ BOOL enable_client_storage = FALSE; + GLsizei width = This->pow2Width; + GLsizei height = This->pow2Height; const BYTE *mem = NULL; + GLenum internal; + + if (srgb) + { + internal = format_desc->glGammaInternal; + } + else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This)) + { + internal = format_desc->rtInternal; + } + else + { + internal = format_desc->glInternal; + } if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale; TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n", This, This->texture_target, This->texture_level, debug_d3dformat(format_desc->format), - internal, width, height, format, type); + internal, width, height, format_desc->glFormat, format_desc->glType); ENTER_GL(); if (gl_info->supported[APPLE_CLIENT_STORAGE]) { - if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_OVERSIZE | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) { + if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) { /* In some cases we want to disable client storage. * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... - * SFLAG_OVERSIZE: The gl texture is smaller than the allocated memory * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively */ @@ -598,7 +852,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, else { glTexImage2D(This->texture_target, This->texture_level, - internal, width, height, 0, format, type, mem); + internal, width, height, 0, format_desc->glFormat, format_desc->glType, mem); checkGLcall("glTexImage2D"); } @@ -613,15 +867,15 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ /* GL locking is done by the caller */ -void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; +void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) +{ + const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; renderbuffer_entry_t *entry; GLuint renderbuffer = 0; unsigned int src_width, src_height; - src_width = This->pow2Width; - src_height = This->pow2Height; + src_width = surface->pow2Width; + src_height = surface->pow2Height; /* A depth stencil smaller than the render target is not valid */ if (width > src_width || height > src_height) return; @@ -630,51 +884,53 @@ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int wi if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || (width == src_width && height == src_height)) { - This->current_renderbuffer = NULL; + surface->current_renderbuffer = NULL; return; } /* Look if we've already got a renderbuffer of the correct dimensions */ - LIST_FOR_EACH_ENTRY(entry, &This->renderbuffers, renderbuffer_entry_t, entry) { - if (entry->width == width && entry->height == height) { + LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, renderbuffer_entry_t, entry) + { + if (entry->width == width && entry->height == height) + { renderbuffer = entry->id; - This->current_renderbuffer = entry; + surface->current_renderbuffer = entry; break; } } - if (!renderbuffer) { + if (!renderbuffer) + { gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, - This->resource.format_desc->glInternal, width, height); + surface->resource.format_desc->glInternal, width, height); entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t)); entry->width = width; entry->height = height; entry->id = renderbuffer; - list_add_head(&This->renderbuffers, &entry->entry); + list_add_head(&surface->renderbuffers, &entry->entry); - This->current_renderbuffer = entry; + surface->current_renderbuffer = entry; } checkGLcall("set_compatible_renderbuffer"); } -GLenum surface_get_gl_buffer(IWineD3DSurface *iface) +GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->container; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; - TRACE("iface %p.\n", iface); + TRACE("surface %p.\n", surface); - if (!(This->Flags & SFLAG_SWAPCHAIN)) + if (!(surface->Flags & SFLAG_SWAPCHAIN)) { - ERR("Surface %p is not on a swapchain.\n", iface); + ERR("Surface %p is not on a swapchain.\n", surface); return GL_NONE; } - if (swapchain->backBuffer && swapchain->backBuffer[0] == iface) + if (swapchain->back_buffers && swapchain->back_buffers[0] == surface) { if (swapchain->render_to_fbo) { @@ -684,7 +940,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface) TRACE("Returning GL_BACK\n"); return GL_BACK; } - else if (swapchain->frontBuffer == iface) + else if (surface == swapchain->front_buffer) { TRACE("Returning GL_FRONT\n"); return GL_FRONT; @@ -695,35 +951,35 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface) } /* Slightly inefficient way to handle multiple dirty rects but it works :) */ -void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) +void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DBaseTexture *baseTexture = NULL; - if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE)) - IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */); + TRACE("surface %p, dirty_rect %s.\n", surface, wine_dbgstr_rect(dirty_rect)); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); + if (!(surface->Flags & SFLAG_INSYSMEM) && (surface->Flags & SFLAG_INTEXTURE)) + /* No partial locking for textures yet. */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE); if (dirty_rect) { - This->dirtyRect.left = min(This->dirtyRect.left, dirty_rect->left); - This->dirtyRect.top = min(This->dirtyRect.top, dirty_rect->top); - This->dirtyRect.right = max(This->dirtyRect.right, dirty_rect->right); - This->dirtyRect.bottom = max(This->dirtyRect.bottom, dirty_rect->bottom); + surface->dirtyRect.left = min(surface->dirtyRect.left, dirty_rect->left); + surface->dirtyRect.top = min(surface->dirtyRect.top, dirty_rect->top); + surface->dirtyRect.right = max(surface->dirtyRect.right, dirty_rect->right); + surface->dirtyRect.bottom = max(surface->dirtyRect.bottom, dirty_rect->bottom); } else { - This->dirtyRect.left = 0; - This->dirtyRect.top = 0; - This->dirtyRect.right = This->currentDesc.Width; - This->dirtyRect.bottom = This->currentDesc.Height; + surface->dirtyRect.left = 0; + surface->dirtyRect.top = 0; + surface->dirtyRect.right = surface->currentDesc.Width; + surface->dirtyRect.bottom = surface->currentDesc.Height; } - TRACE("(%p) : Dirty: yes, Rect:(%d, %d, %d, %d)\n", This, This->dirtyRect.left, - This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom); - /* if the container is a basetexture then mark it dirty. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture))) + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&baseTexture))) { TRACE("Passing to container\n"); IWineD3DBaseTexture_SetDirty(baseTexture, TRUE); @@ -731,15 +987,59 @@ void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) } } -static inline BOOL surface_can_stretch_rect(IWineD3DSurfaceImpl *src, IWineD3DSurfaceImpl *dst) +static BOOL surface_convert_color_to_argb(IWineD3DSurfaceImpl *This, DWORD color, DWORD *argb_color) { - return ((src->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (src->resource.usage & WINED3DUSAGE_RENDERTARGET)) - && ((dst->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (dst->resource.usage & WINED3DUSAGE_RENDERTARGET)) - && (src->resource.format_desc->format == dst->resource.format_desc->format - || (is_identity_fixup(src->resource.format_desc->color_fixup) - && is_identity_fixup(dst->resource.format_desc->color_fixup))); + IWineD3DDeviceImpl *device = This->resource.device; + + switch(This->resource.format_desc->format) + { + case WINED3DFMT_P8_UINT: + { + DWORD alpha; + + if (primary_render_target_is_p8(device)) + alpha = color << 24; + else + alpha = 0xFF000000; + + if (This->palette) { + *argb_color = (alpha | + (This->palette->palents[color].peRed << 16) | + (This->palette->palents[color].peGreen << 8) | + (This->palette->palents[color].peBlue)); + } else { + *argb_color = alpha; + } + } + break; + + case WINED3DFMT_B5G6R5_UNORM: + { + if (color == 0xFFFF) { + *argb_color = 0xFFFFFFFF; + } else { + *argb_color = ((0xFF000000) | + ((color & 0xF800) << 8) | + ((color & 0x07E0) << 5) | + ((color & 0x001F) << 3)); + } + } + break; + + case WINED3DFMT_B8G8R8_UNORM: + case WINED3DFMT_B8G8R8X8_UNORM: + *argb_color = 0xFF000000 | color; + break; + + case WINED3DFMT_B8G8R8A8_UNORM: + *argb_color = color; + break; + + default: + ERR("Unhandled conversion from %s to ARGB!\n", debug_d3dformat(This->resource.format_desc->format)); + return FALSE; + } + return TRUE; } static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) @@ -764,46 +1064,49 @@ static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) IWineD3DSurface IWineD3DResource parts follow **************************************************** */ -void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) +void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb) { /* TODO: check for locks */ - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.device; + IWineD3DDeviceImpl *device = surface->resource.device; IWineD3DBaseTexture *baseTexture = NULL; - TRACE("(%p)Checking to see if the container is a base texture\n", This); - if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { - IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture; + TRACE("(%p)Checking to see if the container is a base texture\n", surface); + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&baseTexture))) + { + IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *)baseTexture; TRACE("Passing to container\n"); tex_impl->baseTexture.internal_preload(baseTexture, srgb); IWineD3DBaseTexture_Release(baseTexture); } else { struct wined3d_context *context = NULL; - TRACE("(%p) : About to load surface\n", This); + TRACE("(%p) : About to load surface\n", surface); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT - || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) + if (surface->resource.format_desc->format == WINED3DFMT_P8_UINT + || surface->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - if(palette9_changed(This)) { + if (palette9_changed(surface)) + { TRACE("Reloading surface because the d3d8/9 palette was changed\n"); /* TODO: This is not necessarily needed with hw palettized texture support */ - IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */ - IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } - IWineD3DSurface_LoadTexture(iface, srgb == SRGB_SRGB ? TRUE : FALSE); + IWineD3DSurface_LoadTexture((IWineD3DSurface *)surface, srgb == SRGB_SRGB ? TRUE : FALSE); - if (This->resource.pool == WINED3DPOOL_DEFAULT) { + if (surface->resource.pool == WINED3DPOOL_DEFAULT) + { /* Tell opengl to try and keep this texture in video ram (well mostly) */ GLclampf tmp; tmp = 0.9f; ENTER_GL(); - glPrioritizeTextures(1, &This->texture_name, &tmp); + glPrioritizeTextures(1, &surface->texture_name, &tmp); LEAVE_GL(); } @@ -811,12 +1114,14 @@ void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) } } -static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) { - surface_internal_preload(iface, SRGB_ANY); +static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) +{ + surface_internal_preload((IWineD3DSurfaceImpl *)iface, SRGB_ANY); } /* Context activation is done by the caller. */ -static void surface_remove_pbo(IWineD3DSurfaceImpl *This) { +static void surface_remove_pbo(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info) +{ This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT); This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); @@ -834,27 +1139,26 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) { This->Flags &= ~SFLAG_PBO; } -BOOL surface_init_sysmem(IWineD3DSurface *iface) +BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - - if(!This->resource.allocatedMemory) + if (!surface->resource.allocatedMemory) { - This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT); - if(!This->resource.heapMemory) + surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + surface->resource.size + RESOURCE_ALIGNMENT); + if (!surface->resource.heapMemory) { ERR("Out of memory\n"); return FALSE; } - This->resource.allocatedMemory = - (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); + surface->resource.allocatedMemory = + (BYTE *)(((ULONG_PTR)surface->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); } else { - memset(This->resource.allocatedMemory, 0, This->resource.size); + memset(surface->resource.allocatedMemory, 0, surface->resource.size); } - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE); return TRUE; } @@ -879,8 +1183,10 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { * or the depth stencil into an FBO the texture or render buffer will be removed * and all flags get lost */ - surface_init_sysmem(iface); - } else { + surface_init_sysmem(This); + } + else + { /* Load the surface into system memory */ IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE); @@ -889,13 +1195,12 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE); This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; /* Destroy PBOs, but load them into real sysmem before */ - if(This->Flags & SFLAG_PBO) { - surface_remove_pbo(This); - } + if (This->Flags & SFLAG_PBO) + surface_remove_pbo(This, gl_info); /* Destroy fbo render buffers. This is needed for implicit render targets, for * all application-created targets the application has to release the surface @@ -936,7 +1241,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { /* Read the framebuffer back into the surface */ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, void *dest, UINT pitch) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BYTE *mem; GLint fmt; @@ -964,26 +1270,29 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v * should help here. Furthermore unlockrect will need the context set up for blitting. The context manager will find * context->last_was_blit set on the unlock. */ - context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); + context = context_acquire(device, This); + context_apply_blit_state(context, device); + gl_info = context->gl_info; + ENTER_GL(); /* Select the correct read buffer, and give some debug output. * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (surface_is_offscreen((IWineD3DSurface *) This)) + if (surface_is_offscreen(This)) { /* Locking the primary render target which is not on a swapchain(=offscreen render target). * Read from the back buffer */ TRACE("Locking offscreen render target\n"); - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); srcIsUpsideDown = TRUE; } else { /* Onscreen surfaces are always part of a swapchain */ - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Locking %#x buffer\n", buffer); glReadBuffer(buffer); checkGLcall("glReadBuffer"); @@ -1005,7 +1314,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v { case WINED3DFMT_P8_UINT: { - if(primary_render_target_is_p8(myDevice)) { + if (primary_render_target_is_p8(device)) + { /* In case of P8 render targets the index is stored in the alpha component */ fmt = GL_ALPHA; type = GL_UNSIGNED_BYTE; @@ -1140,7 +1450,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v * the same color but we have no choice. * In case of P8 render targets, the index is stored in the alpha component so no conversion is needed. */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(myDevice)) + if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(device)) { const PALETTEENTRY *pal = NULL; DWORD width = pitch / 3; @@ -1180,20 +1490,18 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) { IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - int bpp; - GLenum format, internal, type; - CONVERT_TYPES convert; GLint prevRead; - BOOL alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED; - - d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb); /* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer * locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any * states in the stateblock, and no driver was found yet that had bugs in that regard. */ - context = context_acquire(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, This); + gl_info = context->gl_info; + + surface_prepare_texture(This, gl_info, srgb); surface_bind_and_dirtify(This, srgb); ENTER_GL(); @@ -1204,9 +1512,9 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (!surface_is_offscreen((IWineD3DSurface *)This)) + if (!surface_is_offscreen(This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Locking %#x buffer\n", buffer); ENTER_GL(); @@ -1226,12 +1534,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) LEAVE_GL(); } - if(!(This->Flags & alloc_flag)) { - surface_allocate_surface(This, internal, This->pow2Width, - This->pow2Height, format, type); - This->Flags |= alloc_flag; - } - ENTER_GL(); /* If !SrcIsUpsideDown we should flip the surface. * This can be done using glCopyTexSubImage2D but this @@ -1254,34 +1556,47 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) } /* Context activation is done by the caller. */ -void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) +static void surface_prepare_texture_internal(IWineD3DSurfaceImpl *surface, + const struct wined3d_gl_info *gl_info, BOOL srgb) { DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED; - GLenum format, internal, type; - GLsizei width, height; CONVERT_TYPES convert; - int bpp; + struct wined3d_format_desc desc; if (surface->Flags & alloc_flag) return; - d3dfmt_get_conv(surface, TRUE, TRUE, &format, &internal, &type, &convert, &bpp, srgb); - if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED; + d3dfmt_get_conv(surface, TRUE, TRUE, &desc, &convert); + if(convert != NO_CONVERSION || desc.convert) surface->Flags |= SFLAG_CONVERTED; else surface->Flags &= ~SFLAG_CONVERTED; - if ((surface->Flags & SFLAG_NONPOW2) && !(surface->Flags & SFLAG_OVERSIZE)) + surface_bind_and_dirtify(surface, srgb); + surface_allocate_surface(surface, gl_info, &desc, srgb); + surface->Flags |= alloc_flag; +} + +/* Context activation is done by the caller. */ +void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb) +{ + IWineD3DBaseTextureImpl *texture; + + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&texture))) { - width = surface->pow2Width; - height = surface->pow2Height; - } - else - { - width = surface->glRect.right - surface->glRect.left; - height = surface->glRect.bottom - surface->glRect.top; + UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count; + UINT i; + + TRACE("surface %p is a subresource of texture %p.\n", surface, texture); + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *s = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i]; + surface_prepare_texture_internal(s, gl_info, srgb); + } + + IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); } - surface_bind_and_dirtify(surface, srgb); - surface_allocate_surface(surface, internal, width, height, format, type); - surface->Flags |= alloc_flag; + surface_prepare_texture_internal(surface, gl_info, srgb); } static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) @@ -1312,7 +1627,7 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) GLenum error; struct wined3d_context *context; - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); ENTER_GL(); GL_EXTCALL(glGenBuffersARB(1, &This->pbo)); @@ -1360,10 +1675,11 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; const RECT *pass_rect = pRect; - TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory); + TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n", + iface, pLockedRect, wine_dbgstr_rect(pRect), Flags); /* This is also done in the base class, but we have to verify this before loading any data from * gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag @@ -1404,7 +1720,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED } if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE - && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0]))) + && ((This->Flags & SFLAG_SWAPCHAIN) || This == device->render_targets[0]))) { IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect); } @@ -1412,9 +1728,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED lock_end: if (This->Flags & SFLAG_PBO) { + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo)); checkGLcall("glBindBufferARB"); @@ -1443,7 +1762,7 @@ lock_end: * Dirtify on lock * as seen in msdn docs */ - surface_add_dirty_rect(iface, pRect); + surface_add_dirty_rect(This, pRect); /** Dirtify Container if needed */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) { @@ -1463,16 +1782,20 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm GLint prev_rasterpos[4]; GLint skipBytes = 0; UINT pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This); /* target is argb, 4 byte */ - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; /* Activate the correct context for the render target */ - context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); + context = context_acquire(device, This); + context_apply_blit_state(context, device); + gl_info = context->gl_info; + ENTER_GL(); - if (!surface_is_offscreen((IWineD3DSurface *)This)) + if (!surface_is_offscreen(This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Unlocking %#x buffer.\n", buffer); context_set_draw_buffer(context, buffer); } @@ -1480,7 +1803,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm { /* Primary offscreen render target */ TRACE("Offscreen render target.\n"); - context_set_draw_buffer(context, myDevice->offscreenBuffer); + context_set_draw_buffer(context, device->offscreenBuffer); } glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store); @@ -1553,7 +1876,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; BOOL fullsurface; if (!(This->Flags & SFLAG_LOCKED)) { @@ -1563,11 +1886,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { if (This->Flags & SFLAG_PBO) { + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; TRACE("Freeing PBO memory\n"); - context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo)); GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); @@ -1586,7 +1912,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { goto unlock_end; } - if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0])) + if ((This->Flags & SFLAG_SWAPCHAIN) || (device->render_targets && This == device->render_targets[0])) { if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) { static BOOL warned = FALSE; @@ -1633,7 +1959,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { This->dirtyRect.top = This->currentDesc.Height; This->dirtyRect.right = 0; This->dirtyRect.bottom = 0; - } else if(iface == myDevice->stencilBufferTarget) { + } + else if (This == device->depth_stencil) + { FIXME("Depth Stencil buffer locking is not implemented\n"); } else { /* The rest should be a normal texture */ @@ -1643,9 +1971,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { * states need resetting */ if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) { - if(impl->baseTexture.bindCount) { - IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler)); - } + if (impl->baseTexture.bindCount) + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(impl->baseTexture.sampler)); IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl); } } @@ -1661,35 +1988,34 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { return WINED3D_OK; } -static void surface_release_client_storage(IWineD3DSurface *iface) +static void surface_release_client_storage(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; struct wined3d_context *context; - context = context_acquire(This->resource.device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(surface->resource.device, NULL); ENTER_GL(); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - if(This->texture_name) + if (surface->texture_name) { - surface_bind_and_dirtify(This, FALSE); - glTexImage2D(This->texture_target, This->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + surface_bind_and_dirtify(surface, FALSE); + glTexImage2D(surface->texture_target, surface->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } - if(This->texture_name_srgb) + if (surface->texture_name_srgb) { - surface_bind_and_dirtify(This, TRUE); - glTexImage2D(This->texture_target, This->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + surface_bind_and_dirtify(surface, TRUE); + glTexImage2D(surface->texture_target, surface->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); LEAVE_GL(); context_release(context); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); - surface_force_reload(iface); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSRGBTEX, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); + surface_force_reload(surface); } static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) @@ -1720,7 +2046,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD if(!This->hDC) { if(This->Flags & SFLAG_CLIENT) { IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); - surface_release_client_storage(iface); + surface_release_client_storage(This); } hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface); if(FAILED(hr)) return WINED3DERR_INVALIDCALL; @@ -1761,7 +2087,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; - dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; + dds_primary = swapchain->front_buffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } @@ -1815,28 +2141,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC IWineD3DSurface Internal (No mapping to directx api) parts follow ****************************************************** */ -HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) { +HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, struct wined3d_format_desc *desc, CONVERT_TYPES *convert) +{ BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT); - const struct GlPixelFormatDesc *glDesc = This->resource.format_desc; IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + BOOL blit_supported = FALSE; + RECT rect = {0, 0, This->pow2Width, This->pow2Height}; - /* Default values: From the surface */ - *format = glDesc->glFormat; - *type = glDesc->glType; + /* Copy the default values from the surface. Below we might perform fixups */ + /* TODO: get rid of color keying desc fixups by using e.g. a table. */ + *desc = *This->resource.format_desc; *convert = NO_CONVERSION; - *target_bpp = glDesc->byte_count; - - if(srgb_mode) { - *internal = glDesc->glGammaInternal; - } - else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET - && surface_is_offscreen((IWineD3DSurface *) This)) - { - *internal = glDesc->rtInternal; - } else { - *internal = glDesc->glInternal; - } /* Ok, now look if we have to do any conversion */ switch(This->resource.format_desc->format) @@ -1846,34 +2161,30 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ Paletted Texture **************** */ - /* Use conversion when the paletted texture extension OR fragment shaders are available. When either - * of the two is available make sure texturing is requested as neither of the two works in - * conjunction with calls like glDraw-/glReadPixels. Further also use conversion in case of color keying. + blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &rect, This->resource.usage, This->resource.pool, + This->resource.format_desc, &rect, This->resource.usage, + This->resource.pool, This->resource.format_desc); + + /* Use conversion when the blit_shader backend supports it. It only supports this in case of + * texturing. Further also use conversion in case of color keying. * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which * conflicts with this. */ - if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup) - && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0])) + if (!((blit_supported && device->render_targets && This == device->render_targets[0])) || colorkey_active || !use_texturing) { - *format = GL_RGBA; - *internal = GL_RGBA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 4; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA; + desc->glType = GL_UNSIGNED_BYTE; + desc->conv_byte_count = 4; if(colorkey_active) { *convert = CONVERT_PALETTED_CK; } else { *convert = CONVERT_PALETTED; } } - else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)) - { - *format = GL_ALPHA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 1; - } - break; case WINED3DFMT_B2G3R3_UNORM: @@ -1890,149 +2201,40 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ case WINED3DFMT_B5G6R5_UNORM: if (colorkey_active) { *convert = CONVERT_CK_565; - *format = GL_RGBA; - *internal = GL_RGB5_A1; - *type = GL_UNSIGNED_SHORT_5_5_5_1; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGB5_A1; + desc->glType = GL_UNSIGNED_SHORT_5_5_5_1; + desc->conv_byte_count = 2; } break; case WINED3DFMT_B5G5R5X1_UNORM: if (colorkey_active) { *convert = CONVERT_CK_5551; - *format = GL_BGRA; - *internal = GL_RGB5_A1; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + desc->glFormat = GL_BGRA; + desc->glInternal = GL_RGB5_A1; + desc->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV; + desc->conv_byte_count = 2; } break; case WINED3DFMT_B8G8R8_UNORM: if (colorkey_active) { *convert = CONVERT_CK_RGB24; - *format = GL_RGBA; - *internal = GL_RGBA8; - *type = GL_UNSIGNED_INT_8_8_8_8; - *target_bpp = 4; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA8; + desc->glType = GL_UNSIGNED_INT_8_8_8_8; + desc->conv_byte_count = 4; } break; case WINED3DFMT_B8G8R8X8_UNORM: if (colorkey_active) { *convert = CONVERT_RGB32_888; - *format = GL_RGBA; - *internal = GL_RGBA8; - *type = GL_UNSIGNED_INT_8_8_8_8; - } - break; - - case WINED3DFMT_R8G8_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_V8U8; - *format = GL_BGR; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 3; - break; - - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - *convert = CONVERT_L6V5U5; - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - *target_bpp = 3; - /* Use format and types from table */ - } else { - /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */ - *target_bpp = 2; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - } - break; - - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - *convert = CONVERT_X8L8V8U8; - *target_bpp = 4; - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* Use formats from gl table. It is a bit unfortunate, but the conversion - * is needed to set the X format to 255 to get 1.0 for alpha when sampling - * the texture. OpenGL can't use GL_DSDT8_MAG8_NV as internal format with - * the needed type and format parameter, so the internal format contains a - * 4th component, which is returned as alpha - */ - } else { - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - break; - - case WINED3DFMT_R8G8B8A8_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_Q8W8V8U8; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 4; - break; - - case WINED3DFMT_R16G16_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_V16U16; - *format = GL_BGR; - *type = GL_UNSIGNED_SHORT; - *target_bpp = 6; - break; - - case WINED3DFMT_L4A4_UNORM: - /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not - * format+type combination to load it. Thus convert it to A8L8, then load it - * with A4L4 internal, but A8L8 format+type - */ - *convert = CONVERT_A4L4; - *format = GL_LUMINANCE_ALPHA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 2; - break; - - case WINED3DFMT_R16G16_UNORM: - *convert = CONVERT_G16R16; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT; - *target_bpp = 6; - break; - - case WINED3DFMT_R16G16_FLOAT: - *convert = CONVERT_R16G16F; - *format = GL_RGB; - *type = GL_HALF_FLOAT_ARB; - *target_bpp = 6; - break; - - case WINED3DFMT_R32G32_FLOAT: - *convert = CONVERT_R32G32F; - *format = GL_RGB; - *type = GL_FLOAT; - *target_bpp = 12; - break; - - case WINED3DFMT_S1_UINT_D15_UNORM: - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] - || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) - { - *convert = CONVERT_D15S1; - *target_bpp = 4; - } - break; - - case WINED3DFMT_S4X4_UINT_D24_UNORM: - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] - || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) - { - *convert = CONVERT_D24X4S4; - } - break; - - case WINED3DFMT_S8_UINT_D24_FLOAT: - if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT]) - { - *convert = CONVERT_D24FS8; - *target_bpp = 8; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA8; + desc->glType = GL_UNSIGNED_INT_8_8_8_8; + desc->conv_byte_count = 4; } break; @@ -2043,7 +2245,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ return WINED3D_OK; } -static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) +void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) { IWineD3DDeviceImpl *device = This->resource.device; IWineD3DPaletteImpl *pal = This->palette; @@ -2126,8 +2328,6 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4] static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const BYTE *source; BYTE *dest; TRACE("(%p)->(%p),(%d,%d,%d,%d,%p)\n", src, dst, pitch, height, outpitch, convert,This); @@ -2273,338 +2473,12 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI } break; - case CONVERT_V8U8: - { - unsigned int x, y; - const short *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = (const short *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = 0xff; - /* G */ Dest[1] = (color >> 8) + 128; /* V */ - /* R */ Dest[2] = (color) + 128; /* U */ - Dest += 3; - } - } - break; - } - - case CONVERT_V16U16: - { - unsigned int x, y; - const DWORD *Source; - unsigned short *Dest; - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = (unsigned short *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - DWORD color = (*Source++); - /* B */ Dest[0] = 0xffff; - /* G */ Dest[1] = (color >> 16) + 32768; /* V */ - /* R */ Dest[2] = (color ) + 32768; /* U */ - Dest += 3; - } - } - break; - } - - case CONVERT_Q8W8V8U8: - { - unsigned int x, y; - const DWORD *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ - Dest += 4; - } - } - break; - } - - case CONVERT_L6V5U5: - { - unsigned int x, y; - const WORD *Source; - unsigned char *Dest; - - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* This makes the gl surface bigger(24 bit instead of 16), but it works with - * fixed function and shaders without further conversion once the surface is - * loaded - */ - for(y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - char v = ((color >> 5) & 0x3e); - char u = ((color ) & 0x1f); - - /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign - * and doubles the positive range. Thus shift left only once, gl does the 2nd - * shift. GL reads a signed value and converts it into an unsigned value. - */ - /* M */ Dest[2] = l << 1; - - /* Those are read as signed, but kept signed. Just left-shift 3 times to scale - * from 5 bit values to 8 bit values. - */ - /* V */ Dest[1] = v << 3; - /* U */ Dest[0] = u << 3; - Dest += 3; - } - } - } else { - for(y = 0; y < height; y++) { - unsigned short *Dest_s = (unsigned short *) (dst + y * outpitch); - Source = (const WORD *)(src + y * pitch); - for (x = 0; x < width; x++ ) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - short v = ((color >> 5) & 0x3e); - short u = ((color ) & 0x1f); - short v_conv = v + 16; - short u_conv = u + 16; - - *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); - Dest_s += 1; - } - } - } - break; - } - - case CONVERT_X8L8V8U8: - { - unsigned int x, y; - const DWORD *Source; - unsigned char *Dest; - - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* This implementation works with the fixed function pipeline and shaders - * without further modification after converting the surface. - */ - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ - /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ - /* U */ Dest[0] = (color & 0xff); /* U */ - /* I */ Dest[3] = 255; /* X */ - Dest += 4; - } - } - } else { - /* Doesn't work correctly with the fixed function pipeline, but can work in - * shaders if the shader is adjusted. (There's no use for this format in gl's - * standard fixed function pipeline anyway). - */ - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - Dest += 4; - } - } - } - break; - } - - case CONVERT_A4L4: - { - unsigned int x, y; - const unsigned char *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = src + y * pitch; - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - unsigned char color = (*Source++); - /* A */ Dest[1] = (color & 0xf0) << 0; - /* L */ Dest[0] = (color & 0x0f) << 4; - Dest += 2; - } - } - break; - } - - case CONVERT_G16R16: - case CONVERT_R16G16F: - { - unsigned int x, y; - const WORD *Source; - WORD *Dest; - - for(y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = (WORD *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - WORD green = (*Source++); - WORD red = (*Source++); - Dest[0] = green; - Dest[1] = red; - /* Strictly speaking not correct for R16G16F, but it doesn't matter because the - * shader overwrites it anyway - */ - Dest[2] = 0xffff; - Dest += 3; - } - } - break; - } - - case CONVERT_R32G32F: - { - unsigned int x, y; - const float *Source; - float *Dest; - for(y = 0; y < height; y++) { - Source = (const float *)(src + y * pitch); - Dest = (float *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - float green = (*Source++); - float red = (*Source++); - Dest[0] = green; - Dest[1] = red; - Dest[2] = 1.0f; - Dest += 3; - } - } - break; - } - - case CONVERT_D15S1: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const WORD *source = (const WORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - /* The depth data is normalized, so needs to be scaled, - * the stencil data isn't. Scale depth data by - * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ - WORD d15 = source[x] >> 1; - DWORD d24 = (d15 << 9) + (d15 >> 6); - dest[x] = (d24 << 8) | (source[x] & 0x1); - } - } - break; - } - - case CONVERT_D24X4S4: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const DWORD *source = (const DWORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - /* Just need to clear out the X4 part. */ - dest[x] = source[x] & ~0xf0; - } - } - break; - } - - case CONVERT_D24FS8: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const DWORD *source = (const DWORD *)(src + y * pitch); - float *dest_f = (float *)(dst + y * outpitch); - DWORD *dest_s = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); - dest_s[x * 2 + 1] = source[x] & 0xff; - } - } - break; - } - default: ERR("Unsupported conversion type %#x.\n", convert); } return WINED3D_OK; } -/* This function is used in case of 8bit paletted textures to upload the palette. - It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other - extensions like ATI_fragment_shaders is possible. -*/ -/* Context activation is done by the caller. */ -static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - BYTE table[256][4]; - IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - - d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK)); - - /* Try to use the paletted texture extension */ - if (gl_info->supported[EXT_PALETTED_TEXTURE]) - { - TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n"); - ENTER_GL(); - GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table)); - LEAVE_GL(); - } - else - { - /* Let a fragment shader do the color conversion by uploading the palette to a 1D texture. - * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */ - TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n"); - - device->blitter->set_shader((IWineD3DDevice *) device, This->resource.format_desc, - This->texture_target, This->pow2Width, This->pow2Height); - - ENTER_GL(); - GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1)); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Make sure we have discrete color levels. */ - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); /* Upload the palette */ - - /* Switch back to unit 0 in which the 2D texture will be stored. */ - GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0)); - - /* Rebind the texture because it isn't bound anymore */ - glBindTexture(This->texture_target, This->texture_name); - LEAVE_GL(); - } -} - BOOL palette9_changed(IWineD3DSurfaceImpl *This) { IWineD3DDeviceImpl *device = This->resource.device; @@ -2827,7 +2701,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c LEAVE_GL(); } else { /* bind the real texture, and make sure it up to date */ - surface_internal_preload(iface, SRGB_RGB); + surface_internal_preload(This, SRGB_RGB); surface_bind_and_dirtify(This, FALSE); } allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4); @@ -2948,9 +2822,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); /* For client textures opengl has to be notified */ - if(This->Flags & SFLAG_CLIENT) { - surface_release_client_storage(iface); - } + if (This->Flags & SFLAG_CLIENT) + surface_release_client_storage(This); /* Now free the old memory if any */ HeapFree(GetProcessHeap(), 0, release); @@ -2961,9 +2834,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M if(This->resource.heapMemory != NULL) ERR("User pointer surface has heap memory allocated\n"); This->Flags &= ~SFLAG_USERPTR; - if(This->Flags & SFLAG_CLIENT) { - surface_release_client_storage(iface); - } + if (This->Flags & SFLAG_CLIENT) + surface_release_client_storage(This); } return WINED3D_OK; } @@ -3099,7 +2971,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS } /* Flipping a OpenGL surface -> Use WineD3DDevice::Present */ - hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0); + hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain, + NULL, NULL, swapchain->win_handle, NULL, 0); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } @@ -3107,36 +2980,48 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS /* Does a direct frame buffer -> texture copy. Stretching is done * with single pixel copy calls */ -static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, - const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) +static void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = dst_surface->resource.device; float xrel, yrel; UINT row; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; struct wined3d_context *context; + BOOL upsidedown = FALSE; + RECT dst_rect = *dst_rect_in; + /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag + * glCopyTexSubImage is a bit picky about the parameters we pass to it + */ + if(dst_rect.top > dst_rect.bottom) { + UINT tmp = dst_rect.bottom; + dst_rect.bottom = dst_rect.top; + dst_rect.top = tmp; + upsidedown = TRUE; + } - context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT); - surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB); + context = context_acquire(device, src_surface); + context_apply_blit_state(context, device); + surface_internal_preload(dst_surface, SRGB_RGB); ENTER_GL(); /* Bind the target texture */ - glBindTexture(This->texture_target, This->texture_name); + glBindTexture(dst_surface->texture_target, dst_surface->texture_name); checkGLcall("glBindTexture"); - if(surface_is_offscreen(SrcSurface)) { + if (surface_is_offscreen(src_surface)) + { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); } else { - glReadBuffer(surface_get_gl_buffer(SrcSurface)); + glReadBuffer(surface_get_gl_buffer(src_surface)); } checkGLcall("glReadBuffer"); - xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1); - yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1); + xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left); + yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top); if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) { @@ -3158,19 +3043,19 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D { /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */ - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 /*xoffset */, drect->y1 /* y offset */, - srect->x1, Src->currentDesc.Height - srect->y2, - drect->x2 - drect->x1, drect->y2 - drect->y1); + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left /*xoffset */, dst_rect.top /* y offset */, + src_rect->left, src_surface->currentDesc.Height - src_rect->bottom, + dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); } else { - UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1; + UINT yoffset = src_surface->currentDesc.Height - src_rect->top + dst_rect.top - 1; /* I have to process this row by row to swap the image, * otherwise it would be upside down, so stretching in y direction * doesn't cost extra time * * However, stretching in x direction can be avoided if not necessary */ - for(row = drect->y1; row < drect->y2; row++) { + for(row = dst_rect.top; row < dst_rect.bottom; row++) { if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) { /* Well, that stuff works, but it's very slow. @@ -3178,15 +3063,18 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D */ UINT col; - for(col = drect->x1; col < drect->x2; col++) { - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 + col /* x offset */, row /* y offset */, - srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1); + for (col = dst_rect.left; col < dst_rect.right; ++col) + { + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left + col /* x offset */, row /* y offset */, + src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1); } - } else { - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 /* x offset */, row /* y offset */, - srect->x1, yoffset - (int) (row * yrel), drect->x2-drect->x1, 1); + } + else + { + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left /* x offset */, row /* y offset */, + src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1); } } } @@ -3198,37 +3086,39 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D /* The texture is now most up to date - If the surface is a render target and has a drawable, this * path is never entered */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE); } /* Uses the hardware to stretch and flip the image */ -static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, - IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect, - BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) +static void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = dst_surface->resource.device; GLuint src, backup = 0; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; + IWineD3DSwapChainImpl *src_swapchain = NULL; float left, right, top, bottom; /* Texture coordinates */ - UINT fbwidth = Src->currentDesc.Width; - UINT fbheight = Src->currentDesc.Height; + UINT fbwidth = src_surface->currentDesc.Width; + UINT fbheight = src_surface->currentDesc.Height; struct wined3d_context *context; GLenum drawBuffer = GL_BACK; GLenum texture_target; BOOL noBackBufferBackup; BOOL src_offscreen; + BOOL upsidedown = FALSE; + RECT dst_rect = *dst_rect_in; TRACE("Using hwstretch blit\n"); /* Activate the Proper context for reading from the source surface, set it up for blitting */ - context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT); - surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB); + context = context_acquire(device, src_surface); + context_apply_blit_state(context, device); + surface_internal_preload(dst_surface, SRGB_RGB); - src_offscreen = surface_is_offscreen(SrcSurface); + src_offscreen = surface_is_offscreen(src_surface); noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !Src->texture_name) + if (!noBackBufferBackup && !src_surface->texture_name) { /* Get it a description */ - surface_internal_preload(SrcSurface, SRGB_RGB); + surface_internal_preload(src_surface, SRGB_RGB); } ENTER_GL(); @@ -3240,7 +3130,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* Got more than one aux buffer? Use the 2nd aux buffer */ drawBuffer = GL_AUX1; } - else if ((!src_offscreen || myDevice->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1) + else if ((!src_offscreen || device->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1) { /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */ drawBuffer = GL_AUX0; @@ -3256,25 +3146,35 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If * we are reading from the back buffer, the backup can be used as source texture */ - texture_target = Src->texture_target; - glBindTexture(texture_target, Src->texture_name); - checkGLcall("glBindTexture(texture_target, Src->texture_name)"); + texture_target = src_surface->texture_target; + glBindTexture(texture_target, src_surface->texture_name); + checkGLcall("glBindTexture(texture_target, src_surface->texture_name)"); glEnable(texture_target); checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - Src->Flags &= ~SFLAG_INTEXTURE; + src_surface->Flags &= ~SFLAG_INTEXTURE; + } + + /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag + * glCopyTexSubImage is a bit picky about the parameters we pass to it + */ + if(dst_rect.top > dst_rect.bottom) { + UINT tmp = dst_rect.bottom; + dst_rect.bottom = dst_rect.top; + dst_rect.top = tmp; + upsidedown = TRUE; } if (src_offscreen) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); } else { - glReadBuffer(surface_get_gl_buffer(SrcSurface)); + glReadBuffer(surface_get_gl_buffer(src_surface)); } /* TODO: Only back up the part that will be overwritten */ @@ -3294,9 +3194,14 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); checkGLcall("glTexParameteri"); - if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) { - src = backup ? backup : Src->texture_name; - } else { + IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain); + if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)src_swapchain); + if (!src_swapchain || src_surface == src_swapchain->back_buffers[0]) + { + src = backup ? backup : src_surface->texture_name; + } + else + { glReadBuffer(GL_FRONT); checkGLcall("glReadBuffer(GL_FRONT)"); @@ -3305,11 +3210,11 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine glBindTexture(GL_TEXTURE_2D, src); checkGLcall("glBindTexture(GL_TEXTURE_2D, src)"); - /* TODO: Only copy the part that will be read. Use srect->x1, srect->y2 as origin, but with the width watch + /* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch * out for power of 2 sizes */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Src->pow2Width, Src->pow2Height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_surface->pow2Width, + src_surface->pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); checkGLcall("glTexImage2D"); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0 /* read offsets */, @@ -3333,22 +3238,26 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine } checkGLcall("glEnd and previous"); - left = srect->x1; - right = srect->x2; + left = src_rect->left; + right = src_rect->right; - if(upsidedown) { - top = Src->currentDesc.Height - srect->y1; - bottom = Src->currentDesc.Height - srect->y2; - } else { - top = Src->currentDesc.Height - srect->y2; - bottom = Src->currentDesc.Height - srect->y1; + if (upsidedown) + { + top = src_surface->currentDesc.Height - src_rect->top; + bottom = src_surface->currentDesc.Height - src_rect->bottom; + } + else + { + top = src_surface->currentDesc.Height - src_rect->bottom; + bottom = src_surface->currentDesc.Height - src_rect->top; } - if(Src->Flags & SFLAG_NORMCOORD) { - left /= Src->pow2Width; - right /= Src->pow2Width; - top /= Src->pow2Height; - bottom /= Src->pow2Height; + if (src_surface->Flags & SFLAG_NORMCOORD) + { + left /= src_surface->pow2Width; + right /= src_surface->pow2Width; + top /= src_surface->pow2Height; + bottom /= src_surface->pow2Height; } /* draw the source texture stretched and upside down. The correct surface is bound already */ @@ -3365,33 +3274,33 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* top left */ glTexCoord2f(left, top); - glVertex2i(0, fbheight - drect->y2 - drect->y1); + glVertex2i(0, fbheight - dst_rect.bottom - dst_rect.top); /* top right */ glTexCoord2f(right, top); - glVertex2i(drect->x2 - drect->x1, fbheight - drect->y2 - drect->y1); + glVertex2i(dst_rect.right - dst_rect.left, fbheight - dst_rect.bottom - dst_rect.top); /* bottom right */ glTexCoord2f(right, bottom); - glVertex2i(drect->x2 - drect->x1, fbheight); + glVertex2i(dst_rect.right - dst_rect.left, fbheight); glEnd(); checkGLcall("glEnd and previous"); - if (texture_target != This->texture_target) + if (texture_target != dst_surface->texture_target) { glDisable(texture_target); - glEnable(This->texture_target); - texture_target = This->texture_target; + glEnable(dst_surface->texture_target); + texture_target = dst_surface->texture_target; } /* Now read the stretched and upside down image into the destination texture */ - glBindTexture(texture_target, This->texture_name); + glBindTexture(texture_target, dst_surface->texture_name); checkGLcall("glBindTexture"); glCopyTexSubImage2D(texture_target, 0, - drect->x1, drect->y1, /* xoffset, yoffset */ + dst_rect.left, dst_rect.top, /* xoffset, yoffset */ 0, 0, /* We blitted the image to the origin */ - drect->x2 - drect->x1, drect->y2 - drect->y1); + dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); checkGLcall("glCopyTexSubImage2D"); if(drawBuffer == GL_BACK) { @@ -3404,20 +3313,22 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine } glBindTexture(GL_TEXTURE_2D, backup); checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)"); - } else { - if (texture_target != Src->texture_target) + } + else + { + if (texture_target != src_surface->texture_target) { glDisable(texture_target); - glEnable(Src->texture_target); - texture_target = Src->texture_target; + glEnable(src_surface->texture_target); + texture_target = src_surface->texture_target; } - glBindTexture(Src->texture_target, Src->texture_name); - checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)"); + glBindTexture(src_surface->texture_target, src_surface->texture_name); + checkGLcall("glBindTexture(src_surface->texture_target, src_surface->texture_name)"); } glBegin(GL_QUADS); /* top left */ - glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height); + glTexCoord2f(0.0f, (float)fbheight / (float)src_surface->pow2Height); glVertex2i(0, 0); /* bottom left */ @@ -3425,11 +3336,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine glVertex2i(0, fbheight); /* bottom right */ - glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f); - glVertex2i(fbwidth, Src->currentDesc.Height); + glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, 0.0f); + glVertex2i(fbwidth, src_surface->currentDesc.Height); /* top right */ - glTexCoord2f((float) fbwidth / (float) Src->pow2Width, (float) fbheight / (float) Src->pow2Height); + glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, + (float)fbheight / (float)src_surface->pow2Height); glVertex2i(fbwidth, 0); glEnd(); } @@ -3437,7 +3349,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine checkGLcall("glDisable(texture_target)"); /* Cleanup */ - if (src != Src->texture_name && src != backup) + if (src != src_surface->texture_name && src != backup) { glDeleteTextures(1, &src); checkGLcall("glDeleteTextures(1, &src)"); @@ -3449,48 +3361,76 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); /* The texture is now most up to date - If the surface is a render target and has a drawable, this * path is never entered */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE); +} + +/* Until the blit_shader is ready, define some prototypes here. */ +static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc); + +/* Front buffer coordinates are always full screen coordinates, but our GL + * drawable is limited to the window's client area. The sysmem and texture + * copies do have the full screen size. Note that GL has a bottom-left + * origin, while D3D has a top-left origin. */ +void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) +{ + POINT offset = {0, surface->currentDesc.Height}; + RECT windowsize; + + GetClientRect(window, &windowsize); + offset.y -= windowsize.bottom - windowsize.top; + ScreenToClient(window, &offset); + OffsetRect(rect, offset.x, offset.y); } /* Not called from the VTable */ -static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const RECT *DestRect, - IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, +static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface, const RECT *DestRect, + IWineD3DSurfaceImpl *src_surface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; - WINED3DRECT rect; + IWineD3DDeviceImpl *device = dst_surface->resource.device; IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; + RECT dst_rect, src_rect; - TRACE("(%p)->(%p,%p,%p,%08x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(DestRect), src_surface, wine_dbgstr_rect(SrcRect), + Flags, DDBltFx, debug_d3dtexturefiltertype(Filter)); /* Get the swapchain. One of the surfaces has to be a primary surface */ - if(This->resource.pool == WINED3DPOOL_SYSTEMMEM) { + if (dst_surface->resource.pool == WINED3DPOOL_SYSTEMMEM) + { WARN("Destination is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - IWineD3DSurface_GetContainer( (IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&dstSwapchain); - if(dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) dstSwapchain); - if(Src) { - if(Src->resource.pool == WINED3DPOOL_SYSTEMMEM) { + IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dstSwapchain); + if (dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dstSwapchain); + if (src_surface) + { + if (src_surface->resource.pool == WINED3DPOOL_SYSTEMMEM) + { WARN("Src is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - IWineD3DSurface_GetContainer( (IWineD3DSurface *) Src, &IID_IWineD3DSwapChain, (void **)&srcSwapchain); - if(srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) srcSwapchain); + IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&srcSwapchain); + if (srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)srcSwapchain); } /* Early sort out of cases where no render target is used */ - if(!dstSwapchain && !srcSwapchain && - SrcSurface != myDevice->render_targets[0] && This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) { - TRACE("No surface is render target, not using hardware blit. Src = %p, dst = %p\n", Src, This); + if (!dstSwapchain && !srcSwapchain + && src_surface != device->render_targets[0] + && dst_surface != device->render_targets[0]) + { + TRACE("No surface is render target, not using hardware blit.\n"); return WINED3DERR_INVALIDCALL; } @@ -3501,21 +3441,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const return WINED3DERR_INVALIDCALL; } - if (DestRect) { - rect.x1 = DestRect->left; - rect.y1 = DestRect->top; - rect.x2 = DestRect->right; - rect.y2 = DestRect->bottom; - } else { - rect.x1 = 0; - rect.y1 = 0; - rect.x2 = This->currentDesc.Width; - rect.y2 = This->currentDesc.Height; - } + surface_get_rect(dst_surface, DestRect, &dst_rect); + if (src_surface) surface_get_rect(src_surface, SrcRect, &src_rect); /* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */ - if(dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->backBuffer && - ((IWineD3DSurface *) This == dstSwapchain->frontBuffer) && SrcSurface == dstSwapchain->backBuffer[0]) { + if (dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->back_buffers + && dst_surface == dstSwapchain->front_buffer + && src_surface == dstSwapchain->back_buffers[0]) + { /* Half-life does a Blt from the back buffer to the front buffer, * Full surface size, no flags... Use present instead * @@ -3525,57 +3458,50 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Check rects - IWineD3DDevice_Present doesn't handle them */ while(1) { - RECT mySrcRect; TRACE("Looking if a Present can be done...\n"); /* Source Rectangle must be full surface */ - if( SrcRect ) { - if(SrcRect->left != 0 || SrcRect->top != 0 || - SrcRect->right != Src->currentDesc.Width || SrcRect->bottom != Src->currentDesc.Height) { - TRACE("No, Source rectangle doesn't match\n"); - break; - } + if (src_rect.left || src_rect.top + || src_rect.right != src_surface->currentDesc.Width + || src_rect.bottom != src_surface->currentDesc.Height) + { + TRACE("No, Source rectangle doesn't match\n"); + break; } - mySrcRect.left = 0; - mySrcRect.top = 0; - mySrcRect.right = Src->currentDesc.Width; - mySrcRect.bottom = Src->currentDesc.Height; /* No stretching may occur */ - if(mySrcRect.right != rect.x2 - rect.x1 || - mySrcRect.bottom != rect.y2 - rect.y1) { + if(src_rect.right != dst_rect.right - dst_rect.left || + src_rect.bottom != dst_rect.bottom - dst_rect.top) { TRACE("No, stretching is done\n"); break; } /* Destination must be full surface or match the clipping rectangle */ - if(This->clipper && ((IWineD3DClipperImpl *) This->clipper)->hWnd) + if (dst_surface->clipper && ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd) { RECT cliprect; POINT pos[2]; - GetClientRect(((IWineD3DClipperImpl *) This->clipper)->hWnd, &cliprect); - pos[0].x = rect.x1; - pos[0].y = rect.y1; - pos[1].x = rect.x2; - pos[1].y = rect.y2; - MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *) This->clipper)->hWnd, - pos, 2); + GetClientRect(((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, &cliprect); + pos[0].x = dst_rect.left; + pos[0].y = dst_rect.top; + pos[1].x = dst_rect.right; + pos[1].y = dst_rect.bottom; + MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, pos, 2); if(pos[0].x != cliprect.left || pos[0].y != cliprect.top || pos[1].x != cliprect.right || pos[1].y != cliprect.bottom) { TRACE("No, dest rectangle doesn't match(clipper)\n"); - TRACE("Clip rect at (%d,%d)-(%d,%d)\n", cliprect.left, cliprect.top, cliprect.right, cliprect.bottom); - TRACE("Blt dest: (%d,%d)-(%d,%d)\n", rect.x1, rect.y1, rect.x2, rect.y2); + TRACE("Clip rect at %s\n", wine_dbgstr_rect(&cliprect)); + TRACE("Blt dest: %s\n", wine_dbgstr_rect(&dst_rect)); break; } } - else + else if (dst_rect.left || dst_rect.top + || dst_rect.right != dst_surface->currentDesc.Width + || dst_rect.bottom != dst_surface->currentDesc.Height) { - if(rect.x1 != 0 || rect.y1 != 0 || - rect.x2 != This->currentDesc.Width || rect.y2 != This->currentDesc.Height) { - TRACE("No, dest rectangle doesn't match(surface size)\n"); - break; - } + TRACE("No, dest rectangle doesn't match(surface size)\n"); + break; } TRACE("Yes\n"); @@ -3603,7 +3529,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const dstSwapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE; TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n"); - IWineD3DSwapChain_Present((IWineD3DSwapChain *) dstSwapchain, NULL, NULL, 0, NULL, 0); + IWineD3DSwapChain_Present((IWineD3DSwapChain *)dstSwapchain, + NULL, NULL, dstSwapchain->win_handle, NULL, 0); dstSwapchain->presentParms.SwapEffect = orig_swap; @@ -3620,21 +3547,31 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const } else if(dstSwapchain && srcSwapchain) { FIXME("Implement hardware blit between two different swapchains\n"); return WINED3DERR_INVALIDCALL; - } else if(dstSwapchain) { - if(SrcSurface == myDevice->render_targets[0]) { + } + else if (dstSwapchain) + { + /* Handled with regular texture -> swapchain blit */ + if (src_surface == device->render_targets[0]) TRACE("Blit from active render target to a swapchain\n"); - /* Handled with regular texture -> swapchain blit */ - } - } else if(srcSwapchain && This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) { + } + else if (srcSwapchain && dst_surface == device->render_targets[0]) + { FIXME("Implement blit from a swapchain to the active render target\n"); return WINED3DERR_INVALIDCALL; } - if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) { + if ((srcSwapchain || src_surface == device->render_targets[0]) && !dstSwapchain) + { /* Blit from render target to texture */ - WINED3DRECT srect; - BOOL upsideDown, stretchx; - BOOL paletteOverride = FALSE; + BOOL stretchx; + + /* P8 read back is not implemented */ + if (src_surface->resource.format_desc->format == WINED3DFMT_P8_UINT + || dst_surface->resource.format_desc->format == WINED3DFMT_P8_UINT) + { + TRACE("P8 read back not supported by frame buffer to texture blit\n"); + return WINED3DERR_INVALIDCALL; + } if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { TRACE("Color keying not supported by frame buffer to texture blit\n"); @@ -3642,50 +3579,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Destination color key is checked above */ } - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(SrcRect) { - if(SrcRect->top < SrcRect->bottom) { - srect.y1 = SrcRect->top; - srect.y2 = SrcRect->bottom; - upsideDown = FALSE; - } else { - srect.y1 = SrcRect->bottom; - srect.y2 = SrcRect->top; - upsideDown = TRUE; - } - srect.x1 = SrcRect->left; - srect.x2 = SrcRect->right; - } else { - srect.x1 = 0; - srect.y1 = 0; - srect.x2 = Src->currentDesc.Width; - srect.y2 = Src->currentDesc.Height; - upsideDown = FALSE; - } - if(rect.x1 > rect.x2) { - UINT tmp = rect.x2; - rect.x2 = rect.x1; - rect.x1 = tmp; - upsideDown = !upsideDown; - } - - if(rect.x2 - rect.x1 != srect.x2 - srect.x1) { + if(dst_rect.right - dst_rect.left != src_rect.right - src_rect.left) { stretchx = TRUE; } else { stretchx = FALSE; } - /* When blitting from a render target a texture, the texture isn't required to have a palette. - * In this case grab the palette from the render target. */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !This->palette) - { - paletteOverride = TRUE; - TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This); - This->palette = Src->palette; - } - /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot * flip the image nor scale it. * @@ -3701,92 +3600,66 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering * backends. */ - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer - && surface_can_stretch_rect(Src, This)) + if (fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc)) + { + stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter); + } + else if (!stretchx || dst_rect.right - dst_rect.left > src_surface->currentDesc.Width + || dst_rect.bottom - dst_rect.top > src_surface->currentDesc.Height) { - stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect, - (IWineD3DSurface *)This, &rect, Filter, upsideDown); - } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width || - rect.y2 - rect.y1 > Src->currentDesc.Height) { TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n"); - fb_copy_to_texture_direct(This, SrcSurface, &srect, &rect, upsideDown, Filter); + fb_copy_to_texture_direct(dst_surface, src_surface, &src_rect, &dst_rect, Filter); } else { TRACE("Using hardware stretching to flip / stretch the texture\n"); - fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter); + fb_copy_to_texture_hwstretch(dst_surface, src_surface, &src_rect, &dst_rect, Filter); } - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - This->palette = NULL; - - if(!(This->Flags & SFLAG_DONOTFREE)) { - HeapFree(GetProcessHeap(), 0, This->resource.heapMemory); - This->resource.allocatedMemory = NULL; - This->resource.heapMemory = NULL; - } else { - This->Flags &= ~SFLAG_INSYSMEM; + if (!(dst_surface->Flags & SFLAG_DONOTFREE)) + { + HeapFree(GetProcessHeap(), 0, dst_surface->resource.heapMemory); + dst_surface->resource.allocatedMemory = NULL; + dst_surface->resource.heapMemory = NULL; + } + else + { + dst_surface->Flags &= ~SFLAG_INSYSMEM; } return WINED3D_OK; - } else if(Src) { + } + else if (src_surface) + { /* Blit from offscreen surface to render target */ - float glTexCoord[4]; - DWORD oldCKeyFlags = Src->CKeyFlags; - WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey; + DWORD oldCKeyFlags = src_surface->CKeyFlags; + WINEDDCOLORKEY oldBltCKey = src_surface->SrcBltCKey; struct wined3d_context *context; - RECT SourceRectangle; - BOOL paletteOverride = FALSE; - TRACE("Blt from surface %p to rendertarget %p\n", Src, This); + TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); - if(SrcRect) { - SourceRectangle.left = SrcRect->left; - SourceRectangle.right = SrcRect->right; - SourceRectangle.top = SrcRect->top; - SourceRectangle.bottom = SrcRect->bottom; - } else { - SourceRectangle.left = 0; - SourceRectangle.right = Src->currentDesc.Width; - SourceRectangle.top = 0; - SourceRectangle.bottom = Src->currentDesc.Height; - } - - /* When blitting from an offscreen surface to a rendertarget, the source - * surface is not required to have a palette. Our rendering / conversion - * code further down the road retrieves the palette from the surface, so - * it must have a palette set. */ - if (Src->resource.format_desc->format == WINED3DFMT_P8_UINT && !Src->palette) - { - paletteOverride = TRUE; - TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This); - Src->palette = This->palette; - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer - && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) - && surface_can_stretch_rect(Src, This)) + if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) + && fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, + src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) { TRACE("Using stretch_rect_fbo\n"); /* The source is always a texture, but never the currently active render target, and the texture - * contents are never upside down - */ - stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, (WINED3DRECT *) &SourceRectangle, - (IWineD3DSurface *)This, &rect, Filter, FALSE); - - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - Src->palette = NULL; + * contents are never upside down. */ + stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter); return WINED3D_OK; } - if(!CalculateTexRect(Src, &SourceRectangle, glTexCoord)) { - /* Fall back to software */ - WARN("(%p) Source texture area (%d,%d)-(%d,%d) is too big\n", Src, - SourceRectangle.left, SourceRectangle.top, - SourceRectangle.right, SourceRectangle.bottom); - return WINED3DERR_INVALIDCALL; + if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) + && arbfp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, + src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return arbfp_blit_surface(device, src_surface, &src_rect, dst_surface, &dst_rect, BLIT_OP_BLIT, Filter); } /* Color keying: Check if we have to do a color keyed blt, @@ -3800,72 +3673,35 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Use color key from surface */ } else if(Flags & WINEDDBLT_KEYSRCOVERRIDE) { /* Use color key from DDBltFx */ - Src->CKeyFlags |= WINEDDSD_CKSRCBLT; - Src->SrcBltCKey = DDBltFx->ddckSrcColorkey; + src_surface->CKeyFlags |= WINEDDSD_CKSRCBLT; + src_surface->SrcBltCKey = DDBltFx->ddckSrcColorkey; } else { /* Do not use color key */ - Src->CKeyFlags &= ~WINEDDSD_CKSRCBLT; + src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT; } /* Now load the surface */ - surface_internal_preload((IWineD3DSurface *) Src, SRGB_RGB); + surface_internal_preload(src_surface, SRGB_RGB); /* Activate the destination context, set it up for blitting */ - context = context_acquire(myDevice, (IWineD3DSurface *)This, CTXUSAGE_BLIT); + context = context_acquire(device, dst_surface); + context_apply_blit_state(context, device); - /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', - * while OpenGL coordinates are window relative. - * Also beware of the origin difference(top left vs bottom left). - * Also beware that the front buffer's surface size is screen width x screen height, - * whereas the real gl drawable size is the size of the window. - */ - if (dstSwapchain && (IWineD3DSurface *)This == dstSwapchain->frontBuffer) { - RECT windowsize; - POINT offset = {0,0}; - UINT h; - ClientToScreen(dstSwapchain->win_handle, &offset); - GetClientRect(dstSwapchain->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - rect.x1 -= offset.x; rect.x2 -=offset.x; - rect.y1 -= offset.y; rect.y2 -=offset.y; - rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h; - } + if (dstSwapchain && dst_surface == dstSwapchain->front_buffer) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); - if (!is_identity_fixup(This->resource.format_desc->color_fixup)) + if (!device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc)) { - FIXME("Destination format %s has a fixup, this is not supported.\n", - debug_d3dformat(This->resource.format_desc->format)); - dump_color_fixup_desc(This->resource.format_desc->color_fixup); + FIXME("Unsupported blit operation falling back to software\n"); + return WINED3DERR_INVALIDCALL; } - if (!myDevice->blitter->color_fixup_supported(Src->resource.format_desc->color_fixup)) - { - FIXME("Source format %s has an unsupported fixup:\n", - debug_d3dformat(Src->resource.format_desc->format)); - dump_color_fixup_desc(Src->resource.format_desc->color_fixup); - } - - myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc, - Src->texture_target, Src->pow2Width, Src->pow2Height); + device->blitter->set_shader((IWineD3DDevice *)device, src_surface); ENTER_GL(); - /* Bind the texture */ - glBindTexture(Src->texture_target, Src->texture_name); - checkGLcall("glBindTexture"); - - /* Filtering for StretchRect */ - glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER, - wined3d_gl_mag_filter(magLookup, Filter)); - checkGLcall("glTexParameteri"); - glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); - checkGLcall("glTexParameteri"); - glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - checkGLcall("glTexEnvi"); - /* This is for color keying */ if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { glEnable(GL_ALPHA_TEST); @@ -3874,8 +3710,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* When the primary render target uses P8, the alpha component contains the palette index. * Which means that the colorkey is one of the palette entries. In other cases pixels that * should be masked away have alpha set to 0. */ - if(primary_render_target_is_p8(myDevice)) - glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0f); + if (primary_render_target_is_p8(device)) + glAlphaFunc(GL_NOTEQUAL, (float)src_surface->SrcBltCKey.dwColorSpaceLowValue / 256.0f); else glAlphaFunc(GL_NOTEQUAL, 0.0f); checkGLcall("glAlphaFunc"); @@ -3886,46 +3722,26 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Draw a textured quad */ - glBegin(GL_QUADS); - - glColor3f(1.0f, 1.0f, 1.0f); - glTexCoord2f(glTexCoord[0], glTexCoord[2]); - glVertex3f(rect.x1, rect.y1, 0.0f); - - glTexCoord2f(glTexCoord[0], glTexCoord[3]); - glVertex3f(rect.x1, rect.y2, 0.0f); - - glTexCoord2f(glTexCoord[1], glTexCoord[3]); - glVertex3f(rect.x2, rect.y2, 0.0f); - - glTexCoord2f(glTexCoord[1], glTexCoord[2]); - glVertex3f(rect.x2, rect.y1, 0.0f); - - glEnd(); - checkGLcall("glEnd"); + draw_textured_quad(src_surface, &src_rect, &dst_rect, Filter); if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { glDisable(GL_ALPHA_TEST); checkGLcall("glDisable(GL_ALPHA_TEST)"); } - glBindTexture(Src->texture_target, 0); - checkGLcall("glBindTexture(Src->texture_target, 0)"); - /* Restore the color key parameters */ - Src->CKeyFlags = oldCKeyFlags; - Src->SrcBltCKey = oldBltCKey; - - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - Src->palette = NULL; + src_surface->CKeyFlags = oldCKeyFlags; + src_surface->SrcBltCKey = oldBltCKey; LEAVE_GL(); /* Leave the opengl state valid for blitting */ - myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice); + device->blitter->unset_shader((IWineD3DDevice *)device); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering || (dstSwapchain + && (dst_surface == dstSwapchain->front_buffer + || dstSwapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -3933,74 +3749,40 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture * is outdated now */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); return WINED3D_OK; } else { /* Source-Less Blit to render target */ if (Flags & WINEDDBLT_COLORFILL) { - /* This is easy to handle for the D3D Device... */ DWORD color; TRACE("Colorfill\n"); - /* This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0] || dstSwapchain - must be true if we are here */ - if (This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0] && - !(This == (IWineD3DSurfaceImpl*) dstSwapchain->frontBuffer || - (dstSwapchain->backBuffer && This == (IWineD3DSurfaceImpl*) dstSwapchain->backBuffer[0]))) { - TRACE("Surface is higher back buffer, falling back to software\n"); - return WINED3DERR_INVALIDCALL; - } - /* The color as given in the Blt function is in the format of the frame-buffer... * 'clear' expect it in ARGB format => we need to do some conversion :-) */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT) + if (!surface_convert_color_to_argb(dst_surface, DDBltFx->u5.dwFillColor, &color)) { - DWORD alpha; - - if (primary_render_target_is_p8(myDevice)) alpha = DDBltFx->u5.dwFillColor << 24; - else alpha = 0xFF000000; - - if (This->palette) { - color = (alpha | - (This->palette->palents[DDBltFx->u5.dwFillColor].peRed << 16) | - (This->palette->palents[DDBltFx->u5.dwFillColor].peGreen << 8) | - (This->palette->palents[DDBltFx->u5.dwFillColor].peBlue)); - } else { - color = alpha; - } - } - else if (This->resource.format_desc->format == WINED3DFMT_B5G6R5_UNORM) - { - if (DDBltFx->u5.dwFillColor == 0xFFFF) { - color = 0xFFFFFFFF; - } else { - color = ((0xFF000000) | - ((DDBltFx->u5.dwFillColor & 0xF800) << 8) | - ((DDBltFx->u5.dwFillColor & 0x07E0) << 5) | - ((DDBltFx->u5.dwFillColor & 0x001F) << 3)); - } - } - else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8_UNORM - || This->resource.format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) - { - color = 0xFF000000 | DDBltFx->u5.dwFillColor; - } - else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8A8_UNORM) - { - color = DDBltFx->u5.dwFillColor; - } - else { - ERR("Wrong surface type for BLT override(Format doesn't match) !\n"); + /* The color conversion function already prints an error, so need to do it here */ return WINED3DERR_INVALIDCALL; } - TRACE("(%p) executing Render Target override, color = %x\n", This, color); - IWineD3DDeviceImpl_ClearSurface(myDevice, This, 1 /* Number of rectangles */, - &rect, WINED3DCLEAR_TARGET, color, 0.0f /* Z */, 0 /* Stencil */); - return WINED3D_OK; + if (ffp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL, + NULL, 0, 0, NULL, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return ffp_blit.color_fill(device, dst_surface, &dst_rect, color); + } + else if (cpu_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL, + NULL, 0, 0, NULL, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return cpu_blit.color_fill(device, dst_surface, &dst_rect, color); + } + return WINED3DERR_INVALIDCALL; } } @@ -4012,7 +3794,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *DestRect, IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; float depth; if (Flags & WINEDDBLT_DEPTHFILL) { @@ -4036,13 +3818,8 @@ static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *D ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format)); } - return IWineD3DDevice_Clear((IWineD3DDevice *) myDevice, - DestRect == NULL ? 0 : 1, - (const WINED3DRECT *)DestRect, - WINED3DCLEAR_ZBUFFER, - 0x00000000, - depth, - 0x00000000); + return IWineD3DDevice_Clear((IWineD3DDevice *)device, DestRect ? 1 : 0, (const WINED3DRECT *)DestRect, + WINED3DCLEAR_ZBUFFER, 0x00000000, depth, 0x00000000); } FIXME("(%p): Unsupp depthstencil blit\n", This); @@ -4053,7 +3830,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage)); @@ -4067,8 +3844,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT /* Accessing the depth stencil is supposed to fail between a BeginScene and EndScene pair, * except depth blits, which seem to work */ - if(iface == myDevice->stencilBufferTarget || (SrcSurface && SrcSurface == myDevice->stencilBufferTarget)) { - if(myDevice->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) { + if (This == device->depth_stencil || (Src && Src == device->depth_stencil)) + { + if (device->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) + { TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } else if(IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) { @@ -4078,9 +3857,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT } /* Special cases for RenderTargets */ - if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) || - ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) { - if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK; + if ((This->resource.usage & WINED3DUSAGE_RENDERTARGET) + || (Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET))) + { + if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This, DestRect, Src, SrcRect, Flags, DDBltFx, Filter))) + return WINED3D_OK; } /* For the rest call the X11 surface implementation. @@ -4095,7 +3876,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DSurfaceImpl *srcImpl = (IWineD3DSurfaceImpl *) Source; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans); @@ -4105,9 +3886,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD return WINEDDERR_SURFACEBUSY; } - if(myDevice->inScene && - (iface == myDevice->stencilBufferTarget || - (Source == myDevice->stencilBufferTarget))) { + if (device->inScene && (This == device->depth_stencil || srcImpl == device->depth_stencil)) + { TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } @@ -4119,17 +3899,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD RECT SrcRect, DstRect; DWORD Flags=0; - if(rsrc) { - SrcRect.left = rsrc->left; - SrcRect.top= rsrc->top; - SrcRect.bottom = rsrc->bottom; - SrcRect.right = rsrc->right; - } else { - SrcRect.left = 0; - SrcRect.top = 0; - SrcRect.right = srcImpl->currentDesc.Width; - SrcRect.bottom = srcImpl->currentDesc.Height; - } + surface_get_rect(srcImpl, rsrc, &SrcRect); DstRect.left = dstx; DstRect.top=dsty; @@ -4146,7 +3916,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD if(trans & WINEDDBLTFAST_DONOTWAIT) Flags |= WINEDDBLT_DONOTWAIT; - if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_POINT) == WINED3D_OK) return WINED3D_OK; + if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This, + &DstRect, srcImpl, &SrcRect, Flags, NULL, WINED3DTEXF_POINT))) + return WINED3D_OK; } @@ -4166,31 +3938,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - int bpp; - GLenum format, internal, type; - CONVERT_TYPES convert; - - /* Check if we are using a RTL mode which uses texturing for uploads */ - BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX); - - /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */ - d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE); - - if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION)) + if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { - IWineD3DDeviceImpl *device = This->resource.device; - struct wined3d_context *context; - /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */ IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL); /* We want to force a palette refresh, so mark the drawable as not being up to date */ IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE); - - /* Re-upload the palette */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - d3dfmt_p8_upload_palette(iface, convert); - context_release(context); } else { if(!(This->Flags & SFLAG_INSYSMEM)) { TRACE("Palette changed with surface that does not have an up to date system memory copy\n"); @@ -4269,18 +4023,18 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { 3: WARN and return WINED3DERR_NOTAVAILABLE; 4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target. */ - WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n", - This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height); - This->Flags |= SFLAG_OVERSIZE; + if(This->resource.pool == WINED3DPOOL_DEFAULT || This->resource.pool == WINED3DPOOL_MANAGED) + { + WARN("(%p) Unable to allocate a surface which exceeds the maximum OpenGL texture size\n", This); + return WINED3DERR_NOTAVAILABLE; + } - /* This will be initialized on the first blt */ - This->glRect.left = 0; - This->glRect.top = 0; - This->glRect.right = 0; - This->glRect.bottom = 0; - } else { - /* Check this after the oversize check - do not make an oversized surface a texture_rectangle one. - Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE + /* We should never use this surface in combination with OpenGL! */ + TRACE("(%p) Creating an oversized surface: %ux%u\n", This, This->pow2Width, This->pow2Height); + } + else + { + /* Don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE doesn't work in combination with ARB_TEXTURE_RECTANGLE. */ @@ -4294,19 +4048,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { This->pow2Height = This->currentDesc.Height; This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD); } - - /* No oversize, gl rect is the full texture size */ - This->Flags &= ~SFLAG_OVERSIZE; - This->glRect.left = 0; - This->glRect.top = 0; - This->glRect.right = This->pow2Width; - This->glRect.bottom = This->pow2Height; } if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { switch(wined3d_settings.offscreen_rendering_mode) { case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; - case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; } } @@ -4316,104 +4062,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { return WINED3D_OK; } -struct depth_blt_info -{ - GLenum binding; - GLenum bind_target; - enum tex_types tex_type; - GLfloat coords[4][3]; -}; - -static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, struct depth_blt_info *info) -{ - GLfloat (*coords)[3] = info->coords; - - switch (target) - { - default: - FIXME("Unsupported texture target %#x\n", target); - /* Fall back to GL_TEXTURE_2D */ - case GL_TEXTURE_2D: - info->binding = GL_TEXTURE_BINDING_2D; - info->bind_target = GL_TEXTURE_2D; - info->tex_type = tex_2d; - coords[0][0] = 0.0f; coords[0][1] = 1.0f; coords[0][2] = 0.0f; - coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 0.0f; - coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f; - coords[3][0] = 1.0f; coords[3][1] = 0.0f; coords[3][2] = 0.0f; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; - info->bind_target = GL_TEXTURE_RECTANGLE_ARB; - info->tex_type = tex_rect; - coords[0][0] = 0.0f; coords[0][1] = h; coords[0][2] = 0.0f; - coords[1][0] = w; coords[1][1] = h; coords[1][2] = 0.0f; - coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f; - coords[3][0] = w; coords[3][1] = 0.0f; coords[3][2] = 0.0f; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = 1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = -1.0f; coords[2][1] = -1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = -1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - } -} - /* GL locking is done by the caller */ -static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target) +static void surface_depth_blt(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + GLuint texture, GLsizei w, GLsizei h, GLenum target) { IWineD3DDeviceImpl *device = This->resource.device; - struct depth_blt_info info; + GLint compare_mode = GL_NONE; + struct blt_info info; GLint old_binding = 0; glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT); @@ -4429,12 +4084,18 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glViewport(0, 0, w, h); - surface_get_depth_blt_info(target, w, h, &info); + surface_get_blt_info(target, NULL, w, h, &info); GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB)); glGetIntegerv(info.binding, &old_binding); glBindTexture(info.bind_target, texture); + if (gl_info->supported[ARB_SHADOW]) + { + glGetTexParameteriv(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, &compare_mode); + if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } - device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, info.tex_type); + device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, + info.tex_type, &This->ds_current_size); glBegin(GL_TRIANGLE_STRIP); glTexCoord3fv(info.coords[0]); @@ -4447,6 +4108,7 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei glVertex2f(1.0f, 1.0f); glEnd(); + if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, compare_mode); glBindTexture(info.bind_target, old_binding); glPopAttrib(); @@ -4454,139 +4116,156 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei device->shader_backend->shader_deselect_depth_blt((IWineD3DDevice *)device); } -void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, + DWORD location, UINT w, UINT h) +{ + TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); - TRACE("(%p) New location %#x\n", This, location); + if (location & ~SFLAG_DS_LOCATIONS) + FIXME("Invalid location (%#x) specified.\n", location); - if (location & ~SFLAG_DS_LOCATIONS) { - FIXME("(%p) Invalid location (%#x) specified\n", This, location); - } - - This->Flags &= ~SFLAG_DS_LOCATIONS; - This->Flags |= location; + surface->ds_current_size.cx = w; + surface->ds_current_size.cy = h; + surface->Flags &= ~SFLAG_DS_LOCATIONS; + surface->Flags |= location; } /* Context activation is done by the caller. */ -void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) +void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_context *context, DWORD location) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.device; + IWineD3DDeviceImpl *device = surface->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; - TRACE("(%p) New location %#x\n", This, location); + TRACE("surface %p, new location %#x.\n", surface, location); /* TODO: Make this work for modes other than FBO */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - if (This->Flags & location) { - TRACE("(%p) Location (%#x) is already up to date\n", This, location); + if (!(surface->Flags & location)) + { + surface->ds_current_size.cx = 0; + surface->ds_current_size.cy = 0; + } + + if (surface->ds_current_size.cx == surface->currentDesc.Width + && surface->ds_current_size.cy == surface->currentDesc.Height) + { + TRACE("Location (%#x) is already up to date.\n", location); return; } - if (This->current_renderbuffer) { - FIXME("(%p) Not supported with fixed up depth stencil\n", This); + if (surface->current_renderbuffer) + { + FIXME("Not supported with fixed up depth stencil.\n"); return; } - if (location == SFLAG_DS_OFFSCREEN) { - if (This->Flags & SFLAG_DS_ONSCREEN) { - GLint old_binding = 0; - GLenum bind_target; - - TRACE("(%p) Copying onscreen depth buffer to depth texture\n", This); - - ENTER_GL(); - - if (!device->depth_blt_texture) { - glGenTextures(1, &device->depth_blt_texture); - } - - /* Note that we use depth_blt here as well, rather than glCopyTexImage2D - * directly on the FBO texture. That's because we need to flip. */ - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) - { - glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); - bind_target = GL_TEXTURE_RECTANGLE_ARB; - } else { - glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); - bind_target = GL_TEXTURE_2D; - } - glBindTexture(bind_target, device->depth_blt_texture); - glCopyTexImage2D(bind_target, This->texture_level, This->resource.format_desc->glInternal, - 0, 0, This->currentDesc.Width, This->currentDesc.Height, 0); - glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); - glBindTexture(bind_target, old_binding); - - /* Setup the destination */ - if (!device->depth_blt_rb) { - gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb); - checkGLcall("glGenRenderbuffersEXT"); - } - if (device->depth_blt_rb_w != This->currentDesc.Width - || device->depth_blt_rb_h != This->currentDesc.Height) { - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb); - checkGLcall("glBindRenderbufferEXT"); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, - This->currentDesc.Width, This->currentDesc.Height); - checkGLcall("glRenderbufferStorageEXT"); - device->depth_blt_rb_w = This->currentDesc.Width; - device->depth_blt_rb_h = This->currentDesc.Height; - } - - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb); - checkGLcall("glFramebufferRenderbufferEXT"); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE); - - /* Do the actual blit */ - surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target); - checkGLcall("depth_blt"); - - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); - else context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - - LEAVE_GL(); - - wglFlush(); /* Flush to ensure ordering across contexts. */ - } - else - { - FIXME("No up to date depth stencil location\n"); - } - } else if (location == SFLAG_DS_ONSCREEN) { - if (This->Flags & SFLAG_DS_OFFSCREEN) { - TRACE("(%p) Copying depth texture to onscreen depth buffer\n", This); - - ENTER_GL(); - - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - surface_depth_blt(This, This->texture_name, This->currentDesc.Width, - This->currentDesc.Height, This->texture_target); - checkGLcall("depth_blt"); - - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); - - LEAVE_GL(); - - wglFlush(); /* Flush to ensure ordering across contexts. */ - } - else - { - FIXME("No up to date depth stencil location\n"); - } - } else { - ERR("(%p) Invalid location (%#x) specified\n", This, location); + if (!(surface->Flags & SFLAG_LOCATIONS)) + { + FIXME("No up to date depth stencil location.\n"); + surface->Flags |= location; + return; } - This->Flags |= location; + if (location == SFLAG_DS_OFFSCREEN) + { + GLint old_binding = 0; + GLenum bind_target; + + TRACE("Copying onscreen depth buffer to depth texture.\n"); + + ENTER_GL(); + + if (!device->depth_blt_texture) + { + glGenTextures(1, &device->depth_blt_texture); + } + + /* Note that we use depth_blt here as well, rather than glCopyTexImage2D + * directly on the FBO texture. That's because we need to flip. */ + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) + { + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + bind_target = GL_TEXTURE_RECTANGLE_ARB; + } + else + { + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + bind_target = GL_TEXTURE_2D; + } + glBindTexture(bind_target, device->depth_blt_texture); + glCopyTexImage2D(bind_target, surface->texture_level, surface->resource.format_desc->glInternal, + 0, 0, surface->currentDesc.Width, surface->currentDesc.Height, 0); + glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); + glBindTexture(bind_target, old_binding); + + /* Setup the destination */ + if (!device->depth_blt_rb) + { + gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb); + checkGLcall("glGenRenderbuffersEXT"); + } + if (device->depth_blt_rb_w != surface->currentDesc.Width + || device->depth_blt_rb_h != surface->currentDesc.Height) + { + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb); + checkGLcall("glBindRenderbufferEXT"); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, + surface->currentDesc.Width, surface->currentDesc.Height); + checkGLcall("glRenderbufferStorageEXT"); + device->depth_blt_rb_w = surface->currentDesc.Width; + device->depth_blt_rb_h = surface->currentDesc.Height; + } + + context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb); + checkGLcall("glFramebufferRenderbufferEXT"); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, surface, FALSE); + + /* Do the actual blit */ + surface_depth_blt(surface, gl_info, device->depth_blt_texture, + surface->currentDesc.Width, surface->currentDesc.Height, bind_target); + checkGLcall("depth_blt"); + + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); + else context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + + LEAVE_GL(); + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ + } + else if (location == SFLAG_DS_ONSCREEN) + { + TRACE("Copying depth texture to onscreen depth buffer.\n"); + + ENTER_GL(); + + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + surface_depth_blt(surface, gl_info, surface->texture_name, + surface->currentDesc.Width, surface->currentDesc.Height, surface->texture_target); + checkGLcall("depth_blt"); + + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); + + LEAVE_GL(); + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ + } + else + { + ERR("Invalid location (%#x) specified.\n", location); + } + + surface->Flags |= location; + surface->ds_current_size.cx = surface->currentDesc.Width; + surface->ds_current_size.cy = surface->currentDesc.Height; } static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) { @@ -4597,8 +4276,9 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW TRACE("(%p)->(%s, %s)\n", iface, debug_surflocation(flag), persistent ? "TRUE" : "FALSE"); - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (surface_is_offscreen(iface)) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (surface_is_offscreen(This)) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); @@ -4643,185 +4323,44 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW } } -struct coords { - GLfloat x, y, z; -}; - -struct float_rect -{ - float l; - float t; - float r; - float b; -}; - -static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) -{ - f->l = ((r->left * 2.0f) / w) - 1.0f; - f->t = ((r->top * 2.0f) / h) - 1.0f; - f->r = ((r->right * 2.0f) / w) - 1.0f; - f->b = ((r->bottom * 2.0f) / h) - 1.0f; -} - static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) { IWineD3DDeviceImpl *device = This->resource.device; - IWineD3DBaseTextureImpl *texture; + IWineD3DSwapChainImpl *swapchain; struct wined3d_context *context; - struct coords coords[4]; - RECT rect; - GLenum bind_target; - struct float_rect f; + RECT src_rect, dst_rect; - if(rect_in) { - rect = *rect_in; - } else { - rect.left = 0; - rect.top = 0; - rect.right = This->currentDesc.Width; - rect.bottom = This->currentDesc.Height; - } - - switch (This->texture_target) - { - case GL_TEXTURE_2D: - bind_target = GL_TEXTURE_2D; - - coords[0].x = (float)rect.left / This->pow2Width; - coords[0].y = (float)rect.top / This->pow2Height; - coords[0].z = 0; - - coords[1].x = (float)rect.left / This->pow2Width; - coords[1].y = (float)rect.bottom / This->pow2Height; - coords[1].z = 0; - - coords[2].x = (float)rect.right / This->pow2Width; - coords[2].y = (float)rect.bottom / This->pow2Height; - coords[2].z = 0; - - coords[3].x = (float)rect.right / This->pow2Width; - coords[3].y = (float)rect.top / This->pow2Height; - coords[3].z = 0; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - bind_target = GL_TEXTURE_RECTANGLE_ARB; - coords[0].x = rect.left; coords[0].y = rect.top; coords[0].z = 0; - coords[1].x = rect.left; coords[1].y = rect.bottom; coords[1].z = 0; - coords[2].x = rect.right; coords[2].y = rect.bottom; coords[2].z = 0; - coords[3].x = rect.right; coords[3].y = rect.top; coords[3].z = 0; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = 1; coords[0].y = -f.t; coords[0].z = -f.l; - coords[1].x = 1; coords[1].y = -f.b; coords[1].z = -f.l; - coords[2].x = 1; coords[2].y = -f.b; coords[2].z = -f.r; - coords[3].x = 1; coords[3].y = -f.t; coords[3].z = -f.r; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = -1; coords[0].y = -f.t; coords[0].z = f.l; - coords[1].x = -1; coords[1].y = -f.b; coords[1].z = f.l; - coords[2].x = -1; coords[2].y = -f.b; coords[2].z = f.r; - coords[3].x = -1; coords[3].y = -f.t; coords[3].z = f.r; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = 1; coords[0].z = f.t; - coords[1].x = f.l; coords[1].y = 1; coords[1].z = f.b; - coords[2].x = f.r; coords[2].y = 1; coords[2].z = f.b; - coords[3].x = f.r; coords[3].y = 1; coords[3].z = f.t; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = -1; coords[0].z = -f.t; - coords[1].x = f.l; coords[1].y = -1; coords[1].z = -f.b; - coords[2].x = f.r; coords[2].y = -1; coords[2].z = -f.b; - coords[3].x = f.r; coords[3].y = -1; coords[3].z = -f.t; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1; - coords[1].x = f.l; coords[1].y = -f.b; coords[1].z = 1; - coords[2].x = f.r; coords[2].y = -f.b; coords[2].z = 1; - coords[3].x = f.r; coords[3].y = -f.t; coords[3].z = 1; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1; - coords[1].x = -f.l; coords[1].y = -f.b; coords[1].z = -1; - coords[2].x = -f.r; coords[2].y = -f.b; coords[2].z = -1; - coords[3].x = -f.r; coords[3].y = -f.t; coords[3].z = -1; - break; - - default: - ERR("Unexpected texture target %#x\n", This->texture_target); - return; - } - - context = context_acquire(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT); - - ENTER_GL(); - - glEnable(bind_target); - checkGLcall("glEnable(bind_target)"); - glBindTexture(bind_target, This->texture_name); - checkGLcall("glBindTexture(bind_target, This->texture_name)"); - glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); + surface_get_rect(This, rect_in, &src_rect); + context = context_acquire(device, This); + context_apply_blit_state(context, device); if (context->render_offscreen) { - LONG tmp = rect.top; - rect.top = rect.bottom; - rect.bottom = tmp; + dst_rect.left = src_rect.left; + dst_rect.right = src_rect.right; + dst_rect.top = src_rect.bottom; + dst_rect.bottom = src_rect.top; + } + else + { + dst_rect = src_rect; } - glBegin(GL_QUADS); - glTexCoord3fv(&coords[0].x); - glVertex2i(rect.left, rect.top); + if ((This->Flags & SFLAG_SWAPCHAIN) && This == ((IWineD3DSwapChainImpl *)This->container)->front_buffer) + surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect); - glTexCoord3fv(&coords[1].x); - glVertex2i(rect.left, rect.bottom); - - glTexCoord3fv(&coords[2].x); - glVertex2i(rect.right, rect.bottom); - - glTexCoord3fv(&coords[3].x); - glVertex2i(rect.right, rect.top); - glEnd(); - checkGLcall("glEnd"); - - glDisable(bind_target); - checkGLcall("glDisable(bind_target)"); + device->blitter->set_shader((IWineD3DDevice *) device, This); + ENTER_GL(); + draw_textured_quad(This, &src_rect, &dst_rect, WINED3DTEXF_POINT); LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + device->blitter->set_shader((IWineD3DDevice *) device, This); - /* We changed the filtering settings on the texture. Inform the - * container about this to get the filters reset properly next draw. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DBaseTexture, (void **)&texture))) - { - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; - IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); - } + swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL; + if (wined3d_settings.strict_draw_ordering || (swapchain + && (This == swapchain->front_buffer || swapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); } @@ -4851,16 +4390,32 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - GLenum format, internal, type; + struct wined3d_format_desc desc; CONVERT_TYPES convert; - int bpp; int width, pitch, outpitch; BYTE *mem; BOOL drawable_read_ok = TRUE; BOOL in_fbo = FALSE; - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (surface_is_offscreen(iface)) + if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (flag == SFLAG_INTEXTURE) + { + struct wined3d_context *context = context_acquire(device, NULL); + surface_load_ds_location(This, context, SFLAG_DS_OFFSCREEN); + context_release(context); + return WINED3D_OK; + } + else + { + FIXME("Unimplemented location %#x for depth/stencil buffers.\n", flag); + return WINED3DERR_INVALIDCALL; + } + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (surface_is_offscreen(This)) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. * Prefer SFLAG_INTEXTURE. */ @@ -4898,10 +4453,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D { struct wined3d_context *context = NULL; - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE)); - surface_download_data(This); + surface_download_data(This, gl_info); if (context) context_release(context); } @@ -4916,6 +4471,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D if(This->Flags & SFLAG_INTEXTURE) { surface_blt_to_drawable(This, rect); } else { + int byte_count; if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) { /* This needs a shader to convert the srgb data sampled from the GL texture into RGB * values, otherwise we get incorrect values in the target. For now go the slow way @@ -4924,7 +4480,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect); } - d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, FALSE); + d3dfmt_get_conv(This, FALSE /* We need color keying */, FALSE /* We won't use textures */, &desc, &convert); /* The width is in 'length' not in bytes */ width = This->currentDesc.Width; @@ -4938,16 +4494,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D TRACE("Removing the pbo attached to surface %p\n", This); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - surface_remove_pbo(This); + if (!device->isInDraw) context = context_acquire(device, NULL); + surface_remove_pbo(This, gl_info); if (context) context_release(context); } if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { int height = This->currentDesc.Height; + byte_count = desc.conv_byte_count; /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - outpitch = width * bpp; + outpitch = width * byte_count; outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); @@ -4961,9 +4518,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D } else { This->Flags &= ~SFLAG_CONVERTED; mem = This->resource.allocatedMemory; + byte_count = desc.byte_count; } - flush_to_framebuffer_drawpixels(This, format, type, bpp, mem); + flush_to_framebuffer_drawpixels(This, desc.glFormat, desc.glType, byte_count, mem); /* Don't delete PBO memory */ if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO)) @@ -4980,7 +4538,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D struct wined3d_context *context = NULL; d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, - &format, &internal, &type, &convert, &bpp, srgb); + &desc, &convert); if(srgb) { if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) { @@ -5002,9 +4560,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect); } - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); - surface_prepare_texture(This, srgb); + surface_prepare_texture(This, gl_info, srgb); surface_bind_and_dirtify(This, srgb); if(This->CKeyFlags & WINEDDSD_CKSRCBLT) { @@ -5019,16 +4577,32 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D /* Don't use PBOs for converted surfaces. During PBO conversion we look at SFLAG_CONVERTED * but it isn't set (yet) in all cases it is getting called. */ - if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) { + if(((convert != NO_CONVERSION) || desc.convert) && (This->Flags & SFLAG_PBO)) { TRACE("Removing the pbo attached to surface %p\n", This); - surface_remove_pbo(This); + surface_remove_pbo(This, gl_info); } - if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { + if(desc.convert) { + /* This code is entered for texture formats which need a fixup. */ int height = This->currentDesc.Height; /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - outpitch = width * bpp; + outpitch = width * desc.conv_byte_count; + outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); + + mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); + if(!mem) { + ERR("Out of memory %d, %d!\n", outpitch, height); + if (context) context_release(context); + return WINED3DERR_OUTOFVIDEOMEMORY; + } + desc.convert(This->resource.allocatedMemory, mem, pitch, width, height); + } else if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { + /* This code is only entered for color keying fixups */ + int height = This->currentDesc.Height; + + /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ + outpitch = width * desc.conv_byte_count; outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); @@ -5038,12 +4612,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D return WINED3DERR_OUTOFVIDEOMEMORY; } d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This); - } - else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT - && (gl_info->supported[EXT_PALETTED_TEXTURE] || device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup))) - { - d3dfmt_p8_upload_palette(iface, convert); - mem = This->resource.allocatedMemory; } else { mem = This->resource.allocatedMemory; } @@ -5053,19 +4621,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D glPixelStorei(GL_UNPACK_ROW_LENGTH, width); LEAVE_GL(); - if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) { - TRACE("non power of two support\n"); - if (mem || (This->Flags & SFLAG_PBO)) { - surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem); - } - } else { - /* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory - * changed. So also keep track of memory changes. In this case the texture has to be reallocated - */ - if (mem || (This->Flags & SFLAG_PBO)) { - surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem); - } - } + if (mem || (This->Flags & SFLAG_PBO)) + surface_upload_data(This, gl_info, &desc, srgb, mem); /* Restore the default pitch */ ENTER_GL(); @@ -5107,7 +4664,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, I } else if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { switch(wined3d_settings.offscreen_rendering_mode) { case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; - case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; } } @@ -5141,16 +4697,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) { return hr; } -BOOL surface_is_offscreen(IWineD3DSurface *iface) +BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->container; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; /* Not on a swapchain - must be offscreen */ - if (!(This->Flags & SFLAG_SWAPCHAIN)) return TRUE; + if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE; /* The front buffer is always onscreen */ - if(iface == swapchain->frontBuffer) return FALSE; + if (surface == swapchain->front_buffer) return FALSE; /* If the swapchain is rendered to an FBO, the backbuffer is * offscreen, otherwise onscreen */ @@ -5212,20 +4767,42 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_GetImplType, IWineD3DSurfaceImpl_DrawOverlay }; -#undef GLINFO_LOCATION -#define GLINFO_LOCATION device->adapter->gl_info static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } /* Context activation is done by the caller. */ static void ffp_blit_free(IWineD3DDevice *iface) { } +/* This function is used in case of 8bit paletted textures using GL_EXT_paletted_texture */ /* Context activation is done by the caller. */ -static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height) +static void ffp_blit_p8_upload_palette(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info) { + BYTE table[256][4]; + BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE; + + d3dfmt_p8_init_palette(surface, table, colorkey_active); + + TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n"); ENTER_GL(); - glEnable(textype); - checkGLcall("glEnable(textype)"); + GL_EXTCALL(glColorTableEXT(surface->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table)); + LEAVE_GL(); +} + +/* Context activation is done by the caller. */ +static HRESULT ffp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + enum complex_fixup fixup = get_complex_fixup(surface->resource.format_desc->color_fixup); + + /* When EXT_PALETTED_TEXTURE is around, palette conversion is done by the GPU + * else the surface is converted in software at upload time in LoadLocation. + */ + if(fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE]) + ffp_blit_p8_upload_palette(surface, gl_info); + + ENTER_GL(); + glEnable(surface->texture_target); + checkGLcall("glEnable(surface->texture_target)"); LEAVE_GL(); return WINED3D_OK; } @@ -5252,16 +4829,52 @@ static void ffp_blit_unset(IWineD3DDevice *iface) LEAVE_GL(); } -static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup) +static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) { + enum complex_fixup src_fixup; + + if (blit_op == BLIT_OP_COLOR_FILL) + { + if (!(dst_usage & WINED3DUSAGE_RENDERTARGET)) + { + TRACE("Color fill not supported\n"); + return FALSE; + } + + return TRUE; + } + + src_fixup = get_complex_fixup(src_format_desc->color_fixup); if (TRACE_ON(d3d_surface) && TRACE_ON(d3d)) { TRACE("Checking support for fixup:\n"); - dump_color_fixup_desc(fixup); + dump_color_fixup_desc(src_format_desc->color_fixup); + } + + if (blit_op != BLIT_OP_BLIT) + { + TRACE("Unsupported blit_op=%d\n", blit_op); + return FALSE; + } + + if (!is_identity_fixup(dst_format_desc->color_fixup)) + { + TRACE("Destination fixups are not supported\n"); + return FALSE; + } + + if (src_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE]) + { + TRACE("P8 fixup supported\n"); + return TRUE; } /* We only support identity conversions. */ - if (is_identity_fixup(fixup)) + if (is_identity_fixup(src_format_desc->color_fixup)) { TRACE("[OK]\n"); return TRUE; @@ -5271,10 +4884,105 @@ static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup) return FALSE; } +static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + return IWineD3DDeviceImpl_ClearSurface(device, dst_surface, 1 /* Number of rectangles */, + (const WINED3DRECT*)dst_rect, WINED3DCLEAR_TARGET, fill_color, 0.0f /* Z */, 0 /* Stencil */); +} + const struct blit_shader ffp_blit = { ffp_blit_alloc, ffp_blit_free, ffp_blit_set, ffp_blit_unset, - ffp_blit_color_fixup_supported + ffp_blit_supported, + ffp_blit_color_fill }; + +static HRESULT cpu_blit_alloc(IWineD3DDevice *iface) +{ + return WINED3D_OK; +} + +/* Context activation is done by the caller. */ +static void cpu_blit_free(IWineD3DDevice *iface) +{ +} + +/* Context activation is done by the caller. */ +static HRESULT cpu_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) +{ + return WINED3D_OK; +} + +/* Context activation is done by the caller. */ +static void cpu_blit_unset(IWineD3DDevice *iface) +{ +} + +static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) +{ + if (blit_op == BLIT_OP_COLOR_FILL) + { + return TRUE; + } + + return FALSE; +} + +static HRESULT cpu_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + WINEDDBLTFX BltFx; + memset(&BltFx, 0, sizeof(BltFx)); + BltFx.dwSize = sizeof(BltFx); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(fill_color, dst_surface->resource.format_desc->format); + return IWineD3DBaseSurfaceImpl_Blt((IWineD3DSurface*)dst_surface, dst_rect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); +} + +const struct blit_shader cpu_blit = { + cpu_blit_alloc, + cpu_blit_free, + cpu_blit_set, + cpu_blit_unset, + cpu_blit_supported, + cpu_blit_color_fill +}; + +static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) +{ + if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer) + return FALSE; + + /* We only support blitting. Things like color keying / color fill should + * be handled by other blitters. + */ + if (blit_op != BLIT_OP_BLIT) + return FALSE; + + /* Source and/or destination need to be on the GL side */ + if (src_pool == WINED3DPOOL_SYSTEMMEM || dst_pool == WINED3DPOOL_SYSTEMMEM) + return FALSE; + + if(!((src_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET)) + && ((dst_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET))) + return FALSE; + + if (!is_identity_fixup(src_format_desc->color_fixup) || + !is_identity_fixup(dst_format_desc->color_fixup)) + return FALSE; + + if (!(src_format_desc->format == dst_format_desc->format + || (is_identity_fixup(src_format_desc->color_fixup) + && is_identity_fixup(dst_format_desc->color_fixup)))) + return FALSE; + + return TRUE; +} diff --git a/reactos/dll/directx/wine/wined3d/surface_base.c b/reactos/dll/directx/wine/wined3d/surface_base.c index 33e3d3ed885..2b6cdb41f22 100644 --- a/reactos/dll/directx/wine/wined3d/surface_base.c +++ b/reactos/dll/directx/wine/wined3d/surface_base.c @@ -83,9 +83,6 @@ static inline unsigned short float_32_to_16(const float *in) return ret; } - -/* Do NOT define GLINFO_LOCATION in this file. THIS CODE MUST NOT USE IT */ - /* ******************************************* IWineD3DSurface IUnknown parts follow ******************************************* */ @@ -326,7 +323,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; DWORD ret; TRACE("(%p)\n", This); @@ -502,7 +499,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWin HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, &This->resource.device->adapter->gl_info); if (This->resource.format_desc->format != WINED3DFMT_UNKNOWN) @@ -527,7 +524,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; int extraline = 0; SYSTEM_INFO sysInfo; BITMAPINFO* b_info; @@ -742,6 +739,55 @@ static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst, } } +static inline BYTE cliptobyte(int x) +{ + return (BYTE) ((x < 0) ? 0 : ((x > 255) ? 255 : x)); +} + +static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned int x, y; + int c2, d, e, r2 = 0, g2 = 0, b2 = 0; + + TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out); + + for (y = 0; y < h; ++y) + { + const BYTE *src_line = src + y * pitch_in; + DWORD *dst_line = (DWORD *)(dst + y * pitch_out); + for (x = 0; x < w; ++x) + { + /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: + * C = Y - 16; D = U - 128; E = V - 128; + * R = cliptobyte((298 * C + 409 * E + 128) >> 8); + * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); + * B = cliptobyte((298 * C + 516 * D + 128) >> 8); + * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . + * U and V are shared between the pixels. + */ + if (!(x & 1)) /* for every even pixel, read new U and V */ + { + d = (int) src_line[1] - 128; + e = (int) src_line[3] - 128; + r2 = 409 * e + 128; + g2 = - 100 * d - 208 * e + 128; + b2 = 516 * d + 128; + } + c2 = 298 * ((int) src_line[0] - 16); + dst_line[x] = 0xff000000 + | cliptobyte((c2 + r2) >> 8) << 16 /* red */ + | cliptobyte((c2 + g2) >> 8) << 8 /* green */ + | cliptobyte((c2 + b2) >> 8); /* blue */ + /* Scale RGB values to 0..255 range, + * then clip them if still not in range (may be negative), + * then shift them within DWORD if necessary. + */ + src_line += 2; + } + } +} + struct d3dfmt_convertor_desc { WINED3DFORMAT from, to; void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h); @@ -752,6 +798,7 @@ static const struct d3dfmt_convertor_desc convertors[] = {WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float}, {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8}, {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, }; static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to) @@ -892,7 +939,7 @@ static HRESULT /***************************************************************************** * IWineD3DSurface::Blt, SW emulation version * - * Performs blits to a surface, eigher from a source of source-less blts + * Performs a blit to a surface, with or without a source surface. * This is the main functionality of DirectDraw * * Params: @@ -909,7 +956,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D HRESULT ret = WINED3D_OK; WINED3DLOCKED_RECT dlock, slock; int bpp, srcheight, srcwidth, dstheight, dstwidth, width; - const struct GlPixelFormatDesc *sEntry, *dEntry; + const struct wined3d_format_desc *sEntry, *dEntry; int x, y; const BYTE *sbuf; BYTE *dbuf; @@ -943,144 +990,145 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D FIXME("Filters not supported in software blit\n"); } - /* First check for the validity of source / destination rectangles. This was - * verified using a test application + by MSDN. - */ - if ((Src != NULL) && (SrcRect != NULL) && - ((SrcRect->bottom > Src->currentDesc.Height)||(SrcRect->bottom < 0) || - (SrcRect->top > Src->currentDesc.Height)||(SrcRect->top < 0) || - (SrcRect->left > Src->currentDesc.Width) ||(SrcRect->left < 0) || - (SrcRect->right > Src->currentDesc.Width) ||(SrcRect->right < 0) || - (SrcRect->right < SrcRect->left) ||(SrcRect->bottom < SrcRect->top))) - { - WARN("Application gave us bad source rectangle for Blt.\n"); - return WINEDDERR_INVALIDRECT; - } - /* For the Destination rect, it can be out of bounds on the condition that a clipper - * is set for the given surface. - */ - if ((/*This->clipper == NULL*/ TRUE) && (DestRect) && - ((DestRect->bottom > This->currentDesc.Height)||(DestRect->bottom < 0) || - (DestRect->top > This->currentDesc.Height)||(DestRect->top < 0) || - (DestRect->left > This->currentDesc.Width) ||(DestRect->left < 0) || - (DestRect->right > This->currentDesc.Width) ||(DestRect->right < 0) || - (DestRect->right < DestRect->left) ||(DestRect->bottom < DestRect->top))) - { - WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); - return WINEDDERR_INVALIDRECT; - } + /* First check for the validity of source / destination rectangles. + * This was verified using a test application + by MSDN. */ - /* Now handle negative values in the rectangles. Warning: only supported for now - in the 'simple' cases (ie not in any stretching / rotation cases). - - First, the case where nothing is to be done. - */ - if ((DestRect && ((DestRect->bottom <= 0) || (DestRect->right <= 0) || - (DestRect->top >= (int) This->currentDesc.Height) || - (DestRect->left >= (int) This->currentDesc.Width))) || - ((Src != NULL) && (SrcRect != NULL) && - ((SrcRect->bottom <= 0) || (SrcRect->right <= 0) || - (SrcRect->top >= (int) Src->currentDesc.Height) || - (SrcRect->left >= (int) Src->currentDesc.Width)) )) + if (SrcRect) { - TRACE("Nothing to be done !\n"); - return WINED3D_OK; + if (Src) + { + if (SrcRect->right < SrcRect->left || SrcRect->bottom < SrcRect->top + || SrcRect->left > Src->currentDesc.Width || SrcRect->left < 0 + || SrcRect->top > Src->currentDesc.Height || SrcRect->top < 0 + || SrcRect->right > Src->currentDesc.Width || SrcRect->right < 0 + || SrcRect->bottom > Src->currentDesc.Height || SrcRect->bottom < 0) + { + WARN("Application gave us bad source rectangle for Blt.\n"); + return WINEDDERR_INVALIDRECT; + } + + if (!SrcRect->right || !SrcRect->bottom + || SrcRect->left == (int)Src->currentDesc.Width + || SrcRect->top == (int)Src->currentDesc.Height) + { + TRACE("Nothing to be done.\n"); + return WINED3D_OK; + } + } + + xsrc = *SrcRect; + } + else if (Src) + { + xsrc.left = 0; + xsrc.top = 0; + xsrc.right = Src->currentDesc.Width; + xsrc.bottom = Src->currentDesc.Height; + } + else + { + memset(&xsrc, 0, sizeof(xsrc)); } if (DestRect) { - xdst = *DestRect; - } - else - { - xdst.top = 0; - xdst.bottom = This->currentDesc.Height; - xdst.left = 0; - xdst.right = This->currentDesc.Width; - } - - if (SrcRect) - { - xsrc = *SrcRect; - } - else - { - if (Src) + /* For the Destination rect, it can be out of bounds on the condition + * that a clipper is set for the given surface. */ + if (!This->clipper && (DestRect->right < DestRect->left || DestRect->bottom < DestRect->top + || DestRect->left > This->currentDesc.Width || DestRect->left < 0 + || DestRect->top > This->currentDesc.Height || DestRect->top < 0 + || DestRect->right > This->currentDesc.Width || DestRect->right < 0 + || DestRect->bottom > This->currentDesc.Height || DestRect->bottom < 0)) { - xsrc.top = 0; - xsrc.bottom = Src->currentDesc.Height; - xsrc.left = 0; - xsrc.right = Src->currentDesc.Width; + WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); + return WINEDDERR_INVALIDRECT; + } + + if (DestRect->right <= 0 || DestRect->bottom <= 0 + || DestRect->left >= (int)This->currentDesc.Width + || DestRect->top >= (int)This->currentDesc.Height) + { + TRACE("Nothing to be done.\n"); + return WINED3D_OK; + } + + if (!Src) + { + RECT full_rect; + + full_rect.left = 0; + full_rect.top = 0; + full_rect.right = This->currentDesc.Width; + full_rect.bottom = This->currentDesc.Height; + IntersectRect(&xdst, &full_rect, DestRect); } else { - memset(&xsrc,0,sizeof(xsrc)); + BOOL clip_horiz, clip_vert; + + xdst = *DestRect; + clip_horiz = xdst.left < 0 || xdst.right > (int)This->currentDesc.Width; + clip_vert = xdst.top < 0 || xdst.bottom > (int)This->currentDesc.Height; + + if (clip_vert || clip_horiz) + { + /* Now check if this is a special case or not... */ + if ((Flags & WINEDDBLT_DDFX) + || (clip_horiz && xdst.right - xdst.left != xsrc.right - xsrc.left) + || (clip_vert && xdst.bottom - xdst.top != xsrc.bottom - xsrc.top)) + { + WARN("Out of screen rectangle in special case. Not handled right now.\n"); + return WINED3D_OK; + } + + if (clip_horiz) + { + if (xdst.left < 0) + { + xsrc.left -= xdst.left; + xdst.left = 0; + } + if (xdst.right > This->currentDesc.Width) + { + xsrc.right -= (xdst.right - (int)This->currentDesc.Width); + xdst.right = (int)This->currentDesc.Width; + } + } + + if (clip_vert) + { + if (xdst.top < 0) + { + xsrc.top -= xdst.top; + xdst.top = 0; + } + if (xdst.bottom > This->currentDesc.Height) + { + xsrc.bottom -= (xdst.bottom - (int)This->currentDesc.Height); + xdst.bottom = (int)This->currentDesc.Height; + } + } + + /* And check if after clipping something is still to be done... */ + if ((xdst.right <= 0) || (xdst.bottom <= 0) + || (xdst.left >= (int)This->currentDesc.Width) + || (xdst.top >= (int)This->currentDesc.Height) + || (xsrc.right <= 0) || (xsrc.bottom <= 0) + || (xsrc.left >= (int) Src->currentDesc.Width) + || (xsrc.top >= (int)Src->currentDesc.Height)) + { + TRACE("Nothing to be done after clipping.\n"); + return WINED3D_OK; + } + } } } - - /* The easy case : the source-less blits.... */ - if (Src == NULL && DestRect) + else { - RECT full_rect; - RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */ - - full_rect.left = 0; - full_rect.top = 0; - full_rect.right = This->currentDesc.Width; - full_rect.bottom = This->currentDesc.Height; - IntersectRect(&temp_rect, &full_rect, DestRect); - xdst = temp_rect; - } - else if (DestRect) - { - /* Only handle clipping on the destination rectangle */ - int clip_horiz = (DestRect->left < 0) || (DestRect->right > (int) This->currentDesc.Width ); - int clip_vert = (DestRect->top < 0) || (DestRect->bottom > (int) This->currentDesc.Height); - if (clip_vert || clip_horiz) - { - /* Now check if this is a special case or not... */ - if ((((DestRect->bottom - DestRect->top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) || - (((DestRect->right - DestRect->left) != (xsrc.right - xsrc.left)) && clip_horiz) || - (Flags & WINEDDBLT_DDFX)) - { - WARN("Out of screen rectangle in special case. Not handled right now.\n"); - return WINED3D_OK; - } - - if (clip_horiz) - { - if (DestRect->left < 0) { xsrc.left -= DestRect->left; xdst.left = 0; } - if (DestRect->right > This->currentDesc.Width) - { - xsrc.right -= (DestRect->right - (int) This->currentDesc.Width); - xdst.right = (int) This->currentDesc.Width; - } - } - if (clip_vert) - { - if (DestRect->top < 0) - { - xsrc.top -= DestRect->top; - xdst.top = 0; - } - if (DestRect->bottom > This->currentDesc.Height) - { - xsrc.bottom -= (DestRect->bottom - (int) This->currentDesc.Height); - xdst.bottom = (int) This->currentDesc.Height; - } - } - /* And check if after clipping something is still to be done... */ - if ((xdst.bottom <= 0) || (xdst.right <= 0) || - (xdst.top >= (int) This->currentDesc.Height) || - (xdst.left >= (int) This->currentDesc.Width) || - (xsrc.bottom <= 0) || (xsrc.right <= 0) || - (xsrc.top >= (int) Src->currentDesc.Height) || - (xsrc.left >= (int) Src->currentDesc.Width)) - { - TRACE("Nothing to be done after clipping !\n"); - return WINED3D_OK; - } - } + xdst.left = 0; + xdst.top = 0; + xdst.right = This->currentDesc.Width; + xdst.bottom = This->currentDesc.Height; } if (Src == This) @@ -1552,7 +1600,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dst RECT lock_src, lock_dst, lock_union; const BYTE *sbuf; BYTE *dbuf; - const struct GlPixelFormatDesc *sEntry, *dEntry; + const struct wined3d_format_desc *sEntry, *dEntry; if (TRACE_ON(d3d_surface)) { @@ -1833,7 +1881,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL } else { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom); diff --git a/reactos/dll/directx/wine/wined3d/surface_gdi.c b/reactos/dll/directx/wine/wined3d/surface_gdi.c index 3f09dc3c130..580c88a9080 100644 --- a/reactos/dll/directx/wine/wined3d/surface_gdi.c +++ b/reactos/dll/directx/wine/wined3d/surface_gdi.c @@ -200,7 +200,7 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface) /* Tell the swapchain to update the screen */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { - if(iface == swapchain->frontBuffer) + if (This == swapchain->front_buffer) { x11_copy_to_screen(swapchain, &This->lockedRect); } @@ -240,7 +240,8 @@ IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface, return WINEDDERR_NOTFLIPPABLE; } - hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0); + hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain, + NULL, NULL, swapchain->win_handle, NULL, 0); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } @@ -296,9 +297,9 @@ const char* filename) FILE* f = NULL; UINT y = 0, x = 0; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; static char *output = NULL; static UINT size = 0; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; if (This->pow2Width > size) { output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3); @@ -340,14 +341,13 @@ const char* filename) fwrite(output, 3 * This->pow2Width, 1, f); } } else { - int red_shift, green_shift, blue_shift, pix_width, alpha_shift; + int red_shift, green_shift, blue_shift, pix_width; pix_width = format_desc->byte_count; red_shift = get_shift(format_desc->red_mask); green_shift = get_shift(format_desc->green_mask); blue_shift = get_shift(format_desc->blue_mask); - alpha_shift = get_shift(format_desc->alpha_mask); for (y = 0; y < This->pow2Height; y++) { const unsigned char *src = This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface)); @@ -366,8 +366,8 @@ const char* filename) output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift; comp = color & format_desc->green_mask; output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift; - comp = color & format_desc->alpha_mask; - output[3 * x + 2] = alpha_shift > 0 ? comp >> alpha_shift : comp << -alpha_shift; + comp = color & format_desc->blue_mask; + output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift; } fwrite(output, 3 * This->pow2Width, 1, f); } @@ -430,7 +430,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; - dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; + dds_primary = swapchain->front_buffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } @@ -500,7 +500,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) /* Tell the swapchain to update the screen */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { - if(iface == swapchain->frontBuffer) + if (This == swapchain->front_buffer) { x11_copy_to_screen(swapchain, NULL); } diff --git a/reactos/dll/directx/wine/wined3d/swapchain.c b/reactos/dll/directx/wine/wined3d/swapchain.c index cbdb961f705..b0d591a7587 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain.c +++ b/reactos/dll/directx/wine/wined3d/swapchain.c @@ -33,8 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); -#define GLINFO_LOCATION This->device->adapter->gl_info - /*IWineD3DSwapChain parts follow: */ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) { @@ -46,32 +44,32 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); - /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is + /* Release the swapchain's draw buffers. Make sure This->back_buffers[0] is * the last buffer to be destroyed, FindContext() depends on that. */ - if (This->frontBuffer) + if (This->front_buffer) { - IWineD3DSurface_SetContainer(This->frontBuffer, 0); - if (IWineD3DSurface_Release(This->frontBuffer)) + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer)) { WARN("(%p) Something's still holding the front buffer (%p).\n", - This, This->frontBuffer); + This, This->front_buffer); } - This->frontBuffer = NULL; + This->front_buffer = NULL; } - if (This->backBuffer) + if (This->back_buffers) { UINT i = This->presentParms.BackBufferCount; while (i--) { - IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - if (IWineD3DSurface_Release(This->backBuffer[i])) + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) WARN("(%p) Something's still holding back buffer %u (%p).\n", - This, i, This->backBuffer[i]); + This, i, This->back_buffers[i]); } - HeapFree(GetProcessHeap(), 0, This->backBuffer); - This->backBuffer = NULL; + HeapFree(GetProcessHeap(), 0, This->back_buffers); + This->back_buffers = NULL; } for (i = 0; i < This->num_contexts; ++i) @@ -100,11 +98,13 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * const RECT *src_rect, const RECT *dst_rect) { IWineD3DDeviceImpl *device = This->device; - IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]); + IWineD3DSurfaceImpl *backbuffer = This->back_buffers[0]; UINT src_w = src_rect->right - src_rect->left; UINT src_h = src_rect->bottom - src_rect->top; GLenum gl_filter; const struct wined3d_gl_info *gl_info = context->gl_info; + RECT win_rect; + UINT win_h; TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n", This, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect)); @@ -114,12 +114,14 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * else gl_filter = GL_LINEAR; - if (gl_info->fbo_ops.glBlitFramebuffer) + GetClientRect(This->win_handle, &win_rect); + win_h = win_rect.bottom - win_rect.top; + + if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format_desc->color_fixup)) { ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); - context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, This->backBuffer[0]); - context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL); + glReadBuffer(GL_COLOR_ATTACHMENT0); context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); context_set_draw_buffer(context, GL_BACK); @@ -129,8 +131,8 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * /* Note that the texture is upside down */ gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, - dst_rect->left, dst_rect->bottom, dst_rect->right, dst_rect->top, - GL_COLOR_BUFFER_BIT, gl_filter); + dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom, + GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n"); LEAVE_GL(); } @@ -142,7 +144,8 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * float tex_right = src_rect->right; float tex_bottom = src_rect->bottom; - context2 = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_BLIT); + context2 = context_acquire(This->device, This->back_buffers[0]); + context_apply_blit_state(context2, device); if(backbuffer->Flags & SFLAG_NORMCOORD) { @@ -152,30 +155,31 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * tex_bottom /= src_h; } + if (is_complex_fixup(backbuffer->resource.format_desc->color_fixup)) + gl_filter = GL_NEAREST; + ENTER_GL(); context_bind_fbo(context2, GL_DRAW_FRAMEBUFFER, NULL); /* Set up the texture. The surface is not in a IWineD3D*Texture container, * so there are no d3d texture settings to dirtify */ - device->blitter->set_shader((IWineD3DDevice *) device, backbuffer->resource.format_desc, - backbuffer->texture_target, backbuffer->pow2Width, - backbuffer->pow2Height); - glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + device->blitter->set_shader((IWineD3DDevice *) device, backbuffer); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter); context_set_draw_buffer(context, GL_BACK); /* Set the viewport to the destination rectandle, disable any projection - * transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad. + * transformation set up by context_apply_blit_state(), and draw a + * (-1,-1)-(1,1) quad. * * Back up viewport and matrix to avoid breaking last_was_blit * - * Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface - * size - we want the GL drawable(=window) size. - */ + * Note that context_apply_blit_state() set up viewport and ortho to + * match the surface size - we want the GL drawable(=window) size. */ glPushAttrib(GL_VIEWPORT_BIT); - glViewport(dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom); + glViewport(dst_rect->left, win_h - dst_rect->bottom, dst_rect->right, win_h - dst_rect->top); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -211,6 +215,7 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; RECT src_rect, dst_rect; BOOL render_to_fbo; @@ -219,7 +224,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride); - context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, This->back_buffers[0]); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping present.\n"); + return WINED3D_OK; + } + + gl_info = context->gl_info; /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ if (This->device->bCursorVisible && This->device->cursorTexture) @@ -242,17 +255,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO cursor.resource.ref = 1; cursor.resource.device = This->device; cursor.resource.pool = WINED3DPOOL_SCRATCH; - cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, context->gl_info); + cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); cursor.resource.resourceType = WINED3DRTYPE_SURFACE; cursor.texture_name = This->device->cursorTexture; cursor.texture_target = GL_TEXTURE_2D; cursor.texture_level = 0; cursor.currentDesc.Width = This->device->cursorWidth; cursor.currentDesc.Height = This->device->cursorHeight; - cursor.glRect.left = 0; - cursor.glRect.top = 0; - cursor.glRect.right = cursor.currentDesc.Width; - cursor.glRect.bottom = cursor.currentDesc.Height; /* The cursor must have pow2 sizes */ cursor.pow2Width = cursor.currentDesc.Width; cursor.pow2Height = cursor.currentDesc.Height; @@ -264,14 +273,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if (This->presentParms.Windowed) { MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2); } - IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor, + IWineD3DSurface_Blt((IWineD3DSurface *)This->back_buffers[0], &destRect, (IWineD3DSurface *)&cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT); } if (This->device->logo_surface) { /* Blit the logo into the upper left corner of the drawable. */ - IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); + IWineD3DSurface_BltFast((IWineD3DSurface *)This->back_buffers[0], 0, 0, + This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); } TRACE("Presenting HDC %p.\n", context->hdc); @@ -315,8 +325,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO */ if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL); - IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INTEXTURE, NULL); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, FALSE); This->render_to_fbo = TRUE; /* Force the context manager to update the render target configuration next draw. */ @@ -420,14 +430,14 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0); } - if(!This->render_to_fbo && - ( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM || - ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) { + if (!This->render_to_fbo && ((This->front_buffer->Flags & SFLAG_INSYSMEM) + || (This->back_buffers[0]->Flags & SFLAG_INSYSMEM))) + { /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying * Doesn't work with render_to_fbo because we're not flipping */ - IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; - IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; + IWineD3DSurfaceImpl *front = This->front_buffer; + IWineD3DSurfaceImpl *back = This->back_buffers[0]; if(front->resource.size == back->resource.size) { DWORD fbflags; @@ -438,35 +448,45 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO * This serves to update the emulated overlay, if any */ fbflags = front->Flags; - IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)front, SFLAG_INDRAWABLE, TRUE); front->Flags = fbflags; } else { IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE); IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE); } - } else { - IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE); + } + else + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->front_buffer, SFLAG_INDRAWABLE, TRUE); /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. * If the swapeffect is COPY, the content remains the same. If it is FLIP however, * the texture / sysmem copy needs to be reloaded from the drawable */ - if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) { - IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE); + if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, TRUE); } } - if (This->device->stencilBufferTarget) + if (This->device->depth_stencil) { if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD) + || This->device->depth_stencil->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->device->stencilBufferTarget, SFLAG_DS_DISCARDED); + surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED, + This->device->depth_stencil->currentDesc.Width, + This->device->depth_stencil->currentDesc.Height); + if (This->device->depth_stencil == This->device->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil); + This->device->onscreen_depth_stencil = NULL; + } } } if (This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE - && context->gl_info->supported[SGI_VIDEO_SYNC]) + && gl_info->supported[SGI_VIDEO_SYNC]) { retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync)); if(retval != 0) { @@ -514,47 +534,16 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO return WINED3D_OK; } -static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) { - IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; - WINED3DLOCKED_RECT r; - BYTE *mem; +static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) +{ + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface; - if (!window || window == This->win_handle) return WINED3D_OK; + if (!window) window = swapchain->device_window; + if (window == swapchain->win_handle) return WINED3D_OK; - TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window); - if (This->context[0] == This->device->contexts[0]) - { - /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading - * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts - * and reload the resources - */ - delete_opengl_contexts((IWineD3DDevice *)This->device, iface); - This->win_handle = window; - create_primary_opengl_context((IWineD3DDevice *)This->device, iface); - } - else - { - This->win_handle = window; + TRACE("Setting swapchain %p window from %p to %p\n", swapchain, swapchain->win_handle, window); + swapchain->win_handle = window; - /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect - * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code - * So lock read only, copy the surface out, then lock with the discard flag and write back - */ - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY); - mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - - context_destroy(This->device, This->context[0]); - This->context[0] = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, - This->win_handle, FALSE /* pbuffer */, &This->presentParms); - context_release(This->context[0]); - - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD); - memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - HeapFree(GetProcessHeap(), 0, mem); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - } return WINED3D_OK; } @@ -599,7 +588,7 @@ static LONG fullscreen_exstyle(LONG exstyle) void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) { IWineD3DDeviceImpl *device = swapchain->device; - HWND window = swapchain->win_handle; + HWND window = swapchain->device_window; BOOL filter_messages; LONG style, exstyle; @@ -633,7 +622,7 @@ void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain) { IWineD3DDeviceImpl *device = swapchain->device; - HWND window = swapchain->win_handle; + HWND window = swapchain->device_window; BOOL filter_messages; LONG style, exstyle; @@ -671,7 +660,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) { const struct wined3d_adapter *adapter = device->adapter; - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; BOOL displaymode_set = FALSE; WINED3DDISPLAYMODE mode; RECT client_rect; @@ -713,6 +702,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface swapchain->parent = parent; swapchain->ref = 1; swapchain->win_handle = window; + swapchain->device_window = window; if (!present_parameters->Windowed && window) { @@ -768,18 +758,19 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, - swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer); + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, + (IWineD3DSurface **)&swapchain->front_buffer); if (FAILED(hr)) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } - IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain); - ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, (IWineD3DBase *)swapchain); + swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN; if (surface_type == SURFACE_OPENGL) { - IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); } /* MSDN says we're only allowed a single fullscreen swapchain per device, @@ -816,14 +807,49 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (surface_type == SURFACE_OPENGL) { - swapchain->context[0] = context_create(device, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, - window, FALSE /* pbuffer */, present_parameters); + WINED3DFORMAT formats[] = + { + WINED3DFMT_D24_UNORM_S8_UINT, + WINED3DFMT_D32_UNORM, + WINED3DFMT_R24_UNORM_X8_TYPELESS, + WINED3DFMT_D16_UNORM, + WINED3DFMT_S1_UINT_D15_UNORM + }; + + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. + * You are able to add a depth + stencil surface at a later stage when you need it. + * In order to support this properly in WineD3D we need the ability to recreate the opengl context and + * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new + * context, need torecreate shaders, textures and other resources. + * + * The context manager already takes care of the state problem and for the other tasks code from Reset + * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. + * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the + * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this + * issue needs to be fixed. */ + for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) + { + swapchain->ds_format = getFormatDescEntry(formats[i], gl_info); + swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format); + if (swapchain->context[0]) break; + TRACE("Depth stencil format %s is not supported, trying next format\n", + debug_d3dformat(formats[i])); + } + if (!swapchain->context[0]) { WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } + + if (!present_parameters->EnableAutoDepthStencil + || swapchain->presentParms.AutoDepthStencilFormat != swapchain->ds_format->format) + { + FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); + } context_release(swapchain->context[0]); } else @@ -833,9 +859,9 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (swapchain->presentParms.BackBufferCount > 0) { - swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0, - sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount); - if (!swapchain->backBuffer) + swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0, + sizeof(*swapchain->back_buffers) * swapchain->presentParms.BackBufferCount); + if (!swapchain->back_buffers) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; @@ -848,15 +874,16 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, - swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]); + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, + (IWineD3DSurface **)&swapchain->back_buffers[i]); if (FAILED(hr)) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); goto err; } - IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain); - ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[i], (IWineD3DBase *)swapchain); + swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN; } } @@ -864,20 +891,20 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) { TRACE("Creating depth/stencil buffer.\n"); - if (!device->auto_depth_stencil_buffer) + if (!device->auto_depth_stencil) { hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType, swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, - &device->auto_depth_stencil_buffer); + (IWineD3DSurface **)&device->auto_depth_stencil); if (FAILED(hr)) { WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); goto err; } - IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL); + IWineD3DSurface_SetContainer((IWineD3DSurface *)device->auto_depth_stencil, NULL); } } @@ -902,13 +929,13 @@ err: ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); } - if (swapchain->backBuffer) + if (swapchain->back_buffers) { for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) { - if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]); + if (swapchain->back_buffers[i]) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]); } - HeapFree(GetProcessHeap(), 0, swapchain->backBuffer); + HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); } if (swapchain->context) @@ -922,7 +949,7 @@ err: HeapFree(GetProcessHeap(), 0, swapchain->context); } - if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer); + if (swapchain->front_buffer) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer); return hr; } @@ -935,9 +962,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId()); - ctx = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, - This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms); - if (!ctx) + if (!(ctx = context_create(This, This->front_buffer, This->ds_format))) { ERR("Failed to create a new context for the swapchain\n"); return NULL; @@ -962,9 +987,8 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt; /* The drawable size of an onscreen drawable is the surface size. * (Actually: The window size, but the surface is created in window size) */ - *width = surface->currentDesc.Width; - *height = surface->currentDesc.Height; + *width = context->current_rt->currentDesc.Width; + *height = context->current_rt->currentDesc.Height; } diff --git a/reactos/dll/directx/wine/wined3d/swapchain_base.c b/reactos/dll/directx/wine/wined3d/swapchain_base.c index 4c0590e4691..1817de2079a 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain_base.c +++ b/reactos/dll/directx/wine/wined3d/swapchain_base.c @@ -85,7 +85,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *i MapWindowPoints(This->win_handle, NULL, &start, 1); } - IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0); + IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, (IWineD3DSurface *)This->front_buffer, NULL, 0); return WINED3D_OK; } @@ -106,12 +106,13 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, * used (there This->backBuffer is always NULL). We need this because this function has * to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default * scissorrect dimensions. */ - if( !This->backBuffer ) { + if (!This->back_buffers) + { *ppBackBuffer = NULL; return WINED3DERR_INVALIDCALL; } - *ppBackBuffer = This->backBuffer[iBackBuffer]; + *ppBackBuffer = (IWineD3DSurface *)This->back_buffers[iBackBuffer]; TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer); /* Note inc ref on returned surface */ @@ -145,15 +146,14 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface return hr; } -HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) { +HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice **device) +{ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; - *ppDevice = (IWineD3DDevice *)This->device; + *device = (IWineD3DDevice *)This->device; + IWineD3DDevice_AddRef(*device); - /* Note Calling this method will increase the internal reference count - on the IDirect3DDevice9 interface. */ - IWineD3DDevice_AddRef(*ppDevice); - TRACE("(%p) : returning %p\n", This, *ppDevice); + TRACE("(%p) : returning %p\n", This, *device); return WINED3D_OK; } @@ -171,9 +171,9 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; HDC hDC; TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags); - hDC = GetDC(This->win_handle); + hDC = GetDC(This->device_window); SetDeviceGammaRamp(hDC, (LPVOID)pRamp); - ReleaseDC(This->win_handle, hDC); + ReleaseDC(This->device_window, hDC); return WINED3D_OK; } @@ -183,9 +183,9 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; HDC hDC; TRACE("(%p) : pRamp@%p\n", This, pRamp); - hDC = GetDC(This->win_handle); + hDC = GetDC(This->device_window); GetDeviceGammaRamp(hDC, pRamp); - ReleaseDC(This->win_handle, hDC); + ReleaseDC(This->device_window, hDC); return WINED3D_OK; } diff --git a/reactos/dll/directx/wine/wined3d/swapchain_gdi.c b/reactos/dll/directx/wine/wined3d/swapchain_gdi.c index c437b419f8e..b80352c1dce 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain_gdi.c +++ b/reactos/dll/directx/wine/wined3d/swapchain_gdi.c @@ -37,24 +37,27 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); /* release the ref to the front and back buffer parents */ - if(This->frontBuffer) { - IWineD3DSurface_SetContainer(This->frontBuffer, 0); - if (IWineD3DSurface_Release(This->frontBuffer) > 0) + if (This->front_buffer) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0) { WARN("(%p) Something's still holding the front buffer\n",This); } } - if(This->backBuffer) { + if (This->back_buffers) + { UINT i; - for(i = 0; i < This->presentParms.BackBufferCount; i++) { - IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - if (IWineD3DSurface_Release(This->backBuffer[i]) > 0) + for (i = 0; i < This->presentParms.BackBufferCount; ++i) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) { WARN("(%p) Something's still holding the back buffer\n",This); } } - HeapFree(GetProcessHeap(), 0, This->backBuffer); + HeapFree(GetProcessHeap(), 0, This->back_buffers); } /* Restore the screen resolution if we rendered in fullscreen @@ -86,7 +89,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) *****************************************************************************/ void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) { - IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; + IWineD3DSurfaceImpl *front = This->front_buffer; if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) { POINT offset = {0,0}; @@ -172,12 +175,13 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface; IWineD3DSurfaceImpl *front, *back; - if(!This->backBuffer) { + if (!This->back_buffers) + { WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } - front = (IWineD3DSurfaceImpl *) This->frontBuffer; - back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; + front = This->front_buffer; + back = This->back_buffers[0]; /* Flip the DC */ { @@ -226,7 +230,7 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO /* FPS support */ if (TRACE_ON(fps)) { - static long prev_time, frames; + static LONG prev_time, frames; DWORD time = GetTickCount(); frames++; diff --git a/reactos/dll/directx/wine/wined3d/texture.c b/reactos/dll/directx/wine/wined3d/texture.c index 1e272144a8a..98e7909370e 100644 --- a/reactos/dll/directx/wine/wined3d/texture.c +++ b/reactos/dll/directx/wine/wined3d/texture.c @@ -63,21 +63,22 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG { /* context_acquire() sets isInDraw to TRUE when loading a pbuffer into a texture, * thus no danger of recursive calls. */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i])) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + if (palette9_changed(surface)) { TRACE("Reloading surface because the d3d8/9 palette was changed.\n"); /* TODO: This is not necessarily needed with hw palettized texture support. */ - IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */ - IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } } @@ -86,9 +87,9 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG * since the last load then reload the surfaces. */ if (*dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode); + IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode); } } else @@ -108,17 +109,18 @@ static void texture_cleanup(IWineD3DTextureImpl *This) TRACE("(%p) : Cleaning up\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - if (This->surfaces[i]) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + if (surface) { /* Clean out the texture name we gave to the surface so that the * surface doesn't try and release it */ - surface_set_texture_name(This->surfaces[i], 0, TRUE); - surface_set_texture_name(This->surfaces[i], 0, FALSE); - surface_set_texture_target(This->surfaces[i], 0); - IWineD3DSurface_SetContainer(This->surfaces[i], 0); - IWineD3DSurface_Release(This->surfaces[i]); + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); + surface_set_texture_target(surface, 0); + IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL); + IWineD3DSurface_Release((IWineD3DSurface *)surface); } } @@ -204,10 +206,12 @@ static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) { * surface before, this one will be a NOP and vice versa. Unloading an unloaded * surface is fine */ - for (i = 0; i < This->baseTexture.levels; i++) { - IWineD3DSurface_UnLoad(This->surfaces[i]); - surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */ - surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */ + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + IWineD3DSurface_UnLoad((IWineD3DSurface *)surface); + surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */ + surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */ } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -276,14 +280,20 @@ static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BO gl_tex = &This->baseTexture.texture_rgb; } - for (i = 0; i < This->baseTexture.levels; ++i) { - surface_set_texture_name(This->surfaces[i], gl_tex->name, This->baseTexture.is_srgb); + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + surface_set_texture_name(surface, gl_tex->name, This->baseTexture.is_srgb); } - /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect - * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something - * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering. - * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos. - */ + + /* Conditinal non power of two textures use a different clamping + * default. If we're using the GL_WINE_normalized_texrect partial + * driver emulation, we're dealing with a GL_TEXTURE_2D texture which + * has the address mode set to repeat - something that prevents us + * from hitting the accelerated codepath. Thus manually set the GL + * state. The same applies to filtering. Even if the texture has only + * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW + * fallback on macos. */ if(IWineD3DBaseTexture_IsCondNP2(iface)) { ENTER_GL(); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -323,72 +333,94 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) { /* ******************************************* IWineD3DTexture IWineD3DTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; +static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT level, WINED3DSURFACE_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) Level (%d)\n", This, Level); - return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc); + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + + return IWineD3DSurface_GetDesc(surface, desc); } -static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, UINT Level, IWineD3DSurface** ppSurfaceLevel) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, + UINT level, IWineD3DSurface **surface) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *s; - if (Level < This->baseTexture.levels) { - *ppSurfaceLevel = This->surfaces[Level]; - IWineD3DSurface_AddRef(This->surfaces[Level]); - hr = WINED3D_OK; - TRACE("(%p) : returning %p for level %d\n", This, *ppSurfaceLevel, Level); + TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); + + if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK != hr) { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - *ppSurfaceLevel = NULL; /* Just to be on the safe side.. */ - } - return hr; + + IWineD3DSurface_AddRef(s); + *surface = s; + + TRACE("Returning surface %p.\n", *surface); + + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, UINT Level, WINED3DLOCKED_RECT *pLockedRect, - CONST RECT *pRect, DWORD Flags) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, + UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - hr = IWineD3DSurface_LockRect(This->surfaces[Level], pLockedRect, pRect, Flags); - } - if (WINED3D_OK == hr) { - TRACE("(%p) Level (%d) success\n", This, Level); - } else { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); + TRACE("iface %p, level %u, locked_rect %p, rect %s, flags %#x.\n", + iface, level, locked_rect, wine_dbgstr_rect(rect), flags); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags); } -static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT Level) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - hr = IWineD3DSurface_UnlockRect(This->surfaces[Level]); + TRACE("iface %p, level %u.\n", iface, level); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if ( WINED3D_OK == hr) { - TRACE("(%p) Level (%d) success\n", This, Level); - } else { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - } - return hr; + + return IWineD3DSurface_UnlockRect(surface); } -static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of surface Level (0)\n", This); - surface_add_dirty_rect(This->surfaces[0], pDirtyRect); +static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, const RECT *dirty_rect) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurfaceImpl *surface; + + TRACE("iface %p, dirty_rect %s.\n", iface, wine_dbgstr_rect(dirty_rect)); + + if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, 0, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + surface_add_dirty_rect(surface, dirty_rect); return WINED3D_OK; } @@ -434,7 +466,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT pow2_width, pow2_height; UINT tmp_w, tmp_h; unsigned int i; @@ -497,8 +529,8 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT texture->lpVtbl = &IWineD3DTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_TEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels, + WINED3DRTYPE_TEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x.\n", hr); @@ -565,22 +597,24 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT /* Generate all the surfaces. */ tmp_w = width; tmp_h = height; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { + IWineD3DSurface *surface; + /* Use the callback to create the texture surface. */ hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format, - usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]); - if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE) + usage, pool, i, 0, &surface); + if (FAILED(hr)) { FIXME("Failed to create surface %p, hr %#x\n", texture, hr); - texture->surfaces[i] = NULL; texture_cleanup(texture); return hr; } - IWineD3DSurface_SetContainer(texture->surfaces[i], (IWineD3DBase *)texture); - TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[i]); - surface_set_texture_target(texture->surfaces[i], texture->target); + IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture); + surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->target); + texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface; + TRACE("Created surface level %u @ %p.\n", i, surface); /* Calculate the next mipmap level. */ tmp_w = max(1, tmp_w >> 1); tmp_h = max(1, tmp_h >> 1); diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 2ff16752c33..b63a5f8cee8 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -141,31 +141,40 @@ struct wined3d_format_base_flags static const struct wined3d_format_base_flags format_base_flags[] = { - {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, }; struct wined3d_format_compression_info @@ -183,7 +192,7 @@ static const struct wined3d_format_compression_info format_compression_info[] = {WINED3DFMT_DXT3, 4, 4, 16}, {WINED3DFMT_DXT4, 4, 4, 16}, {WINED3DFMT_DXT5, 4, 4, 16}, - {WINED3DFMT_ATI2N, 4, 4, 16}, + {WINED3DFMT_ATI2N, 1, 1, 1}, }; struct wined3d_format_vertex_info @@ -218,20 +227,328 @@ static const struct wined3d_format_vertex_info format_vertex_info[] = {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)} }; -typedef struct { - WINED3DFORMAT fmt; - GLint glInternal, glGammaInternal, rtInternal, glFormat, glType; - unsigned int Flags; +struct wined3d_format_texture_info +{ + WINED3DFORMAT format; + GLint gl_internal; + GLint gl_srgb_internal; + GLint gl_rt_internal; + GLint gl_format; + GLint gl_type; + unsigned int conv_byte_count; + unsigned int flags; GL_SupportedExt extension; -} GlPixelFormatDescTemplate; + void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); +}; -/***************************************************************************** - * OpenGL format template. Contains unexciting formats which do not need - * extension checks. The order in this table is independent of the order in - * the table StaticPixelFormatDesc above. Not all formats have to be in this - * table. - */ -static const GlPixelFormatDescTemplate gl_formats_template[] = { +static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not + * format+type combination to load it. Thus convert it to A8L8, then load it + * with A4L4 internal, but A8L8 format+type + */ + unsigned int x, y; + const unsigned char *Source; + unsigned char *Dest; + UINT outpitch = pitch * 2; + + for(y = 0; y < height; y++) { + Source = src + y * pitch; + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) { + unsigned char color = (*Source++); + /* A */ Dest[1] = (color & 0xf0) << 0; + /* L */ Dest[0] = (color & 0x0f) << 4; + Dest += 2; + } + } +} + +static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + + for(y = 0; y < height; y++) + { + unsigned short *Dest_s = (unsigned short *) (dst + y * pitch); + Source = (const WORD *)(src + y * pitch); + for (x = 0; x < width; x++ ) + { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + short v = ((color >> 5) & 0x3e); + short u = ((color ) & 0x1f); + short v_conv = v + 16; + short u_conv = u + 16; + + *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); + Dest_s += 1; + } + } +} + +static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + unsigned char *Dest; + UINT outpitch = (pitch * 3)/2; + + /* This makes the gl surface bigger(24 bit instead of 16), but it works with + * fixed function and shaders without further conversion once the surface is + * loaded + */ + for(y = 0; y < height; y++) { + Source = (const WORD *)(src + y * pitch); + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + char v = ((color >> 5) & 0x3e); + char u = ((color ) & 0x1f); + + /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign + * and doubles the positive range. Thus shift left only once, gl does the 2nd + * shift. GL reads a signed value and converts it into an unsigned value. + */ + /* M */ Dest[2] = l << 1; + + /* Those are read as signed, but kept signed. Just left-shift 3 times to scale + * from 5 bit values to 8 bit values. + */ + /* V */ Dest[1] = v << 3; + /* U */ Dest[0] = u << 3; + Dest += 3; + } + } +} + +static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const short *Source; + unsigned char *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const short *)(src + y * pitch); + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = 0xff; + /* G */ Dest[1] = (color >> 8) + 128; /* V */ + /* R */ Dest[2] = (color) + 128; /* U */ + Dest += 3; + } + } +} + +static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + /* Doesn't work correctly with the fixed function pipeline, but can work in + * shaders if the shader is adjusted. (There's no use for this format in gl's + * standard fixed function pipeline anyway). + */ + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + Dest += 4; + } + } +} + +static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + /* This implementation works with the fixed function pipeline and shaders + * without further modification after converting the surface. + */ + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ + /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ + /* U */ Dest[0] = (color & 0xff); /* U */ + /* I */ Dest[3] = 255; /* X */ + Dest += 4; + } + } +} + +static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ + Dest += 4; + } + } +} + +static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned short *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = (unsigned short *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + DWORD color = (*Source++); + /* B */ Dest[0] = 0xffff; + /* G */ Dest[1] = (color >> 16) + 32768; /* V */ + /* R */ Dest[2] = (color ) + 32768; /* U */ + Dest += 3; + } + } +} + +static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + WORD *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const WORD *)(src + y * pitch); + Dest = (WORD *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + WORD green = (*Source++); + WORD red = (*Source++); + Dest[0] = green; + Dest[1] = red; + /* Strictly speaking not correct for R16G16F, but it doesn't matter because the + * shader overwrites it anyway + */ + Dest[2] = 0xffff; + Dest += 3; + } + } +} + +static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const float *Source; + float *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const float *)(src + y * pitch); + Dest = (float *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + float green = (*Source++); + float red = (*Source++); + Dest[0] = green; + Dest[1] = red; + Dest[2] = 1.0f; + Dest += 3; + } + } +} + +static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + UINT outpitch = pitch * 2; + + for (y = 0; y < height; ++y) + { + const WORD *source = (const WORD *)(src + y * pitch); + DWORD *dest = (DWORD *)(dst + y * outpitch); + + for (x = 0; x < width; ++x) + { + /* The depth data is normalized, so needs to be scaled, + * the stencil data isn't. Scale depth data by + * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ + WORD d15 = source[x] >> 1; + DWORD d24 = (d15 << 9) + (d15 >> 6); + dest[x] = (d24 << 8) | (source[x] & 0x1); + } + } +} + +static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + + for (y = 0; y < height; ++y) + { + const DWORD *source = (const DWORD *)(src + y * pitch); + DWORD *dest = (DWORD *)(dst + y * pitch); + + for (x = 0; x < width; ++x) + { + /* Just need to clear out the X4 part. */ + dest[x] = source[x] & ~0xf0; + } + } +} + +static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + UINT outpitch = pitch * 2; + + for (y = 0; y < height; ++y) + { + const DWORD *source = (const DWORD *)(src + y * pitch); + float *dest_f = (float *)(dst + y * outpitch); + DWORD *dest_s = (DWORD *)(dst + y * outpitch); + + for (x = 0; x < width; ++x) + { + dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); + dest_s[x * 2 + 1] = source[x] & 0xff; + } + } +} + +static const struct wined3d_format_texture_info format_texture_info[] = +{ /* WINED3DFORMAT internal srgbInternal rtInternal format type flags @@ -244,289 +561,296 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { * endian machine */ {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, - GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, + GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0, WINED3DFMT_FLAG_FILTERING, - APPLE_YCBCR_422}, + APPLE_YCBCR_422, NULL}, {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, - GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, + GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0, WINED3DFMT_FLAG_FILTERING, - APPLE_YCBCR_422}, + APPLE_YCBCR_422, NULL}, {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, /* IEEE formats */ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, - GL_RED, GL_FLOAT, + GL_RED, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0, - GL_RED, GL_FLOAT, + GL_RED, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, - GL_RGB, GL_FLOAT, + GL_RGB, GL_FLOAT, 12, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, &convert_r32g32_float}, {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0, - GL_RG, GL_FLOAT, + GL_RG, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0, - GL_RGBA, GL_FLOAT, - WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + GL_RGBA, GL_FLOAT, 0, + WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, + ARB_TEXTURE_FLOAT, NULL}, /* Float */ {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, - GL_RED, GL_HALF_FLOAT_ARB, + GL_RED, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0, - GL_RED, GL_HALF_FLOAT_ARB, + GL_RED, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, - GL_RGB, GL_HALF_FLOAT_ARB, + GL_RGB, GL_HALF_FLOAT_ARB, 6, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, &convert_r16g16}, {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0, - GL_RG, GL_HALF_FLOAT_ARB, + GL_RG, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0, - GL_RGBA, GL_HALF_FLOAT_ARB, + GL_RGBA, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, /* Palettized formats */ {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0, - GL_RGBA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - ARB_FRAGMENT_PROGRAM}, + ARB_FRAGMENT_PROGRAM, NULL}, {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0, - GL_COLOR_INDEX, GL_UNSIGNED_BYTE, + GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0, 0, - EXT_PALETTED_TEXTURE}, + EXT_PALETTED_TEXTURE, NULL}, /* Standard ARGB formats */ {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_BGR, GL_UNSIGNED_BYTE, + GL_BGR, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET + | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET + | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0, - GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0, - GL_RGB, GL_UNSIGNED_BYTE_3_3_2, + GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, - GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, + GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, - GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, + GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16, - GL_RGB, GL_UNSIGNED_SHORT, + GL_RGB, GL_UNSIGNED_SHORT, 6, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, &convert_r16g16}, {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, - GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, + GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0, - GL_RGBA, GL_UNSIGNED_SHORT, + GL_RGBA, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, /* Luminance */ {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, - GL_LUMINANCE, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, 0, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, &convert_l4a4_unorm}, /* Bump mapping stuff */ {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0, - GL_BGR, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGR, GL_UNSIGNED_BYTE, 3, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8_snorm}, {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0, - GL_DSDT_NV, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_NV, GL_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm}, {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0, - GL_DSDT_MAG_NV, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_MAG_NV, GL_BYTE, 3, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0, - GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv}, {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0, - GL_BGRA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_BYTE, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm}, {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0, - GL_RGBA, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_RGBA, GL_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0, - GL_BGR, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGR, GL_UNSIGNED_SHORT, 6, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r16g16_snorm}, {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0, - GL_HILO_NV, GL_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_HILO_NV, GL_SHORT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, /* Depth stencil formats */ {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, NULL}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, NULL}, {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm}, {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, - GL_LUMINANCE, GL_UNSIGNED_SHORT, + GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0, - GL_DEPTH_COMPONENT, GL_FLOAT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_BUFFER_FLOAT}, + GL_DEPTH_COMPONENT, GL_FLOAT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_BUFFER_FLOAT, NULL}, {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_DEPTH_BUFFER_FLOAT}, + GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float}, /* Vendor-specific formats */ {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - ATI_TEXTURE_COMPRESSION_3DC}, + ATI_TEXTURE_COMPRESSION_3DC, NULL}, {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - EXT_TEXTURE_COMPRESSION_RGTC}, + EXT_TEXTURE_COMPRESSION_RGTC, NULL}, }; static inline int getFmtIdx(WINED3DFORMAT fmt) { @@ -560,7 +884,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) for (i = 0; i < format_count; ++i) { - struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i]; + struct wined3d_format_desc *desc = &gl_info->gl_formats[i]; desc->format = formats[i].format; desc->red_mask = formats[i].redMask; desc->green_mask = formats[i].greenMask; @@ -595,7 +919,7 @@ static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info) for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i) { - struct GlPixelFormatDesc *format_desc; + struct wined3d_format_desc *format_desc; int fmt_idx = getFmtIdx(format_compression_info[i].format); if (fmt_idx == -1) @@ -616,7 +940,7 @@ static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info) } /* Context activation is done by the caller. */ -static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc) +static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc) { /* Check if the default internal format is supported as a frame buffer * target, otherwise fall back to the render target internal. @@ -755,7 +1079,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i) { - struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i]; + struct wined3d_format_desc *desc = &gl_info->gl_formats[i]; if (!desc->glInternal) continue; @@ -798,29 +1122,33 @@ static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info) { unsigned int i; - for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i) + for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i) { - int fmt_idx = getFmtIdx(gl_formats_template[i].fmt); - struct GlPixelFormatDesc *desc; + int fmt_idx = getFmtIdx(format_texture_info[i].format); + struct wined3d_format_desc *desc; if (fmt_idx == -1) { ERR("Format %s (%#x) not found.\n", - debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt); + debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format); return FALSE; } - if (!gl_info->supported[gl_formats_template[i].extension]) continue; + if (!gl_info->supported[format_texture_info[i].extension]) continue; desc = &gl_info->gl_formats[fmt_idx]; - desc->glInternal = gl_formats_template[i].glInternal; - desc->glGammaInternal = gl_formats_template[i].glGammaInternal; - desc->rtInternal = gl_formats_template[i].rtInternal; - desc->glFormat = gl_formats_template[i].glFormat; - desc->glType = gl_formats_template[i].glType; + desc->glInternal = format_texture_info[i].gl_internal; + desc->glGammaInternal = format_texture_info[i].gl_srgb_internal; + desc->rtInternal = format_texture_info[i].gl_rt_internal; + desc->glFormat = format_texture_info[i].gl_format; + desc->glType = format_texture_info[i].gl_type; desc->color_fixup = COLOR_FIXUP_IDENTITY; - desc->Flags |= gl_formats_template[i].Flags; + desc->Flags |= format_texture_info[i].flags; desc->heightscale = 1.0f; + + /* Texture conversion stuff */ + desc->convert = format_texture_info[i].convert; + desc->conv_byte_count = format_texture_info[i].conv_byte_count; } return TRUE; @@ -938,6 +1266,7 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) { + struct wined3d_format_desc *desc; unsigned int fmt_idx, i; WINED3DFORMAT fmts16[] = { WINED3DFMT_R16_FLOAT, @@ -945,7 +1274,6 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3 WINED3DFMT_R16G16B16A16_FLOAT, }; BOOL filtered; - struct GlPixelFormatDesc *desc; if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) { @@ -1043,6 +1371,7 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info) idx = getFmtIdx(WINED3DFMT_R8G8_SNORM); gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc( 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); + idx = getFmtIdx(WINED3DFMT_R16G16_SNORM); gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc( 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); @@ -1098,8 +1427,11 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info) gl_info->gl_formats[idx].heightscale = 1.5f; gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); - idx = getFmtIdx(WINED3DFMT_P8_UINT); - gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); + if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM]) + { + idx = getFmtIdx(WINED3DFMT_P8_UINT); + gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); + } if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) { @@ -1125,7 +1457,7 @@ static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i) { - struct GlPixelFormatDesc *format_desc; + struct wined3d_format_desc *format_desc; int fmt_idx = getFmtIdx(format_vertex_info[i].format); if (fmt_idx == -1) @@ -1182,7 +1514,7 @@ fail: return FALSE; } -const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) +const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) { int idx = getFmtIdx(fmt); @@ -1485,9 +1817,7 @@ const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) { const char* debug_d3drenderstate(DWORD state) { switch (state) { #define D3DSTATE_TO_STR(u) case u: return #u - D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE ); D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS ); D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE ); D3DSTATE_TO_STR(WINED3DRS_WRAPU ); D3DSTATE_TO_STR(WINED3DRS_WRAPV ); @@ -1501,11 +1831,8 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE ); D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE ); D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN ); D3DSTATE_TO_STR(WINED3DRS_SRCBLEND ); D3DSTATE_TO_STR(WINED3DRS_DESTBLEND ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND ); D3DSTATE_TO_STR(WINED3DRS_CULLMODE ); D3DSTATE_TO_STR(WINED3DRS_ZFUNC ); D3DSTATE_TO_STR(WINED3DRS_ALPHAREF ); @@ -1526,9 +1853,6 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE ); D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS ); D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE ); - D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV ); D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS ); D3DSTATE_TO_STR(WINED3DRS_ZBIAS ); D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE ); @@ -1544,38 +1868,6 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_STENCILMASK ); D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK ); D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 ); D3DSTATE_TO_STR(WINED3DRS_WRAP0 ); D3DSTATE_TO_STR(WINED3DRS_WRAP1 ); D3DSTATE_TO_STR(WINED3DRS_WRAP2 ); @@ -2125,7 +2417,7 @@ unsigned int count_bits(unsigned int mask) /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB. * The later function requires individual color components. */ -BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, +BOOL getColorBits(const struct wined3d_format_desc *format_desc, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize) { TRACE("fmt: %s\n", debug_d3dformat(format_desc->format)); @@ -2162,7 +2454,7 @@ BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, } /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */ -BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize) +BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize) { TRACE("fmt: %s\n", debug_d3dformat(format_desc->format)); switch(format_desc->format) @@ -2190,6 +2482,115 @@ BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *dep return TRUE; } +DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) +{ + unsigned int r, g, b, a; + DWORD ret; + + if (destfmt == WINED3DFMT_B8G8R8A8_UNORM + || destfmt == WINED3DFMT_B8G8R8X8_UNORM + || destfmt == WINED3DFMT_B8G8R8_UNORM) + return color; + + TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt)); + + a = (color & 0xff000000) >> 24; + r = (color & 0x00ff0000) >> 16; + g = (color & 0x0000ff00) >> 8; + b = (color & 0x000000ff) >> 0; + + switch(destfmt) + { + case WINED3DFMT_B5G6R5_UNORM: + if(r == 0xff && g == 0xff && b == 0xff) return 0xffff; + r = (r * 32) / 256; + g = (g * 64) / 256; + b = (b * 32) / 256; + ret = r << 11; + ret |= g << 5; + ret |= b; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B5G5R5X1_UNORM: + case WINED3DFMT_B5G5R5A1_UNORM: + a = (a * 2) / 256; + r = (r * 32) / 256; + g = (g * 32) / 256; + b = (b * 32) / 256; + ret = a << 15; + ret |= r << 10; + ret |= g << 5; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_A8_UNORM: + TRACE("Returning %08x\n", a); + return a; + + case WINED3DFMT_B4G4R4X4_UNORM: + case WINED3DFMT_B4G4R4A4_UNORM: + a = (a * 16) / 256; + r = (r * 16) / 256; + g = (g * 16) / 256; + b = (b * 16) / 256; + ret = a << 12; + ret |= r << 8; + ret |= g << 4; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B2G3R3_UNORM: + r = (r * 8) / 256; + g = (g * 8) / 256; + b = (b * 4) / 256; + ret = r << 5; + ret |= g << 2; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_R8G8B8X8_UNORM: + case WINED3DFMT_R8G8B8A8_UNORM: + ret = a << 24; + ret |= b << 16; + ret |= g << 8; + ret |= r << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B10G10R10A2_UNORM: + a = (a * 4) / 256; + r = (r * 1024) / 256; + g = (g * 1024) / 256; + b = (b * 1024) / 256; + ret = a << 30; + ret |= r << 20; + ret |= g << 10; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_R10G10B10A2_UNORM: + a = (a * 4) / 256; + r = (r * 1024) / 256; + g = (g * 1024) / 256; + b = (b * 1024) / 256; + ret = a << 30; + ret |= b << 20; + ret |= g << 10; + ret |= r << 0; + TRACE("Returning %08x\n", ret); + return ret; + + default: + FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt)); + return 0; + } +} + /* DirectDraw stuff */ WINED3DFORMAT pixelformat_for_depth(DWORD depth) { switch(depth) { @@ -2258,147 +2659,6 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { return size; } -/*********************************************************************** - * CalculateTexRect - * - * Calculates the dimensions of the opengl texture used for blits. - * Handled oversized opengl textures and updates the source rectangle - * accordingly - * - * Params: - * This: Surface to operate on - * Rect: Requested rectangle - * - * Returns: - * TRUE if the texture part can be loaded, - * FALSE otherwise - * - *********************************************************************/ -BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) -{ - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; - int x1 = Rect->left, x2 = Rect->right; - int y1 = Rect->top, y2 = Rect->bottom; - GLint maxSize = gl_info->limits.texture_size; - - TRACE("(%p)->(%d,%d)-(%d,%d)\n", This, - Rect->left, Rect->top, Rect->right, Rect->bottom); - - /* The sizes might be reversed */ - if(Rect->left > Rect->right) { - x1 = Rect->right; - x2 = Rect->left; - } - if(Rect->top > Rect->bottom) { - y1 = Rect->bottom; - y2 = Rect->top; - } - - /* No oversized texture? This is easy */ - if(!(This->Flags & SFLAG_OVERSIZE)) { - /* Which rect from the texture do I need? */ - if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) - { - glTexCoord[0] = (float) Rect->left; - glTexCoord[2] = (float) Rect->top; - glTexCoord[1] = (float) Rect->right; - glTexCoord[3] = (float) Rect->bottom; - } else { - glTexCoord[0] = (float) Rect->left / (float) This->pow2Width; - glTexCoord[2] = (float) Rect->top / (float) This->pow2Height; - glTexCoord[1] = (float) Rect->right / (float) This->pow2Width; - glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height; - } - - return TRUE; - } else { - /* Check if we can succeed at all */ - if( (x2 - x1) > maxSize || - (y2 - y1) > maxSize ) { - TRACE("Requested rectangle is too large for gl\n"); - return FALSE; - } - - /* A part of the texture has to be picked. First, check if - * some texture part is loaded already, if yes try to re-use it. - * If the texture is dirty, or the part can't be used, - * re-position the part to load - */ - if(This->Flags & SFLAG_INTEXTURE) { - if(This->glRect.left <= x1 && This->glRect.right >= x2 && - This->glRect.top <= y1 && This->glRect.bottom >= x2 ) { - /* Ok, the rectangle is ok, re-use it */ - TRACE("Using existing gl Texture\n"); - } else { - /* Rectangle is not ok, dirtify the texture to reload it */ - TRACE("Dirtifying texture to force reload\n"); - This->Flags &= ~SFLAG_INTEXTURE; - } - } - - /* Now if we are dirty(no else if!) */ - if(!(This->Flags & SFLAG_INTEXTURE)) { - /* Set the new rectangle. Use the following strategy: - * 1) Use as big textures as possible. - * 2) Place the texture part in the way that the requested - * part is in the middle of the texture(well, almost) - * 3) If the texture is moved over the edges of the - * surface, replace it nicely - * 4) If the coord is not limiting the texture size, - * use the whole size - */ - if((This->pow2Width) > maxSize) { - This->glRect.left = x1 - maxSize / 2; - if(This->glRect.left < 0) { - This->glRect.left = 0; - } - This->glRect.right = This->glRect.left + maxSize; - if(This->glRect.right > This->currentDesc.Width) { - This->glRect.right = This->currentDesc.Width; - This->glRect.left = This->glRect.right - maxSize; - } - } else { - This->glRect.left = 0; - This->glRect.right = This->pow2Width; - } - - if (This->pow2Height > maxSize) - { - This->glRect.top = x1 - gl_info->limits.texture_size / 2; - if(This->glRect.top < 0) This->glRect.top = 0; - This->glRect.bottom = This->glRect.left + maxSize; - if(This->glRect.bottom > This->currentDesc.Height) { - This->glRect.bottom = This->currentDesc.Height; - This->glRect.top = This->glRect.bottom - maxSize; - } - } else { - This->glRect.top = 0; - This->glRect.bottom = This->pow2Height; - } - TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This, - This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom); - } - - /* Re-calculate the rect to draw */ - Rect->left -= This->glRect.left; - Rect->right -= This->glRect.left; - Rect->top -= This->glRect.top; - Rect->bottom -= This->glRect.top; - - /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size, - * or the pow2Width / pow2Height of the surface. - * - * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up - * as regular GL_TEXTURE_2D. - */ - glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left); - glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top); - glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left); - glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top); - } - return TRUE; -} - void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) { #define ARG1 0x01 #define ARG2 0x02 @@ -2518,8 +2778,8 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask) { @@ -2826,8 +3086,10 @@ UINT wined3d_log2i(UINT32 x) * and the user preferences in wined3d_settings. */ void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected) { + BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); + if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE; - else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) + else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl) { /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB @@ -2839,7 +3101,7 @@ void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, else *vs_selected = SHADER_NONE; if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE; - else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) *ps_selected = SHADER_GLSL; + else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL; else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB; else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI; else *ps_selected = SHADER_NONE; diff --git a/reactos/dll/directx/wine/wined3d/view.c b/reactos/dll/directx/wine/wined3d/view.c index bbf0f5f65c1..0c9919dd14c 100644 --- a/reactos/dll/directx/wine/wined3d/view.c +++ b/reactos/dll/directx/wine/wined3d/view.c @@ -97,7 +97,7 @@ static HRESULT STDMETHODCALLTYPE rendertarget_view_GetResource(IWineD3DRendertar return WINED3D_OK; } -const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = +static const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = { /* IUnknown methods */ rendertarget_view_QueryInterface, @@ -108,3 +108,13 @@ const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = /* IWineD3DRendertargetView methods */ rendertarget_view_GetResource, }; + +void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, + IWineD3DResource *resource, IUnknown *parent) +{ + view->vtbl = &wined3d_rendertarget_view_vtbl; + view->refcount = 1; + IWineD3DResource_AddRef(resource); + view->resource = resource; + view->parent = parent; +} diff --git a/reactos/dll/directx/wine/wined3d/volume.c b/reactos/dll/directx/wine/wined3d/volume.c index 8e19ee9c763..42e61e68d22 100644 --- a/reactos/dll/directx/wine/wined3d/volume.c +++ b/reactos/dll/directx/wine/wined3d/volume.c @@ -25,7 +25,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); -#define GLINFO_LOCATION This->resource.device->adapter->gl_info /* Context activation is done by the caller. */ static void volume_bind_and_dirtify(IWineD3DVolume *iface) { @@ -313,9 +312,11 @@ static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWi } /* Context activation is done by the caller. */ -static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) { - IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; - const struct GlPixelFormatDesc *glDesc = This->resource.format_desc; +static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) +{ + IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; + const struct wined3d_format_desc *glDesc = This->resource.format_desc; TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(glDesc->format), glDesc->format); @@ -386,7 +387,7 @@ HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); HRESULT hr; if (!gl_info->supported[EXT_TEXTURE3D]) diff --git a/reactos/dll/directx/wine/wined3d/volumetexture.c b/reactos/dll/directx/wine/wined3d/volumetexture.c index 14ca72fcd49..9fccb2b8936 100644 --- a/reactos/dll/directx/wine/wined3d/volumetexture.c +++ b/reactos/dll/directx/wine/wined3d/volumetexture.c @@ -39,7 +39,7 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE TRACE("(%p) : About to load texture.\n", This); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); else if (gl_info->supported[EXT_TEXTURE_SRGB] && This->baseTexture.bindCount > 0) { srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE]; @@ -51,17 +51,19 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE * since the last load then reload the volumes. */ if (This->baseTexture.texture_rgb.dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; + IWineD3DVolume_LoadTexture(volume, i, srgb_mode); } } else if (srgb_was_toggled) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - volume_add_dirty_box(This->volumes[i], NULL); - IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; + volume_add_dirty_box(volume, NULL); + IWineD3DVolume_LoadTexture(volume, i, srgb_mode); } } else @@ -81,9 +83,9 @@ static void volumetexture_cleanup(IWineD3DVolumeTextureImpl *This) TRACE("(%p) : Cleaning up.\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DVolume *volume = This->volumes[i]; + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; if (volume) { @@ -172,8 +174,9 @@ static void WINAPI IWineD3DVolumeTextureImpl_UnLoad(IWineD3DVolumeTexture *iface * surface before, this one will be a NOP and vice versa. Unloading an unloaded * surface is fine */ - for (i = 0; i < This->baseTexture.levels; i++) { - IWineD3DVolume_UnLoad(This->volumes[i]); + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DVolume_UnLoad((IWineD3DVolume *)This->baseTexture.sub_resources[i]); } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -250,65 +253,95 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_IsCondNP2(IWineD3DVolumeTexture *if /* ******************************************* IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) Level (%d)\n", This, Level); - return IWineD3DVolume_GetDesc(This->volumes[Level], pDesc); - } else { - WARN("(%p) Level (%d)\n", This, Level); +static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, + UINT level, WINED3DVOLUME_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } + + return IWineD3DVolume_GetDesc(volume, desc); +} + +static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, + UINT level, IWineD3DVolume **volume) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *v; + + TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); + + if (!(v = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + IWineD3DVolume_AddRef(v); + *volume = v; + + TRACE("Returning volume %p.\n", *volume); + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, UINT Level, IWineD3DVolume** ppVolumeLevel) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - if (Level < This->baseTexture.levels) { - *ppVolumeLevel = This->volumes[Level]; - IWineD3DVolume_AddRef(*ppVolumeLevel); - TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel); - } else { - WARN("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + +static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, + UINT level, WINED3DLOCKED_BOX *locked_box, const WINED3DBOX *box, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", + iface, level, locked_box, box, flags); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return WINED3D_OK; -} -static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) { - HRESULT hr; - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - - if (Level < This->baseTexture.levels) { - hr = IWineD3DVolume_LockBox(This->volumes[Level], pLockedVolume, pBox, Flags); - TRACE("(%p) Level (%d) success(%u)\n", This, Level, hr); - - } else { - FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; - } - return hr; + return IWineD3DVolume_LockBox(volume, locked_box, box, flags); } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT Level) { - HRESULT hr; - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; - if (Level < This->baseTexture.levels) { - hr = IWineD3DVolume_UnlockBox(This->volumes[Level]); - TRACE("(%p) -> level(%d) success(%u)\n", This, Level, hr); + TRACE("iface %p, level %u.\n", iface, level); - } else { - FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + + return IWineD3DVolume_UnlockBox(volume); } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, CONST WINED3DBOX* pDirtyBox) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of volume Level (0)\n", This); - volume_add_dirty_box(This->volumes[0], pDirtyBox); +static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, const WINED3DBOX *dirty_box) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + volume_add_dirty_box(volume, dirty_box); return WINED3D_OK; } @@ -355,7 +388,7 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT tmp_w, tmp_h, tmp_d; unsigned int i; HRESULT hr; @@ -399,8 +432,8 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT texture->lpVtbl = &IWineD3DVolumeTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_VOLUMETEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels, + WINED3DRTYPE_VOLUMETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x.\n", hr); @@ -418,21 +451,23 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT tmp_h = height; tmp_d = depth; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { + IWineD3DVolume *volume; + /* Create the volume. */ hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent, - tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i]); + tmp_w, tmp_h, tmp_d, format, pool, usage, &volume); if (FAILED(hr)) { ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); - texture->volumes[i] = NULL; volumetexture_cleanup(texture); return hr; } /* Set its container to this texture. */ - IWineD3DVolume_SetContainer(texture->volumes[i], (IWineD3DBase *)texture); + IWineD3DVolume_SetContainer(volume, (IWineD3DBase *)texture); + texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)volume; /* Calculate the next mipmap level. */ tmp_w = max(1, tmp_w >> 1); diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index f8097d65cb9..4ece7e7df9a 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -1754,6 +1754,7 @@ typedef enum wined3d_gl_extension ARB_SHADER_OBJECTS, ARB_SHADER_TEXTURE_LOD, ARB_SHADING_LANGUAGE_100, + ARB_SHADOW, ARB_SYNC, ARB_TEXTURE_BORDER_CLAMP, ARB_TEXTURE_COMPRESSION, @@ -1782,6 +1783,7 @@ typedef enum wined3d_gl_extension EXT_BLEND_EQUATION_SEPARATE, EXT_BLEND_FUNC_SEPARATE, EXT_BLEND_MINMAX, + EXT_DRAW_BUFFERS2, EXT_FOG_COORD, EXT_FRAMEBUFFER_BLIT, EXT_FRAMEBUFFER_MULTISAMPLE, @@ -1829,7 +1831,6 @@ typedef enum wined3d_gl_extension SGIS_GENERATE_MIPMAP, SGI_VIDEO_SYNC, /* WGL extensions */ - WGL_ARB_PBUFFER, WGL_ARB_PIXEL_FORMAT, WGL_WINE_PIXEL_FORMAT_PASSTHROUGH, /* Internally used */ @@ -2404,6 +2405,14 @@ typedef unsigned int GLhandleARB; #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8b8c #endif +/* GL_ARB_shadow */ +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884c +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884d +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884e +#endif + /* GL_ARB_sync */ #ifndef GL_ARB_sync #define GL_ARB_sync 1 @@ -2959,6 +2968,15 @@ typedef void (WINE_GLAPI *PGLFNBLENDEQUATIONSEPARATEEXTPROC)(GLenum modeRGB, GLe typedef void (WINE_GLAPI *PGLFNBLENDFUNCSEPARATEEXTPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +/* GL_EXT_draw_buffers2 */ +typedef GLvoid (WINE_GLAPI *PGLFNCOLORMASKINDEXEDEXTPROC)(GLuint buffer_idx, GLboolean r, GLboolean g, + GLboolean b, GLboolean a); +typedef GLvoid (WINE_GLAPI *PGLFNGETBOOLEANINDEXEDVEXTPROC)(GLenum param, GLuint index, GLboolean *value); +typedef GLvoid (WINE_GLAPI *PGLFNGETINTEGERINDEXEDVEXTPROC)(GLenum param, GLuint index, GLint *value); +typedef GLvoid (WINE_GLAPI *PGLFNENABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef GLvoid (WINE_GLAPI *PGLFNDISABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef GLboolean (WINE_GLAPI *PGLFNISENABLEDINDEXEDEXTPROC)(GLenum target, GLuint index); + /* GL_EXT_fog_coord */ #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 @@ -3680,26 +3698,6 @@ typedef const char *(WINAPI *WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc); #define WGL_SAMPLES_ARB 0x2042 #endif -/* WGL_ARB_pbuffer */ -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#define WGL_DRAW_TO_PBUFFER_ARB 0x202d -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202e -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202f -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif -DECLARE_HANDLE(HPBUFFERARB); -typedef HPBUFFERARB (WINAPI *WINED3D_PFNWGLCREATEPBUFFERARBPROC)(HDC hDC, int iPixelFormat, - int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI *WINED3D_PFNWGLGETPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer); -typedef int (WINAPI *WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI *WINED3D_PFNWGLDESTROYPBUFFERARBPROC)(HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI *WINED3D_PFNWGLQUERYPBUFFERARBPROC)(HPBUFFERARB hPbuffer, int iAttribute, int *piValue); - /* WGL_ARB_pixel_format */ #ifndef WGL_ARB_pixel_format #define WGL_ARB_pixel_format 1 @@ -3930,7 +3928,7 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma glUniform3iARB, ARB_SHADER_OBJECTS, NULL) \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM4IARBPROC, \ glUniform4iARB, ARB_SHADER_OBJECTS, NULL) \ - USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IARBPROC, \ + USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FARBPROC, \ glUniform1fARB, ARB_SHADER_OBJECTS, NULL) \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, \ glUniform2fARB, ARB_SHADER_OBJECTS, NULL) \ @@ -4199,6 +4197,19 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma /* GL_EXT_blend_func_separate */ \ USE_GL_FUNC(PGLFNBLENDEQUATIONSEPARATEEXTPROC, \ glBlendEquationSeparateEXT, EXT_BLEND_EQUATION_SEPARATE, NULL) \ + /* GL_EXT_draw_buffers2 */ \ + USE_GL_FUNC(PGLFNCOLORMASKINDEXEDEXTPROC, \ + glColorMaskIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNGETBOOLEANINDEXEDVEXTPROC, \ + glGetBooleanIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNGETINTEGERINDEXEDVEXTPROC, \ + glGetIntegerIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNENABLEINDEXEDEXTPROC, \ + glEnableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNDISABLEINDEXEDEXTPROC, \ + glDisableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNISENABLEDINDEXEDEXTPROC, \ + glIsEnabledIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ /* GL_EXT_fog_coord */ \ USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC, \ glFogCoordfEXT, EXT_FOG_COORD, NULL) \ @@ -4489,11 +4500,6 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBFVARBPROC, wglGetPixelFormatAttribfvARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLCREATEPBUFFERARBPROC, wglCreatePbufferARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLSETPIXELFORMATWINE, wglSetPixelFormatWINE, 0, NULL) #endif /* __WINE_WINED3D_GL */ diff --git a/reactos/dll/directx/wine/wined3d/wined3d_main.c b/reactos/dll/directx/wine/wined3d/wined3d_main.c index 39416e1f875..6330eba44d4 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_main.c +++ b/reactos/dll/directx/wine/wined3d/wined3d_main.c @@ -72,30 +72,31 @@ wined3d_settings_t wined3d_settings = PCI_DEVICE_NONE,/* PCI Device ID */ 0, /* The default of memory is set in FillGLCaps */ NULL, /* No wine logo by default */ - FALSE /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */ + FALSE, /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */ + FALSE, /* No strict draw ordering. */ }; -IWineD3D* WINAPI WineDirect3DCreate(UINT dxVersion, IUnknown *parent) { - IWineD3DImpl* object; +IWineD3D * WINAPI WineDirect3DCreate(UINT version, IUnknown *parent) +{ + IWineD3DImpl *object; + HRESULT hr; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl)); - object->lpVtbl = &IWineD3D_Vtbl; - object->dxVersion = dxVersion; - object->ref = 1; - object->parent = parent; - - if (!InitAdapters(object)) + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) { - WARN("Failed to initialize direct3d adapters, Direct3D will not be available\n"); - if (dxVersion > 7) - { - ERR("Direct3D%d is not available without opengl\n", dxVersion); - HeapFree(GetProcessHeap(), 0, object); - return NULL; - } + ERR("Failed to allocate wined3d object memory.\n"); + return NULL; } - TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion); + hr = wined3d_init(object, version, parent); + if (FAILED(hr)) + { + WARN("Failed to initialize wined3d object, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return NULL; + } + + TRACE("Created wined3d object %p for d3d%d support.\n", object, version); return (IWineD3D *)object; } @@ -120,7 +121,7 @@ static void CDECL wined3d_do_nothing(void) { } -static BOOL wined3d_init(HINSTANCE hInstDLL) +static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { DWORD wined3d_context_tls_idx; HMODULE mod; @@ -236,11 +237,6 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) TRACE("Using the backbuffer for offscreen rendering\n"); wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; } - else if (!strcmp(buffer,"pbuffer")) - { - TRACE("Using PBuffers for offscreen rendering\n"); - wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER; - } else if (!strcmp(buffer,"fbo")) { TRACE("Using FBOs for offscreen rendering\n"); @@ -324,6 +320,12 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) wined3d_settings.allow_multisampling = TRUE; } } + if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size) + && !strcmp(buffer,"enabled")) + { + TRACE("Enforcing strict draw ordering.\n"); + wined3d_settings.strict_draw_ordering = TRUE; + } } if (wined3d_settings.vs_mode == VS_HW) TRACE("Allow HW vertex shaders\n"); @@ -338,7 +340,7 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) return TRUE; } -static BOOL wined3d_destroy(HINSTANCE hInstDLL) +static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL) { DWORD wined3d_context_tls_idx = context_get_tls_idx(); unsigned int i; @@ -478,10 +480,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) switch (fdwReason) { case DLL_PROCESS_ATTACH: - return wined3d_init(hInstDLL); + return wined3d_dll_init(hInstDLL); case DLL_PROCESS_DETACH: - return wined3d_destroy(hInstDLL); + return wined3d_dll_destroy(hInstDLL); case DLL_THREAD_DETACH: { diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 1d5cd974645..5c96d764389 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -50,6 +50,7 @@ #define WINED3D_QUIRK_GLSL_CLIP_VARYING 0x00000004 #define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA 0x00000008 #define WINED3D_QUIRK_NV_CLIP_BROKEN 0x00000010 +#define WINED3D_QUIRK_FBO_TEX_UPDATE 0x00000020 /* Texture format fixups */ @@ -67,10 +68,11 @@ enum fixup_channel_source enum complex_fixup { - COMPLEX_FIXUP_YUY2 = 0, - COMPLEX_FIXUP_UYVY = 1, - COMPLEX_FIXUP_YV12 = 2, - COMPLEX_FIXUP_P8 = 3, + COMPLEX_FIXUP_NONE = 0, + COMPLEX_FIXUP_YUY2 = 1, + COMPLEX_FIXUP_UYVY = 2, + COMPLEX_FIXUP_YV12 = 3, + COMPLEX_FIXUP_P8 = 4, }; #include @@ -234,8 +236,7 @@ static inline float float_24_to_32(DWORD in) #define VBO_HW 1 #define ORM_BACKBUFFER 0 -#define ORM_PBUFFER 1 -#define ORM_FBO 2 +#define ORM_FBO 1 #define SHADER_ARB 1 #define SHADER_GLSL 2 @@ -267,6 +268,7 @@ typedef struct wined3d_settings_s { unsigned int emulated_textureram; char *logo; int allow_multisampling; + BOOL strict_draw_ordering; } wined3d_settings_t; extern wined3d_settings_t wined3d_settings DECLSPEC_HIDDEN; @@ -539,7 +541,8 @@ typedef struct shader_reg_maps WORD usestexldl : 1; WORD usesifc : 1; WORD usescall : 1; - WORD padding : 4; + WORD usesrcp : 1; + WORD padding : 3; /* Whether or not loops are used in this shader, and nesting depth */ unsigned loop_depth; @@ -643,14 +646,6 @@ struct shader_caps { float PixelShader1xMaxValue; DWORD MaxPixelShaderConst; - WINED3DVSHADERCAPS2_0 VS20Caps; - WINED3DPSHADERCAPS2_0 PS20Caps; - - DWORD MaxVShaderInstructionsExecuted; - DWORD MaxPShaderInstructionsExecuted; - DWORD MaxVertexShader30InstructionSlots; - DWORD MaxPixelShader30InstructionSlots; - BOOL VSClipping; }; @@ -693,6 +688,7 @@ struct ps_compile_args { /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous in D3D10 (unconditional NP2 support mandatory). */ + WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */ }; enum fog_src_type { @@ -711,7 +707,7 @@ struct wined3d_context; typedef struct { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS); - void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type); + void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size); void (*shader_deselect_depth_blt)(IWineD3DDevice *iface); void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count); void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count); @@ -752,7 +748,7 @@ extern int num_lock DECLSPEC_HIDDEN; /* GL related defines */ /* ------------------ */ -#define GL_EXTCALL(FuncName) (GLINFO_LOCATION.FuncName) +#define GL_EXTCALL(f) (gl_info->f) #define D3DCOLOR_B_R(dw) (((dw) >> 16) & 0xFF) #define D3DCOLOR_B_G(dw) (((dw) >> 8) & 0xFF) @@ -771,9 +767,6 @@ extern int num_lock DECLSPEC_HIDDEN; (vec)[3] = D3DCOLOR_A(dw); \ } while(0) -/* DirectX Device Limits */ -/* --------------------- */ -#define MAX_MIP_LEVELS 32 /* Maximum number of mipmap levels. */ #define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */ /* Checking of API calls */ @@ -788,7 +781,7 @@ do { \ TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \ \ } else do { \ - FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \ + ERR(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \ debug_glerror(err), err, A, __FILE__, __LINE__); \ err = glGetError(); \ } while (err != GL_NO_ERROR); \ @@ -830,13 +823,6 @@ extern const float identity[16] DECLSPEC_HIDDEN; * Compilable extra diagnostics */ -/* Trace information per-vertex: (extremely high amount of trace) */ -#if 0 /* NOTE: Must be 0 in cvs */ -# define VTRACE(A) TRACE A -#else -# define VTRACE(A) -#endif - /* TODO: Confirm each of these works when wined3d move completed */ #if 0 /* NOTE: Must be 0 in cvs */ /* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start @@ -910,7 +896,7 @@ enum wined3d_ffp_emit_idx struct wined3d_stream_info_element { - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; GLsizei stride; const BYTE *data; UINT stream_idx; @@ -1039,6 +1025,12 @@ enum wined3d_event_query_result WINED3D_EVENT_QUERY_ERROR }; +void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN; +enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +HRESULT wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; + struct wined3d_context { const struct wined3d_gl_info *gl_info; @@ -1052,8 +1044,8 @@ struct wined3d_context DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ - IWineD3DSurface *surface; - IWineD3DSurface *current_rt; + IWineD3DSwapChainImpl *swapchain; + IWineD3DSurfaceImpl *current_rt; DWORD tid; /* Thread ID which owns this context at the moment */ /* Stores some information about the context state for optimization */ @@ -1089,7 +1081,7 @@ struct wined3d_context HGLRC glCtx; HWND win_handle; HDC hdc; - HPBUFFERARB pbuffer; + int pixel_format; GLint aux_buffers; /* FBOs */ @@ -1097,10 +1089,11 @@ struct wined3d_context struct list fbo_list; struct list fbo_destroy_list; struct fbo_entry *current_fbo; - GLuint src_fbo; GLuint dst_fbo; GLuint fbo_read_binding; GLuint fbo_draw_binding; + BOOL rebind_fbo; + IWineD3DSurfaceImpl **blit_targets; /* Queries */ GLuint *free_occlusion_queries; @@ -1167,60 +1160,69 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; +enum blit_operation +{ + BLIT_OP_BLIT, + BLIT_OP_COLOR_FILL +}; + /* Shaders for color conversions in blits */ struct blit_shader { HRESULT (*alloc_private)(IWineD3DDevice *iface); void (*free_private)(IWineD3DDevice *iface); - HRESULT (*set_shader)(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height); + HRESULT (*set_shader)(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface); void (*unset_shader)(IWineD3DDevice *iface); - BOOL (*color_fixup_supported)(struct color_fixup_desc fixup); + BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format_desc *dst_format_desc); + HRESULT (*color_fill)(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color); }; extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN; extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN; +extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN; -typedef enum ContextUsage { - CTXUSAGE_RESOURCELOAD = 1, /* Only loads textures: No State is applied */ - CTXUSAGE_DRAWPRIM = 2, /* OpenGL states are set up for blitting DirectDraw surfaces */ - CTXUSAGE_BLIT = 3, /* OpenGL states are set up 3D drawing */ - CTXUSAGE_CLEAR = 4, /* Drawable and states are set up for clearing */ -} ContextUsage; +/* Temporary blit_shader helper functions */ +HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) DECLSPEC_HIDDEN; -struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, - IWineD3DSurface *target, enum ContextUsage usage) DECLSPEC_HIDDEN; +struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) DECLSPEC_HIDDEN; void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; -void context_resource_released(IWineD3DDevice *iface, - IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN; -void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN; +void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; +void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void context_attach_depth_stencil_fbo(struct wined3d_context *context, - GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN; -void context_attach_surface_fbo(const struct wined3d_context *context, - GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) DECLSPEC_HIDDEN; -struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, - BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *present_parameters) DECLSPEC_HIDDEN; + GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN; +void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN; +struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target, + const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN; void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) DECLSPEC_HIDDEN; void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; +void context_resource_released(IWineD3DDevice *iface, + IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN; - -void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN; -HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN; +void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; /* Macros for doing basic GPU detection based on opengl capabilities */ #define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE]) #define WINE_D3D7_CAPABLE(gl_info) (gl_info->supported[ARB_TEXTURE_COMPRESSION] && gl_info->supported[ARB_TEXTURE_CUBE_MAP] && gl_info->supported[ARB_TEXTURE_ENV_DOT3]) #define WINE_D3D8_CAPABLE(gl_info) WINE_D3D7_CAPABLE(gl_info) && (gl_info->supported[ARB_MULTISAMPLE] && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) #define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER]) +#define WINE_D3D10_CAPABLE(gl_info) WINE_D3D9_CAPABLE(gl_info) && (gl_info->supported[EXT_GPU_SHADER4]) /***************************************************************************** * Internal representation of a light @@ -1251,7 +1253,6 @@ typedef struct WineD3D_PixelFormat int redSize, greenSize, blueSize, alphaSize, colorSize; int depthSize, stencilSize; BOOL windowDrawable; - BOOL pbufferDrawable; BOOL doubleBuffer; int auxBuffers; int numSamples; @@ -1259,9 +1260,9 @@ typedef struct WineD3D_PixelFormat enum wined3d_gl_vendor { - GL_VENDOR_WINE, + GL_VENDOR_UNKNOWN, GL_VENDOR_APPLE, - GL_VENDOR_ATI, + GL_VENDOR_FGLRX, GL_VENDOR_INTEL, GL_VENDOR_MESA, GL_VENDOR_NVIDIA, @@ -1270,7 +1271,7 @@ enum wined3d_gl_vendor enum wined3d_pci_vendor { - HW_VENDOR_WINE = 0x0000, + HW_VENDOR_SOFTWARE = 0x0000, HW_VENDOR_ATI = 0x1002, HW_VENDOR_NVIDIA = 0x10de, HW_VENDOR_INTEL = 0x8086, @@ -1287,7 +1288,7 @@ enum wined3d_pci_device CARD_ATI_RADEON_XPRESS_200M = 0x5955, CARD_ATI_RADEON_X700 = 0x5e4c, CARD_ATI_RADEON_X1600 = 0x71c2, - CARD_ATI_RADEON_HD2300 = 0x7210, + CARD_ATI_RADEON_HD2350 = 0x94c7, CARD_ATI_RADEON_HD2600 = 0x9581, CARD_ATI_RADEON_HD2900 = 0x9400, CARD_ATI_RADEON_HD3200 = 0x9620, @@ -1418,6 +1419,7 @@ struct wined3d_gl_limits struct wined3d_gl_info { + DWORD glsl_version; UINT vidmem; struct wined3d_gl_limits limits; DWORD reserved_glsl_constants; @@ -1433,7 +1435,7 @@ struct wined3d_gl_info WGL_EXT_FUNCS_GEN #undef USE_GL_FUNC - struct GlPixelFormatDesc *gl_formats; + struct wined3d_format_desc *gl_formats; }; struct wined3d_driver_info @@ -1469,7 +1471,7 @@ struct wined3d_adapter BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) DECLSPEC_HIDDEN; BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram) DECLSPEC_HIDDEN; +extern unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, unsigned int glram) DECLSPEC_HIDDEN; extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; /***************************************************************************** @@ -1564,14 +1566,9 @@ typedef struct IWineD3DImpl struct wined3d_adapter adapters[1]; } IWineD3DImpl; -extern const IWineD3DVtbl IWineD3D_Vtbl DECLSPEC_HIDDEN; - +HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) DECLSPEC_HIDDEN; BOOL wined3d_register_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN; -BOOL InitAdapters(IWineD3DImpl *This) DECLSPEC_HIDDEN; - -/* A helper function that dumps a resource list */ -void dumpResources(struct list *list) DECLSPEC_HIDDEN; /***************************************************************************** * IWineD3DDevice implementation structure @@ -1656,9 +1653,10 @@ struct IWineD3DDeviceImpl unsigned int highest_dirty_ps_const, highest_dirty_vs_const; /* Render Target Support */ - IWineD3DSurface **render_targets; - IWineD3DSurface *auto_depth_stencil_buffer; - IWineD3DSurface *stencilBufferTarget; + IWineD3DSurfaceImpl **render_targets; + IWineD3DSurfaceImpl *auto_depth_stencil; + IWineD3DSurfaceImpl *onscreen_depth_stencil; + IWineD3DSurfaceImpl *depth_stencil; /* palettes texture management */ UINT NumberOfPalettes; @@ -1701,12 +1699,12 @@ struct IWineD3DDeviceImpl /* Stream source management */ struct wined3d_stream_info strided_streams; const WineDirect3DVertexStridedData *up_strided; + struct wined3d_event_query *buffer_queries[MAX_ATTRIBS]; + unsigned int num_buffer_queries; /* Context management */ struct wined3d_context **contexts; UINT numContexts; - struct wined3d_context *pbufferContext; /* The context that has a pbuffer as drawable */ - DWORD pbufferWidth, pbufferHeight; /* Size of the buffer drawable */ /* High level patch management */ #define PATCHMAP_SIZE 43 @@ -1715,6 +1713,9 @@ struct IWineD3DDeviceImpl struct WineD3DRectPatch *currentPatch; }; +BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN; HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, UINT adapter_idx, WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent, IWineD3DDeviceParent *device_parent) DECLSPEC_HIDDEN; @@ -1725,6 +1726,8 @@ void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource) D void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN; void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN; +void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context, + IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN; @@ -1770,7 +1773,7 @@ typedef struct IWineD3DResourceClass WINED3DPOOL pool; UINT size; DWORD usage; - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; DWORD priority; BYTE *allocatedMemory; /* Pointer to the real data location */ BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */ @@ -1793,7 +1796,7 @@ DWORD resource_get_priority(IWineD3DResource *iface) DECLSPEC_HIDDEN; HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid, void *data, DWORD *data_size) DECLSPEC_HIDDEN; HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, + IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface) DECLSPEC_HIDDEN; DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority) DECLSPEC_HIDDEN; @@ -1801,7 +1804,7 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN; /* Tests show that the start address of resources is 32 byte aligned */ -#define RESOURCE_ALIGNMENT 32 +#define RESOURCE_ALIGNMENT 16 /***************************************************************************** * IWineD3DBaseTexture D3D- > openGL state map lookups @@ -1818,10 +1821,8 @@ typedef enum winetexturestates { WINED3DTEXSTA_MAXMIPLEVEL = 7, WINED3DTEXSTA_MAXANISOTROPY = 8, WINED3DTEXSTA_SRGBTEXTURE = 9, - WINED3DTEXSTA_ELEMENTINDEX = 10, - WINED3DTEXSTA_DMAPOFFSET = 11, - WINED3DTEXSTA_TSSADDRESSW = 12, - MAX_WINETEXTURESTATES = 13, + WINED3DTEXSTA_SHADOW = 10, + MAX_WINETEXTURESTATES = 11, } winetexturestates; enum WINED3DSRGB @@ -1845,7 +1846,9 @@ struct gl_texture typedef struct IWineD3DBaseTextureClass { struct gl_texture texture_rgb, texture_srgb; - UINT levels; + IWineD3DResourceImpl **sub_resources; + UINT layer_count; + UINT level_count; float pow2Matrix[16]; UINT LOD; WINED3DTEXTUREFILTERTYPE filterType; @@ -1858,10 +1861,11 @@ typedef struct IWineD3DBaseTextureClass void (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb); } IWineD3DBaseTextureClass; -void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; -BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) DECLSPEC_HIDDEN; +void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; +BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; +BOOL surface_is_offscreen(IWineD3DSurfaceImpl *iface) DECLSPEC_HIDDEN; +void surface_prepare_texture(IWineD3DSurfaceImpl *surface, + const struct wined3d_gl_info *gl_info, BOOL srgb) DECLSPEC_HIDDEN; typedef struct IWineD3DBaseTextureImpl { @@ -1883,9 +1887,12 @@ WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; DWORD basetexture_get_lod(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; -HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, - WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, + UINT layer, UINT level) DECLSPEC_HIDDEN; +HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count, + WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage, + const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type) DECLSPEC_HIDDEN; BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty) DECLSPEC_HIDDEN; @@ -1903,7 +1910,6 @@ typedef struct IWineD3DTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DTexture */ - IWineD3DSurface *surfaces[MAX_MIP_LEVELS]; UINT target; BOOL cond_np2; @@ -1922,9 +1928,6 @@ typedef struct IWineD3DCubeTextureImpl const IWineD3DCubeTextureVtbl *lpVtbl; IWineD3DResourceClass resource; IWineD3DBaseTextureClass baseTexture; - - /* IWineD3DCubeTexture */ - IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS]; } IWineD3DCubeTextureImpl; HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels, @@ -1971,9 +1974,6 @@ typedef struct IWineD3DVolumeTextureImpl const IWineD3DVolumeTextureVtbl *lpVtbl; IWineD3DResourceClass resource; IWineD3DBaseTextureClass baseTexture; - - /* IWineD3DVolumeTexture */ - IWineD3DVolume *volumes[MAX_MIP_LEVELS]; } IWineD3DVolumeTextureImpl; HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height, @@ -2009,8 +2009,8 @@ typedef struct { struct fbo_entry { struct list entry; - IWineD3DSurface **render_targets; - IWineD3DSurface *depth_stencil; + IWineD3DSurfaceImpl **render_targets; + IWineD3DSurfaceImpl *depth_stencil; BOOL attached; GLuint id; }; @@ -2052,9 +2052,6 @@ struct IWineD3DSurfaceImpl /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */ void (*get_drawable_size)(struct wined3d_context *context, UINT *width, UINT *height); - /* Oversized texture */ - RECT glRect; - /* PBO */ GLuint pbo; GLuint texture_name; @@ -2082,6 +2079,7 @@ struct IWineD3DSurfaceImpl struct list renderbuffers; renderbuffer_entry_t *current_renderbuffer; + SIZE ds_current_size; /* DirectDraw clippers */ IWineD3DClipper *clipper; @@ -2097,13 +2095,14 @@ struct IWineD3DSurfaceImpl extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl DECLSPEC_HIDDEN; extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl DECLSPEC_HIDDEN; -UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, +UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height) DECLSPEC_HIDDEN; void surface_gdi_cleanup(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment, UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; /* Predeclare the shared Surface functions */ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, @@ -2153,13 +2152,13 @@ const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface) DECLS void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; -void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; +void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) DECLSPEC_HIDDEN; void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN; /* Surface flags: */ -#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ #define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */ #define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */ #define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */ @@ -2186,7 +2185,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE #define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */ /* In some conditions the surface memory must not be freed: - * SFLAG_OVERSIZE: Not all data can be kept in GL * SFLAG_CONVERTED: Converting the data back would take too long * SFLAG_DIBSECTION: The dib code manages the memory * SFLAG_LOCKED: The app requires access to the surface data @@ -2194,8 +2192,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL. * SFLAG_CLIENT: OpenGL uses our memory as backup */ -#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \ - SFLAG_CONVERTED | \ +#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \ SFLAG_DIBSECTION | \ SFLAG_LOCKED | \ SFLAG_DYNLOCK | \ @@ -2212,38 +2209,19 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE SFLAG_DS_OFFSCREEN) #define SFLAG_DS_DISCARDED SFLAG_DS_LOCATIONS -BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) DECLSPEC_HIDDEN; - typedef enum { NO_CONVERSION, CONVERT_PALETTED, CONVERT_PALETTED_CK, CONVERT_CK_565, CONVERT_CK_5551, - CONVERT_CK_4444, - CONVERT_CK_4444_ARGB, - CONVERT_CK_1555, - CONVERT_555, CONVERT_CK_RGB24, - CONVERT_CK_8888, - CONVERT_CK_8888_ARGB, - CONVERT_RGB32_888, - CONVERT_V8U8, - CONVERT_L6V5U5, - CONVERT_X8L8V8U8, - CONVERT_Q8W8V8U8, - CONVERT_V16U16, - CONVERT_A4L4, - CONVERT_G16R16, - CONVERT_R16G16F, - CONVERT_R32G32F, - CONVERT_D15S1, - CONVERT_D24X4S4, - CONVERT_D24FS8, + CONVERT_RGB32_888 } CONVERT_TYPES; -HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, - GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) DECLSPEC_HIDDEN; +HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, + struct wined3d_format_desc *desc, CONVERT_TYPES *convert) DECLSPEC_HIDDEN; +void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) DECLSPEC_HIDDEN; BOOL palette9_changed(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; @@ -2253,7 +2231,7 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; struct wined3d_vertex_declaration_element { - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; BOOL ffp_valid; WORD input_slot; WORD offset; @@ -2432,6 +2410,14 @@ HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device, WINED3DSTATEBLOCKTYPE type) DECLSPEC_HIDDEN; void stateblock_init_contained_states(IWineD3DStateBlockImpl *object) DECLSPEC_HIDDEN; +static inline void stateblock_apply_state(DWORD state, IWineD3DStateBlockImpl *stateblock, + struct wined3d_context *context) +{ + const struct StateEntry *statetable = stateblock->device->StateTable; + DWORD rep = statetable[state].representative; + statetable[rep].apply(rep, stateblock, context); +} + /* Direct3D terminology with little modifications. We do not have an issued state * because only the driver knows about it, but we have a created state because d3d * allows GetData on a created issue, but opengl doesn't @@ -2485,6 +2471,9 @@ struct wined3d_map_range #define WINED3D_BUFFER_CREATEBO 0x04 /* Attempt to create a buffer object next PreLoad */ #define WINED3D_BUFFER_DOUBLEBUFFER 0x08 /* Use a vbo and local allocated memory */ #define WINED3D_BUFFER_FLUSH 0x10 /* Manual unmap flushing */ +#define WINED3D_BUFFER_DISCARD 0x20 /* A DISCARD lock has occurred since the last PreLoad */ +#define WINED3D_BUFFER_NOSYNC 0x40 /* All locks since the last PreLoad had NOOVERWRITE set */ +#define WINED3D_BUFFER_APPLESYNC 0x80 /* Using sync as in GL_APPLE_flush_buffer_range */ struct wined3d_buffer { @@ -2503,6 +2492,7 @@ struct wined3d_buffer LONG lock_count; struct wined3d_map_range *maps; ULONG maps_size, modified_areas; + struct wined3d_event_query *query; /* conversion stuff */ UINT decl_change_count, full_conversion_count; @@ -2514,8 +2504,9 @@ struct wined3d_buffer UINT *conversion_shift; /* NULL if no shifted conversion */ }; -const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) DECLSPEC_HIDDEN; -BYTE *buffer_get_sysmem(struct wined3d_buffer *This) DECLSPEC_HIDDEN; +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info, + GLuint *buffer_object) DECLSPEC_HIDDEN; +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; @@ -2530,7 +2521,8 @@ struct wined3d_rendertarget_view IUnknown *parent; }; -extern const IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, + IWineD3DResource *resource, IUnknown *parent) DECLSPEC_HIDDEN; /***************************************************************************** * IWineD3DSwapChainImpl implementation structure (extends IUnknown) @@ -2546,21 +2538,23 @@ struct IWineD3DSwapChainImpl IWineD3DDeviceImpl *device; /* IWineD3DSwapChain fields */ - IWineD3DSurface **backBuffer; - IWineD3DSurface *frontBuffer; + IWineD3DSurfaceImpl **back_buffers; + IWineD3DSurfaceImpl *front_buffer; WINED3DPRESENT_PARAMETERS presentParms; DWORD orig_width, orig_height; WINED3DFORMAT orig_fmt; WINED3DGAMMARAMP orig_gamma; BOOL render_to_fbo; + const struct wined3d_format_desc *ds_format; - long prev_time, frames; /* Performance tracking */ + LONG prev_time, frames; /* Performance tracking */ unsigned int vSyncCounter; struct wined3d_context **context; unsigned int num_contexts; HWND win_handle; + HWND device_window; }; const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN; @@ -2580,7 +2574,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *ifac HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE *pMode) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, - IWineD3DDevice **ppDevice) DECLSPEC_HIDDEN; + IWineD3DDevice **device) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, @@ -2624,6 +2618,9 @@ const char *debug_d3dtop(WINED3DTEXTUREOP d3dtop) DECLSPEC_HIDDEN; void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN; const char *debug_surflocation(DWORD flag) DECLSPEC_HIDDEN; +/* Color conversion routines */ +DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) DECLSPEC_HIDDEN; + /* Routines for GL <-> D3D values */ GLenum StencilOp(DWORD op) DECLSPEC_HIDDEN; GLenum CompareFunc(DWORD func) DECLSPEC_HIDDEN; @@ -2650,18 +2647,19 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) DECLSPEC_HIDDEN; -void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) DECLSPEC_HIDDEN; -GLenum surface_get_gl_buffer(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) DECLSPEC_HIDDEN; -void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, +void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) DECLSPEC_HIDDEN; +GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; +void surface_load_ds_location(IWineD3DSurfaceImpl *surface, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; +void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) DECLSPEC_HIDDEN; -void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; -void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) DECLSPEC_HIDDEN; +void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; +void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) DECLSPEC_HIDDEN; -BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, +BOOL getColorBits(const struct wined3d_format_desc *format_desc, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize) DECLSPEC_HIDDEN; -BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, +BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize) DECLSPEC_HIDDEN; /* Math utils */ @@ -2941,8 +2939,8 @@ struct IWineD3DPaletteImpl { DWORD Flags; }; -extern const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl DECLSPEC_HIDDEN; -DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) DECLSPEC_HIDDEN; +HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device, + DWORD flags, const PALETTEENTRY *entries, IUnknown *parent) DECLSPEC_HIDDEN; /* DirectDraw utility functions */ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN; @@ -2952,17 +2950,23 @@ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN; */ /* WineD3D pixel format flags */ -#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1 -#define WINED3DFMT_FLAG_FILTERING 0x2 -#define WINED3DFMT_FLAG_DEPTH 0x4 -#define WINED3DFMT_FLAG_STENCIL 0x8 -#define WINED3DFMT_FLAG_RENDERTARGET 0x10 -#define WINED3DFMT_FLAG_FOURCC 0x20 -#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x40 -#define WINED3DFMT_FLAG_COMPRESSED 0x80 -#define WINED3DFMT_FLAG_GETDC 0x100 +#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x00000001 +#define WINED3DFMT_FLAG_FILTERING 0x00000002 +#define WINED3DFMT_FLAG_DEPTH 0x00000004 +#define WINED3DFMT_FLAG_STENCIL 0x00000008 +#define WINED3DFMT_FLAG_RENDERTARGET 0x00000010 +#define WINED3DFMT_FLAG_FOURCC 0x00000020 +#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040 +#define WINED3DFMT_FLAG_COMPRESSED 0x00000080 +#define WINED3DFMT_FLAG_GETDC 0x00000100 +#define WINED3DFMT_FLAG_FLOAT 0x00000200 +#define WINED3DFMT_FLAG_BUMPMAP 0x00000400 +#define WINED3DFMT_FLAG_SRGB_READ 0x00000800 +#define WINED3DFMT_FLAG_SRGB_WRITE 0x00001000 +#define WINED3DFMT_FLAG_VTF 0x00002000 +#define WINED3DFMT_FLAG_SHADOW 0x00004000 -struct GlPixelFormatDesc +struct wined3d_format_desc { WINED3DFORMAT format; DWORD red_mask; @@ -2989,12 +2993,14 @@ struct GlPixelFormatDesc GLint rtInternal; GLint glFormat; GLint glType; + UINT conv_byte_count; unsigned int Flags; float heightscale; struct color_fixup_desc color_fixup; + void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); }; -const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, +const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock) @@ -3013,9 +3019,9 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock) return (stateblock->pixelShader && stateblock->device->ps_selected_mode != SHADER_NONE); } -void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, - WINED3DRECT *src_rect, IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, - const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) DECLSPEC_HIDDEN; +void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, + const WINED3DTEXTUREFILTERTYPE filter) DECLSPEC_HIDDEN; /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" @@ -3024,4 +3030,6 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff)) + #endif diff --git a/reactos/include/reactos/wine/wined3d.idl b/reactos/include/reactos/wine/wined3d.idl index 6364f9cfe89..1da7d44b738 100644 --- a/reactos/include/reactos/wine/wined3d.idl +++ b/reactos/include/reactos/wine/wined3d.idl @@ -275,9 +275,7 @@ typedef enum _WINED3DFORMAT typedef enum _WINED3DRENDERSTATETYPE { - WINED3DRS_TEXTUREHANDLE = 1, /* d3d7 */ WINED3DRS_ANTIALIAS = 2, /* d3d7 */ - WINED3DRS_TEXTUREADDRESS = 3, /* d3d7 */ WINED3DRS_TEXTUREPERSPECTIVE = 4, /* d3d7 */ WINED3DRS_WRAPU = 5, /* d3d7 */ WINED3DRS_WRAPV = 6, /* d3d7 */ @@ -291,11 +289,8 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_ZWRITEENABLE = 14, WINED3DRS_ALPHATESTENABLE = 15, WINED3DRS_LASTPIXEL = 16, - WINED3DRS_TEXTUREMAG = 17, /* d3d7 */ - WINED3DRS_TEXTUREMIN = 18, /* d3d7 */ WINED3DRS_SRCBLEND = 19, WINED3DRS_DESTBLEND = 20, - WINED3DRS_TEXTUREMAPBLEND = 21, /* d3d7 */ WINED3DRS_CULLMODE = 22, WINED3DRS_ZFUNC = 23, WINED3DRS_ALPHAREF = 24, @@ -316,9 +311,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_STIPPLEENABLE = 39, /* d3d7 */ WINED3DRS_EDGEANTIALIAS = 40, /* d3d7, d3d8 */ WINED3DRS_COLORKEYENABLE = 41, /* d3d7 */ - WINED3DRS_BORDERCOLOR = 43, /* d3d7 */ - WINED3DRS_TEXTUREADDRESSU = 44, /* d3d7 */ - WINED3DRS_TEXTUREADDRESSV = 45, /* d3d7 */ WINED3DRS_MIPMAPLODBIAS = 46, /* d3d7 */ WINED3DRS_ZBIAS = 47, /* d3d7, d3d8 */ WINED3DRS_RANGEFOGENABLE = 48, @@ -334,38 +326,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_STENCILMASK = 58, WINED3DRS_STENCILWRITEMASK = 59, WINED3DRS_TEXTUREFACTOR = 60, - WINED3DRS_STIPPLEPATTERN00 = 64, - WINED3DRS_STIPPLEPATTERN01 = 65, - WINED3DRS_STIPPLEPATTERN02 = 66, - WINED3DRS_STIPPLEPATTERN03 = 67, - WINED3DRS_STIPPLEPATTERN04 = 68, - WINED3DRS_STIPPLEPATTERN05 = 69, - WINED3DRS_STIPPLEPATTERN06 = 70, - WINED3DRS_STIPPLEPATTERN07 = 71, - WINED3DRS_STIPPLEPATTERN08 = 72, - WINED3DRS_STIPPLEPATTERN09 = 73, - WINED3DRS_STIPPLEPATTERN10 = 74, - WINED3DRS_STIPPLEPATTERN11 = 75, - WINED3DRS_STIPPLEPATTERN12 = 76, - WINED3DRS_STIPPLEPATTERN13 = 77, - WINED3DRS_STIPPLEPATTERN14 = 78, - WINED3DRS_STIPPLEPATTERN15 = 79, - WINED3DRS_STIPPLEPATTERN16 = 80, - WINED3DRS_STIPPLEPATTERN17 = 81, - WINED3DRS_STIPPLEPATTERN18 = 82, - WINED3DRS_STIPPLEPATTERN19 = 83, - WINED3DRS_STIPPLEPATTERN20 = 84, - WINED3DRS_STIPPLEPATTERN21 = 85, - WINED3DRS_STIPPLEPATTERN22 = 86, - WINED3DRS_STIPPLEPATTERN23 = 87, - WINED3DRS_STIPPLEPATTERN24 = 88, - WINED3DRS_STIPPLEPATTERN25 = 89, - WINED3DRS_STIPPLEPATTERN26 = 90, - WINED3DRS_STIPPLEPATTERN27 = 91, - WINED3DRS_STIPPLEPATTERN28 = 92, - WINED3DRS_STIPPLEPATTERN29 = 93, - WINED3DRS_STIPPLEPATTERN30 = 94, - WINED3DRS_STIPPLEPATTERN31 = 95, WINED3DRS_WRAP0 = 128, WINED3DRS_WRAP1 = 129, WINED3DRS_WRAP2 = 130, @@ -407,8 +367,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_COLORWRITEENABLE = 168, WINED3DRS_TWEENFACTOR = 170, WINED3DRS_BLENDOP = 171, - WINED3DRS_POSITIONORDER = 172, - WINED3DRS_NORMALORDER = 173, WINED3DRS_POSITIONDEGREE = 172, WINED3DRS_NORMALDEGREE = 173, WINED3DRS_SCISSORTESTENABLE = 174, @@ -3452,6 +3410,15 @@ interface IWineD3DDevice : IWineD3DBase [in] D3DCB_ENUMRESOURCES callback, [in] void *data ); + HRESULT GetSurfaceFromDC( + [in] HDC dc, + [out] IWineD3DSurface **surface + ); + HRESULT AcquireFocusWindow( + [in] HWND window + ); + void ReleaseFocusWindow( + ); } IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent); From c63cf6931f6aa3e83e9d3853a0c43b6d263ff6b3 Mon Sep 17 00:00:00 2001 From: Benedikt Freisen Date: Thu, 27 May 2010 12:21:50 +0000 Subject: [PATCH 053/292] [PAINT] - Improvements by Black_Fox, see bug #5418 - Readability improvement, patch by Katayama Hirofumi, see bug #5420 svn path=/trunk/; revision=47372 --- reactos/base/applications/paint/definitions.h | 18 +++ reactos/base/applications/paint/main.c | 2 +- reactos/base/applications/paint/mouse.c | 134 +++++++++--------- .../base/applications/paint/toolsettings.c | 52 +++---- reactos/base/applications/paint/winproc.c | 100 +++++++++---- 5 files changed, 181 insertions(+), 125 deletions(-) diff --git a/reactos/base/applications/paint/definitions.h b/reactos/base/applications/paint/definitions.h index 5fb041e7a4c..71ec94bf263 100644 --- a/reactos/base/applications/paint/definitions.h +++ b/reactos/base/applications/paint/definitions.h @@ -98,6 +98,24 @@ #define ID_ELLIPSE 614 #define ID_RRECT 615 +//the following 16 numbers need to be in order, increasing by 1 +#define TOOL_FREESEL 1 +#define TOOL_RECTSEL 2 +#define TOOL_RUBBER 3 +#define TOOL_FILL 4 +#define TOOL_COLOR 5 +#define TOOL_ZOOM 6 +#define TOOL_PEN 7 +#define TOOL_BRUSH 8 +#define TOOL_AIRBRUSH 9 +#define TOOL_TEXT 10 +#define TOOL_LINE 11 +#define TOOL_BEZIER 12 +#define TOOL_RECT 13 +#define TOOL_SHAPE 14 +#define TOOL_ELLIPSE 15 +#define TOOL_RRECT 16 + #define ID_ACCELERATORS 800 #define IDD_MIRRORROTATE 700 diff --git a/reactos/base/applications/paint/main.c b/reactos/base/applications/paint/main.c index 904220567d1..3c77cb23999 100644 --- a/reactos/base/applications/paint/main.c +++ b/reactos/base/applications/paint/main.c @@ -50,7 +50,7 @@ short lastY; int lineWidth = 1; int shapeStyle = 0; int brushStyle = 0; -int activeTool = 7; +int activeTool = TOOL_PEN; int airBrushWidth = 5; int rubberRadius = 4; int transpBg = 0; diff --git a/reactos/base/applications/paint/mouse.c b/reactos/base/applications/paint/mouse.c index 9165291594e..543e34e92ed 100644 --- a/reactos/base/applications/paint/mouse.c +++ b/reactos/base/applications/paint/mouse.c @@ -67,7 +67,7 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) lastY = y; switch (activeTool) { - case 1: + case TOOL_FREESEL: ShowWindow(hSelection, SW_HIDE); if (ptStack != NULL) HeapFree(GetProcessHeap(), 0, ptStack); @@ -76,39 +76,39 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) ptStack[0].x = x; ptStack[0].y = y; break; - case 10: - case 11: - case 13: - case 15: - case 16: + case TOOL_TEXT: + case TOOL_LINE: + case TOOL_RECT: + case TOOL_ELLIPSE: + case TOOL_RRECT: newReversible(); break; - case 2: + case TOOL_RECTSEL: newReversible(); ShowWindow(hSelection, SW_HIDE); rectSel_src[2] = rectSel_src[3] = 0; break; - case 3: + case TOOL_RUBBER: newReversible(); Erase(hdc, x, y, x, y, bg, rubberRadius); break; - case 4: + case TOOL_FILL: newReversible(); Fill(hdc, x, y, fg); break; - case 7: + case TOOL_PEN: newReversible(); SetPixel(hdc, x, y, fg); break; - case 8: + case TOOL_BRUSH: newReversible(); Brush(hdc, x, y, x, y, fg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: newReversible(); Airbrush(hdc, x, y, fg, airBrushWidth); break; - case 12: + case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) @@ -117,7 +117,7 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) pointSP++; } break; - case 14: + case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) @@ -136,7 +136,7 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 1: + case TOOL_FREESEL: if (ptSP == 0) newReversible(); ptSP++; @@ -147,7 +147,7 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) resetToU1(); Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE); break; - case 2: + case TOOL_RECTSEL: { short tempX; short tempY; @@ -161,25 +161,25 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) RectSel(hdc, startX, startY, tempX, tempY); break; } - case 3: + case TOOL_RUBBER: Erase(hdc, lastX, lastY, x, y, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, fg, 1); break; - case 8: + case TOOL_BRUSH: Brush(hdc, lastX, lastY, x, y, fg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: Airbrush(hdc, x, y, fg, airBrushWidth); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, fg, lineWidth); break; - case 12: + case TOOL_BEZIER: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -197,13 +197,13 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) break; } break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -213,13 +213,13 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, fg, bg, lineWidth, shapeStyle, FALSE); break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -236,7 +236,7 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 1: + case TOOL_FREESEL: { POINT *ptStackCopy; int i; @@ -286,7 +286,7 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) ptStack = NULL; break; } - case 2: + case TOOL_RECTSEL: resetToU1(); if ((rectSel_src[2] != 0) && (rectSel_src[3] != 0)) { @@ -306,31 +306,31 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) ShowWindow(hSelection, SW_SHOW); } break; - case 3: + case TOOL_RUBBER: Erase(hdc, lastX, lastY, x, y, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, fg, 1); SetPixel(hdc, x, y, fg); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, fg, lineWidth); break; - case 12: + case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -354,13 +354,13 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) if (pointSP == 255) pointSP--; break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -378,35 +378,35 @@ startPaintingR(HDC hdc, short x, short y, int fg, int bg) lastY = y; switch (activeTool) { - case 1: - case 10: - case 11: - case 13: - case 15: - case 16: + case TOOL_FREESEL: + case TOOL_TEXT: + case TOOL_LINE: + case TOOL_RECT: + case TOOL_ELLIPSE: + case TOOL_RRECT: newReversible(); break; - case 3: + case TOOL_RUBBER: newReversible(); Replace(hdc, x, y, x, y, fg, bg, rubberRadius); break; - case 4: + case TOOL_FILL: newReversible(); Fill(hdc, x, y, bg); break; - case 7: + case TOOL_PEN: newReversible(); SetPixel(hdc, x, y, bg); break; - case 8: + case TOOL_BRUSH: newReversible(); Brush(hdc, x, y, x, y, bg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: newReversible(); Airbrush(hdc, x, y, bg, airBrushWidth); break; - case 12: + case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) @@ -415,7 +415,7 @@ startPaintingR(HDC hdc, short x, short y, int fg, int bg) pointSP++; } break; - case 14: + case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) @@ -434,25 +434,25 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 3: + case TOOL_RUBBER: Replace(hdc, lastX, lastY, x, y, fg, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, bg, 1); break; - case 8: + case TOOL_BRUSH: Brush(hdc, lastX, lastY, x, y, bg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: Airbrush(hdc, x, y, bg, airBrushWidth); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, bg, lineWidth); break; - case 12: + case TOOL_BEZIER: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -470,13 +470,13 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) break; } break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -486,13 +486,13 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, bg, fg, lineWidth, shapeStyle, FALSE); break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -509,31 +509,31 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 3: + case TOOL_RUBBER: Replace(hdc, lastX, lastY, x, y, fg, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, bg, 1); SetPixel(hdc, x, y, bg); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, bg, lineWidth); break; - case 12: + case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -557,13 +557,13 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg) if (pointSP == 255) pointSP--; break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); diff --git a/reactos/base/applications/paint/toolsettings.c b/reactos/base/applications/paint/toolsettings.c index bfb2172f0bf..2e5cd67661d 100644 --- a/reactos/base/applications/paint/toolsettings.c +++ b/reactos/base/applications/paint/toolsettings.c @@ -34,13 +34,13 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DefWindowProc(hwnd, message, wParam, lParam); - DrawEdge(hdc, &rect1, BDR_SUNKENOUTER, (activeTool == 6) ? BF_RECT : BF_RECT | BF_MIDDLE); - DrawEdge(hdc, &rect2, (activeTool >= 13) ? BDR_SUNKENOUTER : 0, BF_RECT | BF_MIDDLE); + DrawEdge(hdc, &rect1, BDR_SUNKENOUTER, (activeTool == TOOL_ZOOM) ? BF_RECT : BF_RECT | BF_MIDDLE); + DrawEdge(hdc, &rect2, (activeTool >= TOOL_RECT) ? BDR_SUNKENOUTER : 0, BF_RECT | BF_MIDDLE); switch (activeTool) { - case 1: - case 2: - case 10: + case TOOL_FREESEL: + case TOOL_RECTSEL: + case TOOL_TEXT: { HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); SelectObject(hdc, GetSysColorBrush(COLOR_HIGHLIGHT)); @@ -50,7 +50,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawIconEx(hdc, 1, 33, hTranspIcon, 40, 30, 0, NULL, DI_NORMAL); break; } - case 3: + case TOOL_RUBBER: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -69,7 +69,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 8: + case TOOL_BRUSH: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -82,7 +82,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GetSysColor((i == brushStyle) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT), i); break; } - case 9: + case TOOL_AIRBRUSH: { HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); SelectObject(hdc, GetSysColorBrush(COLOR_HIGHLIGHT)); @@ -112,8 +112,8 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 11: - case 12: + case TOOL_LINE: + case TOOL_BEZIER: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -132,10 +132,10 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 13: - case 14: - case 15: - case 16: + case TOOL_RECT: + case TOOL_SHAPE: + case TOOL_ELLIPSE: + case TOOL_RRECT: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -178,23 +178,23 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (activeTool) { - case 1: - case 2: - case 10: + case TOOL_FREESEL: + case TOOL_RECTSEL: + case TOOL_TEXT: if ((HIWORD(lParam) > 1) && (HIWORD(lParam) < 64)) { transpBg = (HIWORD(lParam) - 2) / 31; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 3: + case TOOL_RUBBER: if ((HIWORD(lParam) > 1) && (HIWORD(lParam) < 62)) { rubberRadius = (HIWORD(lParam) - 2) / 15 + 2; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 8: + case TOOL_BRUSH: if ((LOWORD(lParam) > 1) && (LOWORD(lParam) < 40) && (HIWORD(lParam) > 1) && (HIWORD(lParam) < 62)) { @@ -202,7 +202,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 9: + case TOOL_AIRBRUSH: if (HIWORD(lParam) < 62) { if (HIWORD(lParam) < 30) @@ -222,18 +222,18 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 11: - case 12: + case TOOL_LINE: + case TOOL_BEZIER: if (HIWORD(lParam) <= 62) { lineWidth = (HIWORD(lParam) - 2) / 12 + 1; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 13: - case 14: - case 15: - case 16: + case TOOL_RECT: + case TOOL_SHAPE: + case TOOL_ELLIPSE: + case TOOL_RRECT: if (HIWORD(lParam) <= 60) { shapeStyle = (HIWORD(lParam) - 2) / 20; diff --git a/reactos/base/applications/paint/winproc.c b/reactos/base/applications/paint/winproc.c index 464b62c9842..18bbaa61a67 100644 --- a/reactos/base/applications/paint/winproc.c +++ b/reactos/base/applications/paint/winproc.c @@ -460,19 +460,19 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (activeTool) { - case 4: + case TOOL_FILL: SetCursor(hCurFill); break; - case 5: + case TOOL_COLOR: SetCursor(hCurColor); break; - case 6: + case TOOL_ZOOM: SetCursor(hCurZoom); break; - case 7: + case TOOL_PEN: SetCursor(hCurPen); break; - case 9: + case TOOL_AIRBRUSH: SetCursor(hCurAirbrush); break; default: @@ -486,7 +486,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDOWN: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool == 5)) + if ((!drawing) || (activeTool == TOOL_COLOR)) { SetCapture(hImageArea); drawing = TRUE; @@ -499,7 +499,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) undo(); } SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool == 6) && (zoom < 8000)) + if ((activeTool == TOOL_ZOOM) && (zoom < 8000)) zoomTo(zoom * 2, (short)LOWORD(lParam), (short)HIWORD(lParam)); } break; @@ -507,7 +507,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RBUTTONDOWN: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool == 5)) + if ((!drawing) || (activeTool == TOOL_COLOR)) { SetCapture(hImageArea); drawing = TRUE; @@ -520,7 +520,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) undo(); } SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool == 6) && (zoom > 125)) + if ((activeTool == TOOL_ZOOM) && (zoom > 125)) zoomTo(zoom / 2, (short)LOWORD(lParam), (short)HIWORD(lParam)); } break; @@ -533,7 +533,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) endPaintingL(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool == 5) + if (activeTool == TOOL_COLOR) { int tempColor = GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom); @@ -553,7 +553,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) endPaintingR(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool == 5) + if (activeTool == TOOL_COLOR) { int tempColor = GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom); @@ -568,16 +568,13 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool <= 9)) + short xNow = (short)LOWORD(lParam) * 1000 / zoom; + short yNow = (short)HIWORD(lParam) * 1000 / zoom; + if ((!drawing) || (activeTool <= TOOL_AIRBRUSH)) { TRACKMOUSEEVENT tme; - TCHAR coordStr[100]; - _stprintf(coordStr, _T("%d, %d"), (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom); - SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); - - if (activeTool == 6) + if (activeTool == TOOL_ZOOM) { SendMessage(hImageArea, WM_PAINT, 0, 0); drawZoomFrame((short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -588,32 +585,73 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) tme.hwndTrack = hImageArea; tme.dwHoverTime = 0; TrackMouseEvent(&tme); + + if (!drawing) + { + TCHAR coordStr[100]; + _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); + } } if (drawing) { + /* values displayed in statusbar */ + short xRel = xNow - startX; + short yRel = yNow - startY; + /* freesel, rectsel and text tools always show numbers limited to fit into image area */ + if ((activeTool == TOOL_FREESEL) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_TEXT)) + { + if (xRel < 0) + xRel = (xNow < 0) ? -startX : xRel; + else if (xNow > imgXRes) + xRel = imgXRes-startX; + if (yRel < 0) + yRel = (yNow < 0) ? -startY : yRel; + else if (yNow > imgYRes) + yRel = imgYRes-startY; + } + /* rectsel and shape tools always show non-negative numbers when drawing */ + if ((activeTool == TOOL_RECTSEL) || (activeTool == TOOL_SHAPE)) + { + if (xRel < 0) + xRel = -xRel; + if (yRel < 0) + yRel = -yRel; + } + /* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */ + switch(activeTool) + { + case TOOL_RUBBER: + case TOOL_PEN: + case TOOL_BRUSH: + case TOOL_AIRBRUSH: + case TOOL_SHAPE: + { + TCHAR coordStr[100]; + _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); + break; + } + } if ((wParam & MK_LBUTTON) != 0) { - whilePaintingL(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); + whilePaintingL(hDrawingDC, xNow, yNow, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool >= 10) || (activeTool == 2)) + if ((activeTool >= TOOL_TEXT) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_FREESEL)) { TCHAR sizeStr[100]; - _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX, - (short)HIWORD(lParam) * 1000 / zoom - startY); + _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } if ((wParam & MK_RBUTTON) != 0) { - whilePaintingR(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); + whilePaintingR(hDrawingDC, xNow, yNow, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool >= 10) + if (activeTool >= TOOL_TEXT) { TCHAR sizeStr[100]; - _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX, - (short)HIWORD(lParam) * 1000 / zoom - startY); + _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } @@ -623,7 +661,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSELEAVE: SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T("")); - if (activeTool == 6) + if (activeTool == TOOL_ZOOM) SendMessage(hImageArea, WM_PAINT, 0, 0); break; @@ -747,7 +785,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* remove selection window and already painted content using undo(), paint Rect for rectangular selections and nothing for freeform selections */ undo(); - if (activeTool == 2) + if (activeTool == TOOL_RECTSEL) { newReversible(); Rect(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2] + rectSel_dest[0], @@ -756,7 +794,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; } case IDM_EDITSELECTALL: - if (activeTool == 2) + if (activeTool == TOOL_RECTSEL) { startPaintingL(hDrawingDC, 0, 0, fgColor, bgColor); whilePaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor); From 011d911b661360da2c7bcb428d055d9b08127196 Mon Sep 17 00:00:00 2001 From: Benedikt Freisen Date: Thu, 27 May 2010 14:53:53 +0000 Subject: [PATCH 054/292] [PAINT] - After clearing a new selection and creating an undo-step, draw selection contents - Fixes bug #5246 svn path=/trunk/; revision=47373 --- reactos/base/applications/paint/mouse.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/reactos/base/applications/paint/mouse.c b/reactos/base/applications/paint/mouse.c index 543e34e92ed..d46bbe35eaf 100644 --- a/reactos/base/applications/paint/mouse.c +++ b/reactos/base/applications/paint/mouse.c @@ -279,6 +279,9 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE); newReversible(); + MaskBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0, + 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); + placeSelWin(); ShowWindow(hSelection, SW_SHOW); } @@ -302,6 +305,9 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) rectSel_src[1] + rectSel_src[3], bgColor, bgColor, 0, TRUE); newReversible(); + BitBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0, + 0, SRCCOPY); + placeSelWin(); ShowWindow(hSelection, SW_SHOW); } From b85a7deb221c30f3ed488b24f58721f1a59e271e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 27 May 2010 20:15:35 +0000 Subject: [PATCH 055/292] The global flag FLG_HEAP_ENABLE_CALL_TRACING has been replaced by FLG_ENABLE_SYSTEM_CRIT_BREAKS in Windows XP and above. svn path=/trunk/; revision=47374 --- reactos/include/ndk/pstypes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 43b44680960..414e2dcbec1 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -60,7 +60,11 @@ Author: #define FLG_ENABLE_CSRDEBUG 0x00020000 #define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 #define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 +#if (NTDDI_VERSION < NTDDI_WINXP) #define FLG_HEAP_ENABLE_CALL_TRACING 0x00100000 +#else +#define FLG_ENABLE_SYSTEM_CRIT_BREAKS 0x00100000 +#endif #define FLG_HEAP_DISABLE_COALESCING 0x00200000 #define FLG_ENABLE_CLOSE_EXCEPTIONS 0x00400000 #define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 From f73d8199f715beec7bfb78e460fea723a107dd7c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 27 May 2010 23:52:32 +0000 Subject: [PATCH 056/292] [NPFS] - Partially revert r47370 and apply a better patch - Change ReadEvent and WriteEvent to notification events because we reset those events manually when we run out of buffer space svn path=/trunk/; revision=47375 --- reactos/drivers/filesystems/npfs/create.c | 10 ++++------ reactos/drivers/filesystems/npfs/rw.c | 20 ++++++-------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/create.c b/reactos/drivers/filesystems/npfs/create.c index 86209bdb8ab..2eb0aad9c0e 100644 --- a/reactos/drivers/filesystems/npfs/create.c +++ b/reactos/drivers/filesystems/npfs/create.c @@ -205,8 +205,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, ClientCcb->MaxDataLength = Fcb->OutboundQuota; ExInitializeFastMutex(&ClientCcb->DataListLock); KeInitializeEvent(&ClientCcb->ConnectEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&ClientCcb->ReadEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&ClientCcb->WriteEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&ClientCcb->ReadEvent, NotificationEvent, FALSE); + KeInitializeEvent(&ClientCcb->WriteEvent, NotificationEvent, FALSE); /* @@ -540,8 +540,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, DPRINT("CCB: %p\n", Ccb); KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&Ccb->ReadEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&Ccb->WriteEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&Ccb->ReadEvent, NotificationEvent, FALSE); + KeInitializeEvent(&Ccb->WriteEvent, NotificationEvent, FALSE); KeLockMutex(&Fcb->CcbListLock); InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry); @@ -619,7 +619,6 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject, ExAcquireFastMutex(&OtherSide->DataListLock); ExAcquireFastMutex(&Ccb->DataListLock); } - OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; OtherSide->OtherSide = NULL; /* * Signaling the write event. If is possible that an other @@ -745,7 +744,6 @@ NpfsClose(PDEVICE_OBJECT DeviceObject, /* Disconnect the pipes */ if (Ccb->OtherSide) { - Ccb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE; Ccb->OtherSide->OtherSide = NULL; Ccb->OtherSide = NULL; } diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index 4c83f5cec53..f3f02bdd315 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -331,11 +331,8 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject, if ((Ccb->OtherSide == NULL) && (Ccb->ReadDataAvailable == 0)) { - if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE) - { - DPRINT("File pipe broken\n"); + if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE) Status = STATUS_PIPE_BROKEN; - } else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE) Status = STATUS_PIPE_LISTENING; else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE) @@ -443,7 +440,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject, { break; } - if ((Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) && (Ccb->ReadDataAvailable == 0)) + if (((Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) || (!Ccb->OtherSide)) && (Ccb->ReadDataAvailable == 0)) { DPRINT("PipeState: %x\n", Ccb->PipeState); Status = STATUS_PIPE_BROKEN; @@ -800,13 +797,13 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, { if ((ReaderCcb->WriteQuotaAvailable == 0)) { - KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE); - if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE || !Ccb->OtherSide) { Status = STATUS_PIPE_BROKEN; ExReleaseFastMutex(&ReaderCcb->DataListLock); goto done; } + KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE); ExReleaseFastMutex(&ReaderCcb->DataListLock); DPRINT("Write Waiting for buffer space (%S)\n", Fcb->PipeName.Buffer); @@ -830,20 +827,15 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, * It's possible that the event was signaled because the * other side of pipe was closed. */ - if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE || !Ccb->OtherSide) { DPRINT("PipeState: %x\n", Ccb->PipeState); Status = STATUS_PIPE_BROKEN; goto done; } /* Check that the pipe has not been closed */ - if (ReaderCcb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (ReaderCcb->PipeState != FILE_PIPE_CONNECTED_STATE || !ReaderCcb->OtherSide) { - /* If the other side is valid, fire event */ - if (Ccb) - { - KeResetEvent(&Ccb->WriteEvent); - } Status = STATUS_PIPE_BROKEN; goto done; } From f06be4552d4397e38addc3679e8dcfdaf0ef21a7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 02:25:56 +0000 Subject: [PATCH 057/292] [MSAFD] - Zero the entire struct not just the lpNetworkEvents member - Write the error codes returned from AFD to the iErrorCode array - Fixes hundreds of ws2_32_winetest sock failures (only 104 failures now) - Dedicated to Physicus svn path=/trunk/; revision=47376 --- reactos/dll/win32/msafd/misc/event.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/msafd/misc/event.c b/reactos/dll/win32/msafd/misc/event.c index 9a49e31b282..ab340aebb28 100644 --- a/reactos/dll/win32/msafd/misc/event.c +++ b/reactos/dll/win32/msafd/misc/event.c @@ -179,43 +179,51 @@ WSPEnumNetworkEvents( AFD_DbgPrint(MID_TRACE,("About to touch struct at %x (%d)\n", lpNetworkEvents, sizeof(*lpNetworkEvents))); - lpNetworkEvents->lNetworkEvents = 0; + RtlZeroMemory(lpNetworkEvents, sizeof(*lpNetworkEvents)); AFD_DbgPrint(MID_TRACE,("Zeroed struct\n")); /* Set Events to wait for */ if (EnumReq.PollEvents & AFD_EVENT_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_READ; + lpNetworkEvents->iErrorCode[FD_READ_BIT] = EnumReq.EventStatus[FD_READ_BIT]; } if (EnumReq.PollEvents & AFD_EVENT_SEND) { lpNetworkEvents->lNetworkEvents |= FD_WRITE; + lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = EnumReq.EventStatus[FD_WRITE_BIT]; } if (EnumReq.PollEvents & AFD_EVENT_OOB_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_OOB; + lpNetworkEvents->iErrorCode[FD_OOB_BIT] = EnumReq.EventStatus[FD_OOB_BIT]; } if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) { lpNetworkEvents->lNetworkEvents |= FD_ACCEPT; + lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = EnumReq.EventStatus[FD_ACCEPT_BIT]; } if (EnumReq.PollEvents & (AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL)) { lpNetworkEvents->lNetworkEvents |= FD_CONNECT; + lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = EnumReq.EventStatus[FD_CONNECT_BIT]; } if (EnumReq.PollEvents & (AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) { lpNetworkEvents->lNetworkEvents |= FD_CLOSE; + lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = EnumReq.EventStatus[FD_CLOSE_BIT]; } if (EnumReq.PollEvents & AFD_EVENT_QOS) { lpNetworkEvents->lNetworkEvents |= FD_QOS; + lpNetworkEvents->iErrorCode[FD_QOS_BIT] = EnumReq.EventStatus[FD_QOS_BIT]; } if (EnumReq.PollEvents & AFD_EVENT_GROUP_QOS) { lpNetworkEvents->lNetworkEvents |= FD_GROUP_QOS; + lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = EnumReq.EventStatus[FD_GROUP_QOS_BIT]; } if( NT_SUCCESS(Status) ) *lpErrno = 0; From 219cc11d6adfe0ce093e3e98d29cc217cc524e0b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 03:55:50 +0000 Subject: [PATCH 058/292] [MSAFD] - Remove an incorrect change - Create a new function called TranslateNtStatusError to translate NTSTATUS to winsock error codes - Call the TranslateNtStatusError in MsafdReturnWithErrno and also use it to translate AFD's poll event error codes [AFD] - Track the status for each poll event in our FCB and copy it back when we get an IOCTL_AFD_ENUM_NETWORK_EVENTS IRP - Remove some useless PollReeval calls svn path=/trunk/; revision=47377 --- reactos/dll/win32/msafd/misc/dllmain.c | 129 ++++++++++++---------- reactos/dll/win32/msafd/misc/event.c | 18 +-- reactos/dll/win32/msafd/msafd.h | 2 + reactos/drivers/network/afd/afd/connect.c | 3 + reactos/drivers/network/afd/afd/listen.c | 31 +++--- reactos/drivers/network/afd/afd/main.c | 3 + reactos/drivers/network/afd/afd/read.c | 36 +++--- reactos/drivers/network/afd/afd/select.c | 4 +- reactos/drivers/network/afd/afd/write.c | 11 +- reactos/drivers/network/afd/include/afd.h | 1 + 10 files changed, 127 insertions(+), 111 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index e43ab505bfd..d3165a5814e 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -318,79 +318,86 @@ error: return INVALID_SOCKET; } +INT +TranslateNtStatusError(NTSTATUS Status) +{ + switch (Status) + { + case STATUS_CANT_WAIT: + return WSAEWOULDBLOCK; + + case STATUS_TIMEOUT: + return WSAETIMEDOUT; + + case STATUS_SUCCESS: + return NO_ERROR; + + case STATUS_FILE_CLOSED: + case STATUS_END_OF_FILE: + return WSAESHUTDOWN; + + case STATUS_PENDING: + return WSA_IO_PENDING; + + case STATUS_BUFFER_TOO_SMALL: + case STATUS_BUFFER_OVERFLOW: + DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); + return WSAEMSGSIZE; + + case STATUS_NO_MEMORY: + case STATUS_INSUFFICIENT_RESOURCES: + DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); + return WSAENOBUFS; + + case STATUS_INVALID_CONNECTION: + DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); + return WSAEAFNOSUPPORT; + + case STATUS_INVALID_ADDRESS: + DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n"); + return WSAEADDRNOTAVAIL; + + case STATUS_REMOTE_NOT_LISTENING: + DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); + return WSAECONNREFUSED; + + case STATUS_NETWORK_UNREACHABLE: + DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n"); + return WSAENETUNREACH; + + case STATUS_INVALID_PARAMETER: + DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); + return WSAEINVAL; + + case STATUS_CANCELLED: + DbgPrint("MSAFD: STATUS_CANCELLED\n"); + return WSA_OPERATION_ABORTED; + + default: + DbgPrint("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status); + return WSAENETDOWN; + } +} DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes) { - if( ReturnedBytes ) - *ReturnedBytes = 0; - if( Errno ) + if (Errno) { - switch (Status) + *Errno = TranslateNtStatusError(Status); + + if (ReturnedBytes) { - case STATUS_CANT_WAIT: - *Errno = WSAEWOULDBLOCK; - break; - case STATUS_TIMEOUT: - *Errno = WSAETIMEDOUT; - break; - case STATUS_SUCCESS: - /* Return Number of bytes Read */ - if( ReturnedBytes ) + if (!*Errno) *ReturnedBytes = Received; - break; - case STATUS_FILE_CLOSED: - case STATUS_END_OF_FILE: - *Errno = WSAESHUTDOWN; - break; - case STATUS_PENDING: - *Errno = WSA_IO_PENDING; - break; - case STATUS_BUFFER_TOO_SMALL: - case STATUS_BUFFER_OVERFLOW: - DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); - *Errno = WSAEMSGSIZE; - break; - case STATUS_NO_MEMORY: /* Fall through to STATUS_INSUFFICIENT_RESOURCES */ - case STATUS_INSUFFICIENT_RESOURCES: - DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); - *Errno = WSAENOBUFS; - break; - case STATUS_INVALID_CONNECTION: - DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); - *Errno = WSAEAFNOSUPPORT; - break; - case STATUS_INVALID_ADDRESS: - DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n"); - *Errno = WSAEADDRNOTAVAIL; - break; - case STATUS_REMOTE_NOT_LISTENING: - DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); - *Errno = WSAECONNREFUSED; - break; - case STATUS_NETWORK_UNREACHABLE: - DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n"); - *Errno = WSAENETUNREACH; - break; - case STATUS_INVALID_PARAMETER: - DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); - *Errno = WSAEINVAL; - break; - case STATUS_CANCELLED: - DbgPrint("MSAFD: STATUS_CANCELLED\n"); - *Errno = WSA_OPERATION_ABORTED; - break; - default: - DbgPrint("MSAFD: Error %x is unknown\n", Status); - *Errno = WSAEINVAL; - break; + else + *ReturnedBytes = 0; } } - /* Success */ - return Status == STATUS_SUCCESS ? 0 : SOCKET_ERROR; + return Status ? SOCKET_ERROR : 0; } /* diff --git a/reactos/dll/win32/msafd/misc/event.c b/reactos/dll/win32/msafd/misc/event.c index ab340aebb28..19d5f23d617 100644 --- a/reactos/dll/win32/msafd/misc/event.c +++ b/reactos/dll/win32/msafd/misc/event.c @@ -179,51 +179,51 @@ WSPEnumNetworkEvents( AFD_DbgPrint(MID_TRACE,("About to touch struct at %x (%d)\n", lpNetworkEvents, sizeof(*lpNetworkEvents))); - RtlZeroMemory(lpNetworkEvents, sizeof(*lpNetworkEvents)); + lpNetworkEvents->lNetworkEvents = 0; AFD_DbgPrint(MID_TRACE,("Zeroed struct\n")); /* Set Events to wait for */ if (EnumReq.PollEvents & AFD_EVENT_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_READ; - lpNetworkEvents->iErrorCode[FD_READ_BIT] = EnumReq.EventStatus[FD_READ_BIT]; + lpNetworkEvents->iErrorCode[FD_READ_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_READ_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_SEND) { lpNetworkEvents->lNetworkEvents |= FD_WRITE; - lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = EnumReq.EventStatus[FD_WRITE_BIT]; + lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_WRITE_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_OOB_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_OOB; - lpNetworkEvents->iErrorCode[FD_OOB_BIT] = EnumReq.EventStatus[FD_OOB_BIT]; + lpNetworkEvents->iErrorCode[FD_OOB_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_OOB_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) { lpNetworkEvents->lNetworkEvents |= FD_ACCEPT; - lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = EnumReq.EventStatus[FD_ACCEPT_BIT]; + lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_ACCEPT_BIT]); } if (EnumReq.PollEvents & (AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL)) { lpNetworkEvents->lNetworkEvents |= FD_CONNECT; - lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = EnumReq.EventStatus[FD_CONNECT_BIT]; + lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CONNECT_BIT]); } if (EnumReq.PollEvents & (AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) { lpNetworkEvents->lNetworkEvents |= FD_CLOSE; - lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = EnumReq.EventStatus[FD_CLOSE_BIT]; + lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CLOSE_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_QOS) { lpNetworkEvents->lNetworkEvents |= FD_QOS; - lpNetworkEvents->iErrorCode[FD_QOS_BIT] = EnumReq.EventStatus[FD_QOS_BIT]; + lpNetworkEvents->iErrorCode[FD_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_QOS_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_GROUP_QOS) { lpNetworkEvents->lNetworkEvents |= FD_GROUP_QOS; - lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = EnumReq.EventStatus[FD_GROUP_QOS_BIT]; + lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_GROUP_QOS_BIT]); } if( NT_SUCCESS(Status) ) *lpErrno = 0; diff --git a/reactos/dll/win32/msafd/msafd.h b/reactos/dll/win32/msafd/msafd.h index fbef176ab47..2ae98c67069 100755 --- a/reactos/dll/win32/msafd/msafd.h +++ b/reactos/dll/win32/msafd/msafd.h @@ -409,6 +409,8 @@ PSOCKET_INFORMATION GetSocketStructure( SOCKET Handle ); +INT TranslateNtStatusError( NTSTATUS Status ); + VOID DeleteSocketStructure( SOCKET Handle ); int GetSocketInformation( diff --git a/reactos/drivers/network/afd/afd/connect.c b/reactos/drivers/network/afd/afd/connect.c index 3f47a05941a..28fcfada857 100644 --- a/reactos/drivers/network/afd/afd/connect.c +++ b/reactos/drivers/network/afd/afd/connect.c @@ -247,6 +247,8 @@ NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) { if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND; + FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); return Status; @@ -291,6 +293,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete if( !NT_SUCCESS(Irp->IoStatus.Status) ) { FCB->PollState |= AFD_EVENT_CONNECT_FAIL; + FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status; AFD_DbgPrint(MID_TRACE,("Going to bound state\n")); FCB->State = SOCKET_STATE_BOUND; PollReeval( FCB->DeviceExt, FCB->FileObject ); diff --git a/reactos/drivers/network/afd/afd/listen.c b/reactos/drivers/network/afd/afd/listen.c index 5a1b8f55bbb..f6eb1104210 100644 --- a/reactos/drivers/network/afd/afd/listen.c +++ b/reactos/drivers/network/afd/afd/listen.c @@ -193,11 +193,10 @@ static NTSTATUS NTAPI ListenComplete /* Trigger a select return if appropriate */ if( !IsListEmpty( &FCB->PendingConnections ) ) { FCB->PollState |= AFD_EVENT_ACCEPT; - } else { - FCB->PollState &= ~AFD_EVENT_ACCEPT; - } - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); @@ -293,12 +292,13 @@ NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n")); - if ( IsListEmpty( &FCB->PendingConnections ) ) - FCB->PollState &= ~AFD_EVENT_ACCEPT; - else + if ( !IsListEmpty( &FCB->PendingConnections ) ) + { FCB->PollState |= AFD_EVENT_ACCEPT; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); return Status; @@ -402,13 +402,12 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( PendingConnObj ); - if( IsListEmpty( &FCB->PendingConnections ) ) { - FCB->PollState &= ~AFD_EVENT_ACCEPT; - } else { + if( !IsListEmpty( &FCB->PendingConnections ) ) { FCB->PollState |= AFD_EVENT_ACCEPT; - } - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); return Status; diff --git a/reactos/drivers/network/afd/afd/main.c b/reactos/drivers/network/afd/afd/main.c index bcbb2f56603..95da3c054bf 100644 --- a/reactos/drivers/network/afd/afd/main.c +++ b/reactos/drivers/network/afd/afd/main.c @@ -314,6 +314,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* A datagram socket is always sendable */ FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } @@ -377,6 +378,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->State = SOCKET_STATE_CLOSED; FCB->PollState = AFD_EVENT_CLOSE; + FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; //I think we can return success here PollReeval( FCB->DeviceExt, FCB->FileObject ); InFlightRequest[0] = &FCB->ListenIrp; @@ -542,6 +544,7 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( ConnectionReturnInfo ); FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } else Status = STATUS_INVALID_PARAMETER; diff --git a/reactos/drivers/network/afd/afd/read.c b/reactos/drivers/network/afd/afd/read.c index dccfa559ba8..f98fd17b3aa 100644 --- a/reactos/drivers/network/afd/afd/read.c +++ b/reactos/drivers/network/afd/afd/read.c @@ -46,6 +46,7 @@ static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) { { /* The socket has been closed */ FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = Status; FCB->Overread = TRUE; Status = STATUS_FILE_CLOSED; } @@ -53,6 +54,7 @@ static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) { { FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; } PollReeval( FCB->DeviceExt, FCB->FileObject ); } @@ -189,10 +191,10 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { if( FCB->Recv.Content ) { FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } else - FCB->PollState &= ~AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollState &= ~AFD_EVENT_RECEIVE; AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus)); @@ -538,10 +540,10 @@ PacketSocketRecvComplete( if( !IsListEmpty( &FCB->DatagramList ) ) { AFD_DbgPrint(MID_TRACE,("Signalling\n")); FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } else - FCB->PollState &= ~AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollState &= ~AFD_EVENT_RECEIVE; if( NT_SUCCESS(Irp->IoStatus.Status) ) { /* Now relaunch the datagram request */ @@ -608,12 +610,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = DatagramRecv->Len; - if( IsListEmpty( &FCB->DatagramList ) ) - FCB->PollState &= ~AFD_EVENT_RECEIVE; - else + if( !IsListEmpty( &FCB->DatagramList ) ) { FCB->PollState |= AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_RECEIVE; UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); @@ -624,12 +626,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, ( FCB, Irp, DatagramRecv, (PUINT)&Irp->IoStatus.Information ); - if( IsListEmpty( &FCB->DatagramList ) ) - FCB->PollState &= ~AFD_EVENT_RECEIVE; - else + if( !IsListEmpty( &FCB->DatagramList ) ) { FCB->PollState |= AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_RECEIVE; UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); @@ -640,12 +642,10 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); Status = STATUS_CANT_WAIT; FCB->PollState &= ~AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } else { FCB->PollState &= ~AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); } } diff --git a/reactos/drivers/network/afd/afd/select.c b/reactos/drivers/network/afd/afd/select.c index 4cdbcdffb4a..d201a8c26a9 100644 --- a/reactos/drivers/network/afd/afd/select.c +++ b/reactos/drivers/network/afd/afd/select.c @@ -325,7 +325,9 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, } EnumReq->PollEvents = FCB->PollState; - RtlZeroMemory( EnumReq->EventStatus, sizeof(EnumReq->EventStatus) ); + RtlCopyMemory( EnumReq->EventStatus, + FCB->PollStatus, + sizeof(EnumReq->EventStatus) ); return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 ); diff --git a/reactos/drivers/network/afd/afd/write.c b/reactos/drivers/network/afd/afd/write.c index aa1c9e371a5..7506489be8e 100644 --- a/reactos/drivers/network/afd/afd/write.c +++ b/reactos/drivers/network/afd/afd/write.c @@ -142,10 +142,10 @@ static NTSTATUS NTAPI SendComplete FCB ); } else { FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } - PollReeval( FCB->DeviceExt, FCB->FileObject ); - if( TotalBytesCopied > 0 ) { UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); @@ -186,6 +186,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete /* Request is not in flight any longer */ FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); if( FCB->State == SOCKET_STATE_CLOSED ) { @@ -391,10 +392,6 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); - FCB->PollState &= ~AFD_EVENT_SEND; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); - /* Check that the socket is bound */ if( FCB->State != SOCKET_STATE_BOUND ) return UnlockAndMaybeComplete @@ -425,6 +422,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* Check the size of the Address given ... */ if( NT_SUCCESS(Status) ) { + FCB->PollState &= ~AFD_EVENT_SEND; + Status = TdiSendDatagram ( &FCB->SendIrp.InFlightRequest, FCB->AddressFile.Object, diff --git a/reactos/drivers/network/afd/include/afd.h b/reactos/drivers/network/afd/include/afd.h index 6b5e875ec9b..ac3a286cd6c 100644 --- a/reactos/drivers/network/afd/include/afd.h +++ b/reactos/drivers/network/afd/include/afd.h @@ -192,6 +192,7 @@ typedef struct _AFD_FCB { UNICODE_STRING TdiDeviceName; PVOID Context; DWORD PollState; + NTSTATUS PollStatus[FD_MAX_EVENTS]; UINT ContextSize; PVOID ConnectData; UINT FilledConnectData; From 54b6aff827957b5b59f3bdd75dd6878b278effe5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 04:07:39 +0000 Subject: [PATCH 059/292] [MSAFD] - Pass a valid pointer for lpErrno to WSPBind when performing an implicit bind - Remove the hack in MsafdReturnWithErrno for dealing with stupid callers that provide don't provide a valid Errno pointer svn path=/trunk/; revision=47378 --- reactos/dll/win32/msafd/misc/dllmain.c | 19 ++++++++----------- reactos/dll/win32/msafd/misc/sndrcv.c | 3 ++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index d3165a5814e..f501eb0bfe9 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -384,20 +384,17 @@ DWORD MsafdReturnWithErrno(NTSTATUS Status, DWORD Received, LPDWORD ReturnedBytes) { - if (Errno) - { - *Errno = TranslateNtStatusError(Status); + *Errno = TranslateNtStatusError(Status); - if (ReturnedBytes) - { - if (!*Errno) - *ReturnedBytes = Received; - else - *ReturnedBytes = 0; - } + if (ReturnedBytes) + { + if (!*Errno) + *ReturnedBytes = Received; + else + *ReturnedBytes = 0; } - return Status ? SOCKET_ERROR : 0; + return *Errno ? SOCKET_ERROR : 0; } /* diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index 212b4fc25ca..3c5b2d5c232 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -540,7 +540,8 @@ WSPSendTo(SOCKET Handle, BindAddress, &BindAddressLength); /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); + if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) + return SOCKET_ERROR; } RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength); From d36292eecfcf8f9a9ba4d52d021e07f9a58b1003 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 04:39:49 +0000 Subject: [PATCH 060/292] [TCPIP] - Return STATUS_INVALID_ADDRESS if the caller tries to get a non-local address - Return STATUS_ADDRESS_ALREADY_EXISTS if the caller uses an address that is in use [MSAFD] - Translate STATUS_ADDRESS_ALREADY_EXISTS -> WSAEADDRINUSE, STATUS_LOCAL_DISCONNECT -> WSAECONNABORTED, and STATUS_REMOTE_DISCONNECT -> WSAECONNRESET [IP] - Translate OSK_EADDRINUSE -> STATUS_ADDRESS_ALREADY_EXISTS, OSK_ECONNABORTED -> STATUS_LOCAL_DISCONNECT, and OSK_ECONNRESET -> STATUS_REMOTE_DISCONNECT - Fixes waiting for binding during ws2_32 sock winetest svn path=/trunk/; revision=47379 --- reactos/dll/win32/msafd/misc/dllmain.c | 12 ++++++++++++ reactos/drivers/network/tcpip/tcpip/fileobjs.c | 6 +++--- reactos/lib/drivers/ip/transport/tcp/tcp.c | 5 +++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index f501eb0bfe9..e8126c963f0 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -373,6 +373,18 @@ TranslateNtStatusError(NTSTATUS Status) DbgPrint("MSAFD: STATUS_CANCELLED\n"); return WSA_OPERATION_ABORTED; + case STATUS_ADDRESS_ALREADY_EXISTS: + DbgPrint("MSAFD: STATUS_ADDRESS_ALREADY_EXISTS\n"); + return WSAEADDRINUSE; + + case STATUS_LOCAL_DISCONNECT: + DbgPrint("MSAFD: STATUS_LOCAL_DISCONNECT\n"); + return WSAECONNABORTED; + + case STATUS_REMOTE_DISCONNECT: + DbgPrint("MSAFD: STATUS_REMOTE_DISCONNECT\n"); + return WSAECONNRESET; + default: DbgPrint("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status); return WSAENETDOWN; diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index bd7968e5ede..70357fced9a 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -265,7 +265,7 @@ NTSTATUS FileOpenAddress( !AddrLocateInterface(&AddrFile->Address)) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); - return STATUS_INVALID_PARAMETER; + return STATUS_INVALID_ADDRESS; } TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n", @@ -282,7 +282,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); - return STATUS_INVALID_PARAMETER; + return STATUS_ADDRESS_ALREADY_EXISTS; } AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP); @@ -300,7 +300,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); - return STATUS_INVALID_PARAMETER; + return STATUS_ADDRESS_ALREADY_EXISTS; } TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n", diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 187c9a56cc7..e033ff6b6ec 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -574,10 +574,11 @@ NTSTATUS TCPTranslateError( int OskitError ) { switch( OskitError ) { case 0: Status = STATUS_SUCCESS; break; case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break; + case OSK_EADDRINUSE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break; case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break; - case OSK_ECONNRESET: - case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNRESET: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNABORTED: Status = STATUS_LOCAL_DISCONNECT; break; case OSK_EWOULDBLOCK: case OSK_EINPROGRESS: Status = STATUS_PENDING; break; case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break; From d30c42f36755278bb7d772904a22a823ca597637 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 05:15:42 +0000 Subject: [PATCH 061/292] [MSAFD] - Fix a broken call to WSPBind that I missed in r47378 svn path=/trunk/; revision=47380 --- reactos/dll/win32/msafd/misc/dllmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index e8126c963f0..97e82f867e1 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -1416,7 +1416,8 @@ WSPConnect(SOCKET Handle, BindAddress, &BindAddressLength); /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); + if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) + return INVALID_SOCKET; } /* Set the Connect Data */ From 4e25539b712a24721f197e2be7f98bd01fc85862 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 28 May 2010 15:03:09 +0000 Subject: [PATCH 062/292] [NTOSKRNL] Implement SeFreePrivileges(). svn path=/trunk/; revision=47382 --- reactos/ntoskrnl/se/priv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/se/priv.c b/reactos/ntoskrnl/se/priv.c index d7d3bf95134..0766492106a 100644 --- a/reactos/ntoskrnl/se/priv.c +++ b/reactos/ntoskrnl/se/priv.c @@ -294,13 +294,14 @@ SeAppendPrivileges(PACCESS_STATE AccessState, } /* - * @unimplemented + * @implemented */ VOID NTAPI SeFreePrivileges(IN PPRIVILEGE_SET Privileges) { - UNIMPLEMENTED; + PAGED_CODE(); + ExFreePool(Privileges); } /* From f0910f33d3adc470720e329e939d8c2d1325811d Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 28 May 2010 16:28:27 +0000 Subject: [PATCH 063/292] [FORMATTING] No code changes. svn path=/trunk/; revision=47383 --- reactos/ntoskrnl/se/access.c | 48 ++- reactos/ntoskrnl/se/acl.c | 149 ++++--- reactos/ntoskrnl/se/audit.c | 50 +-- reactos/ntoskrnl/se/lsa.c | 12 +- reactos/ntoskrnl/se/priv.c | 235 +++++------ reactos/ntoskrnl/se/sd.c | 368 ++++++++--------- reactos/ntoskrnl/se/semgr.c | 23 +- reactos/ntoskrnl/se/sid.c | 40 +- reactos/ntoskrnl/se/token.c | 758 ++++++++++++++++++----------------- 9 files changed, 856 insertions(+), 827 deletions(-) diff --git a/reactos/ntoskrnl/se/access.c b/reactos/ntoskrnl/se/access.c index 953166f98b3..fdf4f1376b3 100644 --- a/reactos/ntoskrnl/se/access.c +++ b/reactos/ntoskrnl/se/access.c @@ -30,11 +30,12 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread, OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) { BOOLEAN CopyOnOpen, EffectiveOnly; + PAGED_CODE(); - + /* Save the unique ID */ SubjectContext->ProcessAuditId = Process->UniqueProcessId; - + /* Check if we have a thread */ if (!Thread) { @@ -49,7 +50,7 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread, &EffectiveOnly, &SubjectContext->ImpersonationLevel); } - + /* Get the primary token */ SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process); } @@ -75,7 +76,7 @@ NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE); } @@ -88,7 +89,7 @@ NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + ExReleaseResourceLite(&SepSubjectContextLock); KeLeaveCriticalRegion(); } @@ -101,12 +102,12 @@ NTAPI SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + if (SubjectContext->PrimaryToken != NULL) { ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken); } - + if (SubjectContext->ClientToken != NULL) { ObDereferenceObject(SubjectContext->ClientToken); @@ -127,6 +128,7 @@ SeCreateAccessStateEx(IN PETHREAD Thread, { ACCESS_MASK AccessMask = Access; PTOKEN Token; + PAGED_CODE(); /* Map the Generic Acess to Specific Access if we have a Mapping */ @@ -150,9 +152,9 @@ SeCreateAccessStateEx(IN PETHREAD Thread, ExpAllocateLocallyUniqueId(&AccessState->OperationID); /* Get the Token to use */ - Token = AccessState->SubjectSecurityContext.ClientToken ? - (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken : - (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken; + Token = AccessState->SubjectSecurityContext.ClientToken ? + (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken : + (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken; /* Check for Travers Privilege */ if (Token->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE) @@ -200,6 +202,7 @@ NTAPI SeDeleteAccessState(IN PACCESS_STATE AccessState) { PAUX_ACCESS_DATA AuxData; + PAGED_CODE(); /* Get the Auxiliary Data */ @@ -213,7 +216,8 @@ SeDeleteAccessState(IN PACCESS_STATE AccessState) { ExFreePool(AccessState->ObjectName.Buffer); } - if (AccessState->ObjectTypeName.Buffer) + + if (AccessState->ObjectTypeName.Buffer) { ExFreePool(AccessState->ObjectTypeName.Buffer); } @@ -252,8 +256,9 @@ SeCreateClientSecurity(IN PETHREAD Thread, PACCESS_TOKEN Token; NTSTATUS Status; PACCESS_TOKEN NewToken; + PAGED_CODE(); - + Token = PsReferenceEffectiveToken(Thread, &TokenType, &ThreadEffectiveOnly, @@ -269,7 +274,7 @@ SeCreateClientSecurity(IN PETHREAD Thread, if (Token) ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + if ((ImpersonationLevel == SecurityAnonymous) || (ImpersonationLevel == SecurityIdentification) || ((RemoteClient) && (ImpersonationLevel != SecurityDelegation))) @@ -277,12 +282,11 @@ SeCreateClientSecurity(IN PETHREAD Thread, if (Token) ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) || - (Qos->EffectiveOnly)) ? - TRUE : FALSE; + (Qos->EffectiveOnly)) ? TRUE : FALSE; } - + if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING) { ClientContext->DirectlyAccessClientToken = FALSE; @@ -299,10 +303,10 @@ SeCreateClientSecurity(IN PETHREAD Thread, &ClientContext->ClientTokenControl); #endif } - + NewToken = Token; } - + ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel; ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode; @@ -347,9 +351,9 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, IN PETHREAD ServerThread OPTIONAL) { UCHAR b; - + PAGED_CODE(); - + if (ClientContext->DirectlyAccessClientToken == FALSE) { b = ClientContext->SecurityQos.EffectiveOnly; @@ -358,10 +362,12 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, { b = ClientContext->DirectAccessEffectiveOnly; } + if (ServerThread == NULL) { ServerThread = PsGetCurrentThread(); } + PsImpersonateClient(ServerThread, ClientContext->ClientToken, 1, diff --git a/reactos/ntoskrnl/se/acl.c b/reactos/ntoskrnl/se/acl.c index 5280ef4a888..35e4a7520e9 100644 --- a/reactos/ntoskrnl/se/acl.c +++ b/reactos/ntoskrnl/se/acl.c @@ -34,189 +34,188 @@ NTAPI SepInitDACLs(VOID) { ULONG AclLength; - + /* create PublicDefaultDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); + SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicDefaultDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicDefaultDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicDefaultDacl, ACL_REVISION, GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicDefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - - + /* create PublicDefaultUnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicDefaultUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicDefaultUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, SeRestrictedCodeSid); - + /* create PublicOpenDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + SePublicOpenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicOpenDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicOpenDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + /* create PublicOpenUnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicOpenUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicOpenUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, SeRestrictedCodeSid); - + /* create SystemDefaultDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SeSystemDefaultDacl == NULL) return FALSE; - + RtlCreateAcl(SeSystemDefaultDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SeSystemDefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SeSystemDefaultDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, SeAliasAdminsSid); - + /* create UnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SeUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SeUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SeUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SeUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); - + RtlAddAccessAllowedAce(SeUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, SeRestrictedCodeSid); - - return(TRUE); + + return TRUE; } NTSTATUS NTAPI @@ -226,22 +225,22 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, { ULONG AclLength; PVOID TokenDacl; - + PAGED_CODE(); - + AclLength = sizeof(ACL) + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) + (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid)); - + TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (TokenDacl == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } - + RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION); RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, Token->UserAndGroups->Sid); @@ -251,7 +250,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, SeAliasAdminsSid); RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + /* FIXME */ #if 0 if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL) @@ -260,7 +259,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, SeRestrictedCodeSid); } #endif - + return STATUS_SUCCESS; } @@ -275,9 +274,9 @@ SepCaptureAcl(IN PACL InputAcl, PACL NewAcl; ULONG AclSize = 0; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + if (AccessMode != KernelMode) { _SEH2_TRY @@ -296,10 +295,10 @@ SepCaptureAcl(IN PACL InputAcl, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + NewAcl = ExAllocatePool(PoolType, AclSize); - if(NewAcl != NULL) + if (NewAcl != NULL) { _SEH2_TRY { @@ -322,23 +321,23 @@ SepCaptureAcl(IN PACL InputAcl, Status = STATUS_INSUFFICIENT_RESOURCES; } } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { *CapturedAcl = InputAcl; } else { AclSize = InputAcl->AclSize; - + NewAcl = ExAllocatePool(PoolType, AclSize); - - if(NewAcl != NULL) + + if (NewAcl != NULL) { RtlCopyMemory(NewAcl, InputAcl, AclSize); - + *CapturedAcl = NewAcl; } else @@ -346,7 +345,7 @@ SepCaptureAcl(IN PACL InputAcl, Status = STATUS_INSUFFICIENT_RESOURCES; } } - + return Status; } @@ -357,10 +356,10 @@ SepReleaseAcl(IN PACL CapturedAcl, IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedAcl != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) + + if (CapturedAcl != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) { ExFreePool(CapturedAcl); } diff --git a/reactos/ntoskrnl/se/audit.c b/reactos/ntoskrnl/se/audit.c index bdd7f93d77a..92b87fa8377 100644 --- a/reactos/ntoskrnl/se/audit.c +++ b/reactos/ntoskrnl/se/audit.c @@ -4,7 +4,7 @@ * FILE: ntoskrnl/se/audit.c * PURPOSE: Audit functions * - * PROGRAMMERS: Eric Kohl + * PROGRAMMERS: Eric Kohl */ /* INCLUDES *******************************************************************/ @@ -47,6 +47,7 @@ SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject, POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; ULONG ReturnLength = 8; NTSTATUS Status; + PAGED_CODE(); ASSERT(AuditInfo); @@ -120,6 +121,7 @@ SeLocateProcessImageName(IN PEPROCESS Process, PUNICODE_STRING ImageName; PFILE_OBJECT FileObject; NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); /* Assume failure */ @@ -189,7 +191,7 @@ SeAuditHardLinkCreation(IN PUNICODE_STRING FileName, IN PUNICODE_STRING LinkName, IN BOOLEAN bSuccess) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -200,8 +202,8 @@ NTAPI SeAuditingFileEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -213,8 +215,8 @@ SeAuditingFileEventsWithContext(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -225,8 +227,8 @@ NTAPI SeAuditingHardLinkEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -238,8 +240,8 @@ SeAuditingHardLinkEventsWithContext(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -251,8 +253,8 @@ SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -260,13 +262,11 @@ SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted, */ VOID NTAPI -SeCloseObjectAuditAlarm( - IN PVOID Object, +SeCloseObjectAuditAlarm(IN PVOID Object, IN HANDLE Handle, - IN BOOLEAN PerformAction - ) + IN BOOLEAN PerformAction) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -295,10 +295,10 @@ SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName, OUT PBOOLEAN GenerateOnClose) { PAGED_CODE(); - + /* Audits aren't done on kernel-mode access */ if (AccessMode == KernelMode) return; - + /* Otherwise, unimplemented! */ //UNIMPLEMENTED; return; @@ -333,7 +333,7 @@ SePrivilegeObjectAuditAlarm(IN HANDLE Handle, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE CurrentMode) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* SYSTEM CALLS ***************************************************************/ @@ -363,7 +363,7 @@ NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -373,7 +373,7 @@ NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -392,7 +392,7 @@ NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, OUT PBOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -404,7 +404,7 @@ NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN AccessGranted) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -417,7 +417,7 @@ NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN AccessGranted) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } /* EOF */ diff --git a/reactos/ntoskrnl/se/lsa.c b/reactos/ntoskrnl/se/lsa.c index 15726ad1aa1..b6b36ad6647 100644 --- a/reactos/ntoskrnl/se/lsa.c +++ b/reactos/ntoskrnl/se/lsa.c @@ -110,8 +110,8 @@ NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification(IN PLUID LogonId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* @@ -121,8 +121,8 @@ NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* @@ -132,8 +132,8 @@ NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* EOF */ diff --git a/reactos/ntoskrnl/se/priv.c b/reactos/ntoskrnl/se/priv.c index 0766492106a..7cdbd613d1d 100644 --- a/reactos/ntoskrnl/se/priv.c +++ b/reactos/ntoskrnl/se/priv.c @@ -51,7 +51,7 @@ LUID SeEnableDelegationPrivilege; VOID INIT_FUNCTION NTAPI -SepInitPrivileges (VOID) +SepInitPrivileges(VOID) { SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE; SeCreateTokenPrivilege.HighPart = 0; @@ -110,25 +110,25 @@ SepInitPrivileges (VOID) BOOLEAN NTAPI -SepPrivilegeCheck (PTOKEN Token, - PLUID_AND_ATTRIBUTES Privileges, - ULONG PrivilegeCount, - ULONG PrivilegeControl, - KPROCESSOR_MODE PreviousMode) +SepPrivilegeCheck(PTOKEN Token, + PLUID_AND_ATTRIBUTES Privileges, + ULONG PrivilegeCount, + ULONG PrivilegeControl, + KPROCESSOR_MODE PreviousMode) { ULONG i; ULONG j; ULONG k; - - DPRINT ("SepPrivilegeCheck() called\n"); - + + DPRINT("SepPrivilegeCheck() called\n"); + PAGED_CODE(); - + if (PreviousMode == KernelMode) { return TRUE; } - + k = 0; if (PrivilegeCount > 0) { @@ -139,10 +139,10 @@ SepPrivilegeCheck (PTOKEN Token, if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart && Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart) { - DPRINT ("Found privilege\n"); - DPRINT ("Privilege attributes %lx\n", - Token->Privileges[i].Attributes); - + DPRINT("Found privilege\n"); + DPRINT("Privilege attributes %lx\n", + Token->Privileges[i].Attributes); + if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) { Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS; @@ -152,58 +152,58 @@ SepPrivilegeCheck (PTOKEN Token, } } } - + if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) && PrivilegeCount == k) { return TRUE; } - + if (k > 0 && !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY)) { return TRUE; } - + return FALSE; } NTSTATUS NTAPI -SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, - ULONG PrivilegeCount, - KPROCESSOR_MODE PreviousMode, - PLUID_AND_ATTRIBUTES AllocatedMem, - ULONG AllocatedLength, - POOL_TYPE PoolType, - BOOLEAN CaptureIfKernel, - PLUID_AND_ATTRIBUTES* Dest, - PULONG Length) +SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src, + ULONG PrivilegeCount, + KPROCESSOR_MODE PreviousMode, + PLUID_AND_ATTRIBUTES AllocatedMem, + ULONG AllocatedLength, + POOL_TYPE PoolType, + BOOLEAN CaptureIfKernel, + PLUID_AND_ATTRIBUTES *Dest, + PULONG Length) { ULONG BufferSize; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + if (PrivilegeCount == 0) { *Dest = 0; *Length = 0; return STATUS_SUCCESS; } - + if (PreviousMode == KernelMode && !CaptureIfKernel) { *Dest = Src; return STATUS_SUCCESS; } - + /* FIXME - check PrivilegeCount for a valid number so we don't cause an integer overflow or exhaust system resources! */ - + BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); *Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */ - + /* probe the buffer */ if (PreviousMode != KernelMode) { @@ -220,7 +220,7 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, } _SEH2_END; } - + /* allocate enough memory or check if the provided buffer is large enough to hold the array */ if (AllocatedMem != NULL) @@ -229,14 +229,13 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, { return STATUS_BUFFER_TOO_SMALL; } - + *Dest = AllocatedMem; } else { *Dest = ExAllocatePool(PoolType, BufferSize); - if (*Dest == NULL) { return STATUS_INSUFFICIENT_RESOURCES; @@ -255,23 +254,23 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + if (!NT_SUCCESS(Status) && AllocatedMem == NULL) { ExFreePool(*Dest); } - + return Status; } VOID NTAPI -SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege, - KPROCESSOR_MODE PreviousMode, - BOOLEAN CaptureIfKernel) +SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege, + KPROCESSOR_MODE PreviousMode, + BOOLEAN CaptureIfKernel) { PAGED_CODE(); - + if (Privilege != NULL && (PreviousMode != KernelMode || CaptureIfKernel)) { @@ -307,15 +306,16 @@ SeFreePrivileges(IN PPRIVILEGE_SET Privileges) /* * @implemented */ -BOOLEAN NTAPI -SePrivilegeCheck (PPRIVILEGE_SET Privileges, - PSECURITY_SUBJECT_CONTEXT SubjectContext, - KPROCESSOR_MODE PreviousMode) +BOOLEAN +NTAPI +SePrivilegeCheck(PPRIVILEGE_SET Privileges, + PSECURITY_SUBJECT_CONTEXT SubjectContext, + KPROCESSOR_MODE PreviousMode) { PACCESS_TOKEN Token = NULL; - + PAGED_CODE(); - + if (SubjectContext->ClientToken == NULL) { Token = SubjectContext->PrimaryToken; @@ -328,58 +328,60 @@ SePrivilegeCheck (PPRIVILEGE_SET Privileges, return FALSE; } } - - return SepPrivilegeCheck (Token, - Privileges->Privilege, - Privileges->PrivilegeCount, - Privileges->Control, - PreviousMode); + + return SepPrivilegeCheck(Token, + Privileges->Privilege, + Privileges->PrivilegeCount, + Privileges->Control, + PreviousMode); } /* * @implemented */ -BOOLEAN NTAPI -SeSinglePrivilegeCheck (IN LUID PrivilegeValue, - IN KPROCESSOR_MODE PreviousMode) +BOOLEAN +NTAPI +SeSinglePrivilegeCheck(IN LUID PrivilegeValue, + IN KPROCESSOR_MODE PreviousMode) { SECURITY_SUBJECT_CONTEXT SubjectContext; PRIVILEGE_SET Priv; BOOLEAN Result; - + PAGED_CODE(); - - SeCaptureSubjectContext (&SubjectContext); - + + SeCaptureSubjectContext(&SubjectContext); + Priv.PrivilegeCount = 1; Priv.Control = PRIVILEGE_SET_ALL_NECESSARY; Priv.Privilege[0].Luid = PrivilegeValue; Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; - - Result = SePrivilegeCheck (&Priv, - &SubjectContext, - PreviousMode); - + + Result = SePrivilegeCheck(&Priv, + &SubjectContext, + PreviousMode); + if (PreviousMode != KernelMode) { #if 0 - SePrivilegedServiceAuditAlarm (0, - &SubjectContext, - &PrivilegeValue); + SePrivilegedServiceAuditAlarm(0, + &SubjectContext, + &PrivilegeValue); #endif } - - SeReleaseSubjectContext (&SubjectContext); - + + SeReleaseSubjectContext(&SubjectContext); + return Result; } /* SYSTEM CALLS ***************************************************************/ -NTSTATUS NTAPI -NtPrivilegeCheck (IN HANDLE ClientToken, - IN PPRIVILEGE_SET RequiredPrivileges, - OUT PBOOLEAN Result) +NTSTATUS +NTAPI +NtPrivilegeCheck(IN HANDLE ClientToken, + IN PPRIVILEGE_SET RequiredPrivileges, + OUT PBOOLEAN Result) { PLUID_AND_ATTRIBUTES Privileges; PTOKEN Token; @@ -389,11 +391,11 @@ NtPrivilegeCheck (IN HANDLE ClientToken, BOOLEAN CheckResult; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = KeGetPreviousMode(); - + /* probe the buffers */ if (PreviousMode != KernelMode) { @@ -403,10 +405,10 @@ NtPrivilegeCheck (IN HANDLE ClientToken, FIELD_OFFSET(PRIVILEGE_SET, Privilege), sizeof(ULONG)); - + PrivilegeCount = RequiredPrivileges->PrivilegeCount; PrivilegeControl = RequiredPrivileges->Control; - + /* Check PrivilegeCount to avoid an integer overflow! */ if (FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]) / @@ -414,13 +416,13 @@ NtPrivilegeCheck (IN HANDLE ClientToken, { _SEH2_YIELD(return STATUS_INVALID_PARAMETER); } - + /* probe all of the array */ ProbeForWrite(RequiredPrivileges, FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]), sizeof(ULONG)); - + ProbeForWriteBoolean(Result); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -435,51 +437,51 @@ NtPrivilegeCheck (IN HANDLE ClientToken, PrivilegeCount = RequiredPrivileges->PrivilegeCount; PrivilegeControl = RequiredPrivileges->Control; } - + /* reference the token and make sure we're not doing an anonymous impersonation */ - Status = ObReferenceObjectByHandle (ClientToken, - TOKEN_QUERY, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); + Status = ObReferenceObjectByHandle(ClientToken, + TOKEN_QUERY, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); if (!NT_SUCCESS(Status)) { return Status; } - + if (Token->TokenType == TokenImpersonation && Token->ImpersonationLevel < SecurityIdentification) { - ObDereferenceObject (Token); + ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + /* capture the privileges */ - Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege, - PrivilegeCount, - PreviousMode, - NULL, - 0, - PagedPool, - TRUE, - &Privileges, - &Length); + Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege, + PrivilegeCount, + PreviousMode, + NULL, + 0, + PagedPool, + TRUE, + &Privileges, + &Length); if (!NT_SUCCESS(Status)) { ObDereferenceObject (Token); return Status; } - - CheckResult = SepPrivilegeCheck (Token, - Privileges, - PrivilegeCount, - PrivilegeControl, - PreviousMode); - - ObDereferenceObject (Token); - + + CheckResult = SepPrivilegeCheck(Token, + Privileges, + PrivilegeCount, + PrivilegeControl, + PreviousMode); + + ObDereferenceObject(Token); + /* return the array */ _SEH2_TRY { @@ -494,13 +496,12 @@ NtPrivilegeCheck (IN HANDLE ClientToken, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - - SeReleaseLuidAndAttributesArray (Privileges, - PreviousMode, - TRUE); - + + SeReleaseLuidAndAttributesArray(Privileges, + PreviousMode, + TRUE); + return Status; } - /* EOF */ diff --git a/reactos/ntoskrnl/se/sd.c b/reactos/ntoskrnl/se/sd.c index fded835b6af..a0cb2cc5595 100644 --- a/reactos/ntoskrnl/se/sd.c +++ b/reactos/ntoskrnl/se/sd.c @@ -38,79 +38,79 @@ SepInitSDs(VOID) sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultSd, TRUE, SePublicDefaultDacl, FALSE); - + /* Create PublicDefaultUnrestrictedSd */ SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, TRUE, SePublicDefaultUnrestrictedDacl, FALSE); - + /* Create PublicOpenSd */ SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicOpenSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenSd, TRUE, SePublicOpenDacl, FALSE); - + /* Create PublicOpenUnrestrictedSd */ SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, TRUE, SePublicOpenUnrestrictedDacl, FALSE); - + /* Create SystemDefaultSd */ SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeSystemDefaultSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SeSystemDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, TRUE, SeSystemDefaultDacl, FALSE); - + /* Create UnrestrictedSd */ SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SeUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, TRUE, SeUnrestrictedDacl, FALSE); - + return TRUE; } @@ -125,14 +125,14 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, ULONG SdSize; NTSTATUS Status; PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - + DPRINT("SeSetWorldSecurityDescriptor() called\n"); - + if (SecurityInformation == 0) { return STATUS_ACCESS_DENIED; } - + /* calculate the minimum size of the buffer */ SidSize = RtlLengthSid(SeWorldSid); SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); @@ -144,24 +144,24 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, { SdSize += sizeof(ACL) + sizeof(ACE) + SidSize; } - + if (*BufferLength < SdSize) { *BufferLength = SdSize; return STATUS_BUFFER_TOO_SMALL; } - + *BufferLength = SdSize; - + Status = RtlCreateSecurityDescriptorRelative(SdRel, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { return Status; } - + Current = (ULONG_PTR)(SdRel + 1); - + if (SecurityInformation & OWNER_SECURITY_INFORMATION) { RtlCopyMemory((PVOID)Current, @@ -170,7 +170,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } - + if (SecurityInformation & GROUP_SECURITY_INFORMATION) { RtlCopyMemory((PVOID)Current, @@ -179,33 +179,33 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } - + if (SecurityInformation & DACL_SECURITY_INFORMATION) { PACL Dacl = (PACL)Current; SdRel->Control |= SE_DACL_PRESENT; - + Status = RtlCreateAcl(Dacl, sizeof(ACL) + sizeof(ACE) + SidSize, ACL_REVISION); if (!NT_SUCCESS(Status)) return Status; - + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); if (!NT_SUCCESS(Status)) return Status; - + SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); } - + if (SecurityInformation & SACL_SECURITY_INFORMATION) { /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */ } - + return STATUS_SUCCESS; } @@ -221,33 +221,33 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO { PSECURITY_QUALITY_OF_SERVICE CapturedQos; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + ASSERT(CapturedSecurityQualityOfService); ASSERT(Present); - - if(ObjectAttributes != NULL) + + if (ObjectAttributes != NULL) { - if(AccessMode != KernelMode) + if (AccessMode != KernelMode) { SECURITY_QUALITY_OF_SERVICE SafeQos; - + _SEH2_TRY { ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG)); - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) { - if(ObjectAttributes->SecurityQualityOfService != NULL) + if (ObjectAttributes->SecurityQualityOfService != NULL) { ProbeForRead(ObjectAttributes->SecurityQualityOfService, sizeof(SECURITY_QUALITY_OF_SERVICE), sizeof(ULONG)); - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) + if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) { /* don't allocate memory here because ExAllocate should bugcheck the system if it's buggy, SEH would catch that! So make a local @@ -278,14 +278,14 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO Status = _SEH2_GetExceptionCode(); } _SEH2_END; - - if(NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - if(*Present) + if (*Present) { CapturedQos = ExAllocatePool(PoolType, sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) + if (CapturedQos != NULL) { RtlCopyMemory(CapturedQos, &SafeQos, @@ -305,18 +305,18 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO } else { - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) { - if(CaptureIfKernel) + if (CaptureIfKernel) { - if(ObjectAttributes->SecurityQualityOfService != NULL) + if (ObjectAttributes->SecurityQualityOfService != NULL) { - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) + if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) { CapturedQos = ExAllocatePool(PoolType, sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) + if (CapturedQos != NULL) { RtlCopyMemory(CapturedQos, ObjectAttributes->SecurityQualityOfService, @@ -357,7 +357,7 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO *CapturedSecurityQualityOfService = NULL; *Present = FALSE; } - + return Status; } @@ -369,9 +369,9 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedSecurityQualityOfService != NULL && - (AccessMode != KernelMode || CaptureIfKernel)) + + if (CapturedSecurityQualityOfService != NULL && + (AccessMode != KernelMode || CaptureIfKernel)) { ExFreePool(CapturedSecurityQualityOfService); } @@ -398,13 +398,13 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, ULONG SaclSize = 0, DaclSize = 0; ULONG DescriptorSize = 0; NTSTATUS Status; - - if(OriginalSecurityDescriptor != NULL) + + if (OriginalSecurityDescriptor != NULL) { - if(CurrentMode != KernelMode) + if (CurrentMode != KernelMode) { RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy)); - + _SEH2_TRY { /* first only probe and copy until the control field of the descriptor @@ -414,25 +414,25 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, ProbeForRead(OriginalSecurityDescriptor, DescriptorSize, sizeof(ULONG)); - - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { _SEH2_YIELD(return STATUS_UNKNOWN_REVISION); } - + /* make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - + /* probe and copy the entire security descriptor structure. The SIDs and ACLs will be probed and copied later though */ ProbeForRead(OriginalSecurityDescriptor, DescriptorSize, sizeof(ULONG)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; @@ -456,13 +456,13 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, } _SEH2_END; } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { return STATUS_UNKNOWN_REVISION; } - + *CapturedSecurityDescriptor = OriginalSecurityDescriptor; return STATUS_SUCCESS; } @@ -472,14 +472,14 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, { return STATUS_UNKNOWN_REVISION; } - + /* make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; @@ -496,31 +496,31 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; } } - - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { /* in case we're dealing with a self-relative descriptor, do a basic convert to an absolute descriptor. We do this so we can simply access the data using the pointers without calculating them again. */ DescriptorCopy.Control &= ~SE_SELF_RELATIVE; - if(DescriptorCopy.Owner != NULL) + if (DescriptorCopy.Owner != NULL) { DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner); } - if(DescriptorCopy.Group != NULL) + if (DescriptorCopy.Group != NULL) { DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group); } - if(DescriptorCopy.Dacl != NULL) + if (DescriptorCopy.Dacl != NULL) { DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl); } - if(DescriptorCopy.Sacl != NULL) + if (DescriptorCopy.Sacl != NULL) { DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl); } } - + /* determine the size of the SIDs */ #define DetermineSIDSize(SidType) \ do { \ @@ -555,12 +555,12 @@ DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ } \ } \ } while(0) - + DetermineSIDSize(Owner); DetermineSIDSize(Group); - + #undef DetermineSIDSize - + /* determine the size of the ACLs */ #define DetermineACLSize(AclType, AclFlag) \ do { \ @@ -598,12 +598,12 @@ else \ DescriptorCopy.AclType = NULL; \ } \ } while(0) - + DetermineACLSize(Sacl, SACL); DetermineACLSize(Dacl, DACL); - + #undef DetermineACLSize - + /* allocate enough memory to store a complete copy of a self-relative security descriptor */ NewDescriptor = ExAllocatePoolWithTag(PoolType, @@ -642,12 +642,12 @@ RtlRaiseStatus(STATUS_INVALID_SID); \ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } \ } while(0) - + CopySID(Owner); CopySID(Group); - + #undef CopySID - + #define CopyACL(Type) \ do { \ if(DescriptorCopy.Type != NULL) \ @@ -665,10 +665,10 @@ RtlRaiseStatus(STATUS_INVALID_ACL); \ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } \ } while(0) - + CopyACL(Sacl); CopyACL(Dacl); - + #undef CopyACL } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -678,12 +678,11 @@ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + /* we're finally done! copy the pointer to the captured descriptor to to the caller */ *CapturedSecurityDescriptor = NewDescriptor; return STATUS_SUCCESS; - } else { @@ -695,7 +694,7 @@ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ /* nothing to do... */ *CapturedSecurityDescriptor = NULL; } - + return Status; } @@ -721,9 +720,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, ULONG Control = 0; ULONG_PTR Current; ULONG SdLength; - + RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - + if (*ObjectsSecurityDescriptor == NULL) { if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) @@ -731,15 +730,15 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); return STATUS_BUFFER_TOO_SMALL; } - + *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); RtlCreateSecurityDescriptorRelative(RelSD, SECURITY_DESCRIPTOR_REVISION); return STATUS_SUCCESS; } - + ObjectSd = *ObjectsSecurityDescriptor; - + /* Calculate the required security descriptor length */ Control = SE_SELF_RELATIVE; if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) && @@ -749,7 +748,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); } - + if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) && (ObjectSd->Group != NULL)) { @@ -757,7 +756,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, GroupLength = ROUND_UP(RtlLengthSid(Group), 4); Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); } - + if ((*SecurityInformation & DACL_SECURITY_INFORMATION) && (ObjectSd->Control & SE_DACL_PRESENT)) { @@ -768,7 +767,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, } Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } - + if ((*SecurityInformation & SACL_SECURITY_INFORMATION) && (ObjectSd->Control & SE_SACL_PRESENT)) { @@ -779,7 +778,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, } Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } - + SdLength = OwnerLength + GroupLength + DaclLength + SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE); if (*Length < SdLength) @@ -787,14 +786,14 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, *Length = SdLength; return STATUS_BUFFER_TOO_SMALL; } - + /* Build the new security descrtiptor */ RtlCreateSecurityDescriptorRelative(RelSD, SECURITY_DESCRIPTOR_REVISION); RelSD->Control = (USHORT)Control; - + Current = (ULONG_PTR)(RelSD + 1); - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -803,7 +802,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += OwnerLength; } - + if (GroupLength != 0) { RtlCopyMemory((PVOID)Current, @@ -812,7 +811,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += GroupLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -821,7 +820,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += DaclLength; } - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -830,9 +829,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += SaclLength; } - + *Length = SdLength; - + return STATUS_SUCCESS; } @@ -846,7 +845,7 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, IN BOOLEAN CaptureIfKernelMode) { PAGED_CODE(); - + /* WARNING! You need to call this function with the same value for CurrentMode and CaptureIfKernelMode that you previously passed to SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ @@ -857,7 +856,7 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD); } - + return STATUS_SUCCESS; } @@ -886,26 +885,27 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ULONG Control = 0; ULONG_PTR Current; SECURITY_INFORMATION SecurityInformation; - + ObjectSd = *ObjectsSecurityDescriptor; - + if (!ObjectSd) return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. - + SecurityInformation = *_SecurityInformation; - + /* Get owner and owner size */ if (SecurityInformation & OWNER_SECURITY_INFORMATION) { if (SecurityDescriptor->Owner != NULL) { - if( SecurityDescriptor->Control & SE_SELF_RELATIVE ) + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner + (ULONG_PTR)SecurityDescriptor); else Owner = (PSID)SecurityDescriptor->Owner; OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); } + Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED); } else @@ -915,6 +915,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); } + Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); } @@ -930,6 +931,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Group = (PSID)SecurityDescriptor->Group; GroupLength = ROUND_UP(RtlLengthSid(Group), 4); } + Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED); } else @@ -939,9 +941,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); GroupLength = ROUND_UP(RtlLengthSid(Group), 4); } + Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); } - + /* Get DACL and DACL size */ if (SecurityInformation & DACL_SECURITY_INFORMATION) { @@ -953,9 +956,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, (ULONG_PTR)SecurityDescriptor); else Dacl = (PACL)SecurityDescriptor->Dacl; - + DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } else @@ -966,6 +970,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } @@ -982,6 +987,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Sacl = (PACL)SecurityDescriptor->Sacl; SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); } + Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } else @@ -992,9 +998,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } - + NewSd = ExAllocatePool(NonPagedPool, sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength); @@ -1003,14 +1010,15 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ObDereferenceObject(Object); return STATUS_INSUFFICIENT_RESOURCES; } - + RtlCreateSecurityDescriptor(NewSd, SECURITY_DESCRIPTOR_REVISION1); + /* We always build a self-relative descriptor */ NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE; - + Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR); - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1019,7 +1027,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd); Current += OwnerLength; } - + if (GroupLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1028,7 +1036,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd); Current += GroupLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1037,7 +1045,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd); Current += DaclLength; } - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1045,8 +1053,8 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, SaclLength); NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd); Current += SaclLength; - } - + } + *ObjectsSecurityDescriptor = NewSd; return STATUS_SUCCESS; } @@ -1065,12 +1073,12 @@ SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL, IN PGENERIC_MAPPING GenericMapping) { PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor; - + if (!ObjectSd) return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } @@ -1085,54 +1093,54 @@ SeValidSecurityDescriptor(IN ULONG Length, PISID Sid; PACL Acl; PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; - + if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH) { DPRINT1("Invalid Security Descriptor revision\n"); return FALSE; } - + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { DPRINT1("Invalid Security Descriptor revision\n"); return FALSE; } - + if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE)) { DPRINT1("No self-relative Security Descriptor\n"); return FALSE; } - + SdLength = sizeof(SECURITY_DESCRIPTOR); - + /* Check Owner SID */ if (SecurityDescriptor->Owner == NULL) { DPRINT1("No Owner SID\n"); return FALSE; } - + if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG)) { DPRINT1("Invalid Owner SID alignment\n"); return FALSE; } - + Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner); if (Sid->Revision != SID_REVISION) { DPRINT1("Invalid Owner SID revision\n"); return FALSE; } - + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); if (Length < SdLength) { DPRINT1("Invalid Owner SID size\n"); return FALSE; } - + /* Check Group SID */ if (SecurityDescriptor->Group != NULL) { @@ -1141,14 +1149,14 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid Group SID alignment\n"); return FALSE; } - + Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group); if (Sid->Revision != SID_REVISION) { DPRINT1("Invalid Group SID revision\n"); return FALSE; } - + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); if (Length < SdLength) { @@ -1156,7 +1164,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + /* Check DACL */ if (SecurityDescriptor->Dacl != NULL) { @@ -1165,7 +1173,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid DACL alignment\n"); return FALSE; } - + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl); if ((Acl->AclRevision < MIN_ACL_REVISION) && (Acl->AclRevision > MAX_ACL_REVISION)) @@ -1173,7 +1181,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid DACL revision\n"); return FALSE; } - + SdLength += Acl->AclSize; if (Length < SdLength) { @@ -1181,7 +1189,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + /* Check SACL */ if (SecurityDescriptor->Sacl != NULL) { @@ -1190,7 +1198,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid SACL alignment\n"); return FALSE; } - + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl); if ((Acl->AclRevision < MIN_ACL_REVISION) || (Acl->AclRevision > MAX_ACL_REVISION)) @@ -1198,7 +1206,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid SACL revision\n"); return FALSE; } - + SdLength += Acl->AclSize; if (Length < SdLength) { @@ -1206,7 +1214,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + return TRUE; } @@ -1217,13 +1225,13 @@ NTSTATUS NTAPI SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor) { PAGED_CODE(); - + if (*SecurityDescriptor != NULL) { ExFreePool(*SecurityDescriptor); *SecurityDescriptor = NULL; } - + return STATUS_SUCCESS; } @@ -1273,12 +1281,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, PSID Group = NULL; PACL Dacl = NULL; PACL Sacl = NULL; - + PAGED_CODE(); - + /* Lock subject context */ SeLockSubjectContext(SubjectContext); - + if (SubjectContext->ClientToken != NULL) { Token = SubjectContext->ClientToken; @@ -1287,18 +1295,16 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Token = SubjectContext->PrimaryToken; } - - + /* Inherit the Owner SID */ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL) { DPRINT("Use explicit owner sid!\n"); Owner = ExplicitDescriptor->Owner; - + if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) { Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor); - } } else @@ -1313,13 +1319,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Use default owner sid!\n"); Owner = SeLocalSystemSid; } - + Control |= SE_OWNER_DEFAULTED; } - + OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); - - + /* Inherit the Group SID */ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL) { @@ -1342,13 +1347,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Use default group sid!\n"); Group = SeLocalSystemSid; } - + Control |= SE_OWNER_DEFAULTED; } - + GroupLength = ROUND_UP(RtlLengthSid(Group), 4); - - + /* Inherit the DACL */ if (ExplicitDescriptor != NULL && (ExplicitDescriptor->Control & SE_DACL_PRESENT) && @@ -1360,7 +1364,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor); } - + Control |= SE_DACL_PRESENT; } else if (ParentDescriptor != NULL && @@ -1373,6 +1377,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor); } + Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); } else if (Token != NULL && Token->DefaultDacl != NULL) @@ -1388,10 +1393,9 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Dacl = NULL; Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); } - + DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0; - - + /* Inherit the SACL */ if (ExplicitDescriptor != NULL && (ExplicitDescriptor->Control & SE_SACL_PRESENT) && @@ -1403,7 +1407,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor); } - + Control |= SE_SACL_PRESENT; } else if (ParentDescriptor != NULL && @@ -1416,23 +1420,23 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor); } + Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED); } - + SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0; - - + /* Allocate and initialize the new security descriptor */ Length = sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength; - + DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n", sizeof(SECURITY_DESCRIPTOR), OwnerLength, GroupLength, DaclLength, SaclLength); - + Descriptor = ExAllocatePoolWithTag(PagedPool, Length, TAG_SD); @@ -1442,15 +1446,15 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, /* FIXME: Unlock subject context */ return STATUS_INSUFFICIENT_RESOURCES; } - + RtlZeroMemory( Descriptor, Length ); RtlCreateSecurityDescriptor(Descriptor, SECURITY_DESCRIPTOR_REVISION); - + Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE; - + Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR); - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1459,7 +1463,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); Current += SaclLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1468,7 +1472,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); Current += DaclLength; } - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1479,8 +1483,10 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner); } else + { DPRINT("Owner of %x is zero length\n", Descriptor); - + } + if (GroupLength != 0) { memmove((PVOID)Current, @@ -1488,15 +1494,15 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, GroupLength); Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); } - + /* Unlock subject context */ SeUnlockSubjectContext(SubjectContext); - + *NewDescriptor = Descriptor; - + DPRINT("Descrptor %x\n", Descriptor); ASSERT(RtlLengthSecurityDescriptor(Descriptor)); - + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index de374473139..406003b0af9 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -17,13 +17,15 @@ PSE_EXPORTS SeExports = NULL; SE_EXPORTS SepExports; +ULONG SidInTokenCalls = 0; extern ULONG ExpInitializationPhase; extern ERESOURCE SepSubjectContextLock; /* PRIVATE FUNCTIONS **********************************************************/ -static BOOLEAN INIT_FUNCTION +static BOOLEAN +INIT_FUNCTION SepInitExports(VOID) { SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; @@ -118,6 +120,7 @@ NTAPI SepInitializationPhase1(VOID) { NTSTATUS Status; + PAGED_CODE(); /* Insert the system token into the tree */ @@ -279,8 +282,6 @@ SeDefaultObjectMethod(IN PVOID Object, return STATUS_SUCCESS; } -ULONG SidInTokenCalls = 0; - static BOOLEAN SepSidInToken(PACCESS_TOKEN _Token, PSID Sid) @@ -292,7 +293,7 @@ SepSidInToken(PACCESS_TOKEN _Token, SidInTokenCalls++; if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls); - + if (Token->UserAndGroupCount == 0) { return FALSE; @@ -340,7 +341,8 @@ SepTokenIsOwner(PACCESS_TOKEN Token, return SepSidInToken(Token, Sid); } -VOID NTAPI +VOID +NTAPI SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess) { @@ -351,13 +353,15 @@ SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, { *DesiredAccess |= READ_CONTROL; } + if (SecurityInformation & SACL_SECURITY_INFORMATION) { *DesiredAccess |= ACCESS_SYSTEM_SECURITY; } } -VOID NTAPI +VOID +NTAPI SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess) { @@ -367,10 +371,12 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, { *DesiredAccess |= WRITE_OWNER; } + if (SecurityInformation & DACL_SECURITY_INFORMATION) { *DesiredAccess |= WRITE_DAC; } + if (SecurityInformation & SACL_SECURITY_INFORMATION) { *DesiredAccess |= ACCESS_SYSTEM_SECURITY; @@ -494,7 +500,7 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, { *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; } - + *AccessStatus = STATUS_SUCCESS; return TRUE; } @@ -763,7 +769,8 @@ SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor) /* * @implemented */ -BOOLEAN NTAPI +BOOLEAN +NTAPI SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked, diff --git a/reactos/ntoskrnl/se/sid.c b/reactos/ntoskrnl/se/sid.c index d70a743135a..93b8bde6d16 100644 --- a/reactos/ntoskrnl/se/sid.c +++ b/reactos/ntoskrnl/se/sid.c @@ -99,11 +99,11 @@ SepInitSecurityIDs(VOID) ULONG SidLength1; ULONG SidLength2; PULONG SubAuthority; - + SidLength0 = RtlLengthRequiredSid(0); SidLength1 = RtlLengthRequiredSid(1); SidLength2 = RtlLengthRequiredSid(2); - + /* create NullSid */ SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); @@ -150,9 +150,9 @@ SepInitSecurityIDs(VOID) SeAnonymousLogonSid == NULL) { FreeInitializedSids(); - return(FALSE); + return FALSE; } - + RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1); RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1); RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1); @@ -181,7 +181,7 @@ SepInitSecurityIDs(VOID) RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1); RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1); RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1); - + SubAuthority = RtlSubAuthoritySid(SeNullSid, 0); *SubAuthority = SECURITY_NULL_RID; SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0); @@ -252,8 +252,8 @@ SepInitSecurityIDs(VOID) *SubAuthority = SECURITY_RESTRICTED_CODE_RID; SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0); *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID; - - return(TRUE); + + return TRUE; } NTSTATUS @@ -267,9 +267,9 @@ SepCaptureSid(IN PSID InputSid, ULONG SidSize = 0; PISID NewSid, Sid = (PISID)InputSid; NTSTATUS Status; - + PAGED_CODE(); - + if (AccessMode != KernelMode) { _SEH2_TRY @@ -289,11 +289,11 @@ SepCaptureSid(IN PSID InputSid, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + /* allocate a SID and copy it */ NewSid = ExAllocatePool(PoolType, SidSize); - if(NewSid != NULL) + if (NewSid != NULL) { _SEH2_TRY { @@ -316,7 +316,7 @@ SepCaptureSid(IN PSID InputSid, Status = STATUS_INSUFFICIENT_RESOURCES; } } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { *CapturedSid = InputSid; return STATUS_SUCCESS; @@ -324,16 +324,16 @@ SepCaptureSid(IN PSID InputSid, else { SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); - + /* allocate a SID and copy it */ NewSid = ExAllocatePool(PoolType, SidSize); - if(NewSid != NULL) + if (NewSid != NULL) { RtlCopyMemory(NewSid, Sid, SidSize); - + *CapturedSid = NewSid; } else @@ -341,7 +341,7 @@ SepCaptureSid(IN PSID InputSid, Status = STATUS_INSUFFICIENT_RESOURCES; } } - + return Status; } @@ -352,10 +352,10 @@ SepReleaseSid(IN PSID CapturedSid, IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedSid != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) + + if (CapturedSid != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) { ExFreePool(CapturedSid); } diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 8f73312fde4..7bb2d95bb54 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -25,16 +25,18 @@ ERESOURCE SepTokenLock; TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}}; LUID SeSystemAuthenticationId = SYSTEM_LUID; -static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, +static GENERIC_MAPPING SepTokenMapping = { + TOKEN_READ, TOKEN_WRITE, TOKEN_EXECUTE, -TOKEN_ALL_ACCESS}; + TOKEN_ALL_ACCESS +}; static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = { - + /* Class 0 not used, blame M$! */ ICI_SQ_SAME( 0, 0, 0), - + /* TokenUser */ ICI_SQ_SAME( sizeof(TOKEN_USER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), /* TokenGroups */ @@ -79,11 +81,11 @@ SepCompareTokens(IN PTOKEN FirstToken, OUT PBOOLEAN Equal) { BOOLEAN Restricted, IsEqual = FALSE; - + ASSERT(FirstToken != SecondToken); - + /* FIXME: Check if every SID that is present in either token is also present in the other one */ - + Restricted = SeTokenIsRestricted(FirstToken); if (Restricted == SeTokenIsRestricted(SecondToken)) { @@ -91,10 +93,10 @@ SepCompareTokens(IN PTOKEN FirstToken, { /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */ } - + /* FIXME: Check if every privilege that is present in either token is also present in the other one */ } - + *Equal = IsEqual; return STATUS_SUCCESS; } @@ -108,10 +110,11 @@ SepFreeProxyData(PVOID ProxyData) NTSTATUS NTAPI -SepCopyProxyData(PVOID* Dest, PVOID Src) +SepCopyProxyData(PVOID* Dest, + PVOID Src) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } NTSTATUS @@ -122,24 +125,24 @@ SeExchangePrimaryToken(PEPROCESS Process, { PTOKEN OldToken; PTOKEN NewToken = (PTOKEN)NewTokenP; - + PAGED_CODE(); - + if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE); if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE); - + /* Mark new token in use */ NewToken->TokenInUse = 1; - + /* Reference the New Token */ ObReferenceObject(NewToken); - + /* Replace the old with the new */ OldToken = ObFastReplaceObject(&Process->Token, NewToken); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; - + *OldTokenP = (PACCESS_TOKEN)OldToken; return STATUS_SUCCESS; } @@ -149,10 +152,10 @@ NTAPI SeDeassignPrimaryToken(PEPROCESS Process) { PTOKEN OldToken; - + /* Remove the Token */ OldToken = ObFastReplaceObject(&Process->Token, NULL); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; } @@ -163,14 +166,14 @@ RtlLengthSidAndAttributes(ULONG Count, { ULONG i; ULONG uLength; - + PAGED_CODE(); - + uLength = Count * sizeof(SID_AND_ATTRIBUTES); for (i = 0; i < Count; i++) uLength += RtlLengthSid(Src[i].Sid); - - return(uLength); + + return uLength; } @@ -181,14 +184,14 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token, PSID DefaultOwner) { ULONG i; - + Token->PrimaryGroup = 0; - + if (DefaultOwner) { Token->DefaultOwnerIndex = Token->UserAndGroupCount; } - + /* Validate and set the primary group and user pointers */ for (i = 0; i < Token->UserAndGroupCount; i++) { @@ -197,24 +200,24 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token, { Token->DefaultOwnerIndex = i; } - + if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup)) { Token->PrimaryGroup = Token->UserAndGroups[i].Sid; } } - + if (Token->DefaultOwnerIndex == Token->UserAndGroupCount) { return(STATUS_INVALID_OWNER); } - + if (Token->PrimaryGroup == 0) { return(STATUS_INVALID_PRIMARY_GROUP); } - - return(STATUS_SUCCESS); + + return STATUS_SUCCESS; } @@ -233,9 +236,9 @@ SepDuplicateToken(PTOKEN Token, PVOID EndMem; PTOKEN AccessToken; NTSTATUS Status; - + PAGED_CODE(); - + Status = ObCreateObject(PreviousMode, SepTokenObjectType, ObjectAttributes, @@ -248,7 +251,7 @@ SepDuplicateToken(PTOKEN Token, if (!NT_SUCCESS(Status)) { DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); - return(Status); + return Status; } /* Zero out the buffer */ @@ -258,22 +261,22 @@ SepDuplicateToken(PTOKEN Token, if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); - return(Status); + return Status; } - + Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId); if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); - return(Status); + return Status; } - + AccessToken->TokenLock = &SepTokenLock; - + AccessToken->TokenType = TokenType; AccessToken->ImpersonationLevel = Level; RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId); - + AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart; AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart; memcpy(AccessToken->TokenSource.SourceName, @@ -282,18 +285,18 @@ SepDuplicateToken(PTOKEN Token, AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart; AccessToken->UserAndGroupCount = Token->UserAndGroupCount; AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex; - + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; for (i = 0; i < Token->UserAndGroupCount; i++) uLength += RtlLengthSid(Token->UserAndGroups[i].Sid); - + AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'uKOT'); - + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - + Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount, Token->UserAndGroups, uLength, @@ -308,17 +311,17 @@ SepDuplicateToken(PTOKEN Token, Token->PrimaryGroup, 0); } - + if (NT_SUCCESS(Status)) { AccessToken->PrivilegeCount = Token->PrivilegeCount; - + uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); AccessToken->Privileges = (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'pKOT'); - + for (i = 0; i < AccessToken->PrivilegeCount; i++) { RtlCopyLuid(&AccessToken->Privileges[i].Luid, @@ -326,8 +329,8 @@ SepDuplicateToken(PTOKEN Token, AccessToken->Privileges[i].Attributes = Token->Privileges[i].Attributes; } - - if ( Token->DefaultDacl ) + + if (Token->DefaultDacl) { AccessToken->DefaultDacl = (PACL) ExAllocatePoolWithTag(PagedPool, @@ -338,14 +341,14 @@ SepDuplicateToken(PTOKEN Token, Token->DefaultDacl->AclSize); } } - - if ( NT_SUCCESS(Status) ) + + if (NT_SUCCESS(Status)) { *NewAccessToken = AccessToken; return(STATUS_SUCCESS); } - - return(Status); + + return Status; } NTSTATUS @@ -358,7 +361,7 @@ SeSubProcessToken(IN PTOKEN ParentToken, PTOKEN NewToken; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - + /* Initialize the attributes and duplicate it */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = SepDuplicateToken(ParentToken, @@ -382,12 +385,12 @@ SeSubProcessToken(IN PTOKEN ParentToken, /* Set the session ID */ NewToken->SessionId = SessionId; NewToken->TokenInUse = InUse; - + /* Return the token */ *Token = NewToken; } } - + /* Return status */ return Status; } @@ -399,25 +402,25 @@ SeIsTokenChild(IN PTOKEN Token, { PTOKEN ProcessToken; LUID ProcessLuid, CallerLuid; - + /* Assume failure */ *IsChild = FALSE; - + /* Reference the process token */ ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess()); - + /* Get the ID */ ProcessLuid = ProcessToken->TokenId; - + /* Dereference the token */ ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken); - + /* Get our LUID */ CallerLuid = Token->TokenId; - + /* Compare the LUIDs */ if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE; - + /* Return success */ return STATUS_SUCCESS; } @@ -431,9 +434,9 @@ SeCopyClientToken(IN PACCESS_TOKEN Token, { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; - + PAGED_CODE(); - + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, @@ -446,21 +449,22 @@ SeCopyClientToken(IN PACCESS_TOKEN Token, Level, PreviousMode, (PTOKEN*)NewToken); - - return(Status); + + return Status; } -VOID NTAPI +VOID +NTAPI SepDeleteToken(PVOID ObjectBody) { PTOKEN AccessToken = (PTOKEN)ObjectBody; - + if (AccessToken->UserAndGroups) ExFreePool(AccessToken->UserAndGroups); - + if (AccessToken->Privileges) ExFreePool(AccessToken->Privileges); - + if (AccessToken->DefaultDacl) ExFreePool(AccessToken->DefaultDacl); } @@ -473,12 +477,12 @@ SepInitializeTokenImplementation(VOID) { UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - + ExInitializeResource(&SepTokenLock); - + DPRINT("Creating Token Object Type\n"); - - /* Initialize the Token type */ + + /* Initialize the Token type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Token"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); @@ -499,14 +503,14 @@ SeAssignPrimaryToken(IN PEPROCESS Process, IN PTOKEN Token) { PAGED_CODE(); - + /* Sanity checks */ ASSERT(Token->TokenType == TokenPrimary); ASSERT(!Token->TokenInUse); - + /* Clean any previous token */ if (Process->Token.Object) SeDeassignPrimaryToken(Process); - + /* Set the new token */ ObReferenceObject(Token); Token->TokenInUse = TRUE; @@ -517,25 +521,25 @@ SeAssignPrimaryToken(IN PEPROCESS Process, NTSTATUS NTAPI SepCreateToken(OUT PHANDLE TokenHandle, - IN KPROCESSOR_MODE PreviousMode, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN TOKEN_TYPE TokenType, - IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, - IN PLUID AuthenticationId, - IN PLARGE_INTEGER ExpirationTime, - IN PSID_AND_ATTRIBUTES User, - IN ULONG GroupCount, - IN PSID_AND_ATTRIBUTES Groups, - IN ULONG GroupLength, - IN ULONG PrivilegeCount, - IN PLUID_AND_ATTRIBUTES Privileges, - IN PSID Owner, - IN PSID PrimaryGroup, - IN PACL DefaultDacl, - IN PTOKEN_SOURCE TokenSource, - IN BOOLEAN SystemToken) -{ + IN KPROCESSOR_MODE PreviousMode, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN TOKEN_TYPE TokenType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN PLUID AuthenticationId, + IN PLARGE_INTEGER ExpirationTime, + IN PSID_AND_ATTRIBUTES User, + IN ULONG GroupCount, + IN PSID_AND_ATTRIBUTES Groups, + IN ULONG GroupLength, + IN ULONG PrivilegeCount, + IN PLUID_AND_ATTRIBUTES Privileges, + IN PSID Owner, + IN PSID PrimaryGroup, + IN PACL DefaultDacl, + IN PTOKEN_SOURCE TokenSource, + IN BOOLEAN SystemToken) +{ PTOKEN AccessToken; LUID TokenId; LUID ModifiedId; @@ -544,7 +548,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, ULONG i; NTSTATUS Status; ULONG TokenFlags = 0; - + /* Loop all groups */ for (i = 0; i < GroupCount; i++) { @@ -554,7 +558,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, /* Force them to be enabled */ Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT); } - + /* Check of the group is an admin group */ if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid)) { @@ -562,7 +566,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, TokenFlags |= TOKEN_HAS_ADMIN_GROUP; } } - + /* Loop all privileges */ for (i = 0; i < PrivilegeCount; i++) { @@ -577,12 +581,12 @@ SepCreateToken(OUT PHANDLE TokenHandle, Status = ZwAllocateLocallyUniqueId(&TokenId); if (!NT_SUCCESS(Status)) - return(Status); - + return Status; + Status = ZwAllocateLocallyUniqueId(&ModifiedId); if (!NT_SUCCESS(Status)) - return(Status); - + return Status; + Status = ObCreateObject(PreviousMode, SepTokenObjectType, ObjectAttributes, @@ -595,50 +599,50 @@ SepCreateToken(OUT PHANDLE TokenHandle, if (!NT_SUCCESS(Status)) { DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); + return Status; } /* Zero out the buffer */ RtlZeroMemory(AccessToken, sizeof(TOKEN)); - + AccessToken->TokenLock = &SepTokenLock; - + RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier, &TokenSource->SourceIdentifier); memcpy(AccessToken->TokenSource.SourceName, TokenSource->SourceName, sizeof(TokenSource->SourceName)); - + RtlCopyLuid(&AccessToken->TokenId, &TokenId); RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); AccessToken->ExpirationTime = *ExpirationTime; RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId); - + AccessToken->UserAndGroupCount = GroupCount + 1; AccessToken->PrivilegeCount = PrivilegeCount; - + AccessToken->TokenFlags = TokenFlags; AccessToken->TokenType = TokenType; AccessToken->ImpersonationLevel = ImpersonationLevel; - + /* * Normally we would just point these members into the variable information * area; however, our ObCreateObject() call can't allocate a variable information * area, so we allocate them seperately and provide a destroy function. */ - + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; uLength += RtlLengthSid(User); for (i = 0; i < GroupCount; i++) uLength += RtlLengthSid(Groups[i].Sid); - + AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'uKOT'); - + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - + Status = RtlCopySidAndAttributesArray(1, User, uLength, @@ -656,7 +660,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, &EndMem, &uLength); } - + if (NT_SUCCESS(Status)) { Status = SepFindPrimaryGroupAndDefaultOwner( @@ -664,7 +668,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, PrimaryGroup, Owner); } - + if (NT_SUCCESS(Status)) { uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); @@ -672,7 +676,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'pKOT'); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -694,7 +698,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); } } - + if (NT_SUCCESS(Status)) { AccessToken->DefaultDacl = @@ -705,16 +709,15 @@ SepCreateToken(OUT PHANDLE TokenHandle, DefaultDacl, DefaultDacl->AclSize); } - + if (!SystemToken) { - - Status = ObInsertObject ((PVOID)AccessToken, - NULL, - DesiredAccess, - 0, - NULL, - TokenHandle); + Status = ObInsertObject((PVOID)AccessToken, + NULL, + DesiredAccess, + 0, + NULL, + TokenHandle); if (!NT_SUCCESS(Status)) { DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); @@ -745,24 +748,24 @@ SepCreateSystemProcessToken(VOID) ULONG i; PTOKEN Token; NTSTATUS Status; - + /* Don't ever expire */ Expiration.QuadPart = -1; - + /* All groups mandatory and enabled */ GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT; OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT; - + /* User is system */ UserSid.Sid = SeLocalSystemSid; UserSid.Attributes = 0; - + /* Primary group is local system */ PrimaryGroup = SeLocalSystemSid; - + /* Owner is admins */ Owner = SeAliasAdminsSid; - + /* Groups are admins, world, and authenticated users */ Groups[0].Sid = SeAliasAdminsSid; Groups[0].Attributes = OwnerAttributes; @@ -780,69 +783,69 @@ SepCreateSystemProcessToken(VOID) i = 0; Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeTcbPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeCreateTokenPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeTakeOwnershipPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePagefilePrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeLockMemoryPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePermanentPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeDebugPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeAuditPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSecurityPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeChangeNotifyPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeBackupPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeRestorePrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeShutdownPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeLoadDriverPrivilege; - + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeProfileSingleProcessPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSystemtimePrivilege; ASSERT(i == 20); - + /* Setup the object attributes */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); ASSERT(SeSystemDefaultDacl != NULL); - + /* Create the token */ Status = SepCreateToken((PHANDLE)&Token, KernelMode, @@ -864,13 +867,13 @@ SepCreateSystemProcessToken(VOID) &SeSystemTokenSource, TRUE); ASSERT(Status == STATUS_SUCCESS); - + /* Return the token */ return Token; } /* PUBLIC FUNCTIONS ***********************************************************/ - + /* * @unimplemented */ @@ -915,14 +918,15 @@ SeQuerySessionIdToken(IN PACCESS_TOKEN Token, /* * @implemented */ -NTSTATUS NTAPI +NTSTATUS +NTAPI SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token, OUT PLUID LogonId) { PAGED_CODE(); - + *LogonId = ((PTOKEN)Token)->AuthenticationId; - + return STATUS_SUCCESS; } @@ -935,7 +939,7 @@ NTAPI SeTokenImpersonationLevel(IN PACCESS_TOKEN Token) { PAGED_CODE(); - + return ((PTOKEN)Token)->ImpersonationLevel; } @@ -947,7 +951,7 @@ TOKEN_TYPE NTAPI SeTokenType(IN PACCESS_TOKEN Token) { PAGED_CODE(); - + return ((PTOKEN)Token)->TokenType; } @@ -960,6 +964,7 @@ NTAPI SeTokenIsAdmin(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0; } @@ -971,6 +976,7 @@ NTAPI SeTokenIsRestricted(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0; } @@ -982,6 +988,7 @@ NTAPI SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0; } @@ -1006,11 +1013,11 @@ NtQueryInformationToken(IN HANDLE TokenHandle, ULONG RequiredLength; KPROCESSOR_MODE PreviousMode; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + /* Check buffers and class validity */ Status = DefaultQueryInfoBufferCheck(TokenInformationClass, SeTokenInformationClass, @@ -1020,13 +1027,12 @@ NtQueryInformationToken(IN HANDLE TokenHandle, ReturnLength, NULL, PreviousMode); - - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status); return Status; } - + Status = ObReferenceObjectByHandle(TokenHandle, (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY, SepTokenObjectType, @@ -1040,14 +1046,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle, case TokenUser: { PTOKEN_USER tu = (PTOKEN_USER)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenUser)\n"); RequiredLength = sizeof(TOKEN_USER) + RtlLengthSid(Token->UserAndGroups[0].Sid); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { Status = RtlCopySidAndAttributesArray(1, &Token->UserAndGroups[0], @@ -1061,8 +1067,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1072,27 +1078,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenGroups: { PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenGroups)\n"); RequiredLength = sizeof(tg->GroupCount) + RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)); PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES))); - + tg->GroupCount = Token->UserAndGroupCount - 1; Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1], @@ -1106,8 +1112,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1117,21 +1123,21 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenPrivileges: { PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenPrivileges)\n"); RequiredLength = sizeof(tp->PrivilegeCount) + (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { tp->PrivilegeCount = Token->PrivilegeCount; RtlCopyLuidAndAttributesArray(Token->PrivilegeCount, @@ -1142,8 +1148,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1153,22 +1159,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenOwner: { ULONG SidLen; PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenOwner)\n"); SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); RequiredLength = sizeof(TOKEN_OWNER) + SidLen; - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { to->Owner = (PSID)(to + 1); Status = RtlCopySid(SidLen, @@ -1179,8 +1185,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1190,22 +1196,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenPrimaryGroup: { ULONG SidLen; PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n"); SidLen = RtlLengthSid(Token->PrimaryGroup); RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen; - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { tpg->PrimaryGroup = (PSID)(tpg + 1); Status = RtlCopySid(SidLen, @@ -1216,8 +1222,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1227,27 +1233,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenDefaultDacl: { PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n"); RequiredLength = sizeof(TOKEN_DEFAULT_DACL); - - if(Token->DefaultDacl != NULL) + + if (Token->DefaultDacl != NULL) { RequiredLength += Token->DefaultDacl->AclSize; } - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { - if(Token->DefaultDacl != NULL) + if (Token->DefaultDacl != NULL) { tdd->DefaultDacl = (PACL)(tdd + 1); RtlCopyMemory(tdd->DefaultDacl, @@ -1263,8 +1269,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1274,20 +1280,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenSource: { PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenSource)\n"); RequiredLength = sizeof(TOKEN_SOURCE); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *ts = Token->TokenSource; } @@ -1295,8 +1301,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1306,20 +1312,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenType: { PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenType)\n"); RequiredLength = sizeof(TOKEN_TYPE); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *tt = Token->TokenType; } @@ -1327,8 +1333,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1338,14 +1344,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenImpersonationLevel: { PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n"); /* Fail if the token is not an impersonation token */ @@ -1356,10 +1362,10 @@ NtQueryInformationToken(IN HANDLE TokenHandle, } RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *sil = Token->ImpersonationLevel; } @@ -1367,8 +1373,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1378,20 +1384,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenStatistics: { PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenStatistics)\n"); RequiredLength = sizeof(TOKEN_STATISTICS); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ts->TokenId = Token->TokenId; ts->AuthenticationId = Token->AuthenticationId; @@ -1408,8 +1414,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1419,20 +1425,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenOrigin: { PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenOrigin)\n"); RequiredLength = sizeof(TOKEN_ORIGIN); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { RtlCopyLuid(&to->OriginatingLogonSession, &Token->AuthenticationId); @@ -1441,8 +1447,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1452,32 +1458,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenGroupsAndPrivileges: DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; - + case TokenRestrictedSids: { PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n"); RequiredLength = sizeof(tg->GroupCount) + RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)); PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES))); - + tg->GroupCount = Token->RestrictedSidCount; Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount, Token->RestrictedSids, @@ -1491,8 +1497,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1502,32 +1508,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenSandBoxInert: DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; - + case TokenSessionId: { ULONG SessionId = 0; - + DPRINT("NtQueryInformationToken(TokenSessionId)\n"); - + Status = SeQuerySessionIdToken(Token, &SessionId); - - if(NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { _SEH2_TRY { /* buffer size was already verified, no need to check here again */ *(PULONG)TokenInformation = SessionId; - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = sizeof(ULONG); } @@ -1538,20 +1544,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, } _SEH2_END; } - + break; } - + default: DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass); Status = STATUS_INVALID_INFO_CLASS; break; } - + ObDereferenceObject(Token); } - - return(Status); + + return Status; } @@ -1571,30 +1577,29 @@ NtSetInformationToken(IN HANDLE TokenHandle, KPROCESSOR_MODE PreviousMode; ULONG NeededAccess = TOKEN_ADJUST_DEFAULT; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + Status = DefaultSetInfoBufferCheck(TokenInformationClass, SeTokenInformationClass, sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), TokenInformation, TokenInformationLength, PreviousMode); - - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { /* Invalid buffers */ DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status); return Status; } - - if(TokenInformationClass == TokenSessionId) + + if (TokenInformationClass == TokenSessionId) { NeededAccess |= TOKEN_ADJUST_SESSIONID; } - + Status = ObReferenceObjectByHandle(TokenHandle, NeededAccess, SepTokenObjectType, @@ -1607,11 +1612,11 @@ NtSetInformationToken(IN HANDLE TokenHandle, { case TokenOwner: { - if(TokenInformationLength >= sizeof(TOKEN_OWNER)) + if (TokenInformationLength >= sizeof(TOKEN_OWNER)) { PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; PSID InputSid = NULL, CapturedSid; - + _SEH2_TRY { InputSid = to->Owner; @@ -1621,13 +1626,13 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + Status = SepCaptureSid(InputSid, PreviousMode, PagedPool, FALSE, &CapturedSid); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { RtlCopySid(RtlLengthSid(CapturedSid), Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, @@ -1643,14 +1648,14 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenPrimaryGroup: { - if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) + if (TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) { PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; PSID InputSid = NULL, CapturedSid; - + _SEH2_TRY { InputSid = tpg->PrimaryGroup; @@ -1660,13 +1665,13 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + Status = SepCaptureSid(InputSid, PreviousMode, PagedPool, FALSE, &CapturedSid); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { RtlCopySid(RtlLengthSid(CapturedSid), Token->PrimaryGroup, @@ -1682,14 +1687,14 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenDefaultDacl: { - if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) + if (TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) { PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; PACL InputAcl = NULL; - + _SEH2_TRY { InputAcl = tdd->DefaultDacl; @@ -1700,7 +1705,7 @@ NtSetInformationToken(IN HANDLE TokenHandle, } _SEH2_END; - if(InputAcl != NULL) + if (InputAcl != NULL) { PACL CapturedAcl; @@ -1710,7 +1715,7 @@ NtSetInformationToken(IN HANDLE TokenHandle, PagedPool, TRUE, &CapturedAcl); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* free the previous dacl if present */ if(Token->DefaultDacl != NULL) @@ -1725,7 +1730,7 @@ NtSetInformationToken(IN HANDLE TokenHandle, else { /* clear and free the default dacl if present */ - if(Token->DefaultDacl != NULL) + if (Token->DefaultDacl != NULL) { ExFreePool(Token->DefaultDacl); Token->DefaultDacl = NULL; @@ -1738,11 +1743,11 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenSessionId: { ULONG SessionId = 0; - + _SEH2_TRY { /* buffer size was already verified, no need to check here again */ @@ -1753,9 +1758,9 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, - PreviousMode)) + + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, + PreviousMode)) { Status = STATUS_PRIVILEGE_NOT_HELD; break; @@ -1764,18 +1769,18 @@ NtSetInformationToken(IN HANDLE TokenHandle, Token->SessionId = SessionId; break; } - + default: { Status = STATUS_NOT_IMPLEMENTED; break; } } - + ObDereferenceObject(Token); } - - return(Status); + + return Status; } @@ -1802,11 +1807,11 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService; BOOLEAN QoSPresent; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = KeGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -1820,19 +1825,19 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, } _SEH2_END; } - + Status = SepCaptureSecurityQualityOfService(ObjectAttributes, PreviousMode, PagedPool, FALSE, &CapturedSecurityQualityOfService, &QoSPresent); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status); return Status; } - + Status = ObReferenceObjectByHandle(ExistingTokenHandle, TOKEN_DUPLICATE, SepTokenObjectType, @@ -1848,9 +1853,9 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), PreviousMode, &NewToken); - + ObDereferenceObject(Token); - + if (NT_SUCCESS(Status)) { Status = ObInsertObject((PVOID)NewToken, @@ -1859,7 +1864,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, 0, NULL, &hToken); - + if (NT_SUCCESS(Status)) { _SEH2_TRY @@ -1874,12 +1879,12 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, } } } - + /* free the captured structure */ SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, PreviousMode, FALSE); - + return Status; } @@ -1899,12 +1904,12 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle, * @implemented */ NTSTATUS NTAPI -NtAdjustPrivilegesToken (IN HANDLE TokenHandle, - IN BOOLEAN DisableAllPrivileges, - IN PTOKEN_PRIVILEGES NewState, - IN ULONG BufferLength, - OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, - OUT PULONG ReturnLength OPTIONAL) +NtAdjustPrivilegesToken(IN HANDLE TokenHandle, + IN BOOLEAN DisableAllPrivileges, + IN PTOKEN_PRIVILEGES NewState, + IN ULONG BufferLength, + OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, + OUT PULONG ReturnLength OPTIONAL) { // PLUID_AND_ATTRIBUTES Privileges; KPROCESSOR_MODE PreviousMode; @@ -1921,11 +1926,11 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, ULONG c; #endif NTSTATUS Status; - + PAGED_CODE(); - + DPRINT ("NtAdjustPrivilegesToken() called\n"); - + // PrivilegeCount = NewState->PrivilegeCount; PreviousMode = KeGetPreviousMode (); // SeCaptureLuidAndAttributesArray(NewState->Privileges, @@ -1937,7 +1942,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, // 1, // &Privileges, // &Length); - + Status = ObReferenceObjectByHandle (TokenHandle, TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0), SepTokenObjectType, @@ -1952,8 +1957,8 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, // 0); return Status; } - - + + #if 0 SepAdjustPrivileges(Token, 0, @@ -1965,13 +1970,13 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, &b, &c); #endif - + PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) / sizeof(LUID_AND_ATTRIBUTES); - + if (PreviousState != NULL) PreviousState->PrivilegeCount = 0; - + k = 0; if (DisableAllPrivileges == TRUE) { @@ -1980,7 +1985,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, if (Token->Privileges[i].Attributes != 0) { DPRINT ("Attributes differ\n"); - + /* Save current privilege */ if (PreviousState != NULL) { @@ -1997,13 +2002,15 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, * accordingly and fail. */ } + k++; } - + /* Update current privlege */ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; } } + Status = STATUS_SUCCESS; } else @@ -2017,7 +2024,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart) { DPRINT ("Found privilege\n"); - + if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) != (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED)) { @@ -2025,7 +2032,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, DPRINT ("Current attributes %lx desired attributes %lx\n", Token->Privileges[i].Attributes, NewState->Privileges[j].Attributes); - + /* Save current privilege */ if (PreviousState != NULL) { @@ -2042,9 +2049,10 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, * accordingly and fail. */ } + k++; } - + /* Update current privlege */ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; Token->Privileges[i].Attributes |= @@ -2052,27 +2060,29 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, DPRINT ("New attributes %lx\n", Token->Privileges[i].Attributes); } + Count++; } } } + Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS; } - + if (ReturnLength != NULL) { *ReturnLength = sizeof(TOKEN_PRIVILEGES) + (sizeof(LUID_AND_ATTRIBUTES) * (k - 1)); } - + ObDereferenceObject (Token); - + // SeReleaseLuidAndAttributesArray(Privileges, // PreviousMode, // 0); - + DPRINT ("NtAdjustPrivilegesToken() done\n"); - + return Status; } @@ -2097,12 +2107,12 @@ NtCreateToken(OUT PHANDLE TokenHandle, ULONG nTokenPrivileges = 0; LARGE_INTEGER LocalExpirationTime = {{0, 0}}; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) + + if (PreviousMode != KernelMode) { _SEH2_TRY { @@ -2146,7 +2156,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, nTokenPrivileges = TokenPrivileges->PrivilegeCount; LocalExpirationTime = *ExpirationTime; } - + Status = SepCreateToken(&hToken, PreviousMode, DesiredAccess, @@ -2178,7 +2188,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, } _SEH2_END; } - + return Status; } @@ -2204,11 +2214,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, PACL Dacl = NULL; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -2222,12 +2232,12 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, } _SEH2_END; } - + /* * At first open the thread token for information access and verify * that the token associated with thread is valid. */ - + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, PsThreadType, PreviousMode, (PVOID*)&Thread, NULL); @@ -2235,7 +2245,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, { return Status; } - + Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly, &ImpersonationLevel); if (Token == NULL) @@ -2243,23 +2253,23 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, ObDereferenceObject(Thread); return STATUS_NO_TOKEN; } - + if (ImpersonationLevel == SecurityAnonymous) { PsDereferenceImpersonationToken(Token); ObDereferenceObject(Thread); return STATUS_CANT_OPEN_ANONYMOUS; } - + /* * Revert to self if OpenAsSelf is specified. */ - + if (OpenAsSelf) { PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState); } - + if (CopyOnOpen) { Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, @@ -2268,11 +2278,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, if (NT_SUCCESS(Status)) { PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess); - + Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken); - + if (NT_SUCCESS(Status)) { if (Dacl) @@ -2282,10 +2292,10 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE); } - + InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, NULL, Dacl ? &SecurityDescriptor : NULL); - + Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, TokenImpersonation, ImpersonationLevel, @@ -2305,26 +2315,26 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, NULL, DesiredAccess, SepTokenObjectType, PreviousMode, &hToken); } - + if (Dacl) ExFreePool(Dacl); - + if (OpenAsSelf) { PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); } - + ObDereferenceObject(Token); - + if (NT_SUCCESS(Status) && CopyOnOpen) { PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel); } - + if (NewToken) ObDereferenceObject(NewToken); if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { _SEH2_TRY { @@ -2336,7 +2346,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, } _SEH2_END; } - + return Status; } @@ -2368,11 +2378,11 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, PTOKEN FirstToken, SecondToken; BOOLEAN IsEqual; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -2386,7 +2396,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } _SEH2_END; } - + Status = ObReferenceObjectByHandle(FirstTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2395,7 +2405,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, NULL); if (!NT_SUCCESS(Status)) return Status; - + Status = ObReferenceObjectByHandle(SecondTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2407,7 +2417,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, ObDereferenceObject(FirstToken); return Status; } - + if (FirstToken != SecondToken) { Status = SepCompareTokens(FirstToken, @@ -2416,10 +2426,10 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } else IsEqual = TRUE; - + ObDereferenceObject(FirstToken); ObDereferenceObject(SecondToken); - + if (NT_SUCCESS(Status)) { _SEH2_TRY @@ -2432,7 +2442,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } _SEH2_END; } - + return Status; } From f9cd9b9a5beee7bcabb7c3f8f40c83817a13ce9c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 28 May 2010 19:36:57 +0000 Subject: [PATCH 064/292] [NTOSKRNL] - Implement SeAppendPrivileges(). svn path=/trunk/; revision=47384 --- reactos/ntoskrnl/se/priv.c | 69 +++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/se/priv.c b/reactos/ntoskrnl/se/priv.c index 7cdbd613d1d..603194259e0 100644 --- a/reactos/ntoskrnl/se/priv.c +++ b/reactos/ntoskrnl/se/priv.c @@ -281,15 +281,74 @@ SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege, /* PUBLIC FUNCTIONS ***********************************************************/ /* - * @unimplemented + * @implemented */ NTSTATUS NTAPI -SeAppendPrivileges(PACCESS_STATE AccessState, - PPRIVILEGE_SET Privileges) +SeAppendPrivileges(IN OUT PACCESS_STATE AccessState, + IN PPRIVILEGE_SET Privileges) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PAUX_ACCESS_DATA AuxData; + ULONG OldPrivilegeSetSize; + ULONG NewPrivilegeSetSize; + PPRIVILEGE_SET PrivilegeSet; + + PAGED_CODE(); + + /* Get the Auxiliary Data */ + AuxData = AccessState->AuxData; + + /* Calculate the size of the old privilege set */ + OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) + + (AuxData->PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES); + + if (AuxData->PrivilegeSet->PrivilegeCount + + Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT) + { + /* Calculate the size of the new privilege set */ + NewPrivilegeSetSize = OldPrivilegeSetSize + + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + + /* Allocate a new privilege set */ + PrivilegeSet = ExAllocatePool(PagedPool, NewPrivilegeSetSize); + if (PrivilegeSet == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + /* Copy original privileges from the acess state */ + RtlCopyMemory(PrivilegeSet, + AuxData->PrivilegeSet, + OldPrivilegeSetSize); + + /* Append privileges from the privilege set*/ + RtlCopyMemory((PVOID)((ULONG_PTR)PrivilegeSet + OldPrivilegeSetSize), + (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)), + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + + /* Adjust the number of privileges in the new privilege set */ + PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount; + + /* Free the old privilege set if it was allocated */ + if (AccessState->PrivilegesAllocated == TRUE) + ExFreePool(AuxData->PrivilegeSet); + + /* Now we are using an allocated privilege set */ + AccessState->PrivilegesAllocated = TRUE; + + /* Assign the new privileges to the access state */ + AuxData->PrivilegeSet = PrivilegeSet; + } + else + { + /* Append privileges */ + RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet + OldPrivilegeSetSize), + (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)), + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + + /* Adjust the number of privileges in the target privilege set */ + AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount; + } + + return STATUS_SUCCESS; } /* From 18c065e00d7b592e0ae82671244d43fa96624c52 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Fri, 28 May 2010 20:35:30 +0000 Subject: [PATCH 065/292] [win32k] - Remove use of TMRF_DELETEPENDING for deleting timers as this was a bad idea. Timers need to be deleted immediately as waiting for them to be deleted resulted in some processes running out of handles. Fixes richedit winetest for editor. - Add flag TMRF_TIFROMWND for timers created from user mode so the thread stored in the timer object is from the window and not caller. Fixes an issue where FireFox would not show any of its windows and looked dead. - When creating and deleting timers, If the window is non null and IDEvent is 0 then the IDEvent is changed to 1. - When modifying timer list use UserEnter and Leave instead of a Critical Region only. svn path=/trunk/; revision=47385 --- .../subsystems/win32/win32k/include/timer.h | 1 - .../subsystems/win32/win32k/ntuser/timer.c | 79 ++++++++----------- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index 8e5bce67c15..9b2b07f8c9d 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -23,7 +23,6 @@ typedef struct _TIMER #define TMRF_ONESHOT 0x0010 #define TMRF_WAITING 0x0020 #define TMRF_TIFROMWND 0x0040 -#define TMRF_DELETEPENDING 0x8000 extern PKTIMER MasterTimer; diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index e178241f1ea..3539b0aa6a8 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -69,7 +69,8 @@ RemoveTimer(PTIMER pTmr) if (pTmr) { /* Set the flag, it will be removed when ready */ - pTmr->flags |= TMRF_DELETEPENDING; + RemoveEntryList(&pTmr->ptmrList); + UserDeleteObject( UserHMGetHandle(pTmr), otTimer); return TRUE; } return FALSE; @@ -215,21 +216,25 @@ IntSetTimer( PWINDOW_OBJECT Window, Ret = IDEvent; } + if ((Window) && (IDEvent == 0)) + IDEvent = 1; + pTmr = FindTimer(Window, IDEvent, Type, FALSE); - if ((!pTmr) || (pTmr->flags & TMRF_DELETEPENDING)) + if (!pTmr) { pTmr = CreateTimer(); if (!pTmr) return 0; - if (Window && (Type & TMRF_TIFROMWND)) - pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread; - else - { - if (Type & TMRF_RIT) - pTmr->pti = ptiRawInput; - else - pTmr->pti = PsGetCurrentThreadWin32Thread(); + if (Window && (Type & TMRF_TIFROMWND)) + pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread; + else + { + if (Type & TMRF_RIT) + pTmr->pti = ptiRawInput; + else + pTmr->pti = PsGetCurrentThreadWin32Thread(); } + pTmr->pWnd = Window; pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; @@ -237,9 +242,11 @@ IntSetTimer( PWINDOW_OBJECT Window, pTmr->nID = IDEvent; pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode. } - - pTmr->cmsCountdown = Elapse; - pTmr->cmsRate = Elapse; + else + { + pTmr->cmsCountdown = Elapse; + pTmr->cmsRate = Elapse; + } ASSERT(MasterTimer != NULL); // Start the timer thread! @@ -302,7 +309,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; - KeEnterCriticalRegion(); + UserEnterExclusive(); do { @@ -325,7 +332,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + UserLeave(); return Hit; } @@ -389,25 +396,7 @@ ProcessTimers(VOID) } } } - if (pTmr->flags & TMRF_DELETEPENDING) - { - DPRINT("Removing Timer %x from List\n", pTmr); - - /* FIXME: Fix this!!!! */ -/* - if (!pTmr->pWnd) - { - DPRINT1("Clearing Bits for WindowLess Timer\n"); - IntLockWindowlessTimerBitmap(); - RtlSetBits(&WindowLessTimersBitMap, pTmr->nID, 1); - IntUnlockWindowlessTimerBitmap(); - } -*/ - RemoveEntryList(&pTmr->ptmrList); - UserDeleteObject( UserHMGetHandle(pTmr), otTimer); - } - else - pTmr->cmsCountdown = pTmr->cmsRate; + pTmr->cmsCountdown = pTmr->cmsRate; } else pTmr->cmsCountdown -= Time - TimeLast; @@ -533,21 +522,21 @@ DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) if ((FirstpTmr == NULL) || (Window == NULL)) return FALSE; - KeEnterCriticalRegion(); + UserEnterExclusive(); do { if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) { - pTmr->flags &= ~TMRF_READY; - pTmr->flags |= TMRF_DELETEPENDING; + RemoveEntryList(&pTmr->ptmrList); + UserDeleteObject( UserHMGetHandle(pTmr), otTimer); TimersRemoved = TRUE; } pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + UserLeave(); return TimersRemoved; } @@ -562,21 +551,21 @@ DestroyTimersForThread(PTHREADINFO pti) if (FirstpTmr == NULL) return FALSE; - KeEnterCriticalRegion(); + UserEnterExclusive(); do { if ((pTmr) && (pTmr->pti == pti)) { - pTmr->flags &= ~TMRF_READY; - pTmr->flags |= TMRF_DELETEPENDING; + RemoveEntryList(&pTmr->ptmrList); + UserDeleteObject( UserHMGetHandle(pTmr), otTimer); TimersRemoved = TRUE; } pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + UserLeave(); return TimersRemoved; } @@ -588,8 +577,8 @@ IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) DPRINT("IntKillTimer Window %x id %p systemtimer %s\n", Window, IDEvent, SystemTimer ? "TRUE" : "FALSE"); - if (IDEvent == 0) - return FALSE; + if ((Window) && (IDEvent == 0)) + IDEvent = 1; pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE); return pTmr ? TRUE : FALSE; @@ -692,7 +681,7 @@ NtUserSetTimer DPRINT("Enter NtUserSetTimer\n"); UserEnterExclusive(); - RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, 0)); + RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_TIFROMWND)); CLEANUP: DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_); From 799b6ad5b84fc6ed9e0650870bf737c423f478a9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 22:54:27 +0000 Subject: [PATCH 066/292] [FREELOADER] - Fix DoOptionsMenu and implement AppendBootOptions to support F8 boot options - Fixes bug 5363 svn path=/trunk/; revision=47387 --- .../boot/freeldr/freeldr/include/options.h | 1 + reactos/boot/freeldr/freeldr/options.c | 46 +++++++++++++++++++ .../boot/freeldr/freeldr/reactos/reactos.c | 5 ++ reactos/boot/freeldr/freeldr/windows/winldr.c | 3 ++ 4 files changed, 55 insertions(+) diff --git a/reactos/boot/freeldr/freeldr/include/options.h b/reactos/boot/freeldr/freeldr/include/options.h index 124b64e2326..b00d9f58daf 100644 --- a/reactos/boot/freeldr/freeldr/include/options.h +++ b/reactos/boot/freeldr/freeldr/include/options.h @@ -20,3 +20,4 @@ #pragma once VOID DoOptionsMenu(VOID); +VOID AppendBootTimeOptions(PCHAR BootOptions); diff --git a/reactos/boot/freeldr/freeldr/options.c b/reactos/boot/freeldr/freeldr/options.c index 4dabc89c6f4..5b64b46a077 100644 --- a/reactos/boot/freeldr/freeldr/options.c +++ b/reactos/boot/freeldr/freeldr/options.c @@ -69,6 +69,15 @@ enum OptionMenuItems ULONG OptionsMenuItemCount = sizeof(OptionsMenuList) / sizeof(OptionsMenuList[0]); +BOOLEAN SafeMode = FALSE; +BOOLEAN SafeModeWithNetworking = FALSE; +BOOLEAN SafeModeWithCommandPrompt = FALSE; +BOOLEAN BootLogging = FALSE; +BOOLEAN VgaMode = FALSE; +BOOLEAN LastKnownGoodConfiguration = FALSE; +BOOLEAN DirectoryServicesRepairMode = FALSE; +BOOLEAN DebuggingMode = FALSE; + VOID DoOptionsMenu(VOID) { ULONG SelectedMenuItem; @@ -85,22 +94,33 @@ VOID DoOptionsMenu(VOID) switch (SelectedMenuItem) { case SAFE_MODE: + SafeMode = TRUE; + BootLogging = TRUE; break; case SAFE_MODE_WITH_NETWORKING: + SafeModeWithNetworking = TRUE; + BootLogging = TRUE; break; case SAFE_MODE_WITH_COMMAND_PROMPT: + SafeModeWithCommandPrompt = TRUE; + BootLogging = TRUE; break; //case SEPARATOR1: // break; case ENABLE_BOOT_LOGGING: + BootLogging = TRUE; break; case ENABLE_VGA_MODE: + VgaMode = TRUE; break; case LAST_KNOWN_GOOD_CONFIGURATION: + LastKnownGoodConfiguration = TRUE; break; case DIRECTORY_SERVICES_RESTORE_MODE: + DirectoryServicesRepairMode = TRUE; break; case DEBUGGING_MODE: + DebuggingMode = TRUE; break; //case SEPARATOR2: // break; @@ -117,3 +137,29 @@ VOID DoOptionsMenu(VOID) } } +VOID AppendBootTimeOptions(PCHAR BootOptions) +{ + if (SafeMode) + strcat(BootOptions, " /SAFEBOOT:MINIMAL /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (SafeModeWithNetworking) + strcat(BootOptions, " /SAFEBOOT:NETWORK /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (SafeModeWithCommandPrompt) + strcat(BootOptions, " /SAFEBOOT:MINIMAL(ALTERNATESHELL) /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (BootLogging) + strcat(BootOptions, " /BOOTLOG"); + + if (VgaMode) + strcat(BootOptions, " /BASEVIDEO"); + + if (LastKnownGoodConfiguration) + DbgPrint("Last known good configuration is not supported yet!\n"); + + if (DirectoryServicesRepairMode) + strcat(BootOptions, " /SAFEBOOT:DSREPAIR /SOS"); + + if (DebuggingMode) + strcat(BootOptions, " /DEBUG"); +} diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 81b654b84b9..22f3771b28b 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -606,6 +606,11 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) // if (IniReadSettingByName(SectionId, "Options", value, sizeof(value))) { + // + // Append boot-time options + // + AppendBootTimeOptions(value); + // // Check if a ramdisk file was given // diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index d130472ebae..c068517dd2b 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -475,6 +475,9 @@ LoadAndBootWindows(PCSTR OperatingSystemName, DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions); } + /* Append boot-time options */ + AppendBootTimeOptions(BootOptions); + // // Check if a ramdisk file was given // From 6b6a3291e820e5467da5bee1404a65faacbf648a Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 28 May 2010 23:03:27 +0000 Subject: [PATCH 067/292] [NTOS]: Re-implement IoGetDeviceProperty. Main changes are usage of existing (and new) helper functions for registry/IRP access, much better factored code, correct implementation of DevicePropertyPhysicalDeviceObjectName, fixed implementation of DevicePropertyBootConfigurationTranslated and DevicePropertyBootConfiguration (do not crash the system anymore), and support for more device properties. [NTOS]: Fix caller of IoGetDeviceProperty in pnpres.c to work with new function behavior (which matches WDK documentation and test cases). [NTOS]: Implement helper function PnpBusTypeGuidGet, should be used later in other PnP code, but now used only for this patch. [NTOS]: Implement helper function PnpDetermineResourceListSize, ditto. N.B. Current IopCalculateResourceListSize function is broken and callers should use this one instead. [NTOS]: Implement helper function PpIrpQueryCapabilities, should be used later in device node code, but now only used for this patch. [NTOS]: Implement helper function PnpDeviceObjectToDeviceInstance, ditto. Main purpose of this patch is to unblock the new PCIx driver. svn path=/trunk/; revision=47388 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 669 +++++++++++++++++----------- reactos/ntoskrnl/io/pnpmgr/pnpres.c | 34 +- 2 files changed, 438 insertions(+), 265 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 645b837de81..b745b3d156f 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -3003,6 +3003,241 @@ PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject) /* PUBLIC FUNCTIONS **********************************************************/ +NTSTATUS +NTAPI +PnpBusTypeGuidGet(IN USHORT Index, + IN LPGUID BusTypeGuid) +{ + NTSTATUS Status = STATUS_SUCCESS; + + /* Acquire the lock */ + ExAcquireFastMutex(&PnpBusTypeGuidList->Lock); + + /* Validate size */ + if (Index < PnpBusTypeGuidList->GuidCount) + { + /* Copy the data */ + RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID)); + } + else + { + /* Failure path */ + Status = STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* Release lock and return status */ + ExReleaseFastMutex(&PnpBusTypeGuidList->Lock); + return Index; +} + +NTSTATUS +NTAPI +PpIrpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, + OUT PDEVICE_CAPABILITIES DeviceCaps) +{ + PAGED_CODE(); + PVOID Dummy; + IO_STACK_LOCATION Stack; + + /* Set up the Header */ + RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES)); + DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES); + DeviceCaps->Version = 1; + DeviceCaps->Address = -1; + DeviceCaps->UINumber = -1; + + /* Set up the Stack */ + RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION)); + Stack.MajorFunction = IRP_MJ_PNP; + Stack.MinorFunction = IRP_MN_QUERY_CAPABILITIES; + Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps; + + /* Send the IRP */ + return IopSynchronousCall(DeviceObject, &Stack, &Dummy); +} + +NTSTATUS +NTAPI +PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject, + IN PHANDLE DeviceInstanceHandle, + IN ACCESS_MASK DesiredAccess) +{ + NTSTATUS Status; + HANDLE KeyHandle; + PDEVICE_NODE DeviceNode; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM"); + PAGED_CODE(); + + /* Open the enum key */ + Status = IopOpenRegistryKeyEx(&KeyHandle, + NULL, + &KeyName, + KEY_READ); + if (!NT_SUCCESS(Status)) return Status; + + /* Make sure we have an instance path */ + DeviceNode = IopGetDeviceNode(DeviceObject); + if ((DeviceNode) && (DeviceNode->InstancePath.Length)) + { + /* Get the instance key */ + Status = IopOpenRegistryKeyEx(DeviceInstanceHandle, + KeyHandle, + &DeviceNode->InstancePath, + DesiredAccess); + } + else + { + /* Fail */ + Status = STATUS_INVALID_DEVICE_REQUEST; + } + + /* Close the handle and return status */ + ZwClose(KeyHandle); + return Status; +} + +ULONG +NTAPI +PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList) +{ + ULONG FinalSize, PartialSize, EntrySize, i, j; + PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; + + /* If we don't have one, that's easy */ + if (!ResourceList) return 0; + + /* Start with the minimum size possible */ + FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); + + /* Loop each full descriptor */ + FullDescriptor = ResourceList->List; + for (i = 0; i < ResourceList->Count; i++) + { + /* Start with the minimum size possible */ + PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) + + FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors); + + /* Loop each partial descriptor */ + PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors; + for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++) + { + /* Start with the minimum size possible */ + EntrySize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + + /* Check if there is extra data */ + if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) + { + /* Add that data */ + EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize; + } + + /* The size of partial descriptors is bigger */ + PartialSize += EntrySize; + + /* Go to the next partial descriptor */ + PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize); + } + + /* The size of full descriptors is bigger */ + FinalSize += PartialSize; + + /* Go to the next full descriptor */ + FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize); + } + + /* Return the final size */ + return FinalSize; +} + +NTSTATUS +NTAPI +PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject, + IN ULONG ValueType, + IN PWSTR ValueName, + IN PWSTR KeyName, + OUT PVOID Buffer, + IN PULONG BufferLength) +{ + NTSTATUS Status; + HANDLE KeyHandle, SubHandle; + UNICODE_STRING KeyString; + PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL; + ULONG Length; + PAGED_CODE(); + + /* Find the instance key */ + Status = PnpDeviceObjectToDeviceInstance(DeviceObject, &KeyHandle, KEY_READ); + if (NT_SUCCESS(Status)) + { + /* Check for name given by caller */ + if (KeyName) + { + /* Open this key */ + RtlInitUnicodeString(&KeyString, KeyName); + Status = IopOpenRegistryKeyEx(&SubHandle, + KeyHandle, + &KeyString, + KEY_READ); + if (NT_SUCCESS(Status)) + { + /* And use this handle instead */ + ZwClose(KeyHandle); + KeyHandle = SubHandle; + } + } + + /* Check if sub-key handle succeeded (or no-op if no key name given) */ + if (NT_SUCCESS(Status)) + { + /* Now get the size of the property */ + Status = IopGetRegistryValue(KeyHandle, + ValueName, + &KeyValueInfo); + } + + /* Close the key */ + ZwClose(KeyHandle); + } + + /* Fail if any of the registry operations failed */ + if (!NT_SUCCESS(Status)) return Status; + + /* Check how much data we have to copy */ + Length = KeyValueInfo->DataLength; + if (*BufferLength >= Length) + { + /* Check for a match in the value type */ + if (KeyValueInfo->Type == ValueType) + { + /* Copy the data */ + RtlCopyMemory(Buffer, + (PVOID)((ULONG_PTR)KeyValueInfo + + KeyValueInfo->DataOffset), + Length); + } + else + { + /* Invalid registry property type, fail */ + Status = STATUS_INVALID_PARAMETER_2; + } + } + else + { + /* Buffer is too small to hold data */ + Status = STATUS_BUFFER_TOO_SMALL; + } + + /* Return the required buffer length, free the buffer, and return status */ + *BufferLength = Length; + ExFreePool(KeyValueInfo); + return Status; +} + +#define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; break;} +#define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;} +#define PIP_UNIMPLEMENTED() {UNIMPLEMENTED; while(TRUE); break;} + /* * @implemented */ @@ -3016,281 +3251,205 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, { PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); DEVICE_CAPABILITIES DeviceCaps; - ULONG Length; + ULONG ReturnLength = 0, Length = 0, ValueType; + PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName; PVOID Data = NULL; - PWSTR Ptr; - NTSTATUS Status; + NTSTATUS Status = STATUS_BUFFER_TOO_SMALL; + GUID BusTypeGuid; POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; - ULONG RequiredLength, ObjectNameInfoLength; - DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty); + /* Assume failure */ *ResultLength = 0; - if (DeviceNode == NULL) - return STATUS_INVALID_DEVICE_REQUEST; + /* Only PDOs can call this */ + if (!DeviceNode) return STATUS_INVALID_DEVICE_REQUEST; + /* Handle all properties */ switch (DeviceProperty) { - case DevicePropertyBusNumber: - Length = sizeof(ULONG); - Data = &DeviceNode->ChildBusNumber; - break; + case DevicePropertyBusTypeGuid: - /* Complete, untested */ - case DevicePropertyBusTypeGuid: - /* Sanity check */ - if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) && - (DeviceNode->ChildBusTypeIndex < PnpBusTypeGuidList->GuidCount)) - { - /* Return the GUID */ - *ResultLength = sizeof(GUID); + /* Get the GUID from the internal cache */ + Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid); + if (!NT_SUCCESS(Status)) return Status; - /* Check if the buffer given was large enough */ - if (BufferLength < *ResultLength) + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid); + + case DevicePropertyLegacyBusType: + + /* Validate correct interface type */ + if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType); + + case DevicePropertyBusNumber: + + /* Validate correct bus number */ + if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber); + + case DevicePropertyEnumeratorName: + + /* Get the instance path */ + DeviceInstanceName = DeviceNode->InstancePath.Buffer; + + /* Sanity checks */ + ASSERT((BufferLength & 1) == 0); + ASSERT(DeviceInstanceName != NULL); + + /* Get the name from the path */ + EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR); + ASSERT(EnumeratorNameEnd); + + /* This is the format of the returned data */ + PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * 2, + &DeviceNode->ChildBusNumber); + + case DevicePropertyAddress: + + /* Query the device caps */ + Status = PpIrpQueryCapabilities(DeviceObject, &DeviceCaps); + if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG)) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address); + + case DevicePropertyBootConfigurationTranslated: + + /* Validate we have resources */ + if (!DeviceNode->BootResources) +// if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field { - return STATUS_BUFFER_TOO_SMALL; + /* No resources will still fake success, but with 0 bytes */ + *ResultLength = 0; + return STATUS_SUCCESS; } + + /* This is the format of the returned data */ + PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated + DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated - /* Copy the GUID */ - RtlCopyMemory(PropertyBuffer, - &(PnpBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]), - sizeof(GUID)); - return STATUS_SUCCESS; - } - else - { - return STATUS_OBJECT_NAME_NOT_FOUND; - } - break; - - case DevicePropertyLegacyBusType: - Length = sizeof(INTERFACE_TYPE); - Data = &DeviceNode->ChildInterfaceType; - break; - - case DevicePropertyAddress: - /* Query the device caps */ - Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps); - if (NT_SUCCESS(Status) && (DeviceCaps.Address != MAXULONG)) - { - /* Return length */ - *ResultLength = sizeof(ULONG); - - /* Check if the buffer given was large enough */ - if (BufferLength < *ResultLength) - { - return STATUS_BUFFER_TOO_SMALL; - } - - /* Return address */ - *(PULONG)PropertyBuffer = DeviceCaps.Address; - return STATUS_SUCCESS; - } - else - { - return STATUS_OBJECT_NAME_NOT_FOUND; - } - break; - -// case DevicePropertyUINumber: -// if (DeviceNode->CapabilityFlags == NULL) -// return STATUS_INVALID_DEVICE_REQUEST; -// Length = sizeof(ULONG); -// Data = &DeviceNode->CapabilityFlags->UINumber; -// break; - - case DevicePropertyClassName: - case DevicePropertyClassGuid: - case DevicePropertyDriverKeyName: - case DevicePropertyManufacturer: - case DevicePropertyFriendlyName: - case DevicePropertyHardwareID: - case DevicePropertyCompatibleIDs: - case DevicePropertyDeviceDescription: - case DevicePropertyLocationInformation: - case DevicePropertyUINumber: - { - LPCWSTR RegistryPropertyName; - UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); - UNICODE_STRING ValueName; - KEY_VALUE_PARTIAL_INFORMATION *ValueInformation; - ULONG ValueInformationLength; - HANDLE KeyHandle, EnumRootHandle; - NTSTATUS Status; - - switch (DeviceProperty) - { - case DevicePropertyClassName: - RegistryPropertyName = L"Class"; break; - case DevicePropertyClassGuid: - RegistryPropertyName = L"ClassGuid"; break; - case DevicePropertyDriverKeyName: - RegistryPropertyName = L"Driver"; break; - case DevicePropertyManufacturer: - RegistryPropertyName = L"Mfg"; break; - case DevicePropertyFriendlyName: - RegistryPropertyName = L"FriendlyName"; break; - case DevicePropertyHardwareID: - RegistryPropertyName = L"HardwareID"; break; - case DevicePropertyCompatibleIDs: - RegistryPropertyName = L"CompatibleIDs"; break; - case DevicePropertyDeviceDescription: - RegistryPropertyName = L"DeviceDesc"; break; - case DevicePropertyLocationInformation: - RegistryPropertyName = L"LocationInformation"; break; - case DevicePropertyUINumber: - RegistryPropertyName = L"UINumber"; break; - default: - /* Should not happen */ - ASSERT(FALSE); - return STATUS_UNSUCCESSFUL; - } - - DPRINT("Registry property %S\n", RegistryPropertyName); - - /* Open Enum key */ - Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL, - &EnumRoot, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status); - return Status; - } - - /* Open instance key */ - Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle, - &DeviceNode->InstancePath, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status); - ZwClose(EnumRootHandle); - return Status; - } - - /* Allocate buffer to read as much data as required by the caller */ - ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, - Data[0]) + BufferLength; - ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength); - if (!ValueInformation) - { - ZwClose(KeyHandle); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Read the value */ - RtlInitUnicodeString(&ValueName, RegistryPropertyName); - Status = ZwQueryValueKey(KeyHandle, &ValueName, - KeyValuePartialInformation, ValueInformation, - ValueInformationLength, - &ValueInformationLength); - ZwClose(KeyHandle); - - /* Return data */ - *ResultLength = ValueInformation->DataLength; - - if (!NT_SUCCESS(Status)) - { - ExFreePool(ValueInformation); - if (Status == STATUS_BUFFER_OVERFLOW) - return STATUS_BUFFER_TOO_SMALL; - DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status, *ResultLength); - return Status; - } - - /* FIXME: Verify the value (NULL-terminated, correct format). */ - RtlCopyMemory(PropertyBuffer, ValueInformation->Data, - ValueInformation->DataLength); - ExFreePool(ValueInformation); - - return STATUS_SUCCESS; - } - - case DevicePropertyBootConfiguration: - Length = 0; - if (DeviceNode->BootResources->Count != 0) - { - Length = IopCalculateResourceListSize(DeviceNode->BootResources); - } - Data = DeviceNode->BootResources; - break; - - /* FIXME: use a translated boot configuration instead */ - case DevicePropertyBootConfigurationTranslated: - Length = 0; - if (DeviceNode->BootResources->Count != 0) - { - Length = IopCalculateResourceListSize(DeviceNode->BootResources); - } - Data = DeviceNode->BootResources; - break; - - case DevicePropertyEnumeratorName: - /* A buffer overflow can't happen here, since InstancePath - * always contains the enumerator name followed by \\ */ - Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\'); - ASSERT(Ptr); - Length = (Ptr - DeviceNode->InstancePath.Buffer) * sizeof(WCHAR); - Data = DeviceNode->InstancePath.Buffer; - break; - - case DevicePropertyPhysicalDeviceObjectName: - Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, - NULL, - 0, - &RequiredLength); - if (Status == STATUS_SUCCESS) - { - Length = 0; - Data = L""; - } - else if (Status == STATUS_INFO_LENGTH_MISMATCH) - { - ObjectNameInfoLength = RequiredLength; - ObjectNameInfo = ExAllocatePool(PagedPool, ObjectNameInfoLength); - if (!ObjectNameInfo) - return STATUS_INSUFFICIENT_RESOURCES; - - Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, + case DevicePropertyPhysicalDeviceObjectName: + + /* Sanity check for Unicode-sized string */ + ASSERT((BufferLength & 1) == 0); + + /* Allocate name buffer */ + Length = BufferLength + sizeof(OBJECT_NAME_INFORMATION); + ObjectNameInfo = ExAllocatePool(PagedPool, Length); + if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES; + + /* Query the PDO name */ + Status = ObQueryNameString(DeviceObject, ObjectNameInfo, - ObjectNameInfoLength, - &RequiredLength); - if (NT_SUCCESS(Status)) + Length, + ResultLength); + if (Status == STATUS_INFO_LENGTH_MISMATCH) { - Length = ObjectNameInfo->Name.Length; - Data = ObjectNameInfo->Name.Buffer; + /* It's up to the caller to try again */ + Status = STATUS_BUFFER_TOO_SMALL; } - else - return Status; + + /* Return if successful */ + if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length, + ObjectNameInfo->Name.Buffer); + + /* Let the caller know how big the name is */ + *ResultLength -= sizeof(OBJECT_NAME_INFORMATION); + break; + + /* Handle the registry-based properties */ + case DevicePropertyUINumber: + PIP_REGISTRY_DATA(REGSTR_VAL_UI_NUMBER, REG_DWORD); + case DevicePropertyLocationInformation: + PIP_REGISTRY_DATA(REGSTR_VAL_LOCATION_INFORMATION, REG_SZ); + case DevicePropertyDeviceDescription: + PIP_REGISTRY_DATA(REGSTR_VAL_DEVDESC, REG_SZ); + case DevicePropertyHardwareID: + PIP_REGISTRY_DATA(REGSTR_VAL_HARDWAREID, REG_MULTI_SZ); + case DevicePropertyCompatibleIDs: + PIP_REGISTRY_DATA(REGSTR_VAL_COMPATIBLEIDS, REG_MULTI_SZ); + case DevicePropertyBootConfiguration: + PIP_REGISTRY_DATA(REGSTR_VAL_BOOTCONFIG, REG_RESOURCE_LIST); + case DevicePropertyClassName: + PIP_REGISTRY_DATA(REGSTR_VAL_CLASS, REG_SZ); + case DevicePropertyClassGuid: + PIP_REGISTRY_DATA(REGSTR_VAL_CLASSGUID, REG_SZ); + case DevicePropertyDriverKeyName: + PIP_REGISTRY_DATA(REGSTR_VAL_DRIVER, REG_SZ); + case DevicePropertyManufacturer: + PIP_REGISTRY_DATA(REGSTR_VAL_MFG, REG_SZ); + case DevicePropertyFriendlyName: + PIP_REGISTRY_DATA(REGSTR_VAL_FRIENDLYNAME, REG_SZ); + case DevicePropertyContainerID: + //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7 + PIP_UNIMPLEMENTED(); + case DevicePropertyRemovalPolicy: + PIP_UNIMPLEMENTED(); + case DevicePropertyInstallState: + PIP_UNIMPLEMENTED(); + case DevicePropertyResourceRequirements: + PIP_UNIMPLEMENTED(); + case DevicePropertyAllocatedResources: + PIP_UNIMPLEMENTED(); + default: + return STATUS_INVALID_PARAMETER_2; + } + + /* Having a registry value name implies registry data */ + if (ValueName) + { + /* We know up-front how much data to expect */ + *ResultLength = BufferLength; + + /* Go get the data, use the LogConf subkey if necessary */ + Status = PiGetDeviceRegistryProperty(DeviceObject, + ValueType, + ValueName, + (DeviceProperty == + DevicePropertyBootConfiguration) ? + L"LogConf": NULL, + PropertyBuffer, + ResultLength); + } + else if (NT_SUCCESS(Status)) + { + /* We know up-front how much data to expect, check the caller's buffer */ + *ResultLength = ReturnLength; + if (ReturnLength <= BufferLength) + { + /* Buffer is all good, copy the data */ + RtlCopyMemory(PropertyBuffer, Data, ReturnLength); + + /* Check for properties that require a null-terminated string */ + if ((DeviceProperty == DevicePropertyEnumeratorName) || + (DeviceProperty == DevicePropertyPhysicalDeviceObjectName)) + { + /* Terminate the string */ + ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL; + } + + /* This is the success path */ + Status = STATUS_SUCCESS; } else - return Status; - break; - - default: - return STATUS_INVALID_PARAMETER_2; + { + /* Failure path */ + Status = STATUS_BUFFER_TOO_SMALL; + } } - - /* Prepare returned values */ - *ResultLength = Length; - if (BufferLength < Length) - { - if (ObjectNameInfo != NULL) - ExFreePool(ObjectNameInfo); - - return STATUS_BUFFER_TOO_SMALL; - } - RtlCopyMemory(PropertyBuffer, Data, Length); - - /* NULL terminate the string (if required) */ - if (DeviceProperty == DevicePropertyEnumeratorName || - DeviceProperty == DevicePropertyPhysicalDeviceObjectName) - ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL; - - if (ObjectNameInfo != NULL) - ExFreePool(ObjectNameInfo); - - return STATUS_SUCCESS; + + /* Free any allocation we may have made, and return the status code */ + if (ObjectNameInfo) ExFreePool(ObjectNameInfo); + return Status; } /* diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpres.c b/reactos/ntoskrnl/io/pnpmgr/pnpres.c index 88148901112..aff917b5967 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpres.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpres.c @@ -634,25 +634,37 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (DeviceNode->ResourceList) { - WCHAR NameBuff[256]; + PWCHAR DeviceName = NULL; UNICODE_STRING NameU; UNICODE_STRING Suffix; - ULONG OldLength; + ULONG OldLength = 0; ASSERT(DeviceNode->ResourceListTranslated); - NameU.Buffer = NameBuff; - NameU.Length = 0; - NameU.MaximumLength = 256 * sizeof(WCHAR); - Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, DevicePropertyPhysicalDeviceObjectName, - NameU.MaximumLength, - NameU.Buffer, + 0, + NULL, &OldLength); - ASSERT(Status == STATUS_SUCCESS); + if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL)) + { + DeviceName = ExAllocatePool(NonPagedPool, OldLength); + ASSERT(DeviceName); - NameU.Length = (USHORT)OldLength; + IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, + DevicePropertyPhysicalDeviceObjectName, + OldLength, + DeviceName, + &OldLength); + + RtlInitUnicodeString(&NameU, DeviceName); + } + else + { + /* Some failure */ + ASSERT(!NT_SUCCESS(Status)); + return Status; + } RtlInitUnicodeString(&Suffix, L".Raw"); RtlAppendUnicodeStringToString(&NameU, &Suffix); @@ -682,6 +694,8 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 DeviceNode->ResourceListTranslated, IopCalculateResourceListSize(DeviceNode->ResourceListTranslated)); ZwClose(PnpMgrLevel2); + ASSERT(DeviceName); + ExFreePool(DeviceName); if (!NT_SUCCESS(Status)) return Status; } From 58055397a54b343a278273076ae8c8762879c3bd Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 28 May 2010 23:08:41 +0000 Subject: [PATCH 068/292] [NTOS]: Root Bus PDO should not override Status with STATUS_NOT_IMPLEMENTED and instead use the current IRP status (which drivers/PnP will typically set to STATUS_NOT_SUPPORTED). Found by testing the new PCIx driver (probably fixes other bus drivers too). svn path=/trunk/; revision=47389 --- reactos/ntoskrnl/io/pnpmgr/pnproot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index 6f1834e5298..fb05da9e8d5 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -1085,7 +1085,6 @@ PnpRootPdoPnpControl( default: DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; break; } From 848f77424e9f9cd2ffb5db05ca23adb5b22b01c7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 28 May 2010 23:17:59 +0000 Subject: [PATCH 069/292] [NTOSKRNL] - Use PnpDetermineResourceListSize to determine the resource list size and remove the broken IopCalculateResourceListSize function svn path=/trunk/; revision=47390 --- reactos/ntoskrnl/include/internal/io.h | 4 +-- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 2 +- reactos/ntoskrnl/io/pnpmgr/pnpres.c | 34 ++++---------------------- 3 files changed, 7 insertions(+), 33 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 9398ef1d7ff..326f19c4dc6 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -496,9 +496,7 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT // ULONG NTAPI -IopCalculateResourceListSize( - IN PCM_RESOURCE_LIST ResourceList -); +PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList); NTSTATUS NTAPI diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index b745b3d156f..ec264938038 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -948,7 +948,7 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, 0, REG_RESOURCE_LIST, DeviceNode->BootResources, - IopCalculateResourceListSize(DeviceNode->BootResources)); + PnpDetermineResourceListSize(DeviceNode->BootResources)); } } diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpres.c b/reactos/ntoskrnl/io/pnpmgr/pnpres.c index aff917b5967..699e7970eed 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpres.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpres.c @@ -18,30 +18,6 @@ IopDetectResourceConflict( IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor); -ULONG -NTAPI -IopCalculateResourceListSize( - IN PCM_RESOURCE_LIST ResourceList) -{ - ULONG Size, i, j; - PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; - - Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); - for (i = 0; i < ResourceList->Count; i++) - { - pPartialResourceList = &ResourceList->List[i].PartialResourceList; - Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + - pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - for (j = 0; j < pPartialResourceList->Count; j++) - { - if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific) - Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize; - } - } - - return Size; -} - static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) @@ -533,7 +509,7 @@ IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode) 0, REG_RESOURCE_LIST, DeviceNode->ResourceList, - IopCalculateResourceListSize(DeviceNode->ResourceList)); + PnpDetermineResourceListSize(DeviceNode->ResourceList)); ZwClose(ControlKey); if (!NT_SUCCESS(Status)) @@ -674,7 +650,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 0, REG_RESOURCE_LIST, DeviceNode->ResourceList, - IopCalculateResourceListSize(DeviceNode->ResourceList)); + PnpDetermineResourceListSize(DeviceNode->ResourceList)); if (!NT_SUCCESS(Status)) { ZwClose(PnpMgrLevel2); @@ -692,7 +668,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 0, REG_RESOURCE_LIST, DeviceNode->ResourceListTranslated, - IopCalculateResourceListSize(DeviceNode->ResourceListTranslated)); + PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated)); ZwClose(PnpMgrLevel2); ASSERT(DeviceName); ExFreePool(DeviceName); @@ -732,7 +708,7 @@ IopTranslateDeviceResources( /* That's easy to translate a resource list. Just copy the * untranslated one and change few fields in the copy */ - ListSize = IopCalculateResourceListSize(DeviceNode->ResourceList); + ListSize = PnpDetermineResourceListSize(DeviceNode->ResourceList); DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceListTranslated) @@ -852,7 +828,7 @@ IopAssignDeviceResources( if (DeviceNode->BootResources) { - ListSize = IopCalculateResourceListSize(DeviceNode->BootResources); + ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources); DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceList) From 61325bb2791f7a7ef9f8ee1bd49e2d248125c97a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 29 May 2010 00:29:12 +0000 Subject: [PATCH 070/292] [NTOSKRNL] - Set the Status variable to STATUS_SUCCESS in PIP_RETURN_DATA - Fixes testbot svn path=/trunk/; revision=47391 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index ec264938038..9d130eca9df 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -3234,7 +3234,7 @@ PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject, return Status; } -#define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; break;} +#define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;} #define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;} #define PIP_UNIMPLEMENTED() {UNIMPLEMENTED; while(TRUE); break;} From a8a65751a356829a6b432e3af7ec5c323ec7233e Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sat, 29 May 2010 06:51:03 +0000 Subject: [PATCH 071/292] [win32k] - The timer is created usingUserCreateObject. It may be a good idea to save the handle in the timer object so that it can be deleted later. - Dereference the object before attempting to delete it. svn path=/trunk/; revision=47393 --- .../subsystems/win32/win32k/ntuser/timer.c | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index 3539b0aa6a8..4ab3916c8a6 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -50,13 +50,21 @@ CreateTimer(VOID) if (!FirstpTmr) { FirstpTmr = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); - if (FirstpTmr) InitializeListHead(&FirstpTmr->ptmrList); + if (FirstpTmr) + { + FirstpTmr->head.h = Handle; + InitializeListHead(&FirstpTmr->ptmrList); + } Ret = FirstpTmr; } else { Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); - if (Ret) InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList); + if (Ret) + { + Ret->head.h = Handle; + InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList); + } } return Ret; } @@ -66,14 +74,17 @@ BOOL FASTCALL RemoveTimer(PTIMER pTmr) { + BOOL Ret = FALSE; if (pTmr) { /* Set the flag, it will be removed when ready */ RemoveEntryList(&pTmr->ptmrList); - UserDeleteObject( UserHMGetHandle(pTmr), otTimer); - return TRUE; + UserDereferenceObject(pTmr); + Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer); } - return FALSE; + if (!Ret) DPRINT1("Warning unable to delete timer\n"); + + return Ret; } PTIMER @@ -528,9 +539,7 @@ DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) { if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) { - RemoveEntryList(&pTmr->ptmrList); - UserDeleteObject( UserHMGetHandle(pTmr), otTimer); - TimersRemoved = TRUE; + TimersRemoved = RemoveTimer(pTmr); } pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); @@ -557,9 +566,7 @@ DestroyTimersForThread(PTHREADINFO pti) { if ((pTmr) && (pTmr->pti == pti)) { - RemoveEntryList(&pTmr->ptmrList); - UserDeleteObject( UserHMGetHandle(pTmr), otTimer); - TimersRemoved = TRUE; + TimersRemoved = RemoveTimer(pTmr); } pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); From 11ebf0a0dc29f150a903d1df058150751f29c192 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 08:01:25 +0000 Subject: [PATCH 072/292] [MSI] delete msi_ros.diff svn path=/trunk/; revision=47394 --- reactos/dll/win32/msi/msi_ros.diff | 5400 ---------------------------- 1 file changed, 5400 deletions(-) delete mode 100644 reactos/dll/win32/msi/msi_ros.diff diff --git a/reactos/dll/win32/msi/msi_ros.diff b/reactos/dll/win32/msi/msi_ros.diff deleted file mode 100644 index 1e88f29fb3f..00000000000 --- a/reactos/dll/win32/msi/msi_ros.diff +++ /dev/null @@ -1,5400 +0,0 @@ -Index: cond.tab.c -=================================================================== ---- cond.tab.c (revision 31639) -+++ cond.tab.c (working copy) -@@ -0,0 +1,2439 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ 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, 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., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.1" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* Substitute the variable and function names. */ -+#define yyparse cond_parse -+#define yylex cond_lex -+#define yyerror cond_error -+#define yylval cond_lval -+#define yychar cond_char -+#define yydebug cond_debug -+#define yynerrs cond_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_XOR = 263, -+ COND_IMP = 264, -+ COND_EQV = 265, -+ COND_LT = 266, -+ COND_GT = 267, -+ COND_EQ = 268, -+ COND_NE = 269, -+ COND_GE = 270, -+ COND_LE = 271, -+ COND_ILT = 272, -+ COND_IGT = 273, -+ COND_IEQ = 274, -+ COND_INE = 275, -+ COND_IGE = 276, -+ COND_ILE = 277, -+ COND_LPAR = 278, -+ COND_RPAR = 279, -+ COND_TILDA = 280, -+ COND_SS = 281, -+ COND_ISS = 282, -+ COND_ILHS = 283, -+ COND_IRHS = 284, -+ COND_LHS = 285, -+ COND_RHS = 286, -+ COND_PERCENT = 287, -+ COND_DOLLARS = 288, -+ COND_QUESTION = 289, -+ COND_AMPER = 290, -+ COND_EXCLAM = 291, -+ COND_IDENT = 292, -+ COND_NUMBER = 293, -+ COND_LITER = 294, -+ COND_ERROR = 295 -+ }; -+#endif -+/* Tokens. */ -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_XOR 263 -+#define COND_IMP 264 -+#define COND_EQV 265 -+#define COND_LT 266 -+#define COND_GT 267 -+#define COND_EQ 268 -+#define COND_NE 269 -+#define COND_GE 270 -+#define COND_LE 271 -+#define COND_ILT 272 -+#define COND_IGT 273 -+#define COND_IEQ 274 -+#define COND_INE 275 -+#define COND_IGE 276 -+#define COND_ILE 277 -+#define COND_LPAR 278 -+#define COND_RPAR 279 -+#define COND_TILDA 280 -+#define COND_SS 281 -+#define COND_ISS 282 -+#define COND_ILHS 283 -+#define COND_IRHS 284 -+#define COND_LHS 285 -+#define COND_RHS 286 -+#define COND_PERCENT 287 -+#define COND_DOLLARS 288 -+#define COND_QUESTION 289 -+#define COND_AMPER 290 -+#define COND_EXCLAM 291 -+#define COND_IDENT 292 -+#define COND_NUMBER 293 -+#define COND_LITER 294 -+#define COND_ERROR 295 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "cond.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2003 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#define COBJMACROS -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "winuser.h" -+#include "msi.h" -+#include "msiquery.h" -+#include "objbase.h" -+#include "oleauto.h" -+ -+#include "msipriv.h" -+#include "msiserver.h" -+#include "wine/debug.h" -+#include "wine/unicode.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int cond_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_yyinput -+{ -+ MSIPACKAGE *package; -+ LPCWSTR str; -+ INT n; -+ MSICONDITION result; -+} COND_input; -+ -+struct cond_str { -+ LPCWSTR data; -+ INT len; -+}; -+ -+static LPWSTR COND_GetString( const struct cond_str *str ); -+static LPWSTR COND_GetLiteral( const struct cond_str *str ); -+static int cond_lex( void *COND_lval, COND_input *info); -+static const WCHAR szEmpty[] = { 0 }; -+ -+static INT compare_int( INT a, INT operator, INT b ); -+static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ); -+ -+static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert ) -+{ -+ INT r; -+ -+ r = compare_string( a, op, b, convert ); -+ msi_free( a ); -+ msi_free( b ); -+ return r; -+} -+ -+static BOOL num_from_prop( LPCWSTR p, INT *val ) -+{ -+ INT ret = 0, sign = 1; -+ -+ if (!p) -+ return FALSE; -+ if (*p == '-') -+ { -+ sign = -1; -+ p++; -+ } -+ if (!*p) -+ return FALSE; -+ while (*p) -+ { -+ if( *p < '0' || *p > '9' ) -+ return FALSE; -+ ret = ret*10 + (*p - '0'); -+ p++; -+ } -+ *val = ret*sign; -+ return TRUE; -+} -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 111 "cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+} YYSTYPE; -+/* Line 196 of yacc.c. */ -+#line 286 "cond.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 219 of yacc.c. */ -+#line 298 "cond.tab.c" -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#ifndef YY_ -+# if YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(msgid) msgid -+# endif -+#endif -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYINCLUDED_STDLIB_H -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -+# endif -+# ifdef __cplusplus -+extern "C" { -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifdef __cplusplus -+} -+# endif -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short int yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short int yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 28 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 71 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 41 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 12 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 53 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 70 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 295 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 6, 8, 12, 16, 20, 24, -+ 26, 30, 33, 35, 37, 41, 45, 49, 53, 57, -+ 61, 65, 69, 73, 77, 79, 81, 83, 85, 87, -+ 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, -+ 109, 111, 113, 115, 117, 119, 121, 124, 127, 130, -+ 133, 135, 138, 140 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 42, 0, -1, 43, -1, -1, 44, -1, 43, 5, -+ 44, -1, 43, 9, 44, -1, 43, 8, 44, -1, -+ 43, 10, 44, -1, 45, -1, 44, 6, 45, -1, -+ 7, 45, -1, 49, -1, 47, -1, 49, 46, 49, -+ -1, 50, 46, 49, -1, 49, 46, 50, -1, 50, -+ 46, 50, -1, 50, 46, 48, -1, 48, 46, 50, -+ -1, 48, 46, 48, -1, 48, 46, 49, -1, 49, -+ 46, 48, -1, 23, 43, 24, -1, 13, -1, 14, -+ -1, 11, -1, 12, -1, 16, -1, 15, -1, 26, -+ -1, 19, -1, 20, -1, 17, -1, 18, -1, 22, -+ -1, 21, -1, 27, -1, 30, -1, 31, -1, 28, -+ -1, 29, -1, 50, -1, 48, -1, 39, -1, 52, -+ -1, 33, 51, -1, 34, 51, -1, 35, 51, -1, -+ 36, 51, -1, 51, -1, 32, 51, -1, 37, -1, -+ 38, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short int yyrline[] = -+{ -+ 0, 135, 135, 141, 148, 152, 156, 160, 164, 171, -+ 175, 182, 186, 190, 195, 199, 208, 217, 221, 225, -+ 229, 233, 238, 243, 251, 252, 253, 254, 255, 256, -+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, -+ 267, 268, 272, 276, 283, 292, 296, 305, 314, 327, -+ 339, 346, 360, 369 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", -+ "COND_AND", "COND_NOT", "COND_XOR", "COND_IMP", "COND_EQV", "COND_LT", -+ "COND_GT", "COND_EQ", "COND_NE", "COND_GE", "COND_LE", "COND_ILT", -+ "COND_IGT", "COND_IEQ", "COND_INE", "COND_IGE", "COND_ILE", "COND_LPAR", -+ "COND_RPAR", "COND_TILDA", "COND_SS", "COND_ISS", "COND_ILHS", -+ "COND_IRHS", "COND_LHS", "COND_RHS", "COND_PERCENT", "COND_DOLLARS", -+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", -+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", -+ "expression", "boolean_term", "boolean_factor", "operator", "value_s", -+ "literal", "value_i", "symbol_s", "identifier", "integer", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short int yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 41, 42, 42, 43, 43, 43, 43, 43, 44, -+ 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, -+ 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, -+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -+ 46, 46, 47, 47, 48, 49, 49, 49, 49, 49, -+ 50, 50, 51, 52 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 0, 1, 3, 3, 3, 3, 1, -+ 3, 2, 1, 1, 3, 3, 3, 3, 3, 3, -+ 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, -+ 1, 2, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 3, 0, 0, 0, 0, 0, 0, 0, 52, 53, -+ 44, 0, 2, 4, 9, 13, 43, 12, 42, 50, -+ 45, 11, 0, 51, 46, 47, 48, 49, 1, 0, -+ 0, 0, 0, 0, 26, 27, 24, 25, 29, 28, -+ 33, 34, 31, 32, 36, 35, 30, 37, 40, 41, -+ 38, 39, 0, 0, 0, 23, 5, 7, 6, 8, -+ 10, 20, 21, 19, 22, 14, 16, 18, 15, 17 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 11, 12, 13, 14, 52, 15, 16, 17, 18, -+ 19, 20 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -15 -+static const yysigned_char yypact[] = -+{ -+ -7, -7, -7, -14, -14, -14, -14, -14, -15, -15, -+ -15, 24, 46, 30, -15, -15, -9, -9, -9, -15, -+ -15, -15, 29, -15, -15, -15, -15, -15, -15, -7, -+ -7, -7, -7, -7, -15, -15, -15, -15, -15, -15, -+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -+ -15, -15, 8, 8, 8, -15, 30, 30, 30, 30, -+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -15, -15, 50, 33, 0, -3, -15, -4, 14, 17, -+ 54, -15 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -1 -+static const unsigned char yytable[] = -+{ -+ 1, 21, 34, 35, 36, 37, 38, 39, 40, 41, -+ 42, 43, 44, 45, 53, 54, 2, 46, 47, 48, -+ 49, 50, 51, 8, 28, 3, 4, 5, 6, 7, -+ 8, 9, 10, 60, 29, 0, 33, 30, 31, 32, -+ 3, 4, 5, 6, 7, 8, 9, 10, 61, 64, -+ 67, 29, 22, 55, 30, 31, 32, 23, 24, 25, -+ 26, 27, 56, 57, 58, 59, 62, 65, 68, 63, -+ 66, 69 -+}; -+ -+static const yysigned_char yycheck[] = -+{ -+ 7, 1, 11, 12, 13, 14, 15, 16, 17, 18, -+ 19, 20, 21, 22, 17, 18, 23, 26, 27, 28, -+ 29, 30, 31, 37, 0, 32, 33, 34, 35, 36, -+ 37, 38, 39, 33, 5, -1, 6, 8, 9, 10, -+ 32, 33, 34, 35, 36, 37, 38, 39, 52, 53, -+ 54, 5, 2, 24, 8, 9, 10, 3, 4, 5, -+ 6, 7, 29, 30, 31, 32, 52, 53, 54, 52, -+ 53, 54 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 7, 23, 32, 33, 34, 35, 36, 37, 38, -+ 39, 42, 43, 44, 45, 47, 48, 49, 50, 51, -+ 52, 45, 43, 51, 51, 51, 51, 51, 0, 5, -+ 8, 9, 10, 6, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 26, 27, 28, 29, -+ 30, 31, 46, 46, 46, 24, 44, 44, 44, 44, -+ 45, 48, 49, 50, 48, 49, 50, 48, 49, 50 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (0) -+ -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) -+#endif -+ -+ -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ -+ -+#ifndef YY_LOCATION_PRINT -+# if YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Type, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short int *bottom, short int *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short int *bottom; -+ short int *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ char *yyd = yydest; -+ const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) -+{ -+ if (*yystr == '"') -+ { -+ size_t yyn = 0; -+ char const *yyp = yystr; -+ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; -+ } -+ -+ if (! yyres) -+ return yystrlen (yystr); -+ -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif -+ -+#endif /* YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ ; -+#endif -+#endif -+{ -+ /* The look-ahead symbol. */ -+int yychar; -+ -+/* The semantic value of the look-ahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ int yystate; -+ int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Look-ahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short int yyssa[YYINITDEPTH]; -+ short int *yyss = yyssa; -+ short int *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short int *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short int *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a look-ahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to look-ahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a look-ahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the look-ahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 136 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 3: -+#line 141 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = MSICONDITION_NONE; -+ ;} -+ break; -+ -+ case 4: -+#line 149 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 5: -+#line 153 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-2].value) || (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 6: -+#line 157 "cond.y" -+ { -+ (yyval.value) = !(yyvsp[-2].value) || (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 7: -+#line 161 "cond.y" -+ { -+ (yyval.value) = ( (yyvsp[-2].value) || (yyvsp[0].value) ) && !( (yyvsp[-2].value) && (yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 8: -+#line 165 "cond.y" -+ { -+ (yyval.value) = ( (yyvsp[-2].value) && (yyvsp[0].value) ) || ( !(yyvsp[-2].value) && !(yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 9: -+#line 172 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 10: -+#line 176 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-2].value) && (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 11: -+#line 183 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value) ? 0 : 1; -+ ;} -+ break; -+ -+ case 12: -+#line 187 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value) ? 1 : 0; -+ ;} -+ break; -+ -+ case 13: -+#line 191 "cond.y" -+ { -+ (yyval.value) = ((yyvsp[0].string) && (yyvsp[0].string)[0]) ? 1 : 0; -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 14: -+#line 196 "cond.y" -+ { -+ (yyval.value) = compare_int( (yyvsp[-2].value), (yyvsp[-1].value), (yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 15: -+#line 200 "cond.y" -+ { -+ int num; -+ if (num_from_prop( (yyvsp[-2].string), &num )) -+ (yyval.value) = compare_int( num, (yyvsp[-1].value), (yyvsp[0].value) ); -+ else -+ (yyval.value) = ((yyvsp[-1].value) == COND_NE || (yyvsp[-1].value) == COND_INE ); -+ msi_free((yyvsp[-2].string)); -+ ;} -+ break; -+ -+ case 16: -+#line 209 "cond.y" -+ { -+ int num; -+ if (num_from_prop( (yyvsp[0].string), &num )) -+ (yyval.value) = compare_int( (yyvsp[-2].value), (yyvsp[-1].value), num ); -+ else -+ (yyval.value) = ((yyvsp[-1].value) == COND_NE || (yyvsp[-1].value) == COND_INE ); -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 17: -+#line 218 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 18: -+#line 222 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 19: -+#line 226 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 20: -+#line 230 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), FALSE ); -+ ;} -+ break; -+ -+ case 21: -+#line 234 "cond.y" -+ { -+ (yyval.value) = 0; -+ msi_free((yyvsp[-2].string)); -+ ;} -+ break; -+ -+ case 22: -+#line 239 "cond.y" -+ { -+ (yyval.value) = 0; -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 23: -+#line 244 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-1].value); -+ ;} -+ break; -+ -+ case 24: -+#line 251 "cond.y" -+ { (yyval.value) = COND_EQ; ;} -+ break; -+ -+ case 25: -+#line 252 "cond.y" -+ { (yyval.value) = COND_NE; ;} -+ break; -+ -+ case 26: -+#line 253 "cond.y" -+ { (yyval.value) = COND_LT; ;} -+ break; -+ -+ case 27: -+#line 254 "cond.y" -+ { (yyval.value) = COND_GT; ;} -+ break; -+ -+ case 28: -+#line 255 "cond.y" -+ { (yyval.value) = COND_LE; ;} -+ break; -+ -+ case 29: -+#line 256 "cond.y" -+ { (yyval.value) = COND_GE; ;} -+ break; -+ -+ case 30: -+#line 257 "cond.y" -+ { (yyval.value) = COND_SS; ;} -+ break; -+ -+ case 31: -+#line 258 "cond.y" -+ { (yyval.value) = COND_IEQ; ;} -+ break; -+ -+ case 32: -+#line 259 "cond.y" -+ { (yyval.value) = COND_INE; ;} -+ break; -+ -+ case 33: -+#line 260 "cond.y" -+ { (yyval.value) = COND_ILT; ;} -+ break; -+ -+ case 34: -+#line 261 "cond.y" -+ { (yyval.value) = COND_IGT; ;} -+ break; -+ -+ case 35: -+#line 262 "cond.y" -+ { (yyval.value) = COND_ILE; ;} -+ break; -+ -+ case 36: -+#line 263 "cond.y" -+ { (yyval.value) = COND_IGE; ;} -+ break; -+ -+ case 37: -+#line 264 "cond.y" -+ { (yyval.value) = COND_ISS; ;} -+ break; -+ -+ case 38: -+#line 265 "cond.y" -+ { (yyval.value) = COND_LHS; ;} -+ break; -+ -+ case 39: -+#line 266 "cond.y" -+ { (yyval.value) = COND_RHS; ;} -+ break; -+ -+ case 40: -+#line 267 "cond.y" -+ { (yyval.value) = COND_ILHS; ;} -+ break; -+ -+ case 41: -+#line 268 "cond.y" -+ { (yyval.value) = COND_IRHS; ;} -+ break; -+ -+ case 42: -+#line 273 "cond.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 43: -+#line 277 "cond.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 44: -+#line 284 "cond.y" -+ { -+ (yyval.string) = COND_GetLiteral(&(yyvsp[0].str)); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 45: -+#line 293 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 46: -+#line 297 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = action; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 47: -+#line 306 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = install; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 48: -+#line 315 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ if (action == INSTALLSTATE_UNKNOWN) -+ (yyval.value) = MSICONDITION_FALSE; -+ else -+ (yyval.value) = action; -+ -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 49: -+#line 328 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = install; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 50: -+#line 340 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ -+ (yyval.string) = msi_dup_property( cond->package, (yyvsp[0].string) ); -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 51: -+#line 347 "cond.y" -+ { -+ UINT len = GetEnvironmentVariableW( (yyvsp[0].string), NULL, 0 ); -+ (yyval.string) = NULL; -+ if (len++) -+ { -+ (yyval.string) = msi_alloc( len*sizeof (WCHAR) ); -+ GetEnvironmentVariableW( (yyvsp[0].string), (yyval.string), len ); -+ } -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 52: -+#line 361 "cond.y" -+ { -+ (yyval.string) = COND_GetString(&(yyvsp[0].str)); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 53: -+#line 370 "cond.y" -+ { -+ LPWSTR szNum = COND_GetString(&(yyvsp[0].str)); -+ if( !szNum ) -+ YYABORT; -+ (yyval.value) = atoiW( szNum ); -+ msi_free( szNum ); -+ ;} -+ break; -+ -+ -+ default: break; -+ } -+ -+/* Line 1126 of yacc.c. */ -+#line 1740 "cond.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ int yytype = YYTRANSLATE (yychar); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); -+ YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; -+ int yysize_overflow = 0; -+ char *yymsg = 0; -+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ int yyx; -+ -+#if 0 -+ /* This is so xgettext sees the translatable formats that are -+ constructed on the fly. */ -+ YY_("syntax error, unexpected %s"); -+ YY_("syntax error, unexpected %s, expecting %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -+#endif -+ char *yyfmt; -+ char const *yyf; -+ static char const yyunexpected[] = "syntax error, unexpected %s"; -+ static char const yyexpecting[] = ", expecting %s"; -+ static char const yyor[] = " or %s"; -+ char yyformat[sizeof yyunexpected -+ + sizeof yyexpecting - 1 -+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) -+ * (sizeof yyor - 1))]; -+ char const *yyprefix = yyexpecting; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 1; -+ -+ yyarg[0] = yytname[yytype]; -+ yyfmt = yystpcpy (yyformat, yyunexpected); -+ -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ yyformat[sizeof yyunexpected - 1] = '\0'; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ yyfmt = yystpcpy (yyfmt, yyprefix); -+ yyprefix = yyor; -+ } -+ -+ yyf = YY_(yyformat); -+ yysize1 = yysize + yystrlen (yyf); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ -+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg) -+ { -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ char *yyp = yymsg; -+ int yyi = 0; -+ while ((*yyp = *yyf)) -+ { -+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyf += 2; -+ } -+ else -+ { -+ yyp++; -+ yyf++; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ { -+ yyerror (YY_("syntax error")); -+ goto yyexhaustedlab; -+ } -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror (YY_("syntax error")); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse look-ahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", yytoken, &yylval); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse look-ahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (0) -+ goto yyerrorlab; -+ -+yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ -+ yydestruct ("Error: popping", yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEOF && yychar != YYEMPTY) -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp); -+ YYPOPSTACK; -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 379 "cond.y" -+ -+ -+ -+static int COND_IsAlpha( WCHAR x ) -+{ -+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || -+ ( ( x >= 'a' ) && ( x <= 'z' ) ) || -+ ( ( x == '_' ) ) ); -+} -+ -+static int COND_IsNumber( WCHAR x ) -+{ -+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); -+} -+ -+static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub ) -+{ -+ LPWSTR strlower, sublower, r; -+ strlower = CharLowerW( strdupW( str ) ); -+ sublower = CharLowerW( strdupW( sub ) ); -+ r = strstrW( strlower, sublower ); -+ if (r) -+ r = (LPWSTR)str + (r - strlower); -+ msi_free( strlower ); -+ msi_free( sublower ); -+ return r; -+} -+ -+static BOOL str_is_number( LPCWSTR str ) -+{ -+ int i; -+ -+ if (!*str) -+ return FALSE; -+ -+ for (i = 0; i < lstrlenW( str ); i++) -+ if (!isdigitW(str[i])) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) -+{ -+ int lhs, rhs; -+ -+ /* substring operators return 0 if LHS is missing */ -+ if (!a || !*a) -+ return 0; -+ -+ /* substring operators return 1 if RHS is missing */ -+ if (!b || !*b) -+ return 1; -+ -+ /* if both strings contain only numbers, use integer comparison */ -+ lhs = atoiW(a); -+ rhs = atoiW(b); -+ if (str_is_number(a) && str_is_number(b)) -+ return compare_int( lhs, operator, rhs ); -+ -+ switch (operator) -+ { -+ case COND_SS: -+ return strstrW( a, b ) ? 1 : 0; -+ case COND_ISS: -+ return strstriW( a, b ) ? 1 : 0; -+ case COND_LHS: -+ return 0 == strncmpW( a, b, lstrlenW( b ) ); -+ case COND_RHS: -+ return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b ); -+ case COND_ILHS: -+ return 0 == strncmpiW( a, b, lstrlenW( b ) ); -+ case COND_IRHS: -+ return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b ); -+ default: -+ ERR("invalid substring operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ) -+{ -+ if (operator >= COND_SS && operator <= COND_RHS) -+ return compare_substring( a, operator, b ); -+ -+ /* null and empty string are equivalent */ -+ if (!a) a = szEmpty; -+ if (!b) b = szEmpty; -+ -+ if (convert && str_is_number(a) && str_is_number(b)) -+ return compare_int( atoiW(a), operator, atoiW(b) ); -+ -+ /* a or b may be NULL */ -+ switch (operator) -+ { -+ case COND_LT: -+ return -1 == lstrcmpW( a, b ); -+ case COND_GT: -+ return 1 == lstrcmpW( a, b ); -+ case COND_EQ: -+ return 0 == lstrcmpW( a, b ); -+ case COND_NE: -+ return 0 != lstrcmpW( a, b ); -+ case COND_GE: -+ return -1 != lstrcmpW( a, b ); -+ case COND_LE: -+ return 1 != lstrcmpW( a, b ); -+ case COND_ILT: -+ return -1 == lstrcmpiW( a, b ); -+ case COND_IGT: -+ return 1 == lstrcmpiW( a, b ); -+ case COND_IEQ: -+ return 0 == lstrcmpiW( a, b ); -+ case COND_INE: -+ return 0 != lstrcmpiW( a, b ); -+ case COND_IGE: -+ return -1 != lstrcmpiW( a, b ); -+ case COND_ILE: -+ return 1 != lstrcmpiW( a, b ); -+ default: -+ ERR("invalid string operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+ -+static INT compare_int( INT a, INT operator, INT b ) -+{ -+ switch (operator) -+ { -+ case COND_LT: -+ case COND_ILT: -+ return a < b; -+ case COND_GT: -+ case COND_IGT: -+ return a > b; -+ case COND_EQ: -+ case COND_IEQ: -+ return a == b; -+ case COND_NE: -+ case COND_INE: -+ return a != b; -+ case COND_GE: -+ case COND_IGE: -+ return a >= b; -+ case COND_LE: -+ case COND_ILE: -+ return a <= b; -+ case COND_SS: -+ case COND_ISS: -+ return ( a & b ) ? 1 : 0; -+ case COND_RHS: -+ return ( ( a & 0xffff ) == b ) ? 1 : 0; -+ case COND_LHS: -+ return ( ( (a>>16) & 0xffff ) == b ) ? 1 : 0; -+ default: -+ ERR("invalid integer operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+ -+static int COND_IsIdent( WCHAR x ) -+{ -+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) -+ || ( x == '#' ) || (x == '.') ); -+} -+ -+static int COND_GetOperator( COND_input *cond ) -+{ -+ static const struct { -+ const WCHAR str[4]; -+ int id; -+ } table[] = { -+ { {'~','=',0}, COND_IEQ }, -+ { {'~','<','=',0}, COND_ILE }, -+ { {'~','>','<',0}, COND_ISS }, -+ { {'~','>','>',0}, COND_IRHS }, -+ { {'~','<','>',0}, COND_INE }, -+ { {'~','<',0}, COND_ILT }, -+ { {'~','>','=',0}, COND_IGE }, -+ { {'~','<','<',0}, COND_ILHS }, -+ { {'~','>',0}, COND_IGT }, -+ { {'>','=',0}, COND_GE }, -+ { {'>','<',0}, COND_SS }, -+ { {'<','<',0}, COND_LHS }, -+ { {'<','>',0}, COND_NE }, -+ { {'<','=',0}, COND_LE }, -+ { {'>','>',0}, COND_RHS }, -+ { {'>',0}, COND_GT }, -+ { {'<',0}, COND_LT }, -+ { {0}, 0 } -+ }; -+ LPCWSTR p = &cond->str[cond->n]; -+ int i = 0, len; -+ -+ while ( 1 ) -+ { -+ len = lstrlenW( table[i].str ); -+ if ( !len || 0 == strncmpW( table[i].str, p, len ) ) -+ break; -+ i++; -+ } -+ cond->n += len; -+ return table[i].id; -+} -+ -+static int COND_GetOne( struct cond_str *str, COND_input *cond ) -+{ -+ int rc, len = 1; -+ WCHAR ch; -+ -+ str->data = &cond->str[cond->n]; -+ -+ ch = str->data[0]; -+ -+ switch( ch ) -+ { -+ case 0: return 0; -+ case '(': rc = COND_LPAR; break; -+ case ')': rc = COND_RPAR; break; -+ case '&': rc = COND_AMPER; break; -+ case '!': rc = COND_EXCLAM; break; -+ case '$': rc = COND_DOLLARS; break; -+ case '?': rc = COND_QUESTION; break; -+ case '%': rc = COND_PERCENT; break; -+ case ' ': rc = COND_SPACE; break; -+ case '=': rc = COND_EQ; break; -+ -+ case '~': -+ case '<': -+ case '>': -+ rc = COND_GetOperator( cond ); -+ if (!rc) -+ rc = COND_ERROR; -+ return rc; -+ default: -+ rc = 0; -+ } -+ -+ if ( rc ) -+ { -+ cond->n += len; -+ return rc; -+ } -+ -+ if (ch == '"' ) -+ { -+ LPCWSTR p = strchrW( str->data + 1, '"' ); -+ if (!p) -+ return COND_ERROR; -+ len = p - str->data + 1; -+ rc = COND_LITER; -+ } -+ else if( COND_IsAlpha( ch ) ) -+ { -+ static const WCHAR szNot[] = {'N','O','T',0}; -+ static const WCHAR szAnd[] = {'A','N','D',0}; -+ static const WCHAR szXor[] = {'X','O','R',0}; -+ static const WCHAR szEqv[] = {'E','Q','V',0}; -+ static const WCHAR szImp[] = {'I','M','P',0}; -+ static const WCHAR szOr[] = {'O','R',0}; -+ -+ while( COND_IsIdent( str->data[len] ) ) -+ len++; -+ rc = COND_IDENT; -+ -+ if ( len == 3 ) -+ { -+ if ( !strncmpiW( str->data, szNot, len ) ) -+ rc = COND_NOT; -+ else if( !strncmpiW( str->data, szAnd, len ) ) -+ rc = COND_AND; -+ else if( !strncmpiW( str->data, szXor, len ) ) -+ rc = COND_XOR; -+ else if( !strncmpiW( str->data, szEqv, len ) ) -+ rc = COND_EQV; -+ else if( !strncmpiW( str->data, szImp, len ) ) -+ rc = COND_IMP; -+ } -+ else if( (len == 2) && !strncmpiW( str->data, szOr, len ) ) -+ rc = COND_OR; -+ } -+ else if( COND_IsNumber( ch ) ) -+ { -+ while( COND_IsNumber( str->data[len] ) ) -+ len++; -+ rc = COND_NUMBER; -+ } -+ else -+ { -+ ERR("Got unknown character %c(%x)\n",ch,ch); -+ return COND_ERROR; -+ } -+ -+ cond->n += len; -+ str->len = len; -+ -+ return rc; -+} -+ -+static int cond_lex( void *COND_lval, COND_input *cond ) -+{ -+ int rc; -+ struct cond_str *str = COND_lval; -+ -+ do { -+ rc = COND_GetOne( str, cond ); -+ } while (rc == COND_SPACE); -+ -+ return rc; -+} -+ -+static LPWSTR COND_GetString( const struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data, str->len * sizeof(WCHAR)); -+ ret[str->len]=0; -+ } -+ TRACE("Got identifier %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static LPWSTR COND_GetLiteral( const struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); -+ ret[str->len - 2]=0; -+ } -+ TRACE("Got literal %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static int cond_error(const char *str) -+{ -+ TRACE("%s\n", str ); -+ return 0; -+} -+ -+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) -+{ -+ COND_input cond; -+ MSICONDITION r; -+ -+ TRACE("%s\n", debugstr_w( szCondition ) ); -+ -+ if ( szCondition == NULL ) -+ return MSICONDITION_NONE; -+ -+ cond.package = package; -+ cond.str = szCondition; -+ cond.n = 0; -+ cond.result = MSICONDITION_ERROR; -+ -+ if ( !cond_parse( &cond ) ) -+ r = cond.result; -+ else -+ r = MSICONDITION_ERROR; -+ -+ TRACE("%i <- %s\n", r, debugstr_w(szCondition)); -+ return r; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) -+{ -+ MSIPACKAGE *package; -+ UINT ret; -+ -+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); -+ if( !package ) -+ { -+ HRESULT hr; -+ BSTR condition; -+ IWineMsiRemotePackage *remote_package; -+ -+ remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); -+ if (!remote_package) -+ return MSICONDITION_ERROR; -+ -+ condition = SysAllocString( szCondition ); -+ if (!condition) -+ { -+ IWineMsiRemotePackage_Release( remote_package ); -+ return ERROR_OUTOFMEMORY; -+ } -+ -+ hr = IWineMsiRemotePackage_EvaluateCondition( remote_package, condition ); -+ -+ SysFreeString( condition ); -+ IWineMsiRemotePackage_Release( remote_package ); -+ -+ if (FAILED(hr)) -+ { -+ if (HRESULT_FACILITY(hr) == FACILITY_WIN32) -+ return HRESULT_CODE(hr); -+ -+ return ERROR_FUNCTION_FAILED; -+ } -+ -+ return ERROR_SUCCESS; -+ } -+ -+ ret = MSI_EvaluateConditionW( package, szCondition ); -+ msiobj_release( &package->hdr ); -+ return ret; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) -+{ -+ LPWSTR szwCond = NULL; -+ MSICONDITION r; -+ -+ szwCond = strdupAtoW( szCondition ); -+ if( szCondition && !szwCond ) -+ return MSICONDITION_ERROR; -+ -+ r = MsiEvaluateConditionW( hInstall, szwCond ); -+ msi_free( szwCond ); -+ return r; -+} -+ -Index: cond.tab.h -=================================================================== ---- cond.tab.h (revision 31639) -+++ cond.tab.h (working copy) -@@ -0,0 +1,132 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ 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, 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., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_XOR = 263, -+ COND_IMP = 264, -+ COND_EQV = 265, -+ COND_LT = 266, -+ COND_GT = 267, -+ COND_EQ = 268, -+ COND_NE = 269, -+ COND_GE = 270, -+ COND_LE = 271, -+ COND_ILT = 272, -+ COND_IGT = 273, -+ COND_IEQ = 274, -+ COND_INE = 275, -+ COND_IGE = 276, -+ COND_ILE = 277, -+ COND_LPAR = 278, -+ COND_RPAR = 279, -+ COND_TILDA = 280, -+ COND_SS = 281, -+ COND_ISS = 282, -+ COND_ILHS = 283, -+ COND_IRHS = 284, -+ COND_LHS = 285, -+ COND_RHS = 286, -+ COND_PERCENT = 287, -+ COND_DOLLARS = 288, -+ COND_QUESTION = 289, -+ COND_AMPER = 290, -+ COND_EXCLAM = 291, -+ COND_IDENT = 292, -+ COND_NUMBER = 293, -+ COND_LITER = 294, -+ COND_ERROR = 295 -+ }; -+#endif -+/* Tokens. */ -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_XOR 263 -+#define COND_IMP 264 -+#define COND_EQV 265 -+#define COND_LT 266 -+#define COND_GT 267 -+#define COND_EQ 268 -+#define COND_NE 269 -+#define COND_GE 270 -+#define COND_LE 271 -+#define COND_ILT 272 -+#define COND_IGT 273 -+#define COND_IEQ 274 -+#define COND_INE 275 -+#define COND_IGE 276 -+#define COND_ILE 277 -+#define COND_LPAR 278 -+#define COND_RPAR 279 -+#define COND_TILDA 280 -+#define COND_SS 281 -+#define COND_ISS 282 -+#define COND_ILHS 283 -+#define COND_IRHS 284 -+#define COND_LHS 285 -+#define COND_RHS 286 -+#define COND_PERCENT 287 -+#define COND_DOLLARS 288 -+#define COND_QUESTION 289 -+#define COND_AMPER 290 -+#define COND_EXCLAM 291 -+#define COND_IDENT 292 -+#define COND_NUMBER 293 -+#define COND_LITER 294 -+#define COND_ERROR 295 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 111 "cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+} YYSTYPE; -+/* Line 1447 of yacc.c. */ -+#line 124 "cond.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ -Index: msi.rbuild -=================================================================== ---- msi.rbuild (revision 31639) -+++ msi.rbuild (working copy) -@@ -14,6 +14,7 @@ - appsearch.c - automation.c - classes.c -+ cond.tab.c - create.c - custom.c - database.c -@@ -40,6 +41,7 @@ - script.c - select.c - source.c -+ sql.tab.c - streams.c - string.c - suminfo.c -Index: msi_Ja.rc -=================================================================== ---- msi_Ja.rc (revision 31639) -+++ msi_Ja.rc (working copy) -@@ -0,0 +1,13 @@ -+LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL -+ -+STRINGTABLE DISCARDABLE -+{ -+ 5 "ƒpƒX %s ‚ª‚݂‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½" -+ 9 "ƒfƒBƒXƒN %s ‚ð‘}“ü‚µ‚Ä‚­‚¾‚³‚¢" -+ 10 "–³Œø‚ȃpƒ‰ƒ[ƒ^‚Å‚·" -+ 11 "%s ‚Ì‚ ‚éƒtƒHƒ‹ƒ_‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢" -+ 12 "‹@”\\‚̃Cƒ“ƒXƒg[ƒ‹Œ³‚ª‚ ‚è‚Ü‚¹‚ñ" -+ 13 "‹@”\\‚ª‚ ‚éƒlƒbƒgƒ[ƒN ƒhƒ‰ƒCƒu‚ª‚ ‚è‚Ü‚¹‚ñ" -+ 14 "‹@”\\‚ÌêŠ:" -+ 15 "%s ‚Ì‚ ‚éƒtƒHƒ‹ƒ_‚ð‘I‘ð‚µ‚Ä‚­‚¾‚³‚¢" -+} -Index: regsvr.c -=================================================================== ---- regsvr.c (revision 31639) -+++ regsvr.c (working copy) -@@ -40,6 +40,7 @@ - #include "msi.h" - #include "initguid.h" - #include "msipriv.h" -+#include "msiserver.h" - - WINE_DEFAULT_DEBUG_CHANNEL(msi); - -Index: sql.tab.c -=================================================================== ---- sql.tab.c (revision 31639) -+++ sql.tab.c (working copy) -@@ -0,0 +1,2579 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ 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, 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., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.1" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* Substitute the variable and function names. */ -+#define yyparse sql_parse -+#define yylex sql_lex -+#define yyerror sql_error -+#define yylval sql_lval -+#define yychar sql_char -+#define yydebug sql_debug -+#define yynerrs sql_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ALTER = 258, -+ TK_AND = 259, -+ TK_BY = 260, -+ TK_CHAR = 261, -+ TK_COMMA = 262, -+ TK_CREATE = 263, -+ TK_DELETE = 264, -+ TK_DISTINCT = 265, -+ TK_DOT = 266, -+ TK_EQ = 267, -+ TK_FREE = 268, -+ TK_FROM = 269, -+ TK_GE = 270, -+ TK_GT = 271, -+ TK_HOLD = 272, -+ TK_ADD = 273, -+ TK_ID = 274, -+ TK_ILLEGAL = 275, -+ TK_INSERT = 276, -+ TK_INT = 277, -+ TK_INTEGER = 278, -+ TK_INTO = 279, -+ TK_IS = 280, -+ TK_KEY = 281, -+ TK_LE = 282, -+ TK_LONG = 283, -+ TK_LONGCHAR = 284, -+ TK_LP = 285, -+ TK_LT = 286, -+ TK_LOCALIZABLE = 287, -+ TK_MINUS = 288, -+ TK_NE = 289, -+ TK_NOT = 290, -+ TK_NULL = 291, -+ TK_OBJECT = 292, -+ TK_OR = 293, -+ TK_ORDER = 294, -+ TK_PRIMARY = 295, -+ TK_RP = 296, -+ TK_SELECT = 297, -+ TK_SET = 298, -+ TK_SHORT = 299, -+ TK_SPACE = 300, -+ TK_STAR = 301, -+ TK_STRING = 302, -+ TK_TABLE = 303, -+ TK_TEMPORARY = 304, -+ TK_UPDATE = 305, -+ TK_VALUES = 306, -+ TK_WHERE = 307, -+ TK_WILDCARD = 308, -+ COLUMN = 310, -+ FUNCTION = 311, -+ COMMENT = 312, -+ UNCLOSED_STRING = 313, -+ SPACE = 314, -+ ILLEGAL = 315, -+ END_OF_FILE = 316, -+ TK_LIKE = 317, -+ TK_NEGATION = 318 -+ }; -+#endif -+/* Tokens. */ -+#define TK_ALTER 258 -+#define TK_AND 259 -+#define TK_BY 260 -+#define TK_CHAR 261 -+#define TK_COMMA 262 -+#define TK_CREATE 263 -+#define TK_DELETE 264 -+#define TK_DISTINCT 265 -+#define TK_DOT 266 -+#define TK_EQ 267 -+#define TK_FREE 268 -+#define TK_FROM 269 -+#define TK_GE 270 -+#define TK_GT 271 -+#define TK_HOLD 272 -+#define TK_ADD 273 -+#define TK_ID 274 -+#define TK_ILLEGAL 275 -+#define TK_INSERT 276 -+#define TK_INT 277 -+#define TK_INTEGER 278 -+#define TK_INTO 279 -+#define TK_IS 280 -+#define TK_KEY 281 -+#define TK_LE 282 -+#define TK_LONG 283 -+#define TK_LONGCHAR 284 -+#define TK_LP 285 -+#define TK_LT 286 -+#define TK_LOCALIZABLE 287 -+#define TK_MINUS 288 -+#define TK_NE 289 -+#define TK_NOT 290 -+#define TK_NULL 291 -+#define TK_OBJECT 292 -+#define TK_OR 293 -+#define TK_ORDER 294 -+#define TK_PRIMARY 295 -+#define TK_RP 296 -+#define TK_SELECT 297 -+#define TK_SET 298 -+#define TK_SHORT 299 -+#define TK_SPACE 300 -+#define TK_STAR 301 -+#define TK_STRING 302 -+#define TK_TABLE 303 -+#define TK_TEMPORARY 304 -+#define TK_UPDATE 305 -+#define TK_VALUES 306 -+#define TK_WHERE 307 -+#define TK_WILDCARD 308 -+#define COLUMN 310 -+#define FUNCTION 311 -+#define COMMENT 312 -+#define UNCLOSED_STRING 313 -+#define SPACE 314 -+#define ILLEGAL 315 -+#define END_OF_FILE 316 -+#define TK_LIKE 317 -+#define TK_NEGATION 318 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "sql.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2002-2004 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "query.h" -+#include "wine/list.h" -+#include "wine/debug.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int sql_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_SQL_input -+{ -+ MSIDATABASE *db; -+ LPCWSTR command; -+ DWORD n, len; -+ MSIVIEW **view; /* view structure for the resulting query */ -+ struct list *mem; -+} SQL_input; -+ -+static LPWSTR SQL_getstring( void *info, const struct sql_str *str ); -+static INT SQL_getint( void *info ); -+static int sql_lex( void *SQL_lval, SQL_input *info ); -+ -+static LPWSTR parser_add_table( LPWSTR list, LPWSTR table ); -+static void *parser_alloc( void *info, unsigned int sz ); -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); -+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ); -+static struct expr * EXPR_column( void *info, const column_info *column ); -+static struct expr * EXPR_ival( void *info, int val ); -+static struct expr * EXPR_sval( void *info, const struct sql_str *str ); -+static struct expr * EXPR_wildcard( void *info ); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 74 "sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 196 of yacc.c. */ -+#line 297 "sql.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 219 of yacc.c. */ -+#line 309 "sql.tab.c" -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#ifndef YY_ -+# if YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(msgid) msgid -+# endif -+#endif -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYINCLUDED_STDLIB_H -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -+# endif -+# ifdef __cplusplus -+extern "C" { -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifdef __cplusplus -+} -+# endif -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short int yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short int yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 32 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 138 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 64 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 34 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 79 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 141 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 318 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -+ 55, 56, 57, 58, 59, 60, 61, 62, 63 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned short int yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, -+ 28, 40, 47, 55, 62, 67, 70, 75, 81, 88, -+ 90, 92, 97, 101, 103, 106, 108, 111, 114, 116, -+ 120, 122, 127, 129, 131, 133, 135, 137, 139, 144, -+ 146, 149, 153, 156, 158, 162, 164, 166, 170, 173, -+ 176, 178, 182, 186, 190, 194, 198, 202, 206, 210, -+ 214, 218, 222, 227, 229, 231, 233, 237, 239, 243, -+ 247, 249, 252, 254, 256, 258, 262, 264, 266, 268 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 65, 0, -1, 66, -1, 80, -1, 68, -1, 67, -+ -1, 69, -1, 70, -1, 71, -1, 21, 24, 95, -+ 30, 83, 41, 51, 30, 89, 41, -1, 21, 24, -+ 95, 30, 83, 41, 51, 30, 89, 41, 49, -1, -+ 8, 48, 95, 30, 73, 41, -1, 8, 48, 95, -+ 30, 73, 41, 17, -1, 50, 95, 43, 90, 52, -+ 87, -1, 50, 95, 43, 90, -1, 9, 84, -1, -+ 3, 48, 95, 72, -1, 3, 48, 95, 18, 75, -+ -1, 3, 48, 95, 18, 75, 17, -1, 17, -1, -+ 13, -1, 74, 40, 26, 83, -1, 74, 7, 75, -+ -1, 75, -1, 94, 76, -1, 77, -1, 77, 32, -+ -1, 77, 49, -1, 78, -1, 78, 35, 36, -1, -+ 6, -1, 6, 30, 79, 41, -1, 29, -1, 44, -+ -1, 22, -1, 28, -1, 37, -1, 97, -1, 81, -+ 39, 5, 83, -1, 81, -1, 42, 82, -1, 42, -+ 10, 82, -1, 83, 84, -1, 94, -1, 94, 7, -+ 83, -1, 46, -1, 85, -1, 85, 52, 87, -1, -+ 14, 95, -1, 14, 86, -1, 95, -1, 95, 7, -+ 86, -1, 30, 87, 41, -1, 87, 4, 87, -1, -+ 87, 38, 87, -1, 93, 12, 88, -1, 93, 16, -+ 88, -1, 93, 31, 88, -1, 93, 27, 88, -1, -+ 93, 15, 88, -1, 93, 34, 88, -1, 93, 25, -+ 36, -1, 93, 25, 35, 36, -1, 93, -1, 92, -+ -1, 92, -1, 92, 7, 89, -1, 91, -1, 91, -+ 7, 90, -1, 94, 12, 92, -1, 97, -1, 33, -+ 97, -1, 47, -1, 53, -1, 94, -1, 95, 11, -+ 96, -1, 96, -1, 96, -1, 19, -1, 23, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short int yyrline[] = -+{ -+ 0, 124, 124, 132, 133, 134, 135, 136, 137, 141, -+ 151, 164, 176, 191, 201, 214, 227, 237, 247, 260, -+ 264, 271, 281, 291, 298, 307, 311, 315, 322, 326, -+ 333, 337, 341, 345, 349, 353, 357, 364, 373, 386, -+ 390, 394, 410, 431, 432, 436, 443, 444, 460, 470, -+ 483, 488, 497, 503, 509, 515, 521, 527, 533, 539, -+ 545, 551, 557, 566, 567, 571, 578, 589, 590, 598, -+ 606, 612, 618, 624, 633, 642, 648, 657, 664, 673 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "TK_ALTER", "TK_AND", "TK_BY", "TK_CHAR", -+ "TK_COMMA", "TK_CREATE", "TK_DELETE", "TK_DISTINCT", "TK_DOT", "TK_EQ", -+ "TK_FREE", "TK_FROM", "TK_GE", "TK_GT", "TK_HOLD", "TK_ADD", "TK_ID", -+ "TK_ILLEGAL", "TK_INSERT", "TK_INT", "TK_INTEGER", "TK_INTO", "TK_IS", -+ "TK_KEY", "TK_LE", "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LT", -+ "TK_LOCALIZABLE", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NULL", "TK_OBJECT", -+ "TK_OR", "TK_ORDER", "TK_PRIMARY", "TK_RP", "TK_SELECT", "TK_SET", -+ "TK_SHORT", "TK_SPACE", "TK_STAR", "TK_STRING", "TK_TABLE", -+ "TK_TEMPORARY", "TK_UPDATE", "TK_VALUES", "TK_WHERE", "TK_WILDCARD", -+ "AGG_FUNCTION.", "COLUMN", "FUNCTION", "COMMENT", "UNCLOSED_STRING", -+ "SPACE", "ILLEGAL", "END_OF_FILE", "TK_LIKE", "TK_NEGATION", "$accept", -+ "query", "onequery", "oneinsert", "onecreate", "oneupdate", "onedelete", -+ "onealter", "alterop", "table_def", "column_def", "column_and_type", -+ "column_type", "data_type_l", "data_type", "data_count", "oneselect", -+ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", -+ "tablelist", "expr", "val", "constlist", "update_assign_list", -+ "column_assignment", "const_val", "column_val", "column", "table", "id", -+ "number", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short int yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, -+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, -+ 315, 316, 317, 318 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 64, 65, 66, 66, 66, 66, 66, 66, 67, -+ 67, 68, 68, 69, 69, 70, 71, 71, 71, 72, -+ 72, 73, 74, 74, 75, 76, 76, 76, 77, 77, -+ 78, 78, 78, 78, 78, 78, 78, 79, 80, 80, -+ 81, 81, 82, 83, 83, 83, 84, 84, 85, 85, -+ 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, -+ 87, 87, 87, 88, 88, 89, 89, 90, 90, 91, -+ 92, 92, 92, 92, 93, 94, 94, 95, 96, 97 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 10, -+ 11, 6, 7, 6, 4, 2, 4, 5, 6, 1, -+ 1, 4, 3, 1, 2, 1, 2, 2, 1, 3, -+ 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, -+ 2, 3, 2, 1, 3, 1, 1, 3, 2, 2, -+ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, -+ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, -+ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, -+ 4, 6, 7, 8, 3, 39, 0, 0, 0, 15, -+ 46, 0, 0, 78, 45, 40, 0, 43, 0, 76, -+ 0, 77, 1, 0, 0, 0, 49, 48, 0, 0, -+ 41, 42, 0, 0, 0, 0, 20, 19, 0, 16, -+ 0, 0, 0, 47, 0, 74, 0, 44, 75, 14, -+ 67, 0, 38, 17, 0, 0, 0, 23, 51, 50, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 18, 30, 34, 35, 32, 36, -+ 33, 24, 25, 28, 11, 0, 0, 52, 53, 54, -+ 79, 0, 72, 73, 55, 64, 63, 70, 59, 56, -+ 0, 61, 58, 57, 60, 0, 13, 68, 69, 0, -+ 26, 27, 0, 12, 22, 0, 71, 62, 0, 0, -+ 37, 29, 21, 0, 31, 0, 65, 9, 0, 10, -+ 66 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const short int yydefgoto[] = -+{ -+ -1, 7, 8, 9, 10, 11, 12, 13, 49, 65, -+ 66, 63, 91, 92, 93, 129, 14, 15, 25, 26, -+ 19, 20, 36, 53, 104, 135, 59, 60, 105, 106, -+ 55, 28, 29, 107 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -96 -+static const yysigned_char yypact[] = -+{ -+ 0, -43, -34, 4, 24, 1, 6, 19, -96, -96, -+ -96, -96, -96, -96, -96, 31, 6, 6, 6, -96, -+ 30, 6, 35, -96, -96, -96, 4, 67, 47, 65, -+ 42, -96, -96, 81, 101, 59, -96, 89, 48, 68, -+ -96, -96, 35, 6, 6, 35, -96, -96, 6, -96, -+ 6, 6, 48, 3, 76, -96, 35, -96, -96, 45, -+ 95, 93, -96, 98, 43, 75, 22, -96, -96, 89, -+ 18, 48, 48, 13, 13, 13, -23, 13, 13, 13, -+ 80, 48, 6, 46, -96, 87, -96, -96, -96, -96, -+ -96, -96, 51, 71, 105, 6, 97, -96, -96, 120, -+ -96, 102, -96, -96, -96, -96, -96, -96, -96, -96, -+ 90, -96, -96, -96, -96, 77, 3, -96, -96, 102, -+ -96, -96, 91, -96, -96, 35, -96, -96, 99, 92, -+ -96, -96, -96, 46, -96, 94, 123, 82, 46, -96, -+ -96 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -+ -96, -40, -96, -96, -96, -96, -96, -96, 110, -41, -+ 108, -96, 85, 23, 34, -1, 56, -96, -81, -8, -+ -5, 17, 10, -95 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -78 -+static const short int yytable[] = -+{ -+ 27, 57, 118, 1, 62, 16, 126, 71, 2, 3, -+ 67, 22, 110, 111, 17, 80, 31, 27, 18, 32, -+ 23, 4, 71, 30, 130, 23, 31, 31, 31, 95, -+ 54, 31, 23, 34, 35, 37, 100, 27, 39, 61, -+ 27, 72, 5, 64, 54, 64, 101, 24, 21, 85, -+ 6, 27, 136, 58, 23, 124, 72, 136, 43, 97, -+ 102, 31, 96, 54, 54, 86, 103, 23, 69, 100, -+ 33, 87, 88, 54, 42, 70, -77, 61, 52, 101, -+ 89, 24, 38, 120, 132, 44, 45, 90, 73, 50, -+ 64, 74, 75, 102, 98, 99, 51, 81, 56, 103, -+ 121, 76, 82, 77, 116, 83, 122, 78, 108, 109, -+ 79, 112, 113, 114, 46, 84, 94, 119, 47, 48, -+ 27, 115, 123, 125, 71, 100, 127, 131, 128, 133, -+ 138, 139, 40, 134, 41, 137, 68, 140, 117 -+}; -+ -+static const unsigned char yycheck[] = -+{ -+ 5, 42, 83, 3, 45, 48, 101, 4, 8, 9, -+ 50, 10, 35, 36, 48, 56, 6, 22, 14, 0, -+ 19, 21, 4, 6, 119, 19, 16, 17, 18, 7, -+ 38, 21, 19, 16, 17, 18, 23, 42, 21, 44, -+ 45, 38, 42, 48, 52, 50, 33, 46, 24, 6, -+ 50, 56, 133, 43, 19, 95, 38, 138, 11, 41, -+ 47, 51, 40, 71, 72, 22, 53, 19, 51, 23, -+ 39, 28, 29, 81, 7, 52, 11, 82, 30, 33, -+ 37, 46, 52, 32, 125, 43, 5, 44, 12, 30, -+ 95, 15, 16, 47, 71, 72, 7, 52, 30, 53, -+ 49, 25, 7, 27, 81, 12, 35, 31, 74, 75, -+ 34, 77, 78, 79, 13, 17, 41, 30, 17, 18, -+ 125, 41, 17, 26, 4, 23, 36, 36, 51, 30, -+ 7, 49, 22, 41, 26, 41, 51, 138, 82 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 3, 8, 9, 21, 42, 50, 65, 66, 67, -+ 68, 69, 70, 71, 80, 81, 48, 48, 14, 84, -+ 85, 24, 10, 19, 46, 82, 83, 94, 95, 96, -+ 95, 96, 0, 39, 95, 95, 86, 95, 52, 95, -+ 82, 84, 7, 11, 43, 5, 13, 17, 18, 72, -+ 30, 7, 30, 87, 93, 94, 30, 83, 96, 90, -+ 91, 94, 83, 75, 94, 73, 74, 75, 86, 95, -+ 87, 4, 38, 12, 15, 16, 25, 27, 31, 34, -+ 83, 52, 7, 12, 17, 6, 22, 28, 29, 37, -+ 44, 76, 77, 78, 41, 7, 40, 41, 87, 87, -+ 23, 33, 47, 53, 88, 92, 93, 97, 88, 88, -+ 35, 36, 88, 88, 88, 41, 87, 90, 92, 30, -+ 32, 49, 35, 17, 75, 26, 97, 36, 51, 79, -+ 97, 36, 83, 30, 41, 89, 92, 41, 7, 49, -+ 89 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (0) -+ -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) -+#endif -+ -+ -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ -+ -+#ifndef YY_LOCATION_PRINT -+# if YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Type, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short int *bottom, short int *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short int *bottom; -+ short int *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ char *yyd = yydest; -+ const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) -+{ -+ if (*yystr == '"') -+ { -+ size_t yyn = 0; -+ char const *yyp = yystr; -+ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; -+ } -+ -+ if (! yyres) -+ return yystrlen (yystr); -+ -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif -+ -+#endif /* YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ ; -+#endif -+#endif -+{ -+ /* The look-ahead symbol. */ -+int yychar; -+ -+/* The semantic value of the look-ahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ int yystate; -+ int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Look-ahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short int yyssa[YYINITDEPTH]; -+ short int *yyss = yyssa; -+ short int *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short int *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short int *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a look-ahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to look-ahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a look-ahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the look-ahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 125 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ *sql->view = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 9: -+#line 142 "sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, (yyvsp[-7].string), (yyvsp[-5].column_list), (yyvsp[-1].column_list), FALSE ); -+ if( !insert ) -+ YYABORT; -+ (yyval.query) = insert; -+ ;} -+ break; -+ -+ case 10: -+#line 152 "sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, (yyvsp[-8].string), (yyvsp[-6].column_list), (yyvsp[-2].column_list), TRUE ); -+ if( !insert ) -+ YYABORT; -+ (yyval.query) = insert; -+ ;} -+ break; -+ -+ case 11: -+#line 165 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !(yyvsp[-1].column_list) ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, (yyvsp[-3].string), (yyvsp[-1].column_list), FALSE ); -+ if( !create ) -+ YYABORT; -+ (yyval.query) = create; -+ ;} -+ break; -+ -+ case 12: -+#line 177 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !(yyvsp[-2].column_list) ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, (yyvsp[-4].string), (yyvsp[-2].column_list), TRUE ); -+ if( !create ) -+ YYABORT; -+ (yyval.query) = create; -+ ;} -+ break; -+ -+ case 13: -+#line 192 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, (yyvsp[-4].string), (yyvsp[-2].column_list), (yyvsp[0].expr) ); -+ if( !update ) -+ YYABORT; -+ (yyval.query) = update; -+ ;} -+ break; -+ -+ case 14: -+#line 202 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, (yyvsp[-2].string), (yyvsp[0].column_list), NULL ); -+ if( !update ) -+ YYABORT; -+ (yyval.query) = update; -+ ;} -+ break; -+ -+ case 15: -+#line 215 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *delete = NULL; -+ -+ DELETE_CreateView( sql->db, &delete, (yyvsp[0].query) ); -+ if( !delete ) -+ YYABORT; -+ (yyval.query) = delete; -+ ;} -+ break; -+ -+ case 16: -+#line 228 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-1].string), NULL, (yyvsp[0].integer) ); -+ if( !alter ) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 17: -+#line 238 "sql.y" -+ { -+ SQL_input *sql = (SQL_input *)info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-2].string), (yyvsp[0].column_list), 0 ); -+ if (!alter) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 18: -+#line 248 "sql.y" -+ { -+ SQL_input *sql = (SQL_input *)info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-3].string), (yyvsp[-1].column_list), 1 ); -+ if (!alter) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 19: -+#line 261 "sql.y" -+ { -+ (yyval.integer) = 1; -+ ;} -+ break; -+ -+ case 20: -+#line 265 "sql.y" -+ { -+ (yyval.integer) = -1; -+ ;} -+ break; -+ -+ case 21: -+#line 272 "sql.y" -+ { -+ if( SQL_MarkPrimaryKeys( (yyvsp[-3].column_list), (yyvsp[0].column_list) ) ) -+ (yyval.column_list) = (yyvsp[-3].column_list); -+ else -+ (yyval.column_list) = NULL; -+ ;} -+ break; -+ -+ case 22: -+#line 282 "sql.y" -+ { -+ column_info *ci; -+ -+ for( ci = (yyvsp[-2].column_list); ci->next; ci = ci->next ) -+ ; -+ -+ ci->next = (yyvsp[0].column_list); -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ ;} -+ break; -+ -+ case 23: -+#line 292 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 24: -+#line 299 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-1].column_list); -+ (yyval.column_list)->type = ((yyvsp[0].column_type) | MSITYPE_VALID); -+ (yyval.column_list)->temporary = (yyvsp[0].column_type) & MSITYPE_TEMPORARY ? TRUE : FALSE; -+ ;} -+ break; -+ -+ case 25: -+#line 308 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[0].column_type); -+ ;} -+ break; -+ -+ case 26: -+#line 312 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_LOCALIZABLE; -+ ;} -+ break; -+ -+ case 27: -+#line 316 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_TEMPORARY; -+ ;} -+ break; -+ -+ case 28: -+#line 323 "sql.y" -+ { -+ (yyval.column_type) |= MSITYPE_NULLABLE; -+ ;} -+ break; -+ -+ case 29: -+#line 327 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-2].column_type); -+ ;} -+ break; -+ -+ case 30: -+#line 334 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | 1; -+ ;} -+ break; -+ -+ case 31: -+#line 338 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[-1].column_type); -+ ;} -+ break; -+ -+ case 32: -+#line 342 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 33: -+#line 346 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 34: -+#line 350 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 35: -+#line 354 "sql.y" -+ { -+ (yyval.column_type) = 4; -+ ;} -+ break; -+ -+ case 36: -+#line 358 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 37: -+#line 365 "sql.y" -+ { -+ if( ( (yyvsp[0].integer) > 255 ) || ( (yyvsp[0].integer) < 0 ) ) -+ YYABORT; -+ (yyval.column_type) = (yyvsp[0].integer); -+ ;} -+ break; -+ -+ case 38: -+#line 374 "sql.y" -+ { -+ UINT r; -+ -+ if( (yyvsp[0].column_list) ) -+ { -+ r = (yyvsp[-3].query)->ops->sort( (yyvsp[-3].query), (yyvsp[0].column_list) ); -+ if ( r != ERROR_SUCCESS) -+ YYABORT; -+ } -+ -+ (yyval.query) = (yyvsp[-3].query); -+ ;} -+ break; -+ -+ case 40: -+#line 391 "sql.y" -+ { -+ (yyval.query) = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 41: -+#line 395 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = DISTINCT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query) ); -+ if (r != ERROR_SUCCESS) -+ { -+ (yyvsp[0].query)->ops->delete((yyvsp[0].query)); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 42: -+#line 411 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ if( (yyvsp[-1].column_list) ) -+ { -+ r = SELECT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query), (yyvsp[-1].column_list) ); -+ if (r != ERROR_SUCCESS) -+ { -+ (yyvsp[0].query)->ops->delete((yyvsp[0].query)); -+ YYABORT; -+ } -+ } -+ else -+ (yyval.query) = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 44: -+#line 433 "sql.y" -+ { -+ (yyvsp[-2].column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 45: -+#line 437 "sql.y" -+ { -+ (yyval.column_list) = NULL; -+ ;} -+ break; -+ -+ case 47: -+#line 445 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = WHERE_CreateView( sql->db, &(yyval.query), (yyvsp[-2].query), (yyvsp[0].expr) ); -+ if( r != ERROR_SUCCESS ) -+ { -+ (yyvsp[-2].query)->ops->delete( (yyvsp[-2].query) ); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 48: -+#line 461 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = TABLE_CreateView( sql->db, (yyvsp[0].string), &(yyval.query) ); -+ if( r != ERROR_SUCCESS || !(yyval.query) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 49: -+#line 471 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ r = JOIN_CreateView( sql->db, &(yyval.query), (yyvsp[0].string) ); -+ msi_free( (yyvsp[0].string) ); -+ if( r != ERROR_SUCCESS ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 50: -+#line 484 "sql.y" -+ { -+ (yyval.string) = strdupW((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 51: -+#line 489 "sql.y" -+ { -+ (yyval.string) = parser_add_table((yyvsp[0].string), (yyvsp[-2].string)); -+ if (!(yyval.string)) -+ YYABORT; -+ ;} -+ break; -+ -+ case 52: -+#line 498 "sql.y" -+ { -+ (yyval.expr) = (yyvsp[-1].expr); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 53: -+#line 504 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 54: -+#line 510 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 55: -+#line 516 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 56: -+#line 522 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 57: -+#line 528 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 58: -+#line 534 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 59: -+#line 540 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 60: -+#line 546 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 61: -+#line 552 "sql.y" -+ { -+ (yyval.expr) = EXPR_unary( info, (yyvsp[-2].expr), OP_ISNULL ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 62: -+#line 558 "sql.y" -+ { -+ (yyval.expr) = EXPR_unary( info, (yyvsp[-3].expr), OP_NOTNULL ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 572 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ (yyval.column_list)->val = (yyvsp[0].expr); -+ ;} -+ break; -+ -+ case 66: -+#line 579 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ (yyval.column_list)->val = (yyvsp[-2].expr); -+ (yyval.column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 68: -+#line 591 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ (yyval.column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 69: -+#line 599 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ (yyval.column_list)->val = (yyvsp[0].expr); -+ ;} -+ break; -+ -+ case 70: -+#line 607 "sql.y" -+ { -+ (yyval.expr) = EXPR_ival( info, (yyvsp[0].integer) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 71: -+#line 613 "sql.y" -+ { -+ (yyval.expr) = EXPR_ival( info, -(yyvsp[0].integer) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 72: -+#line 619 "sql.y" -+ { -+ (yyval.expr) = EXPR_sval( info, &(yyvsp[0].str) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 73: -+#line 625 "sql.y" -+ { -+ (yyval.expr) = EXPR_wildcard( info ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 74: -+#line 634 "sql.y" -+ { -+ (yyval.expr) = EXPR_column( info, (yyvsp[0].column_list) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 75: -+#line 643 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, (yyvsp[-2].string), (yyvsp[0].string) ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 76: -+#line 649 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[0].string) ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 77: -+#line 658 "sql.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 78: -+#line 665 "sql.y" -+ { -+ (yyval.string) = SQL_getstring( info, &(yyvsp[0].str) ); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 79: -+#line 674 "sql.y" -+ { -+ (yyval.integer) = SQL_getint( info ); -+ ;} -+ break; -+ -+ -+ default: break; -+ } -+ -+/* Line 1126 of yacc.c. */ -+#line 2080 "sql.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ int yytype = YYTRANSLATE (yychar); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); -+ YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; -+ int yysize_overflow = 0; -+ char *yymsg = 0; -+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ int yyx; -+ -+#if 0 -+ /* This is so xgettext sees the translatable formats that are -+ constructed on the fly. */ -+ YY_("syntax error, unexpected %s"); -+ YY_("syntax error, unexpected %s, expecting %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -+#endif -+ char *yyfmt; -+ char const *yyf; -+ static char const yyunexpected[] = "syntax error, unexpected %s"; -+ static char const yyexpecting[] = ", expecting %s"; -+ static char const yyor[] = " or %s"; -+ char yyformat[sizeof yyunexpected -+ + sizeof yyexpecting - 1 -+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) -+ * (sizeof yyor - 1))]; -+ char const *yyprefix = yyexpecting; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 1; -+ -+ yyarg[0] = yytname[yytype]; -+ yyfmt = yystpcpy (yyformat, yyunexpected); -+ -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ yyformat[sizeof yyunexpected - 1] = '\0'; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ yyfmt = yystpcpy (yyfmt, yyprefix); -+ yyprefix = yyor; -+ } -+ -+ yyf = YY_(yyformat); -+ yysize1 = yysize + yystrlen (yyf); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ -+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg) -+ { -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ char *yyp = yymsg; -+ int yyi = 0; -+ while ((*yyp = *yyf)) -+ { -+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyf += 2; -+ } -+ else -+ { -+ yyp++; -+ yyf++; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ { -+ yyerror (YY_("syntax error")); -+ goto yyexhaustedlab; -+ } -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror (YY_("syntax error")); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse look-ahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", yytoken, &yylval); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse look-ahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (0) -+ goto yyerrorlab; -+ -+yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ -+ yydestruct ("Error: popping", yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEOF && yychar != YYEMPTY) -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp); -+ YYPOPSTACK; -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 679 "sql.y" -+ -+ -+static LPWSTR parser_add_table(LPWSTR list, LPWSTR table) -+{ -+ DWORD size = lstrlenW(list) + lstrlenW(table) + 2; -+ static const WCHAR space[] = {' ',0}; -+ -+ list = msi_realloc(list, size * sizeof(WCHAR)); -+ if (!list) return NULL; -+ -+ lstrcatW(list, space); -+ lstrcatW(list, table); -+ return list; -+} -+ -+static void *parser_alloc( void *info, unsigned int sz ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ struct list *mem; -+ -+ mem = msi_alloc( sizeof (struct list) + sz ); -+ list_add_tail( sql->mem, mem ); -+ return &mem[1]; -+} -+ -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) -+{ -+ column_info *col; -+ -+ col = parser_alloc( info, sizeof (*col) ); -+ if( col ) -+ { -+ col->table = table; -+ col->column = column; -+ col->val = NULL; -+ col->type = 0; -+ col->next = NULL; -+ } -+ -+ return col; -+} -+ -+static int sql_lex( void *SQL_lval, SQL_input *sql ) -+{ -+ int token; -+ struct sql_str * str = SQL_lval; -+ -+ do -+ { -+ sql->n += sql->len; -+ if( ! sql->command[sql->n] ) -+ return 0; /* end of input */ -+ -+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ -+ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); -+ if( sql->len==0 ) -+ break; -+ str->data = &sql->command[sql->n]; -+ str->len = sql->len; -+ } -+ while( token == TK_SPACE ); -+ -+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ -+ -+ return token; -+} -+ -+LPWSTR SQL_getstring( void *info, const struct sql_str *strdata ) -+{ -+ LPCWSTR p = strdata->data; -+ UINT len = strdata->len; -+ LPWSTR str; -+ -+ /* if there's quotes, remove them */ -+ if( ( (p[0]=='`') && (p[len-1]=='`') ) || -+ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) -+ { -+ p++; -+ len -= 2; -+ } -+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); -+ if( !str ) -+ return str; -+ memcpy( str, p, len*sizeof(WCHAR) ); -+ str[len]=0; -+ -+ return str; -+} -+ -+INT SQL_getint( void *info ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ LPCWSTR p = &sql->command[sql->n]; -+ INT i, r = 0; -+ -+ for( i=0; ilen; i++ ) -+ { -+ if( '0' > p[i] || '9' < p[i] ) -+ { -+ ERR("should only be numbers here!\n"); -+ break; -+ } -+ r = (p[i]-'0') + r*10; -+ } -+ -+ return r; -+} -+ -+static int sql_error( const char *str ) -+{ -+ return 0; -+} -+ -+static struct expr * EXPR_wildcard( void *info ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_WILDCARD; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COMPLEX; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = r; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_UNARY; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = NULL; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_column( void *info, const column_info *column ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COLUMN; -+ e->u.sval = column->column; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_ival( void *info, int val ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_IVAL; -+ e->u.ival = val; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_sval( void *info, const struct sql_str *str ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_SVAL; -+ e->u.sval = SQL_getstring( info, str ); -+ } -+ return e; -+} -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, -+ column_info *keys ) -+{ -+ column_info *k; -+ BOOL found = TRUE; -+ -+ for( k = keys; k && found; k = k->next ) -+ { -+ column_info *c; -+ -+ found = FALSE; -+ for( c = cols; c && !found; c = c->next ) -+ { -+ if( lstrcmpW( k->column, c->column ) ) -+ continue; -+ c->type |= MSITYPE_KEY; -+ found = TRUE; -+ } -+ } -+ -+ return found; -+} -+ -+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, -+ struct list *mem ) -+{ -+ SQL_input sql; -+ int r; -+ -+ *phview = NULL; -+ -+ sql.db = db; -+ sql.command = command; -+ sql.n = 0; -+ sql.len = 0; -+ sql.view = phview; -+ sql.mem = mem; -+ -+ r = sql_parse(&sql); -+ -+ TRACE("Parse returned %d\n", r); -+ if( r ) -+ { -+ *sql.view = NULL; -+ return ERROR_BAD_QUERY_SYNTAX; -+ } -+ -+ return ERROR_SUCCESS; -+} -+ -Index: sql.tab.h -=================================================================== ---- sql.tab.h (revision 31639) -+++ sql.tab.h (working copy) -@@ -0,0 +1,180 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ 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, 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., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ALTER = 258, -+ TK_AND = 259, -+ TK_BY = 260, -+ TK_CHAR = 261, -+ TK_COMMA = 262, -+ TK_CREATE = 263, -+ TK_DELETE = 264, -+ TK_DISTINCT = 265, -+ TK_DOT = 266, -+ TK_EQ = 267, -+ TK_FREE = 268, -+ TK_FROM = 269, -+ TK_GE = 270, -+ TK_GT = 271, -+ TK_HOLD = 272, -+ TK_ADD = 273, -+ TK_ID = 274, -+ TK_ILLEGAL = 275, -+ TK_INSERT = 276, -+ TK_INT = 277, -+ TK_INTEGER = 278, -+ TK_INTO = 279, -+ TK_IS = 280, -+ TK_KEY = 281, -+ TK_LE = 282, -+ TK_LONG = 283, -+ TK_LONGCHAR = 284, -+ TK_LP = 285, -+ TK_LT = 286, -+ TK_LOCALIZABLE = 287, -+ TK_MINUS = 288, -+ TK_NE = 289, -+ TK_NOT = 290, -+ TK_NULL = 291, -+ TK_OBJECT = 292, -+ TK_OR = 293, -+ TK_ORDER = 294, -+ TK_PRIMARY = 295, -+ TK_RP = 296, -+ TK_SELECT = 297, -+ TK_SET = 298, -+ TK_SHORT = 299, -+ TK_SPACE = 300, -+ TK_STAR = 301, -+ TK_STRING = 302, -+ TK_TABLE = 303, -+ TK_TEMPORARY = 304, -+ TK_UPDATE = 305, -+ TK_VALUES = 306, -+ TK_WHERE = 307, -+ TK_WILDCARD = 308, -+ COLUMN = 310, -+ FUNCTION = 311, -+ COMMENT = 312, -+ UNCLOSED_STRING = 313, -+ SPACE = 314, -+ ILLEGAL = 315, -+ END_OF_FILE = 316, -+ TK_LIKE = 317, -+ TK_NEGATION = 318 -+ }; -+#endif -+/* Tokens. */ -+#define TK_ALTER 258 -+#define TK_AND 259 -+#define TK_BY 260 -+#define TK_CHAR 261 -+#define TK_COMMA 262 -+#define TK_CREATE 263 -+#define TK_DELETE 264 -+#define TK_DISTINCT 265 -+#define TK_DOT 266 -+#define TK_EQ 267 -+#define TK_FREE 268 -+#define TK_FROM 269 -+#define TK_GE 270 -+#define TK_GT 271 -+#define TK_HOLD 272 -+#define TK_ADD 273 -+#define TK_ID 274 -+#define TK_ILLEGAL 275 -+#define TK_INSERT 276 -+#define TK_INT 277 -+#define TK_INTEGER 278 -+#define TK_INTO 279 -+#define TK_IS 280 -+#define TK_KEY 281 -+#define TK_LE 282 -+#define TK_LONG 283 -+#define TK_LONGCHAR 284 -+#define TK_LP 285 -+#define TK_LT 286 -+#define TK_LOCALIZABLE 287 -+#define TK_MINUS 288 -+#define TK_NE 289 -+#define TK_NOT 290 -+#define TK_NULL 291 -+#define TK_OBJECT 292 -+#define TK_OR 293 -+#define TK_ORDER 294 -+#define TK_PRIMARY 295 -+#define TK_RP 296 -+#define TK_SELECT 297 -+#define TK_SET 298 -+#define TK_SHORT 299 -+#define TK_SPACE 300 -+#define TK_STAR 301 -+#define TK_STRING 302 -+#define TK_TABLE 303 -+#define TK_TEMPORARY 304 -+#define TK_UPDATE 305 -+#define TK_VALUES 306 -+#define TK_WHERE 307 -+#define TK_WILDCARD 308 -+#define COLUMN 310 -+#define FUNCTION 311 -+#define COMMENT 312 -+#define UNCLOSED_STRING 313 -+#define SPACE 314 -+#define ILLEGAL 315 -+#define END_OF_FILE 316 -+#define TK_LIKE 317 -+#define TK_NEGATION 318 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 74 "sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 1447 of yacc.c. */ -+#line 172 "sql.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ From 348790ffe63c650d1b4d6993f94d469787a9fe61 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 08:55:43 +0000 Subject: [PATCH 073/292] [MSI] sync to wine 1.2 RC2 svn path=/trunk/; revision=47397 --- reactos/dll/win32/msi/action.c | 784 ++++++++++++++++++----------- reactos/dll/win32/msi/appsearch.c | 31 +- reactos/dll/win32/msi/automation.c | 12 +- reactos/dll/win32/msi/classes.c | 415 +++++++++++---- reactos/dll/win32/msi/cond.tab.c | 2 +- reactos/dll/win32/msi/cond.y | 2 +- reactos/dll/win32/msi/custom.c | 34 +- reactos/dll/win32/msi/database.c | 102 ++-- reactos/dll/win32/msi/dialog.c | 257 ++++++++-- reactos/dll/win32/msi/events.c | 17 +- reactos/dll/win32/msi/files.c | 67 +-- reactos/dll/win32/msi/font.c | 5 - reactos/dll/win32/msi/format.c | 8 +- reactos/dll/win32/msi/helpers.c | 20 +- reactos/dll/win32/msi/install.c | 8 +- reactos/dll/win32/msi/media.c | 331 ++++++++---- reactos/dll/win32/msi/msi.c | 109 ++-- reactos/dll/win32/msi/msi.spec | 4 +- reactos/dll/win32/msi/msi_Bg.rc | 28 +- reactos/dll/win32/msi/msi_Da.rc | 28 +- reactos/dll/win32/msi/msi_De.rc | 29 +- reactos/dll/win32/msi/msi_En.rc | 29 +- reactos/dll/win32/msi/msi_Eo.rc | 28 +- reactos/dll/win32/msi/msi_Es.rc | 28 +- reactos/dll/win32/msi/msi_Fi.rc | 28 +- reactos/dll/win32/msi/msi_Fr.rc | 29 +- reactos/dll/win32/msi/msi_Hu.rc | 28 +- reactos/dll/win32/msi/msi_It.rc | 28 +- reactos/dll/win32/msi/msi_Ko.rc | 28 +- reactos/dll/win32/msi/msi_Lt.rc | 28 +- reactos/dll/win32/msi/msi_Nl.rc | 36 +- reactos/dll/win32/msi/msi_No.rc | 28 +- reactos/dll/win32/msi/msi_Pl.rc | 28 +- reactos/dll/win32/msi/msi_Pt.rc | 56 ++- reactos/dll/win32/msi/msi_Ro.rc | 28 +- reactos/dll/win32/msi/msi_Ru.rc | 28 +- reactos/dll/win32/msi/msi_Si.rc | 28 +- reactos/dll/win32/msi/msi_Sv.rc | 28 +- reactos/dll/win32/msi/msi_Tr.rc | 28 +- reactos/dll/win32/msi/msi_Uk.rc | 28 +- reactos/dll/win32/msi/msi_Zh.rc | 56 ++- reactos/dll/win32/msi/msipriv.h | 53 +- reactos/dll/win32/msi/package.c | 294 +++++++---- reactos/dll/win32/msi/registry.c | 115 ++++- reactos/dll/win32/msi/script.c | 4 +- reactos/dll/win32/msi/storages.c | 14 +- reactos/dll/win32/msi/streams.c | 6 +- reactos/dll/win32/msi/string.c | 44 +- reactos/dll/win32/msi/table.c | 2 +- reactos/dll/win32/msi/upgrade.c | 53 +- 50 files changed, 2564 insertions(+), 940 deletions(-) diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index 81dcba43ae9..4c5597279ab 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -96,8 +96,6 @@ static const WCHAR szAllocateRegistrySpace[] = {'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y','S','p','a','c','e',0}; static const WCHAR szBindImage[] = {'B','i','n','d','I','m','a','g','e',0}; -static const WCHAR szCCPSearch[] = - {'C','C','P','S','e','a','r','c','h',0}; static const WCHAR szDeleteServices[] = {'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0}; static const WCHAR szDisableRollback[] = @@ -126,8 +124,6 @@ static const WCHAR szPublishComponents[] = {'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szRegisterComPlus[] = {'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0}; -static const WCHAR szRegisterFonts[] = - {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; static const WCHAR szRegisterUser[] = {'R','e','g','i','s','t','e','r','U','s','e','r',0}; static const WCHAR szRemoveEnvironmentStrings[] = @@ -160,18 +156,8 @@ static const WCHAR szUnpublishComponents[] = {'U','n','p','u','b','l','i','s','h', 'C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szUnpublishFeatures[] = {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0}; -static const WCHAR szUnregisterClassInfo[] = - {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0}; static const WCHAR szUnregisterComPlus[] = {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0}; -static const WCHAR szUnregisterExtensionInfo[] = - {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0}; -static const WCHAR szUnregisterFonts[] = - {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; -static const WCHAR szUnregisterMIMEInfo[] = - {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0}; -static const WCHAR szUnregisterProgIdInfo[] = - {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0}; static const WCHAR szUnregisterTypeLibraries[] = {'U','n','r','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0}; static const WCHAR szValidateProductID[] = @@ -291,9 +277,13 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, if (lstrlenW(prop) > 0) { + UINT r = msi_set_property( package->db, prop, val ); + TRACE("Found commandline property (%s) = (%s)\n", debugstr_w(prop), debugstr_w(val)); - MSI_SetPropertyW(package,prop,val); + + if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) + msi_reset_folders( package, TRUE ); } msi_free(val); msi_free(prop); @@ -347,7 +337,7 @@ static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch LPWSTR prod_code, patch_product, langid = NULL, template = NULL; UINT ret = ERROR_FUNCTION_FAILED; - prod_code = msi_dup_property( package, szProductCode ); + prod_code = msi_dup_property( package->db, szProductCode ); patch_product = msi_get_suminfo_product( patch ); TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product)); @@ -379,7 +369,7 @@ static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch goto end; } - langid = msi_dup_property( package, szSystemLanguageID ); + langid = msi_dup_property( package->db, szSystemLanguageID ); if (!langid) { msiobj_release( &si->hdr ); @@ -443,7 +433,7 @@ UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) LPWSTR guid_list, *guids, product_code; UINT i, ret = ERROR_FUNCTION_FAILED; - product_code = msi_dup_property( package, szProductCode ); + product_code = msi_dup_property( package->db, szProductCode ); if (!product_code) { /* FIXME: the property ProductCode should be written into the DB somewhere */ @@ -490,8 +480,8 @@ static UINT msi_set_media_source_prop(MSIPACKAGE *package) if (MSI_ViewFetch(view, &rec) == ERROR_SUCCESS) { prop = MSI_RecordGetString(rec, 1); - patch = msi_dup_property(package, szPatch); - MSI_SetPropertyW(package, prop, patch); + patch = msi_dup_property(package->db, szPatch); + msi_set_property(package->db, prop, patch); msi_free(patch); } @@ -502,76 +492,130 @@ done: return r; } -static UINT msi_parse_patch_summary( MSIPACKAGE *package, MSIDATABASE *patch_db ) +UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) { - MSISUMMARYINFO *si; - LPWSTR str, *substorage; - UINT i, r = ERROR_SUCCESS; + MSIPATCHINFO *pi; + UINT r = ERROR_SUCCESS; - si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); - if (!si) - return ERROR_FUNCTION_FAILED; + pi = msi_alloc_zero( sizeof(MSIPATCHINFO) ); + if (!pi) + return ERROR_OUTOFMEMORY; - if (msi_check_patch_applicable( package, si ) != ERROR_SUCCESS) + pi->patchcode = msi_suminfo_dup_string( si, PID_REVNUMBER ); + if (!pi->patchcode) { - TRACE("Patch not applicable\n"); - return ERROR_SUCCESS; + msi_free( pi ); + return ERROR_OUTOFMEMORY; } - package->patch = msi_alloc(sizeof(MSIPATCHINFO)); - if (!package->patch) + pi->transforms = msi_suminfo_dup_string( si, PID_LASTAUTHOR ); + if (!pi->transforms) + { + msi_free( pi->patchcode ); + msi_free( pi ); return ERROR_OUTOFMEMORY; + } - package->patch->patchcode = msi_suminfo_dup_string(si, PID_REVNUMBER); - if (!package->patch->patchcode) - return ERROR_OUTOFMEMORY; + *patch = pi; + return r; +} - /* enumerate the substorage */ - str = msi_suminfo_dup_string( si, PID_LASTAUTHOR ); - package->patch->transforms = str; +UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch ) +{ + UINT i, r = ERROR_SUCCESS; + WCHAR **substorage; - substorage = msi_split_string( str, ';' ); - for ( i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++ ) + /* apply substorage transforms */ + substorage = msi_split_string( patch->transforms, ';' ); + for (i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++) r = msi_apply_substorage_transform( package, patch_db, substorage[i] ); msi_free( substorage ); - msiobj_release( &si->hdr ); + if (r != ERROR_SUCCESS) + return r; - msi_set_media_source_prop(package); + msi_set_media_source_prop( package ); - return r; + /* + * There might be a CAB file in the patch package, + * so append it to the list of storages to search for streams. + */ + append_storage_to_db( package->db, patch_db->storage ); + + list_add_tail( &package->patches, &patch->entry ); + return ERROR_SUCCESS; } static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file ) { + static const WCHAR dotmsp[] = {'.','m','s','p',0}; MSIDATABASE *patch_db = NULL; - UINT r; + WCHAR localfile[MAX_PATH]; + MSISUMMARYINFO *si; + MSIPATCHINFO *patch = NULL; + UINT r = ERROR_SUCCESS; TRACE("%p %s\n", package, debugstr_w( file ) ); - /* FIXME: - * We probably want to make sure we only open a patch collection here. - * Patch collections (.msp) and databases (.msi) have different GUIDs - * but currently MSI_OpenDatabaseW will accept both. - */ - r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &patch_db ); + r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db ); if ( r != ERROR_SUCCESS ) { ERR("failed to open patch collection %s\n", debugstr_w( file ) ); return r; } - msi_parse_patch_summary( package, patch_db ); + si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); + if (!si) + { + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; + } - /* - * There might be a CAB file in the patch package, - * so append it to the list of storage to search for streams. - */ - append_storage_to_db( package->db, patch_db->storage ); + r = msi_check_patch_applicable( package, si ); + if (r != ERROR_SUCCESS) + { + TRACE("patch not applicable\n"); + r = ERROR_SUCCESS; + goto done; + } + r = msi_parse_patch_summary( si, &patch ); + if ( r != ERROR_SUCCESS ) + goto done; + + r = msi_get_local_package_name( localfile, dotmsp ); + if ( r != ERROR_SUCCESS ) + goto done; + + TRACE("copying to local package %s\n", debugstr_w(localfile)); + + if (!CopyFileW( file, localfile, FALSE )) + { + ERR("Unable to copy package (%s -> %s) (error %u)\n", + debugstr_w(file), debugstr_w(localfile), GetLastError()); + r = GetLastError(); + goto done; + } + patch->localfile = strdupW( localfile ); + + r = msi_apply_patch_db( package, patch_db, patch ); + if ( r != ERROR_SUCCESS ) + WARN("patch failed to apply %u\n", r); + +done: + msiobj_release( &si->hdr ); msiobj_release( &patch_db->hdr ); + if (patch && r != ERROR_SUCCESS) + { + if (patch->localfile) + DeleteFileW( patch->localfile ); - return ERROR_SUCCESS; + msi_free( patch->patchcode ); + msi_free( patch->transforms ); + msi_free( patch->localfile ); + msi_free( patch ); + } + return r; } /* get the PATCH property, and apply all the patches it specifies */ @@ -580,7 +624,7 @@ static UINT msi_apply_patches( MSIPACKAGE *package ) LPWSTR patch_list, *patches; UINT i, r = ERROR_SUCCESS; - patch_list = msi_dup_property( package, szPatch ); + patch_list = msi_dup_property( package->db, szPatch ); TRACE("patches to be applied: %s\n", debugstr_w( patch_list ) ); @@ -601,7 +645,7 @@ static UINT msi_apply_transforms( MSIPACKAGE *package ) LPWSTR xform_list, *xforms; UINT i, r = ERROR_SUCCESS; - xform_list = msi_dup_property( package, szTransforms ); + xform_list = msi_dup_property( package->db, szTransforms ); xforms = msi_split_string( xform_list, ';' ); for( i=0; xforms && xforms[i] && r == ERROR_SUCCESS; i++ ) @@ -644,71 +688,76 @@ static BOOL ui_sequence_exists( MSIPACKAGE *package ) static UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) { - LPWSTR p, db; LPWSTR source, check; - DWORD len; - static const WCHAR szOriginalDatabase[] = - {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; - - db = msi_dup_property( package, szOriginalDatabase ); - if (!db) - return ERROR_OUTOFMEMORY; - - p = strrchrW( db, '\\' ); - if (!p) + if (msi_get_property_int( package->db, szInstalled, 0 )) { - p = strrchrW( db, '/' ); + HKEY hkey; + + MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE ); + source = msi_reg_get_val_str( hkey, INSTALLPROPERTY_INSTALLSOURCEW ); + RegCloseKey( hkey ); + } + else + { + LPWSTR p, db; + DWORD len; + + db = msi_dup_property( package->db, szOriginalDatabase ); + if (!db) + return ERROR_OUTOFMEMORY; + + p = strrchrW( db, '\\' ); if (!p) { - msi_free(db); - return ERROR_SUCCESS; + p = strrchrW( db, '/' ); + if (!p) + { + msi_free(db); + return ERROR_SUCCESS; + } } + + len = p - db + 2; + source = msi_alloc( len * sizeof(WCHAR) ); + lstrcpynW( source, db, len ); + msi_free( db ); } - len = p - db + 2; - source = msi_alloc( len * sizeof(WCHAR) ); - lstrcpynW( source, db, len ); - - check = msi_dup_property( package, cszSourceDir ); + check = msi_dup_property( package->db, cszSourceDir ); if (!check || replace) - MSI_SetPropertyW( package, cszSourceDir, source ); - + { + UINT r = msi_set_property( package->db, cszSourceDir, source ); + if (r == ERROR_SUCCESS) + msi_reset_folders( package, TRUE ); + } msi_free( check ); - check = msi_dup_property( package, cszSOURCEDIR ); + check = msi_dup_property( package->db, cszSOURCEDIR ); if (!check || replace) - MSI_SetPropertyW( package, cszSOURCEDIR, source ); + msi_set_property( package->db, cszSOURCEDIR, source ); msi_free( check ); msi_free( source ); - msi_free( db ); return ERROR_SUCCESS; } static BOOL needs_ui_sequence(MSIPACKAGE *package) { - INT level = msi_get_property_int(package, szUILevel, 0); + INT level = msi_get_property_int(package->db, szUILevel, 0); return (level & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED; } -static UINT msi_set_context(MSIPACKAGE *package) +UINT msi_set_context(MSIPACKAGE *package) { - WCHAR val[10]; - DWORD sz = 10; - DWORD num; - UINT r; + int num; package->Context = MSIINSTALLCONTEXT_USERUNMANAGED; - r = MSI_GetPropertyW(package, szAllUsers, val, &sz); - if (r == ERROR_SUCCESS) - { - num = atolW(val); - if (num == 1 || num == 2) - package->Context = MSIINSTALLCONTEXT_MACHINE; - } + num = msi_get_property_int(package->db, szAllUsers, 0); + if (num == 1 || num == 2) + package->Context = MSIINSTALLCONTEXT_MACHINE; return ERROR_SUCCESS; } @@ -1325,6 +1374,26 @@ done: return r; } +static UINT load_file_disk_id( MSIPACKAGE *package, MSIFILE *file ) +{ + MSIRECORD *row; + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','`','D','i','s','k','I','d','`',' ', 'F','R','O','M',' ', + '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', + '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',' ','%','i',0}; + + row = MSI_QueryGetRecord( package->db, query, file->Sequence ); + if (!row) + { + WARN("query failed\n"); + return ERROR_FUNCTION_FAILED; + } + + file->disk_id = MSI_RecordGetInteger( row, 1 ); + msiobj_release( &row->hdr ); + return ERROR_SUCCESS; +} + static UINT load_file(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = param; @@ -1386,6 +1455,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param) } load_file_hash(package, file); + load_file_disk_id(package, file); TRACE("File Loaded (%s)\n",debugstr_w(file->File)); @@ -1470,7 +1540,7 @@ static UINT load_folder( MSIRECORD *row, LPVOID param ) folder->Parent = msi_dup_record_field( row, 2 ); - folder->Property = msi_dup_property( package, folder->Directory ); + folder->Property = msi_dup_property( package->db, folder->Directory ); list_add_tail( &package->folders, &folder->entry ); @@ -1517,8 +1587,8 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package) static const WCHAR szCosting[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 }; - MSI_SetPropertyW(package, szCosting, szZero); - MSI_SetPropertyW(package, cszRootDrive, c_colon); + msi_set_property( package->db, szCosting, szZero ); + msi_set_property( package->db, cszRootDrive, c_colon ); load_all_folders( package ); load_all_components( package ); @@ -1611,7 +1681,7 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, LPWSTR override; MSIFEATURE *feature; - override = msi_dup_property( package, property ); + override = msi_dup_property( package->db, property ); if (!override) return FALSE; @@ -1688,7 +1758,7 @@ static BOOL process_overrides( MSIPACKAGE *package, int level ) ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED ); if (ret) - MSI_SetPropertyW( package, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne ); return ret; } @@ -1703,9 +1773,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) TRACE("Checking Install Level\n"); - level = msi_get_property_int(package, szlevel, 1); + level = msi_get_property_int(package->db, szlevel, 1); - if (!msi_get_property_int( package, szPreselected, 0 )) + if (!msi_get_property_int( package->db, szPreselected, 0 )) { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { @@ -1906,7 +1976,7 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } -static LPWSTR msi_get_disk_file_version( LPCWSTR filename ) +static LPWSTR get_disk_file_version( LPCWSTR filename ) { static const WCHAR name_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; @@ -1944,7 +2014,36 @@ static LPWSTR msi_get_disk_file_version( LPCWSTR filename ) return strdupW( filever ); } -static UINT msi_check_file_install_states( MSIPACKAGE *package ) +static DWORD get_disk_file_size( LPCWSTR filename ) +{ + HANDLE file; + DWORD size; + + TRACE("%s\n", debugstr_w(filename)); + + file = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); + if (file == INVALID_HANDLE_VALUE) + return INVALID_FILE_SIZE; + + size = GetFileSize( file, NULL ); + CloseHandle( file ); + return size; +} + +static BOOL hash_matches( MSIFILE *file ) +{ + UINT r; + MSIFILEHASHINFO hash; + + hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); + r = MsiGetFileHashW( file->TargetPath, 0, &hash ); + if (r != ERROR_SUCCESS) + return FALSE; + + return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) ); +} + +static UINT set_file_install_states( MSIPACKAGE *package ) { LPWSTR file_version; MSIFILE *file; @@ -1952,6 +2051,7 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package ) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { MSICOMPONENT* comp = file->Component; + DWORD file_size; LPWSTR p; if (!comp) @@ -1975,38 +2075,43 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package ) TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath)); - /* don't check files of components that aren't installed */ - if (comp->Installed == INSTALLSTATE_UNKNOWN || - comp->Installed == INSTALLSTATE_ABSENT) - { - file->state = msifs_missing; /* assume files are missing */ - continue; - } - if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { file->state = msifs_missing; comp->Cost += file->FileSize; continue; } - - if (file->Version && - (file_version = msi_get_disk_file_version( file->TargetPath ))) + if (file->Version && (file_version = get_disk_file_version( file->TargetPath ))) { - TRACE("new %s old %s\n", debugstr_w(file->Version), - debugstr_w(file_version)); - /* FIXME: seems like a bad way to compare version numbers */ - if (lstrcmpiW(file_version, file->Version)<0) + TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version)); + + if (strcmpiW(file_version, file->Version) < 0) { file->state = msifs_overwrite; comp->Cost += file->FileSize; } else + { + TRACE("Destination file version equal or greater, not overwriting\n"); file->state = msifs_present; + } msi_free( file_version ); + continue; } - else + if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) + { + file->state = msifs_overwrite; + comp->Cost += file->FileSize - file_size; + continue; + } + if (file->hash.dwFileHashInfoSize && hash_matches( file )) + { + TRACE("File hashes match, not overwriting\n"); file->state = msifs_present; + continue; + } + file->state = msifs_overwrite; + comp->Cost += file->FileSize - file_size; } return ERROR_SUCCESS; @@ -2051,12 +2156,12 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) ACTION_GetComponentInstallStates(package); ACTION_GetFeatureInstallStates(package); - TRACE("File calculations\n"); - msi_check_file_install_states( package ); + TRACE("Calculating file install states\n"); + set_file_install_states( package ); - if (!process_overrides( package, msi_get_property_int( package, szlevel, 1 ) )) + if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) )) { - TRACE("Evaluating Condition Table\n"); + TRACE("Evaluating feature conditions\n"); rc = MSI_DatabaseOpenViewW( package->db, ConditionQuery, &view ); if (rc == ERROR_SUCCESS) @@ -2064,29 +2169,29 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package ); msiobj_release( &view->hdr ); } + } + TRACE("Evaluating component conditions\n"); - TRACE("Enabling or Disabling Components\n"); - LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) { - if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) - { - TRACE("Disabling component %s\n", debugstr_w(comp->Component)); - comp->Enabled = FALSE; - } - else - comp->Enabled = TRUE; + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; } + else + comp->Enabled = TRUE; } - MSI_SetPropertyW(package,szCosting,szOne); + msi_set_property( package->db, szCosting, szOne ); /* set default run level if not set */ - level = msi_dup_property( package, szlevel ); + level = msi_dup_property( package->db, szlevel ); if (!level) - MSI_SetPropertyW(package,szlevel, szOne); + msi_set_property( package->db, szlevel, szOne ); msi_free(level); /* FIXME: check volume disk space */ - MSI_SetPropertyW(package, szOutOfDiskSpace, szZero); + msi_set_property( package->db, szOutOfDiskSpace, szZero ); return MSI_SetFeatureStates(package); } @@ -2220,7 +2325,7 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key switch (root) { case -1: - if (msi_get_property_int( package, szAllUsers, 0 )) + if (msi_get_property_int( package->db, szAllUsers, 0 )) { *root_key = HKEY_LOCAL_MACHINE; ret = szHLM; @@ -2364,12 +2469,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) uirow = MSI_CreateRecord(3); MSI_RecordSetStringW(uirow,2,deformated); MSI_RecordSetStringW(uirow,1,uikey); - - if (type == REG_SZ) + if (type == REG_SZ || type == REG_EXPAND_SZ) MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data); - else - MSI_RecordSetStringW(uirow,3,value); - ui_actiondata(package,szWriteRegistryValues,uirow); msiobj_release( &uirow->hdr ); @@ -2995,6 +3096,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) else MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL); } + comp->Action = comp->ActionRequest; /* UI stuff */ uirow = MSI_CreateRecord(3); @@ -3103,7 +3205,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) { LPCWSTR guid; guid = MSI_RecordGetString(row,1); - CLSIDFromString((LPWSTR)guid, &tl_struct.clsid); + CLSIDFromString((LPCWSTR)guid, &tl_struct.clsid); tl_struct.source = strdupW( file->TargetPath ); tl_struct.path = NULL; @@ -3204,7 +3306,7 @@ static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param ) ui_actiondata( package, szUnregisterTypeLibraries, row ); guid = MSI_RecordGetString( row, 1 ); - CLSIDFromString( (LPWSTR)guid, &libid ); + CLSIDFromString( (LPCWSTR)guid, &libid ); version = MSI_RecordGetInteger( row, 4 ); language = MSI_RecordGetInteger( row, 2 ); @@ -3610,17 +3712,17 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey) {'C','l','i','e','n','t','s',0}; static const WCHAR szColon[] = {':',0}; - buffer = msi_dup_property(package, INSTALLPROPERTY_PRODUCTNAMEW); + buffer = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW); msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTNAMEW, buffer); msi_free(buffer); - langid = msi_get_property_int(package, szProductLanguage, 0); + langid = msi_get_property_int(package->db, szProductLanguage, 0); msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); /* FIXME */ msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0); - buffer = msi_dup_property(package, szARPProductIcon); + buffer = msi_dup_property(package->db, szARPProductIcon); if (buffer) { LPWSTR path = build_icon_path(package,buffer); @@ -3629,7 +3731,7 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey) msi_free(buffer); } - buffer = msi_dup_property(package, szProductVersion); + buffer = msi_dup_property(package->db, szProductVersion); if (buffer) { DWORD verdword = msi_version_str_to_dword(buffer); @@ -3677,7 +3779,7 @@ static UINT msi_publish_upgrade_code(MSIPACKAGE *package) static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0}; - upgrade = msi_dup_property(package, szUpgradeCode); + upgrade = msi_dup_property(package->db, szUpgradeCode); if (!upgrade) return ERROR_SUCCESS; @@ -3730,34 +3832,80 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package) return TRUE; } -static UINT msi_publish_patch(MSIPACKAGE *package, HKEY prodkey, HKEY hudkey) +static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey ) { + static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0}; WCHAR patch_squashed[GUID_SIZE]; - HKEY patches; + HKEY patches_key = NULL, product_patches_key; LONG res; - UINT r = ERROR_FUNCTION_FAILED; + MSIPATCHINFO *patch; + UINT r; + WCHAR *p, *all_patches = NULL; + DWORD len = 0; - res = RegCreateKeyExW(prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, - &patches, NULL); + res = RegCreateKeyExW( prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL ); if (res != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; - squash_guid(package->patch->patchcode, patch_squashed); + r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; - res = RegSetValueExW(patches, szPatches, 0, REG_MULTI_SZ, - (const BYTE *)patch_squashed, - (lstrlenW(patch_squashed) + 1) * sizeof(WCHAR)); + LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) + { + squash_guid( patch->patchcode, patch_squashed ); + len += strlenW( patch_squashed ) + 1; + } + + p = all_patches = msi_alloc( (len + 1) * sizeof(WCHAR) ); + if (!all_patches) + goto done; + + LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) + { + HKEY patch_key; + + squash_guid( patch->patchcode, p ); + p += strlenW( p ) + 1; + + res = RegSetValueExW( patches_key, patch_squashed, 0, REG_SZ, + (const BYTE *)patch->transforms, + (strlenW(patch->transforms) + 1) * sizeof(WCHAR) ); + if (res != ERROR_SUCCESS) + goto done; + + r = MSIREG_OpenUserDataPatchKey( patch->patchcode, package->Context, &patch_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; + + res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ, + (const BYTE *)patch->localfile, + (strlenW(patch->localfile) + 1) * sizeof(WCHAR) ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; + + res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; + } + + all_patches[len] = 0; + res = RegSetValueExW( patches_key, szPatches, 0, REG_MULTI_SZ, + (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); if (res != ERROR_SUCCESS) goto done; - res = RegSetValueExW(patches, patch_squashed, 0, REG_SZ, - (const BYTE *)package->patch->transforms, - (lstrlenW(package->patch->transforms) + 1) * sizeof(WCHAR)); - if (res == ERROR_SUCCESS) - r = ERROR_SUCCESS; + res = RegSetValueExW( product_patches_key, szAllPatches, 0, REG_MULTI_SZ, + (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); + if (res != ERROR_SUCCESS) + r = ERROR_FUNCTION_FAILED; done: - RegCloseKey(patches); + RegCloseKey( product_patches_key ); + RegCloseKey( patches_key ); + msi_free( all_patches ); return r; } @@ -3791,9 +3939,9 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) goto end; - if (package->patch) + if (!list_empty(&package->patches)) { - rc = msi_publish_patch(package, hukey, hudkey); + rc = msi_publish_patches(package, hukey); if (rc != ERROR_SUCCESS) goto end; } @@ -3836,10 +3984,10 @@ static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row ) { folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL ); if (!folder) - folder = msi_dup_property( package, dirprop ); + folder = msi_dup_property( package->db, dirprop ); } else - folder = msi_dup_property( package, szWindowsFolder ); + folder = msi_dup_property( package->db, szWindowsFolder ); if (!folder) { @@ -4152,21 +4300,16 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param) CloseHandle(info.hProcess); } - msi_free(FullName); - - /* the UI chunk */ uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, filename ); uipath = strdupW( file->TargetPath ); - p = strrchrW(uipath,'\\'); - if (p) - p[0]=0; - MSI_RecordSetStringW( uirow, 1, &p[1] ); - MSI_RecordSetStringW( uirow, 2, uipath); - ui_actiondata( package, szSelfRegModules, uirow); + if ((p = strrchrW( uipath,'\\' ))) *p = 0; + MSI_RecordSetStringW( uirow, 2, uipath ); + ui_actiondata( package, szSelfRegModules, uirow ); msiobj_release( &uirow->hdr ); - msi_free( uipath ); - /* FIXME: call ui_progress? */ + msi_free( FullName ); + msi_free( uipath ); return ERROR_SUCCESS; } @@ -4235,21 +4378,16 @@ static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param ) CloseHandle( pi.hProcess ); } - msi_free( cmdline ); - uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, filename ); uipath = strdupW( file->TargetPath ); - if ((p = strrchrW( uipath, '\\' ))) - { - *p = 0; - MSI_RecordSetStringW( uirow, 1, ++p ); - } + if ((p = strrchrW( uipath,'\\' ))) *p = 0; MSI_RecordSetStringW( uirow, 2, uipath ); ui_actiondata( package, szSelfUnregModules, uirow ); msiobj_release( &uirow->hdr ); - msi_free( uipath ); - /* FIXME call ui_progress? */ + msi_free( cmdline ); + msi_free( uipath ); return ERROR_SUCCESS; } @@ -4351,7 +4489,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { size += sizeof(WCHAR); RegSetValueExW(hkey,feature->Feature,0,REG_SZ, - (LPBYTE)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size); + (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size); } else { @@ -4384,6 +4522,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature) { UINT r; HKEY hkey; + MSIRECORD *uirow; TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature)); @@ -4403,6 +4542,11 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature) RegCloseKey(hkey); } + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, feature->Feature ); + ui_actiondata( package, szUnpublishFeatures, uirow ); + msiobj_release( &uirow->hdr ); + return ERROR_SUCCESS; } @@ -4423,11 +4567,10 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package) static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) { - LPWSTR prop, val, key; SYSTEMTIME systime; DWORD size, langid; - WCHAR date[9]; - LPWSTR buffer; + WCHAR date[9], *val, *buffer; + const WCHAR *prop, *key; static const WCHAR date_fmt[] = {'%','i','%','0','2','i','%','0','2','i',0}; static const WCHAR szWindowsInstaller[] = @@ -4445,43 +4588,84 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; static const WCHAR szProductVersion[] = {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; + static const WCHAR szDisplayVersion[] = + {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR szInstallSource[] = + {'I','n','s','t','a','l','l','S','o','u','r','c','e',0}; + static const WCHAR szARPAUTHORIZEDCDFPREFIX[] = + {'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0}; + static const WCHAR szAuthorizedCDFPrefix[] = + {'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0}; + static const WCHAR szARPCONTACT[] = + {'A','R','P','C','O','N','T','A','C','T',0}; + static const WCHAR szContact[] = + {'C','o','n','t','a','c','t',0}; + static const WCHAR szARPCOMMENTS[] = + {'A','R','P','C','O','M','M','E','N','T','S',0}; + static const WCHAR szComments[] = + {'C','o','m','m','e','n','t','s',0}; static const WCHAR szProductName[] = {'P','r','o','d','u','c','t','N','a','m','e',0}; static const WCHAR szDisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; - static const WCHAR szDisplayVersion[] = - {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR szARPHELPLINK[] = + {'A','R','P','H','E','L','P','L','I','N','K',0}; + static const WCHAR szHelpLink[] = + {'H','e','l','p','L','i','n','k',0}; + static const WCHAR szARPHELPTELEPHONE[] = + {'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0}; + static const WCHAR szHelpTelephone[] = + {'H','e','l','p','T','e','l','e','p','h','o','n','e',0}; + static const WCHAR szARPINSTALLLOCATION[] = + {'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0}; + static const WCHAR szInstallLocation[] = + {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0}; static const WCHAR szManufacturer[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; + static const WCHAR szPublisher[] = + {'P','u','b','l','i','s','h','e','r',0}; + static const WCHAR szARPREADME[] = + {'A','R','P','R','E','A','D','M','E',0}; + static const WCHAR szReadme[] = + {'R','e','a','d','M','e',0}; + static const WCHAR szARPSIZE[] = + {'A','R','P','S','I','Z','E',0}; + static const WCHAR szSize[] = + {'S','i','z','e',0}; + static const WCHAR szARPURLINFOABOUT[] = + {'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0}; + static const WCHAR szURLInfoAbout[] = + {'U','R','L','I','n','f','o','A','b','o','u','t',0}; + static const WCHAR szARPURLUPDATEINFO[] = + {'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0}; + static const WCHAR szURLUpdateInfo[] = + {'U','R','L','U','p','d','a','t','e','I','n','f','o',0}; - static const LPCSTR propval[] = { - "ARPAUTHORIZEDCDFPREFIX", "AuthorizedCDFPrefix", - "ARPCONTACT", "Contact", - "ARPCOMMENTS", "Comments", - "ProductName", "DisplayName", - "ProductVersion", "DisplayVersion", - "ARPHELPLINK", "HelpLink", - "ARPHELPTELEPHONE", "HelpTelephone", - "ARPINSTALLLOCATION", "InstallLocation", - "SourceDir", "InstallSource", - "Manufacturer", "Publisher", - "ARPREADME", "Readme", - "ARPSIZE", "Size", - "ARPURLINFOABOUT", "URLInfoAbout", - "ARPURLUPDATEINFO", "URLUpdateInfo", - NULL, + static const WCHAR *propval[] = { + szARPAUTHORIZEDCDFPREFIX, szAuthorizedCDFPrefix, + szARPCONTACT, szContact, + szARPCOMMENTS, szComments, + szProductName, szDisplayName, + szARPHELPLINK, szHelpLink, + szARPHELPTELEPHONE, szHelpTelephone, + szARPINSTALLLOCATION, szInstallLocation, + cszSourceDir, szInstallSource, + szManufacturer, szPublisher, + szARPREADME, szReadme, + szARPSIZE, szSize, + szARPURLINFOABOUT, szURLInfoAbout, + szARPURLUPDATEINFO, szURLUpdateInfo, + NULL }; - const LPCSTR *p = propval; + const WCHAR **p = propval; while (*p) { - prop = strdupAtoW(*p++); - key = strdupAtoW(*p++); - val = msi_dup_property(package, prop); + prop = *p++; + key = *p++; + val = msi_dup_property(package->db, prop); msi_reg_set_val_str(hkey, key, val); msi_free(val); - msi_free(key); - msi_free(prop); } msi_reg_set_val_dword(hkey, szWindowsInstaller, 1); @@ -4494,26 +4678,14 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) /* FIXME: Write real Estimated Size when we have it */ msi_reg_set_val_dword(hkey, szEstimatedSize, 0); - buffer = msi_dup_property(package, szProductName); - msi_reg_set_val_str(hkey, szDisplayName, buffer); - msi_free(buffer); - - buffer = msi_dup_property(package, cszSourceDir); - msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLSOURCEW, buffer); - msi_free(buffer); - - buffer = msi_dup_property(package, szManufacturer); - msi_reg_set_val_str(hkey, INSTALLPROPERTY_PUBLISHERW, buffer); - msi_free(buffer); - GetLocalTime(&systime); sprintfW(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay); msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLDATEW, date); - langid = msi_get_property_int(package, szProductLanguage, 0); + langid = msi_get_property_int(package->db, szProductLanguage, 0); msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); - buffer = msi_dup_property(package, szProductVersion); + buffer = msi_dup_property(package->db, szProductVersion); msi_reg_set_val_str(hkey, szDisplayVersion, buffer); if (buffer) { @@ -4565,7 +4737,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) goto done; - upgrade_code = msi_dup_property(package, szUpgradeCode); + upgrade_code = msi_dup_property(package->db, szUpgradeCode); if (upgrade_code) { MSIREG_OpenUpgradeCodesKey(upgrade_code, &upgrade, TRUE); @@ -4597,11 +4769,12 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) LPWSTR *features = NULL; BOOL full_uninstall = TRUE; MSIFEATURE *feature; + MSIPATCHINFO *patch; static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0}; - remove = msi_dup_property(package, szRemove); + remove = msi_dup_property(package->db, szRemove); if (!remove) return ERROR_SUCCESS; @@ -4642,13 +4815,18 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) MSIREG_DeleteUserFeaturesKey(package->ProductCode); } - upgrade = msi_dup_property(package, szUpgradeCode); + upgrade = msi_dup_property(package->db, szUpgradeCode); if (upgrade) { MSIREG_DeleteUserUpgradeCodesKey(upgrade); msi_free(upgrade); } + LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry) + { + MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context); + } + done: msi_free(remove); msi_free(features); @@ -4809,7 +4987,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) goto end; } - productid = msi_dup_property( package, INSTALLPROPERTY_PRODUCTIDW ); + productid = msi_dup_property( package->db, INSTALLPROPERTY_PRODUCTIDW ); if (!productid) goto end; @@ -4820,7 +4998,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) for( i = 0; szPropKeys[i][0]; i++ ) { - buffer = msi_dup_property( package, szPropKeys[i] ); + buffer = msi_dup_property( package->db, szPropKeys[i] ); msi_reg_set_val_str( hkey, szRegKeys[i], buffer ); msi_free( buffer ); } @@ -5162,10 +5340,11 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = param; MSICOMPONENT *comp; + MSIRECORD *uirow; SC_HANDLE scm = NULL, service = NULL; LPCWSTR component, *vector = NULL; - LPWSTR name, args; - DWORD event, numargs; + LPWSTR name, args, display_name = NULL; + DWORD event, numargs, len; UINT r = ERROR_FUNCTION_FAILED; component = MSI_RecordGetString(rec, 6); @@ -5198,6 +5377,14 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) goto done; } + len = 0; + if (!GetServiceDisplayNameW( scm, name, NULL, &len ) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if ((display_name = msi_alloc( ++len * sizeof(WCHAR )))) + GetServiceDisplayNameW( scm, name, display_name, &len ); + } + service = OpenServiceW(scm, name, SERVICE_START); if (!service) { @@ -5217,12 +5404,19 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) r = ERROR_SUCCESS; done: + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, display_name ); + MSI_RecordSetStringW( uirow, 2, name ); + ui_actiondata( package, szStartServices, uirow ); + msiobj_release( &uirow->hdr ); + CloseServiceHandle(service); CloseServiceHandle(scm); msi_free(name); msi_free(args); msi_free(vector); + msi_free(display_name); return r; } @@ -5335,9 +5529,11 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; MSICOMPONENT *comp; + MSIRECORD *uirow; LPCWSTR component; - LPWSTR name; - DWORD event; + LPWSTR name = NULL, display_name = NULL; + DWORD event, len; + SC_HANDLE scm; event = MSI_RecordGetInteger( rec, 3 ); if (!(event & msidbServiceControlEventStop)) @@ -5356,10 +5552,34 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param ) } comp->Action = INSTALLSTATE_ABSENT; + scm = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT ); + if (!scm) + { + ERR("Failed to open the service control manager\n"); + goto done; + } + + len = 0; + if (!GetServiceDisplayNameW( scm, name, NULL, &len ) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if ((display_name = msi_alloc( ++len * sizeof(WCHAR )))) + GetServiceDisplayNameW( scm, name, display_name, &len ); + } + CloseServiceHandle( scm ); + deformat_string( package, MSI_RecordGetString( rec, 2 ), &name ); stop_service( name ); - msi_free( name ); +done: + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, display_name ); + MSI_RecordSetStringW( uirow, 2, name ); + ui_actiondata( package, szStopServices, uirow ); + msiobj_release( &uirow->hdr ); + + msi_free( name ); + msi_free( display_name ); return ERROR_SUCCESS; } @@ -6749,19 +6969,19 @@ static UINT ACTION_ValidateProductID( MSIPACKAGE *package ) LPWSTR key, template, id; UINT r = ERROR_SUCCESS; - id = msi_dup_property( package, szProductID ); + id = msi_dup_property( package->db, szProductID ); if (id) { msi_free( id ); return ERROR_SUCCESS; } - template = msi_dup_property( package, szPIDTemplate ); - key = msi_dup_property( package, szPIDKEY ); + template = msi_dup_property( package->db, szPIDTemplate ); + key = msi_dup_property( package->db, szPIDKEY ); if (key && template) { FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); - r = MSI_SetPropertyW( package, szProductID, key ); + r = msi_set_property( package->db, szProductID, key ); } msi_free( template ); msi_free( key ); @@ -6780,7 +7000,7 @@ static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package ) static const WCHAR szAvailableFreeReg[] = {'A','V','A','I','L','A','B','L','E','F','R','E','E','R','E','G',0}; MSIRECORD *uirow; - int space = msi_get_property_int( package, szAvailableFreeReg, 0 ); + int space = msi_get_property_int( package->db, szAvailableFreeReg, 0 ); TRACE("%p %d kilobytes\n", package, space); @@ -6804,6 +7024,40 @@ static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package ) return ERROR_SUCCESS; } +static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) +{ + UINT r, count; + MSIQUERY *view; + + static const WCHAR driver_query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + 'O','D','B','C','D','r','i','v','e','r',0 }; + + static const WCHAR translator_query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + 'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 }; + + r = MSI_DatabaseOpenViewW( package->db, driver_query, &view ); + if (r == ERROR_SUCCESS) + { + count = 0; + r = MSI_IterateRecords( view, &count, NULL, package ); + msiobj_release( &view->hdr ); + if (count) FIXME("ignored %u rows in ODBCDriver table\n", count); + } + + r = MSI_DatabaseOpenViewW( package->db, translator_query, &view ); + if (r == ERROR_SUCCESS) + { + count = 0; + r = MSI_IterateRecords( view, &count, NULL, package ); + msiobj_release( &view->hdr ); + if (count) FIXME("ignored %u rows in ODBCTranslator table\n", count); + } + + return ERROR_SUCCESS; +} + static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) { @@ -6890,36 +7144,6 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); } -static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 }; - return msi_unimplemented_action_stub( package, "SetODBCFolders", table ); -} - -static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'A','p','p','I','d',0 }; - return msi_unimplemented_action_stub( package, "UnregisterClassInfo", table ); -} - -static UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'E','x','t','e','n','s','i','o','n',0 }; - return msi_unimplemented_action_stub( package, "UnregisterExtensionInfo", table ); -} - -static UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'M','I','M','E',0 }; - return msi_unimplemented_action_stub( package, "UnregisterMIMEInfo", table ); -} - -static UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'P','r','o','g','I','d',0 }; - return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table ); -} - typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); static const struct @@ -7171,7 +7395,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; - MSI_SetPropertyW(package, szAction, szInstall); + msi_set_property( package->db, szAction, szInstall ); package->script->InWhatSequence = SEQUENCE_INSTALL; @@ -7216,10 +7440,10 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_apply_transforms( package ); msi_apply_patches( package ); - if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 )) + if (!szCommandLine && msi_get_property_int( package->db, szInstalled, 0 )) { TRACE("setting reinstall property\n"); - MSI_SetPropertyW( package, szReinstall, szAll ); + msi_set_property( package->db, szReinstall, szAll ); } /* properties may have been added by a transform */ diff --git a/reactos/dll/win32/msi/appsearch.c b/reactos/dll/win32/msi/appsearch.c index 12c741178e3..336bfcae0f8 100644 --- a/reactos/dll/win32/msi/appsearch.c +++ b/reactos/dll/win32/msi/appsearch.c @@ -929,7 +929,8 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU 'D','r','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; - LPWSTR parentName = NULL, parent = NULL; + LPWSTR parent = NULL; + LPCWSTR parentName; WCHAR path[MAX_PATH]; WCHAR expanded[MAX_PATH]; MSIRECORD *row; @@ -949,14 +950,15 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU } /* check whether parent is set */ - parentName = msi_dup_record_field(row,2); + parentName = MSI_RecordGetString(row, 2); if (parentName) { MSISIGNATURE parentSig; rc = ACTION_AppSearchSigName(package, parentName, &parentSig, &parent); ACTION_FreeSignature(&parentSig); - msi_free(parentName); + if (!parent) + return ERROR_SUCCESS; } sz = MAX_PATH; @@ -1041,7 +1043,10 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) r = ACTION_AppSearchSigName(package, sigName, &sig, &value); if (value) { - MSI_SetPropertyW(package, propName, value); + r = msi_set_property( package->db, propName, value ); + if (r == ERROR_SUCCESS && !strcmpW( propName, cszSourceDir )) + msi_reset_folders( package, TRUE ); + msi_free(value); } ACTION_FreeSignature(&sig); @@ -1064,6 +1069,14 @@ UINT ACTION_AppSearch(MSIPACKAGE *package) MSIQUERY *view = NULL; UINT r; + if (check_unique_action(package, szAppSearch)) + { + TRACE("Skipping AppSearch action: already done in UI sequence\n"); + return ERROR_SUCCESS; + } + else + register_unique_action(package, szAppSearch); + r = MSI_OpenQuery( package->db, &view, query ); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; @@ -1092,7 +1105,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) if (value) { TRACE("Found signature %s\n", debugstr_w(signature)); - MSI_SetPropertyW(package, success, szOne); + msi_set_property(package->db, success, szOne); msi_free(value); r = ERROR_NO_MORE_ITEMS; } @@ -1111,6 +1124,14 @@ UINT ACTION_CCPSearch(MSIPACKAGE *package) MSIQUERY *view = NULL; UINT r; + if (check_unique_action(package, szCCPSearch)) + { + TRACE("Skipping AppSearch action: already done in UI sequence\n"); + return ERROR_SUCCESS; + } + else + register_unique_action(package, szCCPSearch); + r = MSI_OpenQuery(package->db, &view, query); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; diff --git a/reactos/dll/win32/msi/automation.c b/reactos/dll/win32/msi/automation.c index f935a64397d..d6ef5c98781 100644 --- a/reactos/dll/win32/msi/automation.c +++ b/reactos/dll/win32/msi/automation.c @@ -167,7 +167,7 @@ static HRESULT create_automation_object(MSIHANDLE msiHandle, IUnknown *pUnkOuter if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AutomationObject)+sizetPrivateData); + object = msi_alloc_zero( sizeof(AutomationObject) + sizetPrivateData ); /* Set all the VTable references */ object->lpVtbl = &AutomationObject_Vtbl; @@ -184,7 +184,7 @@ static HRESULT create_automation_object(MSIHANDLE msiHandle, IUnknown *pUnkOuter object->iTypeInfo = NULL; hr = load_type_info((IDispatch *)object, &object->iTypeInfo, clsid, 0x0); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, object); + msi_free( object ); return hr; } @@ -203,7 +203,7 @@ static HRESULT create_list_enumerator(IUnknown *pUnkOuter, LPVOID *ppObj, Automa if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ListEnumerator)); + object = msi_alloc_zero( sizeof(ListEnumerator) ); /* Set all the VTable references */ object->lpVtbl = &ListEnumerator_Vtbl; @@ -288,7 +288,7 @@ static ULONG WINAPI AutomationObject_Release(IDispatch* iface) if (This->funcFree) This->funcFree(This); ITypeInfo_Release(This->iTypeInfo); MsiCloseHandle(This->msiHandle); - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); } return ref; @@ -607,7 +607,7 @@ static ULONG WINAPI ListEnumerator_Release(IEnumVARIANT* iface) if (!ref) { if (This->pObj) IDispatch_Release((IDispatch *)This->pObj); - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); } return ref; @@ -1043,7 +1043,7 @@ static void WINAPI ListImpl_Free(AutomationObject *This) for (idx=0; idxulCount; idx++) VariantClear(&data->pVars[idx]); - HeapFree(GetProcessHeap(), 0, data->pVars); + msi_free(data->pVars); } static HRESULT WINAPI ViewImpl_Invoke( diff --git a/reactos/dll/win32/msi/classes.c b/reactos/dll/win32/msi/classes.c index acd8429bec4..22d11c1441c 100644 --- a/reactos/dll/win32/msi/classes.c +++ b/reactos/dll/win32/msi/classes.c @@ -18,15 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* actions handled in this module +/* Actions handled in this module: + * * RegisterClassInfo * RegisterProgIdInfo * RegisterExtensionInfo * RegisterMIMEInfo - * UnRegisterClassInfo (TODO) - * UnRegisterProgIdInfo (TODO) - * UnRegisterExtensionInfo (TODO) - * UnRegisterMIMEInfo (TODO) + * UnregisterClassInfo + * UnregisterProgIdInfo + * UnregisterExtensionInfo + * UnregisterMIMEInfo */ #include @@ -343,7 +344,7 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR extensio static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row ) { - LPCWSTR buffer; + LPCWSTR extension; MSIMIME *mt; /* fill in the data */ @@ -355,8 +356,9 @@ static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row ) mt->ContentType = msi_dup_record_field( row, 1 ); TRACE("loading mime %s\n", debugstr_w(mt->ContentType)); - buffer = MSI_RecordGetString( row, 2 ); - mt->Extension = load_given_extension( package, buffer ); + extension = MSI_RecordGetString( row, 2 ); + mt->Extension = load_given_extension( package, extension ); + mt->suffix = strdupW( extension ); mt->clsid = msi_dup_record_field( row, 3 ); mt->Class = load_given_class( package, mt->clsid ); @@ -720,6 +722,25 @@ static void mark_progid_for_install( MSIPACKAGE* package, MSIPROGID *progid ) } } +static void mark_progid_for_uninstall( MSIPACKAGE *package, MSIPROGID *progid ) +{ + MSIPROGID *child; + + if (!progid) + return; + + if (!progid->InstallMe) + return; + + progid->InstallMe = FALSE; + + LIST_FOR_EACH_ENTRY( child, &package->progids, MSIPROGID, entry ) + { + if (child->Parent == progid) + mark_progid_for_uninstall( package, child ); + } +} + static void mark_mime_for_install( MSIMIME *mime ) { if (!mime) @@ -727,9 +748,15 @@ static void mark_mime_for_install( MSIMIME *mime ) mime->InstallMe = TRUE; } +static void mark_mime_for_uninstall( MSIMIME *mime ) +{ + if (!mime) + return; + mime->InstallMe = FALSE; +} + static UINT register_appid(const MSIAPPID *appid, LPCWSTR app ) { - static const WCHAR szAppID[] = { 'A','p','p','I','D',0 }; static const WCHAR szRemoteServerName[] = {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0}; static const WCHAR szLocalService[] = @@ -776,24 +803,13 @@ static UINT register_appid(const MSIAPPID *appid, LPCWSTR app ) UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) { - /* - * Again I am assuming the words, "Whose key file represents" when referring - * to a Component as to meaning that Components KeyPath file - */ - - UINT rc; - MSIRECORD *uirow; - static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; - static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 }; - static const WCHAR szVIProgID[] = { 'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0 }; - static const WCHAR szAppID[] = { 'A','p','p','I','D',0 }; static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0}; + MSIRECORD *uirow; HKEY hkey,hkey2,hkey3; MSICLASS *cls; load_classes_and_such(package); - rc = RegCreateKeyW(HKEY_CLASSES_ROOT,szCLSID,&hkey); - if (rc != ERROR_SUCCESS) + if (RegCreateKeyW(HKEY_CLASSES_ROOT, szCLSID, &hkey) != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry ) @@ -812,16 +828,21 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) if (!feature) continue; - /* - * MSDN says that these are based on Feature not on Component. - */ if (feature->ActionRequest != INSTALLSTATE_LOCAL && feature->ActionRequest != INSTALLSTATE_ADVERTISED ) { - TRACE("Feature %s not scheduled for installation, skipping regstration of class %s\n", + TRACE("Feature %s not scheduled for installation, skipping registration of class %s\n", debugstr_w(feature->Feature), debugstr_w(cls->clsid)); continue; } + feature->Action = feature->ActionRequest; + + file = get_loaded_file( package, comp->KeyPath ); + if (!file) + { + TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); + continue; + } TRACE("Registering class %s (%p)\n", debugstr_w(cls->clsid), cls); @@ -834,12 +855,6 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) msi_reg_set_val_str( hkey2, NULL, cls->Description ); RegCreateKeyW( hkey2, cls->Context, &hkey3 ); - file = get_loaded_file( package, comp->KeyPath ); - if (!file) - { - TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); - continue; - } /* * FIXME: Implement install on demand (advertised components). @@ -887,35 +902,18 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) if (cls->AppID) { MSIAPPID *appid = cls->AppID; - msi_reg_set_val_str( hkey2, szAppID, appid->AppID ); - register_appid( appid, cls->Description ); } if (cls->IconPath) - { - static const WCHAR szDefaultIcon[] = - {'D','e','f','a','u','l','t','I','c','o','n',0}; - msi_reg_set_subkey_val( hkey2, szDefaultIcon, NULL, cls->IconPath ); - } if (cls->DefInprocHandler) - { - static const WCHAR szInproc[] = - {'I','n','p','r','o','c','H','a','n','d','l','e','r',0}; - - msi_reg_set_subkey_val( hkey2, szInproc, NULL, cls->DefInprocHandler ); - } + msi_reg_set_subkey_val( hkey2, szInprocHandler, NULL, cls->DefInprocHandler ); if (cls->DefInprocHandler32) - { - static const WCHAR szInproc32[] = - {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; - - msi_reg_set_subkey_val( hkey2, szInproc32, NULL, cls->DefInprocHandler32 ); - } + msi_reg_set_subkey_val( hkey2, szInprocHandler32, NULL, cls->DefInprocHandler32 ); RegCloseKey(hkey2); @@ -947,14 +945,92 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) } uirow = MSI_CreateRecord(1); - MSI_RecordSetStringW( uirow, 1, cls->clsid ); ui_actiondata(package,szRegisterClassInfo,uirow); msiobj_release(&uirow->hdr); } RegCloseKey(hkey); - return rc; + return ERROR_SUCCESS; +} + +UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package ) +{ + static const WCHAR szFileType[] = {'F','i','l','e','T','y','p','e','\\',0}; + MSIRECORD *uirow; + MSICLASS *cls; + HKEY hkey, hkey2; + + load_classes_and_such( package ); + if (RegOpenKeyW( HKEY_CLASSES_ROOT, szCLSID, &hkey ) != ERROR_SUCCESS) + return ERROR_SUCCESS; + + LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry ) + { + MSIFEATURE *feature; + MSICOMPONENT *comp; + LPWSTR filetype; + LONG res; + + comp = cls->Component; + if (!comp) + continue; + + feature = cls->Feature; + if (!feature) + continue; + + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + { + TRACE("Feature %s not scheduled for removal, skipping unregistration of class %s\n", + debugstr_w(feature->Feature), debugstr_w(cls->clsid)); + continue; + } + feature->Action = feature->ActionRequest; + + TRACE("Unregistering class %s (%p)\n", debugstr_w(cls->clsid), cls); + + cls->Installed = FALSE; + mark_progid_for_uninstall( package, cls->ProgID ); + + res = RegDeleteTreeW( hkey, cls->clsid ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete class key %d\n", res); + + if (cls->AppID) + { + res = RegOpenKeyW( HKEY_CLASSES_ROOT, szAppID, &hkey2 ); + if (res == ERROR_SUCCESS) + { + res = RegDeleteKeyW( hkey2, cls->AppID->AppID ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete appid key %d\n", res); + RegCloseKey( hkey2 ); + } + } + if (cls->FileTypeMask) + { + filetype = msi_alloc( (strlenW( szFileType ) + strlenW( cls->clsid ) + 1) * sizeof(WCHAR) ); + if (filetype) + { + strcpyW( filetype, szFileType ); + strcatW( filetype, cls->clsid ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, filetype ); + msi_free( filetype ); + + if (res != ERROR_SUCCESS) + WARN("Failed to delete file type %d\n", res); + } + } + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, cls->clsid ); + ui_actiondata( package, szUnregisterClassInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + RegCloseKey( hkey ); + return ERROR_SUCCESS; } static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid ) @@ -972,11 +1048,7 @@ static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid ) static UINT register_progid( const MSIPROGID* progid ) { - static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; - static const WCHAR szDefaultIcon[] = - {'D','e','f','a','u','l','t','I','c','o','n',0}; - static const WCHAR szCurVer[] = - {'C','u','r','V','e','r',0}; + static const WCHAR szCurVer[] = {'C','u','r','V','e','r',0}; HKEY hkey = 0; UINT rc; @@ -1041,6 +1113,41 @@ UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package) return ERROR_SUCCESS; } +UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package ) +{ + MSIPROGID *progid; + MSIRECORD *uirow; + LONG res; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry ) + { + /* check if this progid is to be removed */ + if (progid->Class && !progid->Class->Installed) + progid->InstallMe = FALSE; + + if (progid->InstallMe) + { + TRACE("progid %s not scheduled to be removed\n", debugstr_w(progid->ProgID)); + continue; + } + + TRACE("Unregistering progid %s\n", debugstr_w(progid->ProgID)); + + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid->ProgID ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete progid key %d\n", res); + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, progid->ProgID ); + ui_actiondata( package, szUnregisterProgIdInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, MSICOMPONENT* component, const MSIEXTENSION* extension, MSIVERB* verb, INT* Sequence ) @@ -1122,10 +1229,11 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) { static const WCHAR szContentType[] = {'C','o','n','t','e','n','t',' ','T','y','p','e',0 }; - HKEY hkey; + HKEY hkey = NULL; MSIEXTENSION *ext; MSIRECORD *uirow; BOOL install_on_demand = TRUE; + LONG res; load_classes_and_such(package); @@ -1157,6 +1265,7 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) debugstr_w(feature->Feature), debugstr_w(ext->Extension)); continue; } + feature->Action = feature->ActionRequest; TRACE("Registering extension %s (%p)\n", debugstr_w(ext->Extension), ext); @@ -1170,12 +1279,16 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) mark_mime_for_install(ext->Mime); - extension = msi_alloc( (lstrlenW( ext->Extension ) + 2)*sizeof(WCHAR) ); - extension[0] = '.'; - lstrcpyW(extension+1,ext->Extension); - - RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey); - msi_free( extension ); + extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) ); + if (extension) + { + extension[0] = '.'; + strcpyW( extension + 1, ext->Extension ); + res = RegCreateKeyW( HKEY_CLASSES_ROOT, extension, &hkey ); + msi_free( extension ); + if (res != ERROR_SUCCESS) + WARN("Failed to create extension key %d\n", res); + } if (ext->Mime) msi_reg_set_val_str( hkey, szContentType, ext->Mime->ContentType ); @@ -1225,6 +1338,86 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) return ERROR_SUCCESS; } +UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package ) +{ + MSIEXTENSION *ext; + MSIRECORD *uirow; + LONG res; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry ) + { + LPWSTR extension; + MSIFEATURE *feature; + + if (!ext->Component) + continue; + + feature = ext->Feature; + if (!feature) + continue; + + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + { + TRACE("Feature %s not scheduled for removal, skipping unregistration of extension %s\n", + debugstr_w(feature->Feature), debugstr_w(ext->Extension)); + continue; + } + + TRACE("Unregistering extension %s\n", debugstr_w(ext->Extension)); + + ext->Installed = FALSE; + + if (ext->ProgID && !list_empty( &ext->verbs )) + mark_progid_for_uninstall( package, ext->ProgID ); + + mark_mime_for_uninstall( ext->Mime ); + + extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) ); + if (extension) + { + extension[0] = '.'; + strcpyW( extension + 1, ext->Extension ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, extension ); + msi_free( extension ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete extension key %d\n", res); + } + + if (ext->ProgID || ext->ProgIDText) + { + static const WCHAR shellW[] = {'\\','s','h','e','l','l',0}; + LPCWSTR progid; + LPWSTR progid_shell; + + if (ext->ProgID) + progid = ext->ProgID->ProgID; + else + progid = ext->ProgIDText; + + progid_shell = msi_alloc( (strlenW( progid ) + strlenW( shellW ) + 1) * sizeof(WCHAR) ); + if (progid_shell) + { + strcpyW( progid_shell, progid ); + strcatW( progid_shell, shellW ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid_shell ); + msi_free( progid_shell ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete shell key %d\n", res); + RegDeleteKeyW( HKEY_CLASSES_ROOT, progid ); + } + } + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, ext->Extension ); + ui_actiondata( package, szUnregisterExtensionInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) { static const WCHAR szExten[] = @@ -1237,11 +1430,6 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry ) { LPWSTR extension; - LPCWSTR exten; - LPCWSTR mime; - static const WCHAR fmt[] = - {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\', - 'C','o','n','t','e','n','t',' ','T','y','p','e','\\', '%','s',0}; LPWSTR key; /* @@ -1254,33 +1442,80 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) if (!mt->InstallMe) { - TRACE("MIME %s not scheduled to be installed\n", - debugstr_w(mt->ContentType)); + TRACE("MIME %s not scheduled to be installed\n", debugstr_w(mt->ContentType)); continue; } - - mime = mt->ContentType; - exten = mt->Extension->Extension; - extension = msi_alloc( (lstrlenW( exten ) + 2)*sizeof(WCHAR) ); - extension[0] = '.'; - lstrcpyW(extension+1,exten); + TRACE("Registering MIME type %s\n", debugstr_w(mt->ContentType)); - key = msi_alloc( (strlenW(mime)+strlenW(fmt)+1) * sizeof(WCHAR) ); - sprintfW(key,fmt,mime); - msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExten, extension ); + extension = msi_alloc( (strlenW( mt->Extension->Extension ) + 2) * sizeof(WCHAR) ); + key = msi_alloc( (strlenW( mt->ContentType ) + strlenW( szMIMEDatabase ) + 1) * sizeof(WCHAR) ); - msi_free(extension); - msi_free(key); + if (extension && key) + { + extension[0] = '.'; + strcpyW( extension + 1, mt->Extension->Extension ); - if (mt->clsid) - FIXME("Handle non null for field 3\n"); + strcpyW( key, szMIMEDatabase ); + strcatW( key, mt->ContentType ); + msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExten, extension ); - uirow = MSI_CreateRecord(2); - MSI_RecordSetStringW(uirow,1,mt->ContentType); - MSI_RecordSetStringW(uirow,2,exten); - ui_actiondata(package,szRegisterMIMEInfo,uirow); - msiobj_release(&uirow->hdr); + if (mt->clsid) + msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szCLSID, mt->clsid ); + } + msi_free( extension ); + msi_free( key ); + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, mt->ContentType ); + MSI_RecordSetStringW( uirow, 2, mt->suffix ); + ui_actiondata( package, szRegisterMIMEInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + +UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package ) +{ + MSIRECORD *uirow; + MSIMIME *mime; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( mime, &package->mimes, MSIMIME, entry ) + { + LONG res; + LPWSTR mime_key; + + mime->InstallMe = (mime->InstallMe || + (mime->Class && mime->Class->Installed) || + (mime->Extension && mime->Extension->Installed)); + + if (mime->InstallMe) + { + TRACE("MIME %s not scheduled to be removed\n", debugstr_w(mime->ContentType)); + continue; + } + + TRACE("Unregistering MIME type %s\n", debugstr_w(mime->ContentType)); + + mime_key = msi_alloc( (strlenW( szMIMEDatabase ) + strlenW( mime->ContentType ) + 1) * sizeof(WCHAR) ); + if (mime_key) + { + strcpyW( mime_key, szMIMEDatabase ); + strcatW( mime_key, mime->ContentType ); + res = RegDeleteKeyW( HKEY_CLASSES_ROOT, mime_key ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete MIME key %d\n", res); + msi_free( mime_key ); + } + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, mime->ContentType ); + MSI_RecordSetStringW( uirow, 2, mime->suffix ); + ui_actiondata( package, szUnregisterMIMEInfo, uirow ); + msiobj_release( &uirow->hdr ); } return ERROR_SUCCESS; diff --git a/reactos/dll/win32/msi/cond.tab.c b/reactos/dll/win32/msi/cond.tab.c index 5449d99fdab..2b10d209be6 100644 --- a/reactos/dll/win32/msi/cond.tab.c +++ b/reactos/dll/win32/msi/cond.tab.c @@ -1989,7 +1989,7 @@ yyreduce: COND_input* cond = (COND_input*) info; UINT len; - (yyval.string) = msi_dup_property( cond->package, (yyvsp[(1) - (1)].string) ); + (yyval.string) = msi_dup_property( cond->package->db, (yyvsp[(1) - (1)].string) ); if ((yyval.string)) { len = (lstrlenW((yyval.string)) + 1) * sizeof (WCHAR); diff --git a/reactos/dll/win32/msi/cond.y b/reactos/dll/win32/msi/cond.y index f3db635a10a..9a7a16d67df 100644 --- a/reactos/dll/win32/msi/cond.y +++ b/reactos/dll/win32/msi/cond.y @@ -347,7 +347,7 @@ symbol_s: COND_input* cond = (COND_input*) info; UINT len; - $$ = msi_dup_property( cond->package, $1 ); + $$ = msi_dup_property( cond->package->db, $1 ); if ($$) { len = (lstrlenW($$) + 1) * sizeof (WCHAR); diff --git a/reactos/dll/win32/msi/custom.c b/reactos/dll/win32/msi/custom.c index 584c0507c53..5a1787f7d15 100644 --- a/reactos/dll/win32/msi/custom.c +++ b/reactos/dll/win32/msi/custom.c @@ -163,17 +163,17 @@ static void set_deferred_action_props(MSIPACKAGE *package, LPWSTR deferred_data) end = strstrW(beg, sep); *end = '\0'; - MSI_SetPropertyW(package, szCustomActionData, beg); + msi_set_property(package->db, szCustomActionData, beg); beg = end + 3; end = strstrW(beg, sep); *end = '\0'; - MSI_SetPropertyW(package, szUserSID, beg); + msi_set_property(package->db, szUserSID, beg); beg = end + 3; end = strchrW(beg, ']'); *end = '\0'; - MSI_SetPropertyW(package, szProductCode, beg); + msi_set_property(package->db, szProductCode, beg); } UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL execute) @@ -231,9 +231,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL } if (!execute) { - LPWSTR actiondata = msi_dup_property(package, action); - LPWSTR usersid = msi_dup_property(package, szUserSID); - LPWSTR prodcode = msi_dup_property(package, szProductCode); + LPWSTR actiondata = msi_dup_property(package->db, action); + LPWSTR usersid = msi_dup_property(package->db, szUserSID); + LPWSTR prodcode = msi_dup_property(package->db, szProductCode); LPWSTR deferred = msi_get_deferred_action(action, actiondata, usersid, prodcode); if (type & msidbCustomActionTypeCommit) @@ -256,7 +256,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL } else { - LPWSTR actiondata = msi_dup_property( package, action ); + LPWSTR actiondata = msi_dup_property( package->db, action ); switch (script) { @@ -276,9 +276,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL if (deferred_data) set_deferred_action_props(package, deferred_data); else if (actiondata) - MSI_SetPropertyW(package, szCustomActionData, actiondata); + msi_set_property(package->db, szCustomActionData, actiondata); else - MSI_SetPropertyW(package, szCustomActionData, szEmpty); + msi_set_property(package->db, szCustomActionData, szEmpty); msi_free(actiondata); } @@ -327,7 +327,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL break; deformat_string(package,target,&deformated); - rc = MSI_SetPropertyW(package,source,deformated); + rc = msi_set_property( package->db, source, deformated ); + if (rc == ERROR_SUCCESS && !strcmpW( source, cszSourceDir )) + msi_reset_folders( package, TRUE ); msi_free(deformated); break; case 37: /* JScript/VBScript text stored in target column. */ @@ -376,7 +378,7 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source, DWORD sz = MAX_PATH; UINT r; - if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz) != ERROR_SUCCESS) + if (msi_get_property(package->db, cszTempFolder, fmt, &sz) != ERROR_SUCCESS) GetTempPathW(MAX_PATH, fmt); if (GetTempFileNameW(fmt, szMsi, 0, tmp_file) == 0) @@ -864,7 +866,7 @@ static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source, UINT r; size = MAX_PATH; - MSI_GetPropertyW(package, cszSourceDir, package_path, &size); + msi_get_property(package->db, cszSourceDir, package_path, &size); lstrcatW(package_path, szBackSlash); lstrcatW(package_path, source); @@ -1078,7 +1080,7 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, memset(&si,0,sizeof(STARTUPINFOW)); memset(&info,0,sizeof(PROCESS_INFORMATION)); - prop = msi_dup_property( package, source ); + prop = msi_dup_property( package->db, source ); if (!prop) return ERROR_SUCCESS; @@ -1380,7 +1382,7 @@ static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source, TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); - prop = msi_dup_property(package,source); + prop = msi_dup_property( package->db, source ); if (!prop) return ERROR_SUCCESS; @@ -1415,7 +1417,7 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package) EnterCriticalSection( &msi_custom_action_cs ); handle_count = list_count( &msi_pending_custom_actions ); - wait_handles = HeapAlloc( GetProcessHeap(), 0, handle_count * sizeof(HANDLE) ); + wait_handles = msi_alloc( handle_count * sizeof(HANDLE) ); handle_count = 0; LIST_FOR_EACH_ENTRY_SAFE( info, cursor, &msi_pending_custom_actions, msi_custom_action_info, entry ) @@ -1435,7 +1437,7 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package) CloseHandle( wait_handles[i] ); } - HeapFree( GetProcessHeap(), 0, wait_handles ); + msi_free( wait_handles ); } typedef struct _msi_custom_remote_impl { diff --git a/reactos/dll/win32/msi/database.c b/reactos/dll/win32/msi/database.c index cfa11e97ed5..3e577926340 100644 --- a/reactos/dll/win32/msi/database.c +++ b/reactos/dll/win32/msi/database.c @@ -164,64 +164,6 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED; } -UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, - USHORT **pdata, UINT *psz ) -{ - HRESULT r; - UINT ret = ERROR_FUNCTION_FAILED; - VOID *data; - ULONG sz, count; - IStream *stm = NULL; - STATSTG stat; - LPWSTR encname; - - encname = encode_streamname( FALSE, stname ); - r = db_get_raw_stream( db, encname, &stm ); - msi_free( encname ); - - if( r != ERROR_SUCCESS) - return ret; - - r = IStream_Stat(stm, &stat, STATFLAG_NONAME ); - if( FAILED( r ) ) - { - WARN("open stream failed r = %08x!\n", r); - goto end; - } - - if( stat.cbSize.QuadPart >> 32 ) - { - WARN("Too big!\n"); - goto end; - } - - sz = stat.cbSize.QuadPart; - data = msi_alloc( sz ); - if( !data ) - { - WARN("couldn't allocate memory r=%08x!\n", r); - ret = ERROR_NOT_ENOUGH_MEMORY; - goto end; - } - - r = IStream_Read(stm, data, sz, &count ); - if( FAILED( r ) || ( count != sz ) ) - { - msi_free( data ); - WARN("read stream failed r = %08x!\n", r); - goto end; - } - - *pdata = data; - *psz = sz; - ret = ERROR_SUCCESS; - -end: - IStream_Release( stm ); - - return ret; -} - static void free_transforms( MSIDATABASE *db ) { while( !list_empty( &db->transforms ) ) @@ -234,6 +176,37 @@ static void free_transforms( MSIDATABASE *db ) } } +void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname ) +{ + MSISTREAM *stream, *stream2; + + LIST_FOR_EACH_ENTRY_SAFE( stream, stream2, &db->streams, MSISTREAM, entry ) + { + HRESULT r; + STATSTG stat; + + r = IStream_Stat( stream->stm, &stat, 0 ); + if (FAILED(r)) + { + WARN("failed to stat stream r = %08x\n", r); + continue; + } + + if (!strcmpW( stname, stat.pwcsName )) + { + TRACE("destroying %s\n", debugstr_w(stname)); + + list_remove( &stream->entry ); + IStream_Release( stream->stm ); + msi_free( stream ); + IStorage_DestroyElement( db->storage, stname ); + CoTaskMemFree( stat.pwcsName ); + break; + } + CoTaskMemFree( stat.pwcsName ); + } +} + static void free_streams( MSIDATABASE *db ) { while( !list_empty( &db->streams ) ) @@ -289,7 +262,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) UINT ret = ERROR_FUNCTION_FAILED; LPCWSTR szMode, save_path; STATSTG stat; - BOOL created = FALSE; + BOOL created = FALSE, patch = FALSE; WCHAR path[MAX_PATH]; static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 }; @@ -304,6 +277,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) { TRACE("Database is a patch\n"); szPersist -= MSIDBOPEN_PATCHFILE; + patch = TRUE; } save_path = szDBPath; @@ -331,7 +305,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg); if( r == ERROR_SUCCESS ) { - IStorage_SetClass( stg, &CLSID_MsiDatabase ); + IStorage_SetClass( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase ); /* create the _Tables stream */ r = write_stream_data(stg, szTables, NULL, 0, TRUE); if (SUCCEEDED(r)) @@ -379,6 +353,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) goto end; } + if ( patch && !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) ) + { + ERR("storage GUID is not the MSI patch GUID %s\n", + debugstr_guid(&stat.clsid) ); + ret = ERROR_OPEN_FAILED; + goto end; + } + db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE), MSI_CloseDatabase ); if( !db ) diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index ac2e95af91f..2a00aa7cdeb 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -171,6 +171,8 @@ static MSIFEATURE *msi_seltree_get_selected_feature( msi_control *control ); static DWORD uiThreadId; static HWND hMsiHiddenWindow; +static LPWSTR msi_get_window_text( HWND hwnd ); + static INT msi_dialog_scale_unit( msi_dialog *dialog, INT val ) { return MulDiv( val, dialog->scale, 12 ); @@ -234,7 +236,7 @@ static LPWSTR msi_dialog_dup_property( msi_dialog *dialog, LPCWSTR property, BOO return NULL; if (indirect) - prop = msi_dup_property( dialog->package, property ); + prop = msi_dup_property( dialog->package->db, property ); if (!prop) prop = strdupW( property ); @@ -581,6 +583,13 @@ static void msi_dialog_update_controls( msi_dialog *dialog, LPCWSTR property ) } } +static void msi_dialog_set_property( MSIPACKAGE *package, LPCWSTR property, LPCWSTR value ) +{ + UINT r = msi_set_property( package->db, property, value ); + if (r == ERROR_SUCCESS && !strcmpW( property, cszSourceDir )) + msi_reset_folders( package, TRUE ); +} + /* called from the Control Event subscription code */ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, LPCWSTR attribute, MSIRECORD *rec ) @@ -634,14 +643,14 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, else if ( !lstrcmpW(attribute, szProperty) ) { MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl ); - MSI_SetPropertyW( dialog->package, ctrl->property, feature->Directory ); + msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory ); } else if ( !lstrcmpW(attribute, szSelectionPath) ) { LPWSTR prop = msi_dialog_dup_property( dialog, ctrl->property, TRUE ); LPWSTR path; if (!prop) return; - path = msi_dup_property( dialog->package, prop ); + path = msi_dup_property( dialog->package->db, prop ); SetWindowTextW( ctrl->hwnd, path ); msi_free(prop); msi_free(path); @@ -884,7 +893,7 @@ static LPWSTR msi_get_checkbox_value( msi_dialog *dialog, LPCWSTR prop ) if (ret) return ret; - ret = msi_dup_property( dialog->package, prop ); + ret = msi_dup_property( dialog->package->db, prop ); if( ret && !ret[0] ) { msi_free( ret ); @@ -1222,10 +1231,167 @@ static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec ) return ERROR_SUCCESS; } +/******************** Combo Box ***************************************/ + +struct msi_combobox_info +{ + msi_dialog *dialog; + HWND hwnd; + WNDPROC oldproc; + DWORD num_items; + DWORD addpos_items; + LPWSTR *items; +}; + +static LRESULT WINAPI MSIComboBox_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct msi_combobox_info *info; + LRESULT r; + DWORD j; + + TRACE("%p %04x %08lx %08lx\n", hWnd, msg, wParam, lParam); + + info = GetPropW( hWnd, szButtonData ); + if (!info) + return 0; + + r = CallWindowProcW( info->oldproc, hWnd, msg, wParam, lParam ); + + switch (msg) + { + case WM_NCDESTROY: + for (j = 0; j < info->num_items; j++) + msi_free( info->items[j] ); + msi_free( info->items ); + msi_free( info ); + RemovePropW( hWnd, szButtonData ); + break; + } + + return r; +} + +static UINT msi_combobox_add_item( MSIRECORD *rec, LPVOID param ) +{ + struct msi_combobox_info *info = param; + LPCWSTR value, text; + int pos; + + value = MSI_RecordGetString( rec, 3 ); + text = MSI_RecordGetString( rec, 4 ); + + info->items[info->addpos_items] = strdupW( value ); + + pos = SendMessageW( info->hwnd, CB_ADDSTRING, 0, (LPARAM)text ); + SendMessageW( info->hwnd, CB_SETITEMDATA, pos, (LPARAM)info->items[info->addpos_items] ); + info->addpos_items++; + + return ERROR_SUCCESS; +} + +static UINT msi_combobox_add_items( struct msi_combobox_info *info, LPCWSTR property ) +{ + UINT r; + MSIQUERY *view = NULL; + DWORD count; + + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ', + 'F','R','O','M',' ','`','C','o','m','b','o','B','o','x','`',' ', + 'W','H','E','R','E',' ', + '`','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',' ', + 'O','R','D','E','R',' ','B','Y',' ','`','O','r','d','e','r','`',0 + }; + + r = MSI_OpenQuery( info->dialog->package->db, &view, query, property ); + if (r != ERROR_SUCCESS) + return r; + + /* just get the number of records */ + count = 0; + r = MSI_IterateRecords( view, &count, NULL, NULL ); + + info->num_items = count; + info->items = msi_alloc( sizeof(*info->items) * count ); + + r = MSI_IterateRecords( view, NULL, msi_combobox_add_item, info ); + msiobj_release( &view->hdr ); + + return r; +} + +static UINT msi_dialog_combobox_handler( msi_dialog *dialog, + msi_control *control, WPARAM param ) +{ + struct msi_combobox_info *info; + int index; + LPWSTR value; + + if (HIWORD(param) != CBN_SELCHANGE && HIWORD(param) != CBN_EDITCHANGE) + return ERROR_SUCCESS; + + info = GetPropW( control->hwnd, szButtonData ); + index = SendMessageW( control->hwnd, CB_GETCURSEL, 0, 0 ); + if (index == CB_ERR) + value = msi_get_window_text( control->hwnd ); + else + value = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, index, 0 ); + + msi_dialog_set_property( info->dialog->package, control->property, value ); + msi_dialog_evaluate_control_conditions( info->dialog ); + + if (index == CB_ERR) + msi_free( value ); + + return ERROR_SUCCESS; +} + +static void msi_dialog_combobox_update( msi_dialog *dialog, + msi_control *control ) +{ + struct msi_combobox_info *info; + LPWSTR value, tmp; + DWORD j; + + info = GetPropW( control->hwnd, szButtonData ); + + value = msi_dup_property( dialog->package->db, control->property ); + if (!value) + { + SendMessageW( control->hwnd, CB_SETCURSEL, -1, 0 ); + return; + } + + for (j = 0; j < info->num_items; j++) + { + tmp = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, j, 0 ); + if (!lstrcmpW( value, tmp )) + break; + } + + if (j < info->num_items) + { + SendMessageW( control->hwnd, CB_SETCURSEL, j, 0 ); + } + else + { + SendMessageW( control->hwnd, CB_SETCURSEL, -1, 0 ); + SetWindowTextW( control->hwnd, value ); + } + + msi_free(value); +} + static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec ) { - static const WCHAR szCombo[] = { 'C','O','M','B','O','B','O','X',0 }; + struct msi_combobox_info *info; + msi_control *control; DWORD attributes, style; + LPCWSTR prop; + + info = msi_alloc( sizeof *info ); + if (!info) + return ERROR_FUNCTION_FAILED; style = CBS_AUTOHSCROLL | WS_TABSTOP | WS_GROUP | WS_CHILD; attributes = MSI_RecordGetInteger( rec, 8 ); @@ -1236,7 +1402,33 @@ static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec ) else style |= CBS_DROPDOWN; - msi_dialog_add_control( dialog, rec, szCombo, style ); + control = msi_dialog_add_control( dialog, rec, WC_COMBOBOXW, style ); + if (!control) + { + msi_free( info ); + return ERROR_FUNCTION_FAILED; + } + + control->handler = msi_dialog_combobox_handler; + control->update = msi_dialog_combobox_update; + + prop = MSI_RecordGetString( rec, 9 ); + control->property = msi_dialog_dup_property( dialog, prop, FALSE ); + + /* subclass */ + info->dialog = dialog; + info->hwnd = control->hwnd; + info->items = NULL; + info->addpos_items = 0; + info->oldproc = (WNDPROC)SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC, + (LONG_PTR)MSIComboBox_WndProc ); + SetPropW( control->hwnd, szButtonData, info ); + + if (control->property) + msi_combobox_add_items( info, control->property ); + + msi_dialog_combobox_update( dialog, control ); + return ERROR_SUCCESS; } @@ -1276,7 +1468,7 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec ) if( prop ) control->property = strdupW( prop ); - val = msi_dup_property( dialog->package, control->property ); + val = msi_dup_property( dialog->package->db, control->property ); SetWindowTextW( control->hwnd, val ); msi_free( val ); return ERROR_SUCCESS; @@ -1352,10 +1544,9 @@ static void msi_mask_control_change( struct msi_maskedit_info *info ) if( i == info->num_groups ) { - TRACE("Set property %s to %s\n", - debugstr_w(info->prop), debugstr_w(val) ); + TRACE("Set property %s to %s\n", debugstr_w(info->prop), debugstr_w(val)); CharUpperBuffW( val, info->num_chars ); - MSI_SetPropertyW( info->dialog->package, info->prop, val ); + msi_dialog_set_property( info->dialog->package, info->prop, val ); msi_dialog_evaluate_control_conditions( info->dialog ); } msi_free( val ); @@ -1587,7 +1778,7 @@ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec ) if( prop ) { - val = msi_dup_property( dialog->package, prop ); + val = msi_dup_property( dialog->package->db, prop ); if( val ) { msi_maskedit_set_text( info, val ); @@ -1705,7 +1896,7 @@ static BOOL msi_dialog_onkillfocus( msi_dialog *dialog, msi_control *control ) else { valid = TRUE; - MSI_SetPropertyW( dialog->package, prop, buf ); + msi_dialog_set_property( dialog->package, prop, buf ); } msi_dialog_update_pathedit( dialog, control ); @@ -1855,7 +2046,7 @@ static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec ) group.dialog = dialog; group.parent = control; group.attributes = MSI_RecordGetInteger( rec, 8 ); - group.propval = msi_dup_property( dialog->package, control->property ); + group.propval = msi_dup_property( dialog->package->db, control->property ); r = MSI_IterateRecords( view, 0, msi_dialog_create_radiobutton, &group ); msiobj_release( &view->hdr ); @@ -2357,8 +2548,7 @@ static UINT msi_dialog_listbox_handler( msi_dialog *dialog, index = SendMessageW( control->hwnd, LB_GETCURSEL, 0, 0 ); value = (LPCWSTR) SendMessageW( control->hwnd, LB_GETITEMDATA, index, 0 ); - MSI_SetPropertyW( info->dialog->package, - control->property, value ); + msi_dialog_set_property( info->dialog->package, control->property, value ); msi_dialog_evaluate_control_conditions( info->dialog ); return ERROR_SUCCESS; @@ -2521,7 +2711,7 @@ UINT msi_dialog_directorylist_up( msi_dialog *dialog ) if (ptr != path) *(ptr - 1) = '\0'; PathAddBackslashW( path ); - MSI_SetPropertyW( dialog->package, prop, path ); + msi_dialog_set_property( dialog->package, prop, path ); msi_dialog_update_directory_list( dialog, NULL ); msi_dialog_update_directory_combo( dialog, NULL ); @@ -2567,7 +2757,7 @@ static UINT msi_dialog_dirlist_handler( msi_dialog *dialog, lstrcatW( new_path, text ); lstrcatW( new_path, szBackSlash ); - MSI_SetPropertyW( dialog->package, prop, new_path ); + msi_dialog_set_property( dialog->package, prop, new_path ); msi_dialog_update_directory_list( dialog, NULL ); msi_dialog_update_directory_combo( dialog, NULL ); @@ -2810,7 +3000,7 @@ static UINT msi_dialog_volsel_handler( msi_dialog *dialog, indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect ); - MSI_SetPropertyW( dialog->package, prop, text ); + msi_dialog_set_property( dialog->package, prop, text ); msi_free( prop ); return ERROR_SUCCESS; @@ -3078,8 +3268,8 @@ static void msi_dialog_adjust_dialog_pos( msi_dialog *dialog, MSIRECORD *rec, LP sz.cx = msi_dialog_scale_unit( dialog, sz.cx ); sz.cy = msi_dialog_scale_unit( dialog, sz.cy ); - xres = msi_get_property_int( dialog->package, szScreenX, 0 ); - yres = msi_get_property_int( dialog->package, szScreenY, 0 ); + xres = msi_get_property_int( dialog->package->db, szScreenX, 0 ); + yres = msi_get_property_int( dialog->package->db, szScreenY, 0 ); center.x = MulDiv( center.x, xres, 100 ); center.y = MulDiv( center.y, yres, 100 ); @@ -3172,7 +3362,7 @@ static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) dialog->attributes = MSI_RecordGetInteger( rec, 6 ); - dialog->default_font = msi_dup_property( dialog->package, df ); + dialog->default_font = msi_dup_property( dialog->package->db, df ); if (!dialog->default_font) { dialog->default_font = strdupW(dfv); @@ -3213,7 +3403,7 @@ static UINT msi_dialog_send_event( msi_dialog *dialog, LPCWSTR event, LPCWSTR ar return ERROR_SUCCESS; } -static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR arg ) +static UINT msi_dialog_set_property_event( msi_dialog *dialog, LPCWSTR event, LPCWSTR arg ) { static const WCHAR szNullArg[] = { '{','}',0 }; LPWSTR p, prop, arg_fmt = NULL; @@ -3228,7 +3418,7 @@ static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR *p = 0; if( strcmpW( szNullArg, arg ) ) deformat_string( dialog->package, arg, &arg_fmt ); - MSI_SetPropertyW( dialog->package, prop, arg_fmt ); + msi_dialog_set_property( dialog->package, prop, arg_fmt ); msi_dialog_update_controls( dialog, prop ); msi_free( arg_fmt ); } @@ -3251,7 +3441,7 @@ static UINT msi_dialog_control_event( MSIRECORD *rec, LPVOID param ) event = MSI_RecordGetString( rec, 3 ); arg = MSI_RecordGetString( rec, 4 ); if( event[0] == '[' ) - msi_dialog_set_property( dialog, event, arg ); + msi_dialog_set_property_event( dialog, event, arg ); else msi_dialog_send_event( dialog, event, arg ); } @@ -3366,7 +3556,7 @@ static UINT msi_dialog_get_checkbox_state( msi_dialog *dialog, WCHAR state[2] = { 0 }; DWORD sz = 2; - MSI_GetPropertyW( dialog->package, control->property, state, &sz ); + msi_get_property( dialog->package->db, control->property, state, &sz ); return state[0] ? 1 : 0; } @@ -3379,7 +3569,7 @@ static void msi_dialog_set_checkbox_state( msi_dialog *dialog, /* if uncheck then the property is set to NULL */ if (!state) { - MSI_SetPropertyW( dialog->package, control->property, NULL ); + msi_dialog_set_property( dialog->package, control->property, NULL ); return; } @@ -3389,7 +3579,7 @@ static void msi_dialog_set_checkbox_state( msi_dialog *dialog, else val = szState; - MSI_SetPropertyW( dialog->package, control->property, val ); + msi_dialog_set_property( dialog->package, control->property, val ); } static void msi_dialog_checkbox_sync_state( msi_dialog *dialog, @@ -3433,8 +3623,7 @@ static UINT msi_dialog_edit_handler( msi_dialog *dialog, debugstr_w(control->property)); buf = msi_get_window_text( control->hwnd ); - MSI_SetPropertyW( dialog->package, control->property, buf ); - + msi_dialog_set_property( dialog->package, control->property, buf ); msi_free( buf ); return ERROR_SUCCESS; @@ -3449,7 +3638,7 @@ static UINT msi_dialog_radiogroup_handler( msi_dialog *dialog, TRACE("clicked radio button %s, set %s\n", debugstr_w(control->name), debugstr_w(control->property)); - MSI_SetPropertyW( dialog->package, control->property, control->name ); + msi_dialog_set_property( dialog->package, control->property, control->name ); return msi_dialog_button_handler( dialog, control, param ); } @@ -3835,7 +4024,7 @@ static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event, if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) || !lstrcmpW( argument, error_no ) ) { - MSI_SetPropertyW( package, result_prop, error_abort ); + msi_set_property( package->db, result_prop, error_abort ); } ControlEvent_CleanupSubscriptions(package); @@ -3878,12 +4067,12 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0 }; - if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE ) + if ( (msi_get_property_int( package->db, szUILevel, 0 ) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE ) return ERROR_SUCCESS; if ( !error_dialog ) { - LPWSTR product_name = msi_dup_property( package, pn_prop ); + LPWSTR product_name = msi_dup_property( package->db, pn_prop ); WCHAR title[MAX_PATH]; sprintfW( title, title_fmt, product_name ); @@ -3911,7 +4100,7 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er if ( r != ERROR_SUCCESS ) goto done; - r = MSI_GetPropertyW( package, result_prop, result, &size ); + r = msi_get_property( package->db, result_prop, result, &size ); if ( r != ERROR_SUCCESS) r = ERROR_SUCCESS; diff --git a/reactos/dll/win32/msi/events.c b/reactos/dll/win32/msi/events.c index e8f22975594..4ed395bbc59 100644 --- a/reactos/dll/win32/msi/events.c +++ b/reactos/dll/win32/msi/events.c @@ -226,7 +226,7 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument, msi_dialog* dialog) { - LPWSTR path = msi_dup_property( package, argument ); + LPWSTR path = msi_dup_property( package->db, argument ); MSIRECORD *rec = MSI_CreateRecord( 1 ); UINT r; @@ -380,7 +380,13 @@ static UINT ControlEvent_DirectoryListUp(MSIPACKAGE *package, LPCWSTR argument, static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog) { - return MSI_SetPropertyW( package, szReinstallMode, argument ); + return msi_set_property( package->db, szReinstallMode, argument ); +} + +static UINT ControlEvent_Reinstall( MSIPACKAGE *package, LPCWSTR argument, + msi_dialog *dialog ) +{ + return msi_set_property( package->db, szReinstall, argument ); } static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument, @@ -389,13 +395,13 @@ static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument LPWSTR key, template; UINT ret = ERROR_SUCCESS; - template = msi_dup_property( package, szPIDTemplate ); - key = msi_dup_property( package, szPIDKEY ); + template = msi_dup_property( package->db, szPIDTemplate ); + key = msi_dup_property( package->db, szPIDKEY ); if (key && template) { FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); - ret = MSI_SetPropertyW( package, szProductID, key ); + ret = msi_set_property( package->db, szProductID, key ); } msi_free( template ); msi_free( key ); @@ -417,6 +423,7 @@ static const struct _events Events[] = { { "DirectoryListUp",ControlEvent_DirectoryListUp }, { "SelectionBrowse",ControlEvent_SpawnDialog }, { "ReinstallMode",ControlEvent_ReinstallMode }, + { "Reinstall",ControlEvent_Reinstall }, { "ValidateProductID",ControlEvent_ValidateProductID }, { NULL,NULL }, }; diff --git a/reactos/dll/win32/msi/files.c b/reactos/dll/win32/msi/files.c index 40501636af2..052a1588e2e 100644 --- a/reactos/dll/win32/msi/files.c +++ b/reactos/dll/win32/msi/files.c @@ -98,6 +98,8 @@ static void schedule_install_files(MSIPACKAGE *package) ui_progress(package,2,file->FileSize,0,0); file->state = msifs_skipped; } + else + file->Component->Action = INSTALLSTATE_LOCAL; } } @@ -119,8 +121,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) { UINT gle; - TRACE("Copying %s to %s\n", debugstr_w(source), - debugstr_w(file->TargetPath)); + TRACE("Copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath)); gle = copy_file(file, source); if (gle == ERROR_SUCCESS) @@ -147,7 +148,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) GetTempFileNameW(szBackSlash, szMsi, 0, tmpfileW); len = strlenW(file->TargetPath) + strlenW(tmpfileW) + 1; - if (!(pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + if (!(pathW = msi_alloc(len * sizeof(WCHAR)))) return ERROR_OUTOFMEMORY; strcpyW(pathW, file->TargetPath); @@ -167,32 +168,17 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) gle = GetLastError(); WARN("failed to schedule rename operation: %d)\n", gle); } - HeapFree(GetProcessHeap(), 0, pathW); + msi_free(pathW); } return gle; } -static BOOL check_dest_hash_matches(MSIFILE *file) -{ - MSIFILEHASHINFO hash; - UINT r; - - if (!file->hash.dwFileHashInfoSize) - return FALSE; - - hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); - r = MsiGetFileHashW(file->TargetPath, 0, &hash); - if (r != ERROR_SUCCESS) - return FALSE; - - return !memcmp(&hash, &file->hash, sizeof(MSIFILEHASHINFO)); -} - static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, LPWSTR *path, DWORD *attrs, PVOID user) { static MSIFILE *f = NULL; + MSIMEDIAINFO *mi = user; if (action == MSICABEXTRACT_BEGINEXTRACT) { @@ -203,11 +189,8 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, return FALSE; } - if (f->state != msifs_missing && f->state != msifs_overwrite) - { - TRACE("Skipping extraction of %s\n", debugstr_w(file)); + if (f->disk_id != mi->disk_id || (f->state != msifs_missing && f->state != msifs_overwrite)) return FALSE; - } msi_file_update_ui(package, f, szInstallFiles); @@ -256,19 +239,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite) continue; - if (check_dest_hash_matches(file)) - { - TRACE("File hashes match, not overwriting\n"); - continue; - } - - if (MsiGetFileVersionW(file->TargetPath, NULL, NULL, NULL, NULL) == ERROR_SUCCESS && - msi_compare_file_version(file) >= 0) - { - TRACE("Destination file version greater, not overwriting\n"); - continue; - } - if (file->Sequence > mi->last_sequence || mi->is_continuous || (file->IsCompressed && !mi->is_extracted)) { @@ -277,20 +247,20 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) rc = ready_media(package, file, mi); if (rc != ERROR_SUCCESS) { - ERR("Failed to ready media\n"); + ERR("Failed to ready media for %s\n", debugstr_w(file->File)); break; } data.mi = mi; data.package = package; data.cb = installfiles_cb; - data.user = NULL; + data.user = mi; if (file->IsCompressed && !msi_cabextract(package, mi, &data)) { ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet)); - rc = ERROR_FUNCTION_FAILED; + rc = ERROR_INSTALL_FAILURE; break; } } @@ -317,8 +287,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) } else if (file->state != msifs_installed) { - ERR("compressed file wasn't extracted (%s)\n", - debugstr_w(file->TargetPath)); + ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->TargetPath)); rc = ERROR_INSTALL_FAILURE; break; } @@ -555,11 +524,11 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) sourcename = MSI_RecordGetString(rec, 3); options = MSI_RecordGetInteger(rec, 7); - sourcedir = msi_dup_property(package, MSI_RecordGetString(rec, 5)); + sourcedir = msi_dup_property(package->db, MSI_RecordGetString(rec, 5)); if (!sourcedir) goto done; - destdir = msi_dup_property(package, MSI_RecordGetString(rec, 6)); + destdir = msi_dup_property(package->db, MSI_RecordGetString(rec, 6)); if (!destdir) goto done; @@ -704,7 +673,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const if (!dst_path) { /* try a property */ - dst_path = msi_dup_property( package, dst_key ); + dst_path = msi_dup_property( package->db, dst_key ); if (!dst_path) { FIXME("Unable to get destination folder, try AppSearch properties\n"); @@ -917,7 +886,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) UINT install_mode; LPWSTR dir = NULL, path = NULL; DWORD size; - UINT r; + UINT ret = ERROR_SUCCESS; component = MSI_RecordGetString(row, 2); filename = MSI_RecordGetString(row, 3); @@ -938,7 +907,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } - dir = msi_dup_property(package, dirprop); + dir = msi_dup_property(package->db, dirprop); if (!dir) return ERROR_OUTOFMEMORY; @@ -947,7 +916,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) path = msi_alloc(size * sizeof(WCHAR)); if (!path) { - r = ERROR_OUTOFMEMORY; + ret = ERROR_OUTOFMEMORY; goto done; } @@ -975,7 +944,7 @@ done: msi_free(path); msi_free(dir); - return ERROR_SUCCESS; + return ret; } UINT ACTION_RemoveFiles( MSIPACKAGE *package ) diff --git a/reactos/dll/win32/msi/font.c b/reactos/dll/win32/msi/font.c index 1b2c3c729dd..1d99a4c0d3a 100644 --- a/reactos/dll/win32/msi/font.c +++ b/reactos/dll/win32/msi/font.c @@ -64,11 +64,6 @@ typedef struct _tagTT_NAME_RECORD { #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) -static const WCHAR szRegisterFonts[] = - {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; -static const WCHAR szUnregisterFonts[] = - {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; - static const WCHAR regfont1[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', diff --git a/reactos/dll/win32/msi/format.c b/reactos/dll/win32/msi/format.c index f59024abf86..c4ff30f4111 100644 --- a/reactos/dll/win32/msi/format.c +++ b/reactos/dll/win32/msi/format.c @@ -175,7 +175,7 @@ static LPWSTR deformat_property(FORMAT *format, FORMSTR *str) val = msi_alloc((str->len + 1) * sizeof(WCHAR)); lstrcpynW(val, get_formstr_data(format, str), str->len + 1); - ret = msi_dup_property(format->package, val); + ret = msi_dup_property(format->package->db, val); msi_free(val); return ret; @@ -805,12 +805,12 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, format.deformatted = *data; format.len = *len; - stack = create_stack(); - temp = create_stack(); - if (!verify_format(*data)) return ERROR_SUCCESS; + stack = create_stack(); + temp = create_stack(); + while ((type = format_lex(&format, &str)) != FORMAT_NULL) { if (type == FORMAT_LBRACK || type == FORMAT_LBRACE || diff --git a/reactos/dll/win32/msi/helpers.c b/reactos/dll/win32/msi/helpers.c index c45ba236d50..54d21994a6d 100644 --- a/reactos/dll/win32/msi/helpers.c +++ b/reactos/dll/win32/msi/helpers.c @@ -47,7 +47,7 @@ LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name ) static const WCHAR szFolder[] = {'A','p','p','D','a','t','a','F','o','l','d','e','r',0}; - SystemFolder = msi_dup_property( package, szFolder ); + SystemFolder = msi_dup_property( package->db, szFolder ); dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode); @@ -160,11 +160,11 @@ static LPWSTR get_source_root( MSIPACKAGE *package ) { LPWSTR path, p; - path = msi_dup_property( package, cszSourceDir ); + path = msi_dup_property( package->db, cszSourceDir ); if (path) return path; - path = msi_dup_property( package, cszDatabase ); + path = msi_dup_property( package->db, cszDatabase ); if (path) { p = strrchrW(path,'\\'); @@ -265,19 +265,19 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, if (!f->ResolvedTarget && !f->Property) { LPWSTR check_path; - check_path = msi_dup_property( package, cszTargetDir ); + check_path = msi_dup_property( package->db, cszTargetDir ); if (!check_path) { - check_path = msi_dup_property( package, cszRootDrive ); + check_path = msi_dup_property( package->db, cszRootDrive ); if (set_prop) - MSI_SetPropertyW(package,cszTargetDir,check_path); + msi_set_property( package->db, cszTargetDir, check_path ); } /* correct misbuilt target dir */ path = build_directory_name(2, check_path, NULL); clean_spaces_from_path( path ); if (strcmpiW(path,check_path)!=0) - MSI_SetPropertyW(package,cszTargetDir,path); + msi_set_property( package->db, cszTargetDir, path ); msi_free(check_path); f->ResolvedTarget = path; @@ -310,11 +310,11 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, TRACE(" internally set to %s\n",debugstr_w(path)); if (set_prop) - MSI_SetPropertyW( package, name, path ); + msi_set_property( package->db, name, path ); return path; } - if (!source && load_prop && (path = msi_dup_property( package, name ))) + if (!source && load_prop && (path = msi_dup_property( package->db, name ))) { f->ResolvedTarget = strdupW( path ); TRACE(" property set to %s\n", debugstr_w(path)); @@ -338,7 +338,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, f->ResolvedTarget = strdupW( path ); TRACE("target -> %s\n", debugstr_w(path)); if (set_prop) - MSI_SetPropertyW(package,name,path); + msi_set_property( package->db, name, path ); } else { diff --git a/reactos/dll/win32/msi/install.c b/reactos/dll/win32/msi/install.c index c23075d61d3..fda49b90d8d 100644 --- a/reactos/dll/win32/msi/install.c +++ b/reactos/dll/win32/msi/install.c @@ -709,7 +709,7 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) break; case MSIRUNMODE_MAINTENANCE: - r = msi_get_property_int( package, szInstalled, 0 ) != 0; + r = msi_get_property_int( package->db, szInstalled, 0 ) != 0; break; case MSIRUNMODE_REBOOTATEND: @@ -721,6 +721,7 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) r = TRUE; } + msiobj_release( &package->hdr ); return r; } @@ -774,6 +775,7 @@ UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState) r = ERROR_ACCESS_DENIED; } + msiobj_release( &package->hdr ); return r; } @@ -1262,7 +1264,7 @@ LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall) return 0; } - langid = msi_get_property_int( package, szProductLanguage, 0 ); + langid = msi_get_property_int( package->db, szProductLanguage, 0 ); msiobj_release( &package->hdr ); return langid; } @@ -1284,7 +1286,7 @@ UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) return MSI_SetFeatureStates( package ); sprintfW( level, fmt, iInstallLevel ); - r = MSI_SetPropertyW( package, szInstallLevel, level ); + r = msi_set_property( package->db, szInstallLevel, level ); if ( r == ERROR_SUCCESS ) r = MSI_SetFeatureStates( package ); diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c index 0a6c4314fbc..49bc199cc36 100644 --- a/reactos/dll/win32/msi/media.c +++ b/reactos/dll/win32/msi/media.c @@ -20,6 +20,8 @@ #include +#define COBJMACROS + #include "windef.h" #include "winerror.h" #include "wine/debug.h" @@ -28,6 +30,7 @@ #include "winuser.h" #include "winreg.h" #include "shlwapi.h" +#include "objidl.h" #include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -76,13 +79,13 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; - if ((msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == + if ((msi_get_property_int(package->db, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE && !gUIHandlerA && !gUIHandlerW && !gUIHandlerRecord) return ERROR_SUCCESS; error = generate_error_string(package, 1302, 1, mi->disk_prompt); - error_dialog = msi_dup_property(package, error_prop); - source_dir = msi_dup_property(package, cszSourceDir); + error_dialog = msi_dup_property(package->db, error_prop); + source_dir = msi_dup_property(package->db, cszSourceDir); while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir)) { @@ -114,49 +117,6 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) return r; } -static UINT writeout_cabinet_stream(MSIPACKAGE *package, LPCWSTR stream, - WCHAR* source) -{ - UINT rc; - USHORT* data; - UINT size; - DWORD write; - HANDLE hfile; - WCHAR tmp[MAX_PATH]; - - static const WCHAR cszTempFolder[]= { - 'T','e','m','p','F','o','l','d','e','r',0}; - - rc = read_raw_stream_data(package->db, stream, &data, &size); - if (rc != ERROR_SUCCESS) - return rc; - - write = MAX_PATH; - if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write)) - GetTempPathW(MAX_PATH, tmp); - - GetTempFileNameW(tmp, stream, 0, source); - - track_tempfile(package, source); - hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (hfile == INVALID_HANDLE_VALUE) - { - ERR("Unable to create file %s\n", debugstr_w(source)); - rc = ERROR_FUNCTION_FAILED; - goto end; - } - - WriteFile(hfile, data, size, &write, NULL); - CloseHandle(hfile); - TRACE("wrote %i bytes to %s\n", write, debugstr_w(source)); - -end: - msi_free(data); - return rc; -} - static void * CDECL cabinet_alloc(ULONG cb) { return msi_alloc(cb); @@ -238,10 +198,72 @@ static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype) return SetFilePointer(handle, dist, NULL, seektype); } +struct cab_stream +{ + MSIDATABASE *db; + WCHAR *name; +}; + +static struct cab_stream cab_stream; + +static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode ) +{ + UINT r; + IStream *stm; + + if (oflag) + WARN("ignoring open flags 0x%08x\n", oflag); + + r = db_get_raw_stream( cab_stream.db, cab_stream.name, &stm ); + if (r != ERROR_SUCCESS) + { + WARN("Failed to get cabinet stream %u\n", r); + return 0; + } + + return (INT_PTR)stm; +} + +static UINT CDECL cabinet_read_stream( INT_PTR hf, void *pv, UINT cb ) +{ + IStream *stm = (IStream *)hf; + DWORD read; + HRESULT hr; + + hr = IStream_Read( stm, pv, cb, &read ); + if (hr == S_OK || hr == S_FALSE) + return read; + + return 0; +} + +static int CDECL cabinet_close_stream( INT_PTR hf ) +{ + IStream *stm = (IStream *)hf; + IStream_Release( stm ); + return 0; +} + +static LONG CDECL cabinet_seek_stream( INT_PTR hf, LONG dist, int seektype ) +{ + IStream *stm = (IStream *)hf; + LARGE_INTEGER move; + ULARGE_INTEGER newpos; + HRESULT hr; + + move.QuadPart = dist; + hr = IStream_Seek( stm, move, seektype, &newpos ); + if (SUCCEEDED(hr)) + { + if (newpos.QuadPart <= MAXLONG) return newpos.QuadPart; + ERR("Too big!\n"); + } + return -1; +} + static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi) { MSIRECORD *row; - LPWSTR ptr; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', @@ -262,10 +284,7 @@ static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); - ptr = strrchrW(mi->source, '\\') + 1; - lstrcpyW(ptr, mi->cabinet); msiobj_release(&row->hdr); - return ERROR_SUCCESS; } @@ -277,12 +296,24 @@ static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint, return 0; } +static WCHAR *get_cabinet_filename(MSIMEDIAINFO *mi) +{ + int len; + WCHAR *ret; + + len = strlenW(mi->sourcedir) + strlenW(mi->cabinet) + 1; + if (!(ret = msi_alloc(len * sizeof(WCHAR)))) return NULL; + strcpyW(ret, mi->sourcedir); + strcatW(ret, mi->cabinet); + return ret; +} + static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { MSICABDATA *data = pfdin->pv; MSIMEDIAINFO *mi = data->mi; - LPWSTR cab = strdupAtoW(pfdin->psz1); + LPWSTR cabinet_file = NULL, cab = strdupAtoW(pfdin->psz1); INT_PTR res = -1; UINT rc; @@ -309,10 +340,13 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, goto done; } - TRACE("Searching for %s\n", debugstr_w(mi->source)); + if (!(cabinet_file = get_cabinet_filename(mi))) + goto done; + + TRACE("Searching for %s\n", debugstr_w(cabinet_file)); res = 0; - if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES) { if (msi_change_media(data->package, mi) != ERROR_SUCCESS) res = -1; @@ -320,6 +354,7 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, done: msi_free(cab); + msi_free(cabinet_file); return res; } @@ -376,7 +411,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, GetTempFileNameW(szBackSlash, szMsi, 0, tmpfileW); len = strlenW(path) + strlenW(tmpfileW) + 1; - if (!(tmppathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + if (!(tmppathW = msi_alloc(len * sizeof(WCHAR)))) return ERROR_OUTOFMEMORY; strcpyW(tmppathW, path); @@ -394,7 +429,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, else WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError()); - HeapFree(GetProcessHeap(), 0, tmppathW); + msi_free(tmppathW); } else WARN("failed to create %s (error %d)\n", debugstr_w(path), err); @@ -436,8 +471,6 @@ static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint, static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { - TRACE("(%d)\n", fdint); - switch (fdint) { case fdintPARTIAL_FILE: @@ -457,48 +490,58 @@ static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION } } -/*********************************************************************** - * msi_cabextract - * - * Extract files from a cab file. - */ -BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data) +static INT_PTR CDECL cabinet_notify_stream( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin ) +{ + switch (fdint) + { + case fdintCOPY_FILE: + return cabinet_copy_file( fdint, pfdin ); + + case fdintCLOSE_FILE_INFO: + return cabinet_close_file_info( fdint, pfdin ); + + case fdintCABINET_INFO: + return 0; + + default: + ERR("Unexpected notification %d\n", fdint); + return 0; + } +} + +static BOOL extract_cabinet( MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data ) { LPSTR cabinet, cab_path = NULL; - LPWSTR ptr; HFDI hfdi; ERF erf; BOOL ret = FALSE; - TRACE("Extracting %s\n", debugstr_w(mi->source)); + TRACE("Extracting %s\n", debugstr_w(mi->cabinet)); - hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, - cabinet_write, cabinet_close, cabinet_seek, 0, &erf); + hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, + cabinet_write, cabinet_close, cabinet_seek, 0, &erf ); if (!hfdi) { ERR("FDICreate failed\n"); return FALSE; } - ptr = strrchrW(mi->source, '\\') + 1; - cabinet = strdupWtoA(ptr); + cabinet = strdupWtoA( mi->cabinet ); if (!cabinet) goto done; - cab_path = strdupWtoA(mi->source); + cab_path = strdupWtoA( mi->sourcedir ); if (!cab_path) goto done; - cab_path[ptr - mi->source] = '\0'; - - ret = FDICopy(hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data); + ret = FDICopy( hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data ); if (!ret) ERR("FDICopy failed\n"); done: - FDIDestroy(hfdi); - msi_free(cabinet); - msi_free(cab_path); + FDIDestroy( hfdi ); + msi_free(cabinet ); + msi_free( cab_path ); if (ret) mi->is_extracted = TRUE; @@ -506,6 +549,56 @@ done: return ret; } +static BOOL extract_cabinet_stream( MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data ) +{ + static char filename[] = {'<','S','T','R','E','A','M','>',0}; + HFDI hfdi; + ERF erf; + BOOL ret = FALSE; + + TRACE("Extracting %s\n", debugstr_w(mi->cabinet)); + + hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open_stream, cabinet_read_stream, + cabinet_write, cabinet_close_stream, cabinet_seek_stream, 0, &erf ); + if (!hfdi) + { + ERR("FDICreate failed\n"); + return FALSE; + } + + cab_stream.db = package->db; + cab_stream.name = encode_streamname( FALSE, mi->cabinet + 1 ); + if (!cab_stream.name) + goto done; + + ret = FDICopy( hfdi, filename, NULL, 0, cabinet_notify_stream, NULL, data ); + if (!ret) + ERR("FDICopy failed\n"); + +done: + FDIDestroy( hfdi ); + msi_free( cab_stream.name ); + + if (ret) + mi->is_extracted = TRUE; + + return ret; +} + +/*********************************************************************** + * msi_cabextract + * + * Extract files from a cabinet file or stream. + */ +BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data) +{ + if (mi->cabinet[0] == '#') + { + return extract_cabinet_stream( package, mi, data ); + } + return extract_cabinet( package, mi, data ); +} + void msi_free_media_info(MSIMEDIAINFO *mi) { msi_free(mi->disk_prompt); @@ -532,7 +625,6 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO LPWSTR source_dir; LPWSTR source; DWORD options; - UINT r; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', @@ -563,25 +655,10 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); - source_dir = msi_dup_property(package, cszSourceDir); - lstrcpyW(mi->source, source_dir); + source_dir = msi_dup_property(package->db, cszSourceDir); + lstrcpyW(mi->sourcedir, source_dir); mi->type = get_drive_type(source_dir); - if (file->IsCompressed && mi->cabinet) - { - if (mi->cabinet[0] == '#') - { - r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source); - if (r != ERROR_SUCCESS) - { - ERR("Failed to extract cabinet stream\n"); - return ERROR_FUNCTION_FAILED; - } - } - else - lstrcatW(mi->source, mi->cabinet); - } - options = MSICODE_PRODUCT; if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) { @@ -595,7 +672,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO } else { - source = mi->source; + source = mi->sourcedir; options |= MSISOURCETYPE_NETWORK; } @@ -610,7 +687,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO return ERROR_SUCCESS; } -/* FIXME: search NETWORK and URL sources as well */ +/* FIXME: search URL sources as well */ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) { WCHAR source[MAX_PATH]; @@ -618,8 +695,16 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) WCHAR prompt[MAX_PATH]; DWORD volumesz, promptsz; DWORD index, size, id; + WCHAR last_type[2]; UINT r; + size = 2; + r = MsiSourceListGetInfoW(package->ProductCode, NULL, + package->Context, MSICODE_PRODUCT, + INSTALLPROPERTY_LASTUSEDTYPEW, last_type, &size); + if (r != ERROR_SUCCESS) + return r; + size = MAX_PATH; r = MsiSourceListGetInfoW(package->ProductCode, NULL, package->Context, MSICODE_PRODUCT, @@ -627,6 +712,26 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (r != ERROR_SUCCESS) return r; + index = 0; + volumesz = MAX_PATH; + promptsz = MAX_PATH; + + if (last_type[0] == 'n') + { + while (MsiSourceListEnumSourcesW(package->ProductCode, NULL, + package->Context, + MSISOURCETYPE_NETWORK, index++, + volume, &volumesz) == ERROR_SUCCESS) + { + if (!strncmpiW(source, volume, strlenW(source))) + { + lstrcpyW(mi->sourcedir, source); + TRACE("Found network source %s\n", debugstr_w(mi->sourcedir)); + return ERROR_SUCCESS; + } + } + } + index = 0; volumesz = MAX_PATH; promptsz = MAX_PATH; @@ -644,7 +749,8 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (source_matches_volume(mi, source)) { /* FIXME: what about SourceDir */ - lstrcpyW(mi->source, source); + lstrcpyW(mi->sourcedir, source); + TRACE("Found disk source %s\n", debugstr_w(mi->sourcedir)); return ERROR_SUCCESS; } } @@ -655,6 +761,7 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { UINT rc = ERROR_SUCCESS; + WCHAR *cabinet_file; /* media info for continuous cabinet is already loaded */ if (mi->is_continuous) @@ -663,7 +770,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) rc = msi_load_media_info(package, file, mi); if (rc != ERROR_SUCCESS) { - ERR("Unable to load media info\n"); + ERR("Unable to load media info %u\n", rc); return ERROR_FUNCTION_FAILED; } @@ -671,15 +778,24 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) if (!mi->cabinet || mi->cabinet[0] == '#') return ERROR_SUCCESS; + cabinet_file = get_cabinet_filename(mi); + /* package should be downloaded */ if (file->IsCompressed && - GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES && + GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES && package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL)) { - WCHAR temppath[MAX_PATH]; + WCHAR temppath[MAX_PATH], *p; - msi_download_file(mi->source, temppath); - lstrcpyW(mi->source, temppath); + msi_download_file(cabinet_file, temppath); + if ((p = strrchrW(temppath, '\\'))) *p = 0; + + msi_free(mi->sourcedir); + strcpyW(mi->sourcedir, temppath); + msi_free(mi->cabinet); + strcpyW(mi->cabinet, p + 1); + + msi_free(cabinet_file); return ERROR_SUCCESS; } @@ -687,7 +803,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) if (mi->volume_label && mi->disk_id > 1 && lstrcmpW(mi->first_volume, mi->volume_label)) { - LPWSTR source = msi_dup_property(package, cszSourceDir); + LPWSTR source = msi_dup_property(package->db, cszSourceDir); BOOL matches; matches = source_matches_volume(mi, source); @@ -697,20 +813,25 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { rc = msi_change_media(package, mi); if (rc != ERROR_SUCCESS) + { + msi_free(cabinet_file); return rc; + } } } if (file->IsCompressed && - GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES) { rc = find_published_source(package, mi); if (rc != ERROR_SUCCESS) { - ERR("Cabinet not found: %s\n", debugstr_w(mi->source)); + ERR("Cabinet not found: %s\n", debugstr_w(cabinet_file)); + msi_free(cabinet_file); return ERROR_INSTALL_FAILURE; } } + msi_free(cabinet_file); return ERROR_SUCCESS; } diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index 07356405718..9d8a88a48fe 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -305,9 +305,8 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS UINT r = ERROR_SUCCESS, type; DWORD size = 0; LPCWSTR cmd_ptr = szCommandLine; - LPCWSTR product_code = szProductCode; - LPWSTR beg, end; - LPWSTR cmd = NULL, codes = NULL; + LPWSTR beg, end, cmd = NULL, codes = NULL; + BOOL succeeded = FALSE; static const WCHAR patcheq[] = {'P','A','T','C','H','=',0}; static WCHAR empty[] = {0}; @@ -342,8 +341,6 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size); if (r != ERROR_SUCCESS) goto done; - - product_code = codes; } if (!szCommandLine) @@ -362,16 +359,25 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS lstrcatW(cmd, patcheq); lstrcatW(cmd, szPatchPackage); - beg = codes; - while ((end = strchrW(beg, '}'))) + if (szProductCode) + r = MsiConfigureProductExW(szProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); + else { - *(end + 1) = '\0'; + beg = codes; + while ((end = strchrW(beg, '}'))) + { + *(end + 1) = '\0'; + r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); + if (r == ERROR_SUCCESS) + { + TRACE("patch applied\n"); + succeeded = TRUE; + } + beg = end + 2; + } - r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); - if (r != ERROR_SUCCESS) - goto done; - - beg = end + 2; + if (succeeded) + r = ERROR_SUCCESS; } done: @@ -480,10 +486,43 @@ UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages, UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo) { - FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath), - cPatchInfo, pPatchInfo); + UINT i, r; + WCHAR *package_path = NULL; + MSIPATCHSEQUENCEINFOW *psi; - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("(%s, %d, %p)\n", debugstr_a(szProductPackagePath), cPatchInfo, pPatchInfo); + + if (szProductPackagePath && !(package_path = strdupAtoW( szProductPackagePath ))) + return ERROR_OUTOFMEMORY; + + psi = msi_alloc( cPatchInfo * sizeof(*psi) ); + if (!psi) + { + msi_free( package_path ); + return ERROR_OUTOFMEMORY; + } + + for (i = 0; i < cPatchInfo; i++) + { + psi[i].szPatchData = strdupAtoW( pPatchInfo[i].szPatchData ); + psi[i].ePatchDataType = pPatchInfo[i].ePatchDataType; + } + + r = MsiDetermineApplicablePatchesW( package_path, cPatchInfo, psi ); + if (r == ERROR_SUCCESS) + { + for (i = 0; i < cPatchInfo; i++) + { + pPatchInfo[i].dwOrder = psi[i].dwOrder; + pPatchInfo[i].uStatus = psi[i].uStatus; + } + } + + msi_free( package_path ); + for (i = 0; i < cPatchInfo; i++) + msi_free( (WCHAR *)psi[i].szPatchData ); + msi_free( psi ); + return r; } static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) @@ -502,15 +541,14 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); if (!si) { - r = ERROR_FUNCTION_FAILED; - goto done; + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; } r = msi_check_patch_applicable( package, si ); if (r != ERROR_SUCCESS) TRACE("patch not applicable\n"); -done: msiobj_release( &patch_db->hdr ); msiobj_release( &si->hdr ); return r; @@ -596,10 +634,6 @@ static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context, WCHAR sourcepath[MAX_PATH]; WCHAR filename[MAX_PATH]; - static const WCHAR szLocalPackage[] = { - 'L','o','c','a','l','P','a','c','k','a','g','e',0}; - - r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE); if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION; @@ -1181,7 +1215,7 @@ done: static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size) { - UINT r; + UINT r = ERROR_SUCCESS; if (!val) return ERROR_UNKNOWN_PROPERTY; @@ -1201,7 +1235,7 @@ static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size) if (size) *size = lstrlenW(val); - return ERROR_SUCCESS; + return r; } UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, @@ -2149,6 +2183,22 @@ UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uT return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId); } +UINT WINAPI MsiMessageBoxExA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, + DWORD unknown, WORD wLanguageId, DWORD f) +{ + FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_a(lpText), + debugstr_a(lpCaption), uType, unknown, wLanguageId, f); + return MessageBoxExA(hWnd, lpText, lpCaption, uType, wLanguageId); +} + +UINT WINAPI MsiMessageBoxExW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, + DWORD unknown, WORD wLanguageId, DWORD f) +{ + FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_w(lpText), + debugstr_w(lpCaption), uType, unknown, wLanguageId, f); + return MessageBoxExW(hWnd, lpText, lpCaption, uType, wLanguageId); +} + UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf, LPDWORD pcchPathBuf ) @@ -2337,6 +2387,7 @@ done: r = ERROR_SUCCESS; } + msiobj_release(&package->hdr); return r; } @@ -3519,10 +3570,10 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, if (r != ERROR_SUCCESS) return r; - MSI_SetPropertyW( package, szReinstallMode, reinstallmode ); - MSI_SetPropertyW( package, szInstalled, szOne ); - MSI_SetPropertyW( package, szLogVerbose, szOne ); - MSI_SetPropertyW( package, szReinstall, szFeature ); + msi_set_property( package->db, szReinstallMode, reinstallmode ); + msi_set_property( package->db, szInstalled, szOne ); + msi_set_property( package->db, szLogVerbose, szOne ); + msi_set_property( package->db, szReinstall, szFeature ); r = MSI_InstallPackage( package, sourcepath, NULL ); diff --git a/reactos/dll/win32/msi/msi.spec b/reactos/dll/win32/msi/msi.spec index 30daec931a6..94e3ed3cb23 100644 --- a/reactos/dll/win32/msi/msi.spec +++ b/reactos/dll/win32/msi/msi.spec @@ -272,8 +272,8 @@ 276 stub MsiSourceListClearMediaDiskW 277 stdcall MsiDetermineApplicablePatchesA(str long ptr) 278 stdcall MsiDetermineApplicablePatchesW(wstr long ptr) -279 stub MsiMessageBoxExA -280 stub MsiMessageBoxExW +279 stdcall MsiMessageBoxExA(long str str long long long long) +280 stdcall MsiMessageBoxExW(long wstr wstr long long long long) 281 stdcall MsiSetExternalUIRecord(ptr long ptr ptr) @ stdcall -private DllCanUnloadNow() diff --git a/reactos/dll/win32/msi/msi_Bg.rc b/reactos/dll/win32/msi/msi_Bg.rc index d3b8ca84abb..8aea16940f3 100644 --- a/reactos/dll/win32/msi/msi_Bg.rc +++ b/reactos/dll/win32/msi/msi_Bg.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "ïúòÿò %s íå å íàìåðåí" 9 "ïîñòàâåòå äèñê %s" - 10 "íåêîðåêòíè ïàðàìåòðè" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "âúâåäåòå ïàïêàòà, êîÿòî ñúäúðæà %s" 12 "èçòî÷íèêà çà èíñòàëàöèÿ íà ôóíêöèîíàëíîñòòà ëèïñâà" 13 "ìðåæîâîòî óñòðîéñòâà íóæíî çà ôóíêöèîíàëíîñòòà ëèïñâà " diff --git a/reactos/dll/win32/msi/msi_Da.rc b/reactos/dll/win32/msi/msi_Da.rc index beee42765ee..fa7e1c43c39 100644 --- a/reactos/dll/win32/msi/msi_Da.rc +++ b/reactos/dll/win32/msi/msi_Da.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Kunne ikke åbne den specificerede installationspakke. Kontroller stien og prøv igen." 5 "kunne ikke finden stien '%s'." 9 "indsæt disk '%s'" - 10 "forkerte parametere." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "angiv kataloget som indeholder '%s'." 12 "featurens installationskilde mangler." 13 "featurens netværksdrev mangler." diff --git a/reactos/dll/win32/msi/msi_De.rc b/reactos/dll/win32/msi/msi_De.rc index e0cccf07806..e07b5efd127 100644 --- a/reactos/dll/win32/msi/msi_De.rc +++ b/reactos/dll/win32/msi/msi_De.rc @@ -2,6 +2,7 @@ * German resources for MSI * * Copyright 2005 Henning Gerhardt + * Copyright 2010 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Das angegebene Installationspaket konnte nicht geöffnet werden. Bitte überprüfen Sie den Pfadnamen und versuchen Sie es noch einmal." 5 "Der Pfad %s wurde nicht gefunden." 9 "Bitte Disk %s einlegen." - 10 "Falsche Parameter" + 10 "Windows Installer %s\n\n" \ + "Benutzung:\n" \ + "msiexec Befehl {Parameter} [Zusätzliche Parammeter]\n\n" \ + "Produkt installieren:\n" \ + "\t/i {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/package {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/a Paket [Eigenschaft]\n" \ + "Installation reparieren:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {Paket|Produktcode}\n" \ + "Produkt deinstallieren:\n" \ + "\t/uninstall {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/x {Paket|Produktcode} [Eigenschaft]\n" \ + "Produkt ankündigen:\n" \ + "\t/j[u|m] Paket [/t Transformationspaket] [/g Sprachkennung]\n" \ + "Patch integrieren:\n" \ + "\t/p Patchpaket [Eigenschaft]\n" \ + "\t/p Patchpaket /a Paket [Eigenschaft]\n" \ + "Protokollierung und Benutzeroberfläche für die oberen Befehle anpassen:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] Protokolldatei\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "MSI Service registrieren:\n" \ + "\t/y\n" \ + "Registrierung des MSI Service aufheben:\n" \ + "\t/z\n" \ + "Hilfe anzeigen:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Geben Sie das Verzeichnis ein, dass %s enthält." 12 "Die Installationsquelle für das Feature fehlt." 13 "Das Netzwerklaufwerk für das Feature fehlt." diff --git a/reactos/dll/win32/msi/msi_En.rc b/reactos/dll/win32/msi/msi_En.rc index 74fc5c14a85..c506e003445 100644 --- a/reactos/dll/win32/msi/msi_En.rc +++ b/reactos/dll/win32/msi/msi_En.rc @@ -2,6 +2,7 @@ * English resources for MSI * * Copyright 2005 Mike McCormack + * Copyright 2010 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "path %s not found" 9 "insert disk %s" - 10 "bad parameters" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parameter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "enter which folder contains %s" 12 "install source for feature missing" 13 "network drive for feature missing" diff --git a/reactos/dll/win32/msi/msi_Eo.rc b/reactos/dll/win32/msi/msi_Eo.rc index 7579bdc65cb..8b8c8d36fbd 100644 --- a/reactos/dll/win32/msi/msi_Eo.rc +++ b/reactos/dll/win32/msi/msi_Eo.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "Mi ne trovis la vojon %s" 9 "enþovu la diskon %s" - 10 "nekorektaj parametroj" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "enigu la nomon de dosierujo kiu enhavas %s" 12 "instalad-fonto por mankanta taýgeco" 13 "retdrajvo por mankanta taýgeco" diff --git a/reactos/dll/win32/msi/msi_Es.rc b/reactos/dll/win32/msi/msi_Es.rc index 781be071802..f5425dbb654 100644 --- a/reactos/dll/win32/msi/msi_Es.rc +++ b/reactos/dll/win32/msi/msi_Es.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "No se ha podido abrir el paquete de instalación especificado. Por favor, compruebe la ruta del archivo y vuelva a intentarlo." 5 "ruta %s no encontrada" 9 "inserte el disco %s" - 10 "parámetros incorrectos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "introduzca qué carpeta contiene %s" 12 "instalar fuente para característica ausente" 13 "unidad de red para característica ausente" diff --git a/reactos/dll/win32/msi/msi_Fi.rc b/reactos/dll/win32/msi/msi_Fi.rc index 17721aa4b01..f3d58bff2bc 100644 --- a/reactos/dll/win32/msi/msi_Fi.rc +++ b/reactos/dll/win32/msi/msi_Fi.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "Polkua %s ei löydy." 9 "Anna levy %s" - 10 "Virheelliset parametrit." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Anna kansio, joka sisältää %s" 12 "Ominaisuuden asennuslähde puuttuu." 13 "Ominaisuuden verkkolevy puuttuu." diff --git a/reactos/dll/win32/msi/msi_Fr.rc b/reactos/dll/win32/msi/msi_Fr.rc index f7f733803bc..6cd1fc5ca21 100644 --- a/reactos/dll/win32/msi/msi_Fr.rc +++ b/reactos/dll/win32/msi/msi_Fr.rc @@ -2,6 +2,7 @@ * French resources for MSI * * Copyright 2005 Jonathan Ernst + * Copyright 2009-2010 Frédéric Delanoy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +31,33 @@ STRINGTABLE DISCARDABLE 4 "Le paquet d'installation spécifié n'a pu être ouvert. Veuillez vérifier le chemin du fichier et réessayer." 5 "Le chemin %s est introuvable" 9 "insérez le disque %s" - 10 "mauvais paramètres" + 10 "Programme d'installation Windows %s\n\n" \ + "Usage :\n" \ + "msiexec commande {paramètre obligatoire} [paramètre optionnel]\n\n" \ + "Installer un produit :\n" \ + "\t/i {paquet|code_produit} [propriété]\n" \ + "\t/package {paquet|code_produit} [propriété]\n" \ + "\t/a paquet [propriété]\n" \ + "Réparer une installation :\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {paquet|code_produit}\n" \ + "Désinstaller un produit :\n" \ + "\t/uninstall {paquet|code_produit} [propriété]\n" \ + "\t/x {paquet|code_produit} [propriété]\n" \ + "Publier un produit :\n" \ + "\t/j[u|m] paquet [/t transformation] [/g id_langue]\n" \ + "Appliquer un patch :\n" \ + "\t/p paquet_patch [propriété]\n" \ + "\t/p paquet_patch /a paquet [propriété]\n" \ + "Modificateurs de journalisation et d'interface utilisateur pour les commandes ci-dessus :\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] fichier_journal\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Enregistrer le service MSI :\n" \ + "\t/y\n" \ + "Annuler l'enregistrement du service MSI :\n" \ + "\t/z\n" \ + "Afficher cette aide :\n" \ + "\t/help\n" \ + "\t/?\n" 11 "saisissez le nom du dossier contenant %s" 12 "source d'installation pour la fonctionnalité manquante" 13 "lecteur réseau pour la fonctionnalité manquante" diff --git a/reactos/dll/win32/msi/msi_Hu.rc b/reactos/dll/win32/msi/msi_Hu.rc index 21ba5cf30c1..846de4ccada 100644 --- a/reactos/dll/win32/msi/msi_Hu.rc +++ b/reactos/dll/win32/msi/msi_Hu.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "%s útvonal nem található" 9 "helyezze be a lemezt: %s" - 10 "rossz paraméterek" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "adja meg melyik mappa tartalmazza ezt: %s" 12 "hiányzó tulajdonság a telepítési forráshoz" 13 "hiányzó tulajdonság a hálózati meghajtóhoz" diff --git a/reactos/dll/win32/msi/msi_It.rc b/reactos/dll/win32/msi/msi_It.rc index a40a7303425..0586bb4bab5 100644 --- a/reactos/dll/win32/msi/msi_It.rc +++ b/reactos/dll/win32/msi/msi_It.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Impossibile aprire il pacchetto di installazione specificato. Per favore controlla l'indirizzo del file e riprova." 5 "percorso %s non trovato" 9 "inserire disco %s" - 10 "parametri incorretti" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "immettere il nome della cartella che contiene %s" 12 "sorgente di installazione per la funzionalità mancante" 13 "periferica di rete per la funzionalità mancante" diff --git a/reactos/dll/win32/msi/msi_Ko.rc b/reactos/dll/win32/msi/msi_Ko.rc index ca14253307d..17ab488ce2f 100644 --- a/reactos/dll/win32/msi/msi_Ko.rc +++ b/reactos/dll/win32/msi/msi_Ko.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 " ÁöÁ¤ÇÑ ¼³Ä¡ ÆÐŰÁö¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù. ÆÄÀÏ °æ·Î¸¦ È®ÀÎÇÏ°í ´Ù½Ã ½ÃµµÇϽʽÿÀ." 5 "%s °æ·Î¸¦ ãÀ»¼ö ¾ø½À´Ï´Ù" 9 "µð½ºÅ© %s »ðÀÔ" - 10 "À߸øµÈ ¸Å°³º¯¼ö" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "%s¸¦ Æ÷ÇÔÇÏ´Â Æú´õ¸¦ ÀÔ·ÂÇϼ¼¿©" 12 "ºüÁø ºÎºÐ(feature)À» À§ÇÑ ¼³Ä¡ ¿øº»" 13 "ºüÁø ºÎºÐ(feature)À» À§ÇÑ ³×Æ®¿öÅ© µå¶óÀ̺ê" diff --git a/reactos/dll/win32/msi/msi_Lt.rc b/reactos/dll/win32/msi/msi_Lt.rc index 1cf1c52924e..c88592c49bc 100644 --- a/reactos/dll/win32/msi/msi_Lt.rc +++ b/reactos/dll/win32/msi/msi_Lt.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Nepavyko atverti nurodyto diegimo paketo. Patikrinkite failo keliÄ… ir mÄ—ginkite dar kartÄ…." 5 "kelias %s nerastas" 9 "įdÄ—kite diskÄ… %s" - 10 "blogi parametrai" + 10 "Windows diegimo programa %s\n\n" \ + "Naudojimas:\n" \ + "msiexec komanda {bÅ«tinas parametras} [nebÅ«tinas parametras]\n\n" \ + "Ä®diegti produktÄ…:\n" \ + "\t/i {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/package {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/a paketas [savybÄ—]\n" \ + "Taisyti įdiegimÄ…:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {paketas|produkto_kodas}\n" \ + "PaÅ¡alinti produktÄ…:\n" \ + "\t/uninstall {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/x {paketas|produkto_kodas} [savybÄ—]\n" \ + "Skelbti produktÄ…:\n" \ + "\t/j[u|m] paketas [/t pakeitimas] [/g kalbos_identifikatorius]\n" \ + "Pritaikyti pataisÄ…:\n" \ + "\t/p pataisos_paketas [savybÄ—]\n" \ + "\t/p pataisos_paketas /a paketas [savybÄ—]\n" \ + "Žurnalo ir sÄ…sajos modifikatoriai aukÅ¡Äiau iÅ¡vardintoms komandoms:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] žurnalo_failas\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Registruoti MSI tarnybÄ…:\n" \ + "\t/y\n" \ + "IÅ¡registruoti MSI tarnybÄ…:\n" \ + "\t/z\n" \ + "Parodyti Å¡iÄ… pagalbÄ…:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "įveskite aplankÄ…, kuris turi %s" 12 "trÅ«ksta diegimo Å¡altinio komponentui" 13 "trÅ«ksta tinklo disko komponentui" diff --git a/reactos/dll/win32/msi/msi_Nl.rc b/reactos/dll/win32/msi/msi_Nl.rc index da304304ed3..306cfd7e30a 100644 --- a/reactos/dll/win32/msi/msi_Nl.rc +++ b/reactos/dll/win32/msi/msi_Nl.rc @@ -1,5 +1,5 @@ /* - * Durch resources for MSI + * Dutch resources for MSI * * Copyright 2005 Hans Leidekker * @@ -24,13 +24,39 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { - 4 "The specified installation package could not be opened. Please check the file path and try again." + 4 "Het opgegeven installatie pakket kon niet worden geopend. Verifieer het bestandspad en probeer opnieuw." 5 "Pad %s niet gevonden" 9 "Plaats disk %s" - 10 "Ongeldige parameters" + 10 "Windows Installer %s\n\n" \ + "Gebruik:\n" \ + "msiexec commando {vereiste parameter} [optionele parameter]\n\n" \ + "Installeer een product:\n" \ + "\t/i {pakket|productcode} [eigenschap]\n" \ + "\t/package {pakket|productcode} [eigenschap]\n" \ + "\t/a pakket [eigenschap]\n" \ + "Herstel een installatie:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {pakket|productcode}\n" \ + "Verwijder een product:\n" \ + "\t/uninstall {pakket|productcode} [eigenschap]\n" \ + "\t/x {pakket|productcode} [eigenschap]\n" \ + "Adverteer een product:\n" \ + "\t/j[u|m] pakket [/t transform] [/g languageid]\n" \ + "Pas een patch toe:\n" \ + "\t/p patchpakket [eigenschap]\n" \ + "\t/p patchpakket /a pakket [eigenschap]\n" \ + "Log en UI Modifiers voor bovenstaande commando's:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logbestand\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Registreer MSI Service:\n" \ + "\t/y\n" \ + "Maak registratie MSI Service ongedaan:\n" \ + "\t/z\n" \ + "Laat dit helpvenster zien:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Voer de map in die %s bevat" - 12 "De installatiebron van het feature ontbreekt" - 13 "De netwerkschijf met het feature ontbreekt" + 12 "De installatiebron van de feature ontbreekt" + 13 "De netwerkschijf met de feature ontbreekt" 14 "Feature van:" 15 "Kies de map die %s bevat" } diff --git a/reactos/dll/win32/msi/msi_No.rc b/reactos/dll/win32/msi/msi_No.rc index e885f5adbda..93e26c67211 100644 --- a/reactos/dll/win32/msi/msi_No.rc +++ b/reactos/dll/win32/msi/msi_No.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Klarte ikke åpne den oppgitte installasjonspakken. Kontroller filbanen og prøv igjen." 5 "Fant ikke stien '%s'." 9 "Sett i disk '%s'" - 10 "Gale parametere." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Oppgi katalogen som inneholder '%s'." 12 "Egenskapens installasjonskilde mangler." 13 "Egenskapens nettverksstasjon mangler." diff --git a/reactos/dll/win32/msi/msi_Pl.rc b/reactos/dll/win32/msi/msi_Pl.rc index c31311ebf7e..ceb64dd9c8c 100644 --- a/reactos/dll/win32/msi/msi_Pl.rc +++ b/reactos/dll/win32/msi/msi_Pl.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "Nie uda³o siê otworzyæ wybranego pakietu instalacyjnego. SprawdŸ czy œcie¿ka jest poprawna i spróbuj ponownie." 5 "œcie¿ka '%s' nie zosta³a odnaleziona" 9 "w³ó¿ dysk '%s'" - 10 "z³e parametry" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "wprowadŸ sice¿kê do folderu zawieraj¹cego '%s'" 12 "Ÿród³o danych zawieraj¹ce ¿¹danê funkcjê jest niedostêpne" 13 "dysk siecowy zawieraj¹cy ¿¹dan¹ funckje jest niedostêpny" diff --git a/reactos/dll/win32/msi/msi_Pt.rc b/reactos/dll/win32/msi/msi_Pt.rc index 64ab16348d4..94cc6330e0c 100644 --- a/reactos/dll/win32/msi/msi_Pt.rc +++ b/reactos/dll/win32/msi/msi_Pt.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "caminho %s não encontrado" 9 "insira disco %s" - 10 "parâmetros inválidos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "entre qual pasta contém %s" 12 "instalar fonte para característica faltando" 13 "drive de rede para característica faltando" @@ -43,7 +69,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "localização %s não encontrada" 9 "insira o disco %s" - 10 "parâmetros inválidos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "indique que pasta contém %s" 12 "instalar fonte para a opção em falta" 13 "controlador de rede para a opção em falta" diff --git a/reactos/dll/win32/msi/msi_Ro.rc b/reactos/dll/win32/msi/msi_Ro.rc index b877b42a34e..ffd9c5e08d7 100644 --- a/reactos/dll/win32/msi/msi_Ro.rc +++ b/reactos/dll/win32/msi/msi_Ro.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "Pachetul de instalare menÈ›ionat nu a putut fi deschis. VerificaÈ›i calea È™i încercaÈ›i din nou." 5 "calea %s nu a fost găsită" 9 "inseraÈ›i discul %s" - 10 "parameteri greÈ™iÈ›i" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "introduceÈ›i fiÈ™ierul care conÈ›ine %s" 12 "lipseÈ™te sursa de instalare pentru această caracteristică" 13 "lipseÈ™te unitatea de reÈ›ea pentru această caracteristică" diff --git a/reactos/dll/win32/msi/msi_Ru.rc b/reactos/dll/win32/msi/msi_Ru.rc index 8e7aafdda31..7cd4a2b0737 100644 --- a/reactos/dll/win32/msi/msi_Ru.rc +++ b/reactos/dll/win32/msi/msi_Ru.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Указанный пакет не может быть открыт. Проверьте файл и повторите попытку." 5 "путь %s не найден" 9 "вÑтавьте диÑк %s" - 10 "неверные параметры" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "укажите каталог, Ñодержащий %s" 12 "иÑточник уÑтановки данной возможноÑти не указан" 13 "Ñетевой диÑк Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ возможноÑти не указан" diff --git a/reactos/dll/win32/msi/msi_Si.rc b/reactos/dll/win32/msi/msi_Si.rc index 75823390635..3477f1ba6e5 100644 --- a/reactos/dll/win32/msi/msi_Si.rc +++ b/reactos/dll/win32/msi/msi_Si.rc @@ -29,7 +29,33 @@ STRINGTABLE DISCARDABLE 4 "Navedenega namestitvenega paketa ni mogoÄe odpreti. Preverite ime datoteke in poskusite znova." 5 "pot %s ne obstaja" 9 "vnesite disk %s" - 10 "neveljavni parametri" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "vnesite ime mape, ki vsebuje %s" 12 "manjkajoÄ namestitveni vir za namestitev funkcije" 13 "manjkajoÄ omrežni pogon za namestitev funkcijo" diff --git a/reactos/dll/win32/msi/msi_Sv.rc b/reactos/dll/win32/msi/msi_Sv.rc index 47bf09b00c4..4c37cfc475b 100644 --- a/reactos/dll/win32/msi/msi_Sv.rc +++ b/reactos/dll/win32/msi/msi_Sv.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Det angivna installationspaketet kunde inte öppnas. Kontrollera filsökvägen och försök igen." 5 "sökvägen %s hittades inte" 9 "mata in %s" - 10 "felaktiga parametrar" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "ange vilken mapp som innehåller %s" 12 "installationskälla för funktion saknar" 13 "nätverksenhet för funktion saknar" diff --git a/reactos/dll/win32/msi/msi_Tr.rc b/reactos/dll/win32/msi/msi_Tr.rc index a8e0f369666..c6a12c1ae07 100644 --- a/reactos/dll/win32/msi/msi_Tr.rc +++ b/reactos/dll/win32/msi/msi_Tr.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "%s yolu bulunamadý" 9 "%s nolu diski yerleþtirin" - 10 "bozuk parametreler" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "%s öðesini içeren dizini girin" 12 "eksik özellik için kurulum kaynaðý" 13 "eksik özellik için að sürücüsü" diff --git a/reactos/dll/win32/msi/msi_Uk.rc b/reactos/dll/win32/msi/msi_Uk.rc index 4b7173e8d4a..2407bbe6e6d 100644 --- a/reactos/dll/win32/msi/msi_Uk.rc +++ b/reactos/dll/win32/msi/msi_Uk.rc @@ -32,7 +32,33 @@ STRINGTABLE DISCARDABLE 4 "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ вказаний пакет інÑталÑції. Перевірте шлÑÑ… до файлу та Ñпробуйте знов." 5 "шлÑÑ… %s не знайдено" 9 "вÑтавте диÑк %s" - 10 "невірні параметри" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "вкажіть папку, що міÑтить %s" 12 "джерело вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¾Ñ— можливоÑті не вказане" 13 "мережевий диÑк Ð´Ð»Ñ Ð´Ð°Ð½Ð¾Ñ— можливоÑті не вказаний" diff --git a/reactos/dll/win32/msi/msi_Zh.rc b/reactos/dll/win32/msi/msi_Zh.rc index a6d5cd1eff6..91fd5400258 100644 --- a/reactos/dll/win32/msi/msi_Zh.rc +++ b/reactos/dll/win32/msi/msi_Zh.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "ä¸èƒ½æ‰“开所指定的安装软件包. 请检查文件路径åŽå†è¯•." 5 "路径 %s 没找到" 9 "æ’入软盘 %s" - 10 "é”™è¯¯å‚æ•°" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "è¾“å…¥åŒ…å« %s 的文件夹" 12 "本功能的安装æºä¸å­˜åœ¨" 13 "本功能的网络驱动器ä¸å­˜åœ¨" @@ -45,7 +71,33 @@ STRINGTABLE DISCARDABLE 4 "ä¸èƒ½é–‹å•Ÿæ‰€æŒ‡å®šçš„安è£è»Ÿä»¶åŒ…. 請檢查檔案路徑後å†è©¦." 5 "路徑 %s 沒找到" 9 "æ’入軟碟 %s" - 10 "éŒ¯èª¤åƒæ•¸" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "è¼¸å…¥åŒ…å« %s 的檔案夾" 12 "æœ¬åŠŸèƒ½çš„å®‰è£æºä¸å­˜åœ¨" 13 "本功能的網路儲存槽ä¸å­˜åœ¨" diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 0516dd18da7..cf9e6909f5d 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -143,13 +143,15 @@ typedef struct tagMSIMEDIAINFO LPWSTR volume_label; BOOL is_continuous; BOOL is_extracted; - WCHAR source[MAX_PATH]; + WCHAR sourcedir[MAX_PATH]; } MSIMEDIAINFO; typedef struct tagMSIPATCHINFO { + struct list entry; LPWSTR patchcode; LPWSTR transforms; + LPWSTR localfile; } MSIPATCHINFO; typedef struct _column_info @@ -302,7 +304,7 @@ typedef struct tagMSIPACKAGE { MSIOBJECTHDR hdr; MSIDATABASE *db; - MSIPATCHINFO *patch; + struct list patches; struct list components; struct list features; struct list files; @@ -466,6 +468,7 @@ typedef struct tagMSIFILE LPWSTR TargetPath; BOOL IsCompressed; MSIFILEHASHINFO hash; + UINT disk_id; } MSIFILE; typedef struct tagMSITEMPFILE @@ -553,6 +556,7 @@ struct tagMSIMIME struct list entry; LPWSTR ContentType; /* Primary Key */ MSIEXTENSION *Extension; + LPWSTR suffix; LPWSTR clsid; MSICLASS *Class; /* not in the table, set during installation */ @@ -660,8 +664,7 @@ enum StringPersistence StringNonPersistent = 1 }; -extern BOOL msi_addstringW( string_table *st, UINT string_no, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ); - +extern BOOL msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence ); extern UINT msi_string2idW( const string_table *st, LPCWSTR buffer, UINT *id ); extern VOID msi_destroy_stringtable( string_table *st ); extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ); @@ -672,8 +675,6 @@ extern UINT msi_save_string_table( const string_table *st, IStorage *storage ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ); extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); -extern UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, - USHORT **pdata, UINT *psz ); extern UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table, BYTE **pdata, UINT *psz ); extern UINT write_stream_data( IStorage *stg, LPCWSTR stname, @@ -685,7 +686,10 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, LPCWSTR szTransformFile, int iErrorCond ); extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ); +/* patch functions */ extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ); +extern UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ); +extern UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch ); /* action internals */ extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ); @@ -724,6 +728,7 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out); /* database internals */ extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ); +void db_destroy_stream( MSIDATABASE *, LPCWSTR ); extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** ); extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ); extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ); @@ -748,10 +753,7 @@ extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ); extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *, LPCWSTR ); extern UINT MSI_OpenPackageW( LPCWSTR szPackage, MSIPACKAGE **pPackage ); extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR ); -extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR ); extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * ); -extern UINT MSI_GetPropertyW( MSIPACKAGE *, LPCWSTR, LPWSTR, LPDWORD ); -extern UINT MSI_GetPropertyA(MSIPACKAGE *, LPCSTR, LPSTR, LPDWORD ); extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR ); extern UINT MSI_GetComponentStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * ); extern UINT MSI_GetFeatureStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * ); @@ -760,6 +762,7 @@ extern UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ); extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR); extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR); extern UINT msi_clone_properties(MSIPACKAGE *); +extern UINT msi_set_context(MSIPACKAGE *); extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT); /* for deformating */ @@ -787,12 +790,15 @@ extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT d LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create); +extern UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create); extern UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct); +extern UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context); extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid); @@ -963,16 +969,23 @@ extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterFonts(MSIPACKAGE *package); +extern UINT ACTION_UnregisterClassInfo(MSIPACKAGE *package); +extern UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package); +extern UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package); +extern UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package); /* Helpers */ extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ); extern LPWSTR msi_dup_record_field(MSIRECORD *row, INT index); -extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop); -extern int msi_get_property_int( MSIPACKAGE *package, LPCWSTR prop, int def ); +extern LPWSTR msi_dup_property( MSIDATABASE *db, LPCWSTR prop ); +extern UINT msi_set_property( MSIDATABASE *, LPCWSTR, LPCWSTR ); +extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD ); +extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def ); extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, BOOL set_prop, BOOL load_prop, MSIFOLDER **folder); extern LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file); +extern void msi_reset_folders( MSIPACKAGE *package, BOOL source ); extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component ); extern MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature ); extern MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file ); @@ -992,6 +1005,7 @@ extern WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... ); extern UINT msi_create_component_directories( MSIPACKAGE *package ); extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); +extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix); /* media */ @@ -1084,6 +1098,23 @@ static const WCHAR szHU[] = {'H','K','E','Y','_','U','S','E','R','S','\\',0}; static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l','d','e','r',0}; static const WCHAR szAppSearch[] = {'A','p','p','S','e','a','r','c','h',0}; static const WCHAR szMoveFiles[] = {'M','o','v','e','F','i','l','e','s',0}; +static const WCHAR szCCPSearch[] = {'C','C','P','S','e','a','r','c','h',0}; +static const WCHAR szUnregisterClassInfo[] = {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0}; +static const WCHAR szUnregisterExtensionInfo[] = {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0}; +static const WCHAR szUnregisterMIMEInfo[] = {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0}; +static const WCHAR szUnregisterProgIdInfo[] = {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0}; +static const WCHAR szRegisterFonts[] = {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; +static const WCHAR szUnregisterFonts[] = {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; +static const WCHAR szCLSID[] = {'C','L','S','I','D',0}; +static const WCHAR szProgID[] = {'P','r','o','g','I','D',0}; +static const WCHAR szVIProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0}; +static const WCHAR szAppID[] = {'A','p','p','I','D',0}; +static const WCHAR szDefaultIcon[] = {'D','e','f','a','u','l','t','I','c','o','n',0}; +static const WCHAR szInprocHandler[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r',0}; +static const WCHAR szInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; +static const WCHAR szMIMEDatabase[] = {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',' ','T','y','p','e','\\',0}; +static const WCHAR szLocalPackage[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0}; +static const WCHAR szOriginalDatabase[] = {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; /* memory allocation macro functions */ static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index b1741ae87cf..fba722fe55c 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -214,6 +214,7 @@ static void free_package_structures( MSIPACKAGE *package ) MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry ); list_remove( &mt->entry ); + msi_free( mt->suffix ); msi_free( mt->clsid ); msi_free( mt->ContentType ); msi_free( mt ); @@ -263,11 +264,15 @@ static void free_package_structures( MSIPACKAGE *package ) msi_free( package->script ); } - if (package->patch) + LIST_FOR_EACH_SAFE( item, cursor, &package->patches ) { - msi_free( package->patch->patchcode ); - msi_free( package->patch->transforms ); - msi_free( package->patch ); + MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry ); + + list_remove( &patch->entry ); + msi_free( patch->patchcode ); + msi_free( patch->transforms ); + msi_free( patch->localfile ); + msi_free( patch ); } msi_free( package->BaseURL ); @@ -388,7 +393,7 @@ static UINT set_installed_prop( MSIPACKAGE *package ) if (r == ERROR_SUCCESS) { RegCloseKey( hkey ); - MSI_SetPropertyW( package, szInstalled, szOne ); + msi_set_property( package->db, szInstalled, szOne ); } return r; @@ -431,7 +436,7 @@ static UINT set_user_sid_prop( MSIPACKAGE *package ) if (!ConvertSidToStringSidW( psid, &sid_str )) goto done; - r = MSI_SetPropertyW( package, szUserSID, sid_str ); + r = msi_set_property( package->db, szUserSID, sid_str ); done: LocalFree( sid_str ); @@ -563,7 +568,7 @@ static void set_msi_assembly_prop(MSIPACKAGE *package) if (!val_len || !verstr) goto done; - MSI_SetPropertyW(package, netasm, verstr); + msi_set_property(package->db, netasm, verstr); done: msi_free(fusion); @@ -689,96 +694,96 @@ static VOID set_installer_properties(MSIPACKAGE *package) SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, CFF, pth); + msi_set_property(package->db, CFF, pth); SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PFF, pth); + msi_set_property(package->db, PFF, pth); SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, CADF, pth); + msi_set_property(package->db, CADF, pth); SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, FaF, pth); + msi_set_property(package->db, FaF, pth); SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, FoF, pth); + msi_set_property(package->db, FoF, pth); SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SendTF, pth); + msi_set_property(package->db, SendTF, pth); SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SMF, pth); + msi_set_property(package->db, SMF, pth); SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, StF, pth); + msi_set_property(package->db, StF, pth); SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, TemplF, pth); + msi_set_property(package->db, TemplF, pth); SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, DF, pth); + msi_set_property(package->db, DF, pth); SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PMF, pth); + msi_set_property(package->db, PMF, pth); SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, ATF, pth); + msi_set_property(package->db, ATF, pth); SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, ADF, pth); + msi_set_property(package->db, ADF, pth); SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SF, pth); - MSI_SetPropertyW(package, SF16, pth); + msi_set_property(package->db, SF, pth); + msi_set_property(package->db, SF16, pth); SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, LADF, pth); + msi_set_property(package->db, LADF, pth); SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, MPF, pth); + msi_set_property(package->db, MPF, pth); SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PF, pth); + msi_set_property(package->db, PF, pth); SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, WF, pth); + msi_set_property(package->db, WF, pth); /* Physical Memory is specified in MB. Using total amount. */ msex.dwLength = sizeof(msex); GlobalMemoryStatusEx( &msex ); sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys/1024/1024)); - MSI_SetPropertyW(package, szPhysicalMemory, bufstr); + msi_set_property(package->db, szPhysicalMemory, bufstr); SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); ptr = strchrW(pth,'\\'); if (ptr) *(ptr+1) = 0; - MSI_SetPropertyW(package, WV, pth); + msi_set_property(package->db, WV, pth); GetTempPathW(MAX_PATH,pth); - MSI_SetPropertyW(package, TF, pth); + msi_set_property(package->db, TF, pth); /* in a wine environment the user is always admin and privileged */ - MSI_SetPropertyW(package,szAdminUser,szOne); - MSI_SetPropertyW(package,szPriv,szOne); + msi_set_property(package->db, szAdminUser, szOne); + msi_set_property(package->db, szPriv, szOne); /* set the os things */ OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); @@ -788,54 +793,54 @@ static VOID set_installer_properties(MSIPACKAGE *package) switch (OSVersion.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: - MSI_SetPropertyW(package,v9x,verstr); + msi_set_property(package->db, v9x, verstr); break; case VER_PLATFORM_WIN32_NT: - MSI_SetPropertyW(package,vNT,verstr); + msi_set_property(package->db, vNT, verstr); sprintfW(verstr,szFormat,OSVersion.wProductType); - MSI_SetPropertyW(package,szMsiNTProductType,verstr); + msi_set_property(package->db, szMsiNTProductType, verstr); break; } sprintfW(verstr,szFormat,OSVersion.dwBuildNumber); - MSI_SetPropertyW(package,szWinBuild,verstr); + msi_set_property(package->db, szWinBuild, verstr); /* just fudge this */ - MSI_SetPropertyW(package,szSPL,szSix); + msi_set_property(package->db, szSPL, szSix); sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION); - MSI_SetPropertyW( package, szVersionMsi, bufstr ); + msi_set_property( package->db, szVersionMsi, bufstr ); sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100); - MSI_SetPropertyW( package, szVersionDatabase, bufstr ); + msi_set_property( package->db, szVersionDatabase, bufstr ); GetSystemInfo( &sys_info ); if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); - MSI_SetPropertyW( package, szIntel, bufstr ); + msi_set_property( package->db, szIntel, bufstr ); } /* Screen properties. */ dc = GetDC(0); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, HORZRES ) ); - MSI_SetPropertyW( package, szScreenX, bufstr ); + msi_set_property( package->db, szScreenX, bufstr ); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, VERTRES )); - MSI_SetPropertyW( package, szScreenY, bufstr ); + msi_set_property( package->db, szScreenY, bufstr ); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, BITSPIXEL )); - MSI_SetPropertyW( package, szColorBits, bufstr ); + msi_set_property( package->db, szColorBits, bufstr ); ReleaseDC(0, dc); /* USERNAME and COMPANYNAME */ - username = msi_dup_property( package, szUSERNAME ); - companyname = msi_dup_property( package, szCOMPANYNAME ); + username = msi_dup_property( package->db, szUSERNAME ); + companyname = msi_dup_property( package->db, szCOMPANYNAME ); if ((!username || !companyname) && RegOpenKeyW( HKEY_CURRENT_USER, szUserInfo, &hkey ) == ERROR_SUCCESS) { if (!username && (username = msi_reg_get_val_str( hkey, szDefName ))) - MSI_SetPropertyW( package, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szDefCompany ))) - MSI_SetPropertyW( package, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname ); CloseHandle( hkey ); } if ((!username || !companyname) && @@ -843,10 +848,10 @@ static VOID set_installer_properties(MSIPACKAGE *package) { if (!username && (username = msi_reg_get_val_str( hkey, szRegisteredUser ))) - MSI_SetPropertyW( package, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szRegisteredOrg ))) - MSI_SetPropertyW( package, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname ); CloseHandle( hkey ); } msi_free( username ); @@ -859,7 +864,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) GetSystemTime( &systemtime ); if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - MSI_SetPropertyW( package, szDate, bufstr ); + msi_set_property( package->db, szDate, bufstr ); else ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError()); @@ -867,7 +872,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - MSI_SetPropertyW( package, szTime, bufstr ); + msi_set_property( package->db, szTime, bufstr ); else ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError()); @@ -875,26 +880,24 @@ static VOID set_installer_properties(MSIPACKAGE *package) langid = GetUserDefaultLangID(); sprintfW(bufstr, szIntFormat, langid); - - MSI_SetPropertyW( package, szUserLangID, bufstr ); + msi_set_property( package->db, szUserLangID, bufstr ); langid = GetSystemDefaultLangID(); sprintfW(bufstr, szIntFormat, langid); - - MSI_SetPropertyW( package, szSystemLangID, bufstr ); + msi_set_property( package->db, szSystemLangID, bufstr ); sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode)); - MSI_SetPropertyW( package, szProductState, bufstr ); + msi_set_property( package->db, szProductState, bufstr ); len = 0; if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_MORE_DATA) { WCHAR *username; - if ((username = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + if ((username = msi_alloc( len * sizeof(WCHAR) ))) { if (GetUserNameW( username, &len )) - MSI_SetPropertyW( package, szLogonUser, username ); - HeapFree( GetProcessHeap(), 0, username ); + msi_set_property( package->db, szLogonUser, username ); + msi_free( username ); } } } @@ -952,7 +955,7 @@ static UINT msi_load_summary_properties( MSIPACKAGE *package ) goto done; } - MSI_SetPropertyW( package, szPackageCode, package_code ); + msi_set_property( package->db, szPackageCode, package_code ); msi_free( package_code ); /* load package attributes */ @@ -988,6 +991,7 @@ static MSIPACKAGE *msi_alloc_package( void ) list_init( &package->RunningActions ); list_init( &package->sourcelist_info ); list_init( &package->sourcelist_media ); + list_init( &package->patches ); } return package; @@ -1013,10 +1017,10 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package) static void adjust_allusers_property( MSIPACKAGE *package ) { /* FIXME: this should depend on the user's privileges */ - if (msi_get_property_int( package, szAllUsers, 0 ) == 2) + if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2) { TRACE("resetting ALLUSERS property from 2 to 1\n"); - MSI_SetPropertyW( package, szAllUsers, szOne ); + msi_set_property( package->db, szAllUsers, szOne ); } } @@ -1043,12 +1047,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) create_temp_property_table( package ); msi_clone_properties( package ); - package->ProductCode = msi_dup_property( package, szProductCode ); + package->ProductCode = msi_dup_property( package->db, szProductCode ); + package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); + set_installed_prop( package ); set_installer_properties( package ); sprintfW(uilevel,szpi,gUILevel); - MSI_SetPropertyW(package, szLevel, uilevel); + msi_set_property(package->db, szLevel, uilevel); r = msi_load_summary_properties( package ); if (r != ERROR_SUCCESS) @@ -1107,16 +1113,16 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) GetUrlCacheEntryInfoW( szUrl, NULL, &size ); if ( GetLastError() != ERROR_FILE_NOT_FOUND ) { - cache_entry = HeapAlloc( GetProcessHeap(), 0, size ); + cache_entry = msi_alloc( size ); if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) ) { UINT error = GetLastError(); - HeapFree( GetProcessHeap(), 0, cache_entry ); + msi_free( cache_entry ); return error; } lstrcpyW( filename, cache_entry->lpszLocalFileName ); - HeapFree( GetProcessHeap(), 0, cache_entry ); + msi_free( cache_entry ); return ERROR_SUCCESS; } @@ -1130,12 +1136,12 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) return ERROR_SUCCESS; } -static UINT msi_get_local_package_name( LPWSTR path ) +UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix ) { static const WCHAR szInstaller[] = { '\\','I','n','s','t','a','l','l','e','r','\\',0}; - static const WCHAR fmt[] = { '%','x','.','m','s','i',0}; - DWORD time, len, i; + static const WCHAR fmt[] = {'%','x',0}; + DWORD time, len, i, offset; HANDLE handle; time = GetTickCount(); @@ -1146,7 +1152,8 @@ static UINT msi_get_local_package_name( LPWSTR path ) len = strlenW(path); for (i = 0; i < 0x10000; i++) { - snprintfW( &path[len], MAX_PATH - len, fmt, (time + i)&0xffff ); + offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff ); + memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) ); handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); if (handle != INVALID_HANDLE_VALUE) @@ -1162,11 +1169,64 @@ static UINT msi_get_local_package_name( LPWSTR path ) return ERROR_SUCCESS; } +static UINT apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code ) +{ + UINT r; + DWORD len; + WCHAR patch_file[MAX_PATH]; + MSIDATABASE *patch_db; + MSIPATCHINFO *patch_info; + MSISUMMARYINFO *si; + + len = sizeof(patch_file) / sizeof(WCHAR); + r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context, + INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len ); + if (r != ERROR_SUCCESS) + { + ERR("failed to get patch filename %u\n", r); + return r; + } + + r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db ); + if (r != ERROR_SUCCESS) + { + ERR("failed to open patch database %s\n", debugstr_w( patch_file )); + return r; + } + + si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); + if (!si) + { + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; + } + + r = msi_parse_patch_summary( si, &patch_info ); + msiobj_release( &si->hdr ); + if (r != ERROR_SUCCESS) + { + ERR("failed to parse patch summary %u\n", r); + msiobj_release( &patch_db->hdr ); + return r; + } + + r = msi_apply_patch_db( package, patch_db, patch_info ); + msiobj_release( &patch_db->hdr ); + if (r != ERROR_SUCCESS) + { + ERR("failed to apply patch %u\n", r); + msi_free( patch_info->patchcode ); + msi_free( patch_info->transforms ); + msi_free( patch_info->localfile ); + msi_free( patch_info ); + } + return r; +} + UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) { - static const WCHAR OriginalDatabase[] = - {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; static const WCHAR Database[] = {'D','A','T','A','B','A','S','E',0}; + static const WCHAR dotmsi[] = {'.','m','s','i',0}; MSIDATABASE *db = NULL; MSIPACKAGE *package; MSIHANDLE handle; @@ -1174,6 +1234,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) UINT r; WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH]; LPCWSTR file = szPackage; + DWORD index = 0; TRACE("%s %p\n", debugstr_w(szPackage), pPackage); @@ -1225,7 +1286,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) file = temppath; } - r = msi_get_local_package_name( localfile ); + r = msi_get_local_package_name( localfile, dotmsi ); if (r != ERROR_SUCCESS) return r; @@ -1273,23 +1334,44 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) if( file != szPackage ) track_tempfile( package, file ); - MSI_SetPropertyW( package, Database, db->path ); + msi_set_property( package->db, Database, db->path ); if( UrlIsW( szPackage, URLIS_URL ) ) - MSI_SetPropertyW( package, OriginalDatabase, szPackage ); + msi_set_property( package->db, szOriginalDatabase, szPackage ); else if( szPackage[0] == '#' ) - MSI_SetPropertyW( package, OriginalDatabase, db->path ); + msi_set_property( package->db, szOriginalDatabase, db->path ); else { WCHAR fullpath[MAX_PATH]; GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL ); - MSI_SetPropertyW( package, OriginalDatabase, fullpath ); + msi_set_property( package->db, szOriginalDatabase, fullpath ); } - package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); - *pPackage = package; + msi_set_context( package ); + while (1) + { + WCHAR patch_code[GUID_SIZE]; + r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context, + MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL ); + if (r != ERROR_SUCCESS) + break; + + TRACE("found registered patch %s\n", debugstr_w(patch_code)); + + r = apply_registered_patch( package, patch_code ); + if (r != ERROR_SUCCESS) + { + ERR("registered patch failed to apply %u\n", r); + MSI_FreePackage( (MSIOBJECTHDR *)package ); + return r; + } + + index++; + } + + *pPackage = package; return ERROR_SUCCESS; } @@ -1357,6 +1439,7 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall) { MSIPACKAGE *package; MSIHANDLE handle = 0; + IUnknown *remote_unk; IWineMsiRemotePackage *remote_package; TRACE("(%d)\n",hInstall); @@ -1367,10 +1450,19 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall) handle = alloc_msihandle( &package->db->hdr ); msiobj_release( &package->hdr ); } - else if ((remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ))) + else if ((remote_unk = msi_get_remote(hInstall))) { - IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle); - IWineMsiRemotePackage_Release(remote_package); + if (IUnknown_QueryInterface(remote_unk, &IID_IWineMsiRemotePackage, + (LPVOID *)&remote_package) == S_OK) + { + IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle); + IWineMsiRemotePackage_Release(remote_package); + } + else + { + WARN("remote handle %d is not a package\n", hInstall); + } + IUnknown_Release(remote_unk); } return handle; @@ -1621,7 +1713,7 @@ end: return r; } -static void msi_reset_folders( MSIPACKAGE *package, BOOL source ) +void msi_reset_folders( MSIPACKAGE *package, BOOL source ) { MSIFOLDER *folder; @@ -1640,7 +1732,7 @@ static void msi_reset_folders( MSIPACKAGE *package, BOOL source ) } } -UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) +UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue ) { MSIQUERY *view; MSIRECORD *row = NULL; @@ -1664,7 +1756,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) '`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ', '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0}; - TRACE("%p %s %s\n", package, debugstr_w(szName), debugstr_w(szValue)); + TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue)); if (!szName) return ERROR_INVALID_PARAMETER; @@ -1673,7 +1765,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) if (!szName[0]) return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS; - rc = MSI_GetPropertyW(package, szName, 0, &sz); + rc = msi_get_property(db, szName, 0, &sz); if (!szValue || !*szValue) { sprintfW(Query, Delete, szName); @@ -1694,7 +1786,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) MSI_RecordSetStringW(row, 2, szValue); } - rc = MSI_DatabaseOpenViewW(package->db, Query, &view); + rc = MSI_DatabaseOpenViewW(db, Query, &view); if (rc == ERROR_SUCCESS) { rc = MSI_ViewExecute(view, row); @@ -1705,9 +1797,6 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) if (row) msiobj_release(&row->hdr); - if (rc == ERROR_SUCCESS && (!lstrcmpW(szName, cszSourceDir))) - msi_reset_folders(package, TRUE); - return rc; } @@ -1754,12 +1843,15 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue return ERROR_SUCCESS; } - ret = MSI_SetPropertyW( package, szName, szValue); + ret = msi_set_property( package->db, szName, szValue ); + if (ret == ERROR_SUCCESS && !strcmpW( szName, cszSourceDir )) + msi_reset_folders( package, TRUE ); + msiobj_release( &package->hdr ); return ret; } -static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) +static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name ) { MSIQUERY *view; MSIRECORD *rec, *row = NULL; @@ -1780,7 +1872,7 @@ static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) MSI_RecordSetStringW(rec, 1, name); - r = MSI_DatabaseOpenViewW(package->db, query, &view); + r = MSI_DatabaseOpenViewW(db, query, &view); if (r == ERROR_SUCCESS) { MSI_ViewExecute(view, rec); @@ -1794,13 +1886,13 @@ static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) } /* internal function, not compatible with MsiGetPropertyW */ -UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName, +UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName, LPWSTR szValueBuf, LPDWORD pchValueBuf ) { MSIRECORD *row; UINT rc = ERROR_FUNCTION_FAILED; - row = MSI_GetPropertyRow( package, szName ); + row = msi_get_property_row( db, szName ); if (*pchValueBuf > 0) szValueBuf[0] = 0; @@ -1826,19 +1918,19 @@ UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName, return rc; } -LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop) +LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) { DWORD sz = 0; LPWSTR str; UINT r; - r = MSI_GetPropertyW(package, prop, NULL, &sz); + r = msi_get_property(db, prop, NULL, &sz); if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) return NULL; sz++; str = msi_alloc(sz * sizeof(WCHAR)); - r = MSI_GetPropertyW(package, prop, str, &sz); + r = msi_get_property(db, prop, str, &sz); if (r != ERROR_SUCCESS) { msi_free(str); @@ -1848,9 +1940,9 @@ LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop) return str; } -int msi_get_property_int(MSIPACKAGE *package, LPCWSTR prop, int def) +int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def ) { - LPWSTR str = msi_dup_property(package, prop); + LPWSTR str = msi_dup_property( db, prop ); int val = str ? atoiW(str) : def; msi_free(str); return val; @@ -1929,7 +2021,7 @@ done: return r; } - row = MSI_GetPropertyRow( package, name ); + row = msi_get_property_row( package->db, name ); if (row) val = MSI_RecordGetString( row, 1 ); diff --git a/reactos/dll/win32/msi/registry.c b/reactos/dll/win32/msi/registry.c index 1cbdcc95288..518303f5da0 100644 --- a/reactos/dll/win32/msi/registry.c +++ b/reactos/dll/win32/msi/registry.c @@ -183,6 +183,16 @@ static const WCHAR szUserDataPatch_fmt[] = { 'U','s','e','r','D','a','t','a','\\', '%','s','\\','P','a','t','c','h','e','s','\\','%','s',0}; +static const WCHAR szUserDataProductPatches_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'M','i','c','r','o','s','o','f','t','\\', +'W','i','n','d','o','w','s','\\', +'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', +'I','n','s','t','a','l','l','e','r','\\', +'U','s','e','r','D','a','t','a','\\', +'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\', +'P','a','t','c','h','e','s',0}; + static const WCHAR szInstallProperties_fmt[] = { 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -286,7 +296,7 @@ BOOL squash_guid(LPCWSTR in, LPWSTR out) out[0] = 0; - if (FAILED(CLSIDFromString((LPOLESTR)in, &guid))) + if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid))) return FALSE; for(i=0; i<8; i++) @@ -887,6 +897,69 @@ UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } +UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context) +{ + UINT r; + WCHAR squished_patch[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(patch)); + if (!squash_guid(patch, squished_patch)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_patch)); + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataPatch_fmt, szLocalSid, squished_patch); + else + { + r = get_user_sid(&usersid); + if (r != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", r); + return r; + } + + sprintfW(keypath, szUserDataPatch_fmt, usersid, squished_patch); + LocalFree(usersid); + } + + return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); +} + +UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create) +{ + UINT rc; + WCHAR squished_product[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(product)); + if (!squash_guid(product, squished_product)) + return ERROR_FUNCTION_FAILED; + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataProductPatches_fmt, szLocalSid, squished_product); + else + { + rc = get_user_sid(&usersid); + if (rc != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", rc); + return rc; + } + + sprintfW(keypath, szUserDataProductPatches_fmt, usersid, squished_product); + LocalFree(usersid); + } + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create) { @@ -1156,7 +1229,7 @@ UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, len = ( &p[21] - szDescriptor ); TRACE("length = %d\n", len); - *pUsed = len; + if (pUsed) *pUsed = len; return ERROR_SUCCESS; } @@ -1236,17 +1309,13 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) if (index && index - last_index != 1) return ERROR_INVALID_PARAMETER; + key = 0; r = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesProd, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &machine_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (machine_count && index <= machine_count) { @@ -1261,26 +1330,23 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) } RegCloseKey(key); + key = 0; r = get_user_sid(&usersid); if (r != ERROR_SUCCESS || !usersid) { ERR("Failed to retrieve user SID: %d\n", r); + last_index = 0; return r; } sprintfW(keypath, szInstaller_LocalManaged_fmt, usersid); LocalFree(usersid); r = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &managed_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (managed_count && index <= machine_count + managed_count) { @@ -1295,17 +1361,13 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) } RegCloseKey(key); + key = 0; r = RegCreateKeyW(HKEY_CURRENT_USER, szUserProduct, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &unmanaged_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (unmanaged_count && index <= machine_count + managed_count + unmanaged_count) { @@ -1318,8 +1380,9 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) return ERROR_SUCCESS; } } +failed: RegCloseKey(key); - + last_index = 0; return ERROR_NO_MORE_ITEMS; } @@ -2051,7 +2114,7 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, DWORD idx = 0; UINT r; - static int last_index = 0; + static DWORD last_index; TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n", debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext, dwFilter, @@ -2087,6 +2150,8 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, if (r == ERROR_SUCCESS) last_index = dwIndex; + else + last_index = 0; return r; } diff --git a/reactos/dll/win32/msi/script.c b/reactos/dll/win32/msi/script.c index 8dfa6d2ac05..4f223daa8b0 100644 --- a/reactos/dll/win32/msi/script.c +++ b/reactos/dll/win32/msi/script.c @@ -62,7 +62,7 @@ static HRESULT create_ActiveScriptSite(IUnknown *pUnkOuter, LPVOID *ppObj) if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MsiActiveScriptSite)); + object = msi_alloc_zero( sizeof(MsiActiveScriptSite) ); object->lpVtbl.lpVtbl = &ASS_Vtbl; object->ref = 1; @@ -236,7 +236,7 @@ static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface) TRACE("(%p/%p)\n", iface, This); if (!ref) - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); return ref; } diff --git a/reactos/dll/win32/msi/storages.c b/reactos/dll/win32/msi/storages.c index 6a8134b5627..3e8887437a7 100644 --- a/reactos/dll/win32/msi/storages.c +++ b/reactos/dll/win32/msi/storages.c @@ -43,7 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct tabSTORAGE { UINT str_index; - LPWSTR name; IStorage *storage; } STORAGE; @@ -70,7 +69,7 @@ static BOOL storages_set_table_size(MSISTORAGESVIEW *sv, UINT size) return TRUE; } -static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPWSTR name, IStorage *stg) +static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPCWSTR name, IStorage *stg) { STORAGE *storage; @@ -78,14 +77,7 @@ static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPWSTR name, IStorage *stg) if (!storage) return NULL; - storage->name = strdupW(name); - if (!storage->name) - { - msi_free(storage); - return NULL; - } - - storage->str_index = msi_addstringW(sv->db->strings, 0, storage->name, -1, 1, StringNonPersistent); + storage->str_index = msi_addstringW(sv->db->strings, name, -1, 1, StringNonPersistent); storage->storage = stg; if (storage->storage) @@ -436,8 +428,6 @@ static UINT STORAGES_delete(struct tagMSIVIEW *view) { if (sv->storages[i]->storage) IStorage_Release(sv->storages[i]->storage); - - msi_free(sv->storages[i]->name); msi_free(sv->storages[i]); } diff --git a/reactos/dll/win32/msi/streams.c b/reactos/dll/win32/msi/streams.c index 66bda767a00..59e845df82d 100644 --- a/reactos/dll/win32/msi/streams.c +++ b/reactos/dll/win32/msi/streams.c @@ -68,7 +68,7 @@ static BOOL streams_set_table_size(MSISTREAMSVIEW *sv, UINT size) return TRUE; } -static STREAM *create_stream(MSISTREAMSVIEW *sv, LPWSTR name, BOOL encoded, IStream *stm) +static STREAM *create_stream(MSISTREAMSVIEW *sv, LPCWSTR name, BOOL encoded, IStream *stm) { STREAM *stream; WCHAR decoded[MAX_STREAM_NAME_LEN]; @@ -84,7 +84,7 @@ static STREAM *create_stream(MSISTREAMSVIEW *sv, LPWSTR name, BOOL encoded, IStr name = decoded; } - stream->str_index = msi_addstringW(sv->db->strings, 0, name, -1, 1, StringNonPersistent); + stream->str_index = msi_addstringW(sv->db->strings, name, -1, 1, StringNonPersistent); stream->stream = stm; return stream; } @@ -183,7 +183,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U } encname = encode_streamname(FALSE, name); - IStorage_DestroyElement(sv->db->storage, encname); + db_destroy_stream(sv->db, encname); r = write_stream_data(sv->db->storage, name, data, count, FALSE); if (r != ERROR_SUCCESS) diff --git a/reactos/dll/win32/msi/string.c b/reactos/dll/win32/msi/string.c index 3bdc4360bd0..21b1db2a405 100644 --- a/reactos/dll/win32/msi/string.c +++ b/reactos/dll/win32/msi/string.c @@ -44,8 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct _msistring { - UINT persistent_refcount; - UINT nonpersistent_refcount; + USHORT persistent_refcount; + USHORT nonpersistent_refcount; LPWSTR str; } msistring; @@ -188,7 +188,7 @@ static void insert_string_sorted( string_table *st, UINT string_id ) st->sortcount++; } -static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, enum StringPersistence persistence ) +static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount, enum StringPersistence persistence ) { if (persistence == StringPersistent) { @@ -237,7 +237,7 @@ static UINT msi_string2idA( const string_table *st, LPCSTR buffer, UINT *id ) return r; } -static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount, enum StringPersistence persistence ) +static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) { LPWSTR str; int sz; @@ -288,42 +288,28 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U return n; } -int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ) +int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) { + UINT n; LPWSTR str; - /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */ - if( !data ) return 0; if( !data[0] ) return 0; - if( n > 0 ) + + if( msi_string2idW( st, data, &n ) == ERROR_SUCCESS ) { - if( st->strings[n].persistent_refcount || - st->strings[n].nonpersistent_refcount ) - return -1; - } - else - { - if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) ) - { - if (persistence == StringPersistent) - st->strings[n].persistent_refcount += refcount; - else - st->strings[n].nonpersistent_refcount += refcount; - return n; - } - n = st_find_free_entry( st ); - if( n == -1 ) - return -1; + if (persistence == StringPersistent) + st->strings[n].persistent_refcount += refcount; + else + st->strings[n].nonpersistent_refcount += refcount; + return n; } - if( n < 1 ) - { - ERR("invalid index adding %s (%d)\n", debugstr_w( data ), n ); + n = st_find_free_entry( st ); + if( n == -1 ) return -1; - } /* allocate a new string */ if(len<0) diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 6737ac59168..3b117ae53c4 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -1383,7 +1383,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI if ( r != ERROR_SUCCESS ) { LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); - val = msi_addstringW( tv->db->strings, 0, sval, -1, 1, + val = msi_addstringW( tv->db->strings, sval, -1, 1, persistent ? StringPersistent : StringNonPersistent ); } diff --git a/reactos/dll/win32/msi/upgrade.c b/reactos/dll/win32/msi/upgrade.c index a440070a4d8..b131d666fe2 100644 --- a/reactos/dll/win32/msi/upgrade.c +++ b/reactos/dll/win32/msi/upgrade.c @@ -61,8 +61,9 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, LPWSTR prop; LPWSTR newprop; DWORD len; + UINT r; - prop = msi_dup_property(package, action_property ); + prop = msi_dup_property(package->db, action_property ); if (prop) len = strlenW(prop); else @@ -87,9 +88,13 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, newprop[0] = 0; strcatW(newprop,productid); - MSI_SetPropertyW(package, action_property, newprop); - TRACE("Found Related Product... %s now %s\n",debugstr_w(action_property), - debugstr_w(newprop)); + r = msi_set_property( package->db, action_property, newprop ); + if (r == ERROR_SUCCESS && !strcmpW( action_property, cszSourceDir )) + msi_reset_folders( package, TRUE ); + + TRACE("Found Related Product... %s now %s\n", + debugstr_w(action_property), debugstr_w(newprop)); + msi_free( prop ); msi_free( newprop ); } @@ -146,26 +151,30 @@ static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param) (LPBYTE)&check, &sz); /* check min */ ver = MSI_RecordGetString(rec,2); - comp_ver = msi_version_str_to_dword(ver); - r = check - comp_ver; - if (r < 0 || (r == 0 && !(attributes & - msidbUpgradeAttributesVersionMinInclusive))) + if (ver) { - RegCloseKey(hukey); - index ++; - continue; + comp_ver = msi_version_str_to_dword(ver); + r = check - comp_ver; + if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive))) + { + RegCloseKey(hukey); + index ++; + continue; + } } /* check max */ ver = MSI_RecordGetString(rec,3); - comp_ver = msi_version_str_to_dword(ver); - r = check - comp_ver; - if (r > 0 || (r == 0 && !(attributes & - msidbUpgradeAttributesVersionMaxInclusive))) + if (ver) { - RegCloseKey(hukey); - index ++; - continue; + comp_ver = msi_version_str_to_dword(ver); + r = check - comp_ver; + if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive))) + { + RegCloseKey(hukey); + index ++; + continue; + } } /* check language*/ @@ -203,19 +212,19 @@ UINT ACTION_FindRelatedProducts(MSIPACKAGE *package) UINT rc = ERROR_SUCCESS; MSIQUERY *view; - if (msi_get_property_int(package, szInstalled, 0)) + if (msi_get_property_int(package->db, szInstalled, 0)) { TRACE("Skipping FindRelatedProducts action: product already installed\n"); return ERROR_SUCCESS; } - if (check_unique_action(package,szFindRelatedProducts)) + if (check_unique_action(package, szFindRelatedProducts)) { - TRACE("Skipping FindRelatedProducts action: already done on client side\n"); + TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n"); return ERROR_SUCCESS; } else - register_unique_action(package,szFindRelatedProducts); + register_unique_action(package, szFindRelatedProducts); rc = MSI_DatabaseOpenViewW(package->db, Query, &view); if (rc != ERROR_SUCCESS) From bc732ca2d3b511c4253e559b955217cb40011b1c Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:02:25 +0000 Subject: [PATCH 074/292] [MSXML3] sync to wine 1.2 RC2 svn path=/trunk/; revision=47398 --- reactos/dll/win32/msxml3/domdoc.c | 3 +- reactos/dll/win32/msxml3/regsvr.c | 67 ++- reactos/include/psdk/msxml2.idl | 657 ++++++++++++++++++++++++++++++ reactos/include/psdk/msxml2did.h | 82 ++++ 4 files changed, 805 insertions(+), 4 deletions(-) diff --git a/reactos/dll/win32/msxml3/domdoc.c b/reactos/dll/win32/msxml3/domdoc.c index aae8a343500..d72d20be8dc 100644 --- a/reactos/dll/win32/msxml3/domdoc.c +++ b/reactos/dll/win32/msxml3/domdoc.c @@ -2177,8 +2177,7 @@ xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk ) return S_OK; } - if ( punk ) - IUnknown_AddRef( punk ); + IUnknown_AddRef( punk ); if(This->site) IUnknown_Release( This->site ); diff --git a/reactos/dll/win32/msxml3/regsvr.c b/reactos/dll/win32/msxml3/regsvr.c index d9b47dde89b..415e5af613a 100644 --- a/reactos/dll/win32/msxml3/regsvr.c +++ b/reactos/dll/win32/msxml3/regsvr.c @@ -515,8 +515,23 @@ static struct regsvr_coclass const coclass_list[] = { "Both", "Microsoft.FreeThreadedXMLDOM.1.0", "1.0" + }, + { &CLSID_FreeThreadedDOMDocument26, + "Free Threaded XML DOM Document 2.6", + NULL, + "msxml3.dll", + "Both", + "Microsoft.FreeThreadedXMLDOM.1.0", + "1.0" + }, + { &CLSID_FreeThreadedDOMDocument30, + "Free Threaded XML DOM Document 3.0", + NULL, + "msxml3.dll", + "Both", + "Microsoft.FreeThreadedDOMDocument.1.0", + "1.0" }, - { &CLSID_XMLHTTPRequest, "XML HTTP Request", NULL, @@ -548,6 +563,14 @@ static struct regsvr_coclass const coclass_list[] = { "Msxml2.XMLSchemaCache", "3.0" }, + { &CLSID_XMLSchemaCache26, + "XML Schema Cache 2.6", + NULL, + "msxml3.dll", + "Both", + "Msxml2.XMLSchemaCache", + "2.6" + }, { &CLSID_XMLSchemaCache30, "XML Schema Cache 3.0", NULL, @@ -588,6 +611,22 @@ static struct regsvr_coclass const coclass_list[] = { "Msxml2.MXXMLWriter", "3.0" }, + { &CLSID_SAXAttributes, + "SAX Attribute", + NULL, + "msxml3.dll", + "Both", + "Msxml2.SAXAttributes", + NULL + }, + { &CLSID_SAXAttributes30, + "SAX Attribute 3.0", + NULL, + "msxml3.dll", + "Both", + "Msxml2.SAXAttributes", + "3.0" + }, { NULL } /* list terminator */ }; @@ -642,6 +681,16 @@ static struct progid const progid_list[] = { &CLSID_DOMFreeThreadedDocument, "Microsoft.FreeThreadedXMLDOM.1.0" }, + { "MSXML.FreeThreadedDOMDocument26", + "Free threaded XML DOM Document 2.6", + &CLSID_FreeThreadedDOMDocument26, + NULL + }, + { "MSXML.FreeThreadedDOMDocument30", + "Free threaded XML DOM Document 3.0", + &CLSID_FreeThreadedDOMDocument30, + NULL + }, { "Microsoft.XMLHTTP", "XML HTTP Request", &CLSID_XMLHTTPRequest, @@ -672,6 +721,11 @@ static struct progid const progid_list[] = { &CLSID_XMLSchemaCache, "Msxml2.XMLSchemaCache.3.0" }, + { "Msxml2.XMLSchemaCache.2.6", + "XML Schema Cache 2.6", + &CLSID_XMLSchemaCache26, + "Msxml2.XMLSchemaCache.2.6" + }, { "Msxml2.XMLSchemaCache.3.0", "XML Schema Cache 3.0", &CLSID_XMLSchemaCache30, @@ -697,7 +751,16 @@ static struct progid const progid_list[] = { &CLSID_MXXMLWriter30, NULL }, - + { "Msxml2.SAXAttributes", + "SAX Attribute", + &CLSID_SAXAttributes, + NULL + }, + { "Msxml2.SAXAttributes.3.0", + "SAX Attribute 3.0", + &CLSID_SAXAttributes30, + NULL + }, { NULL } /* list terminator */ }; diff --git a/reactos/include/psdk/msxml2.idl b/reactos/include/psdk/msxml2.idl index 89914004955..f2841a5f3f2 100644 --- a/reactos/include/psdk/msxml2.idl +++ b/reactos/include/psdk/msxml2.idl @@ -85,6 +85,22 @@ interface IMXAttributes; interface IMXReaderControl; interface IMXWriter; +interface IXMLDOMSchemaCollection2; +interface ISchemaStringCollection; +interface ISchemaItemCollection; +interface ISchemaItem; +interface ISchema; +interface ISchemaParticle; +interface ISchemaAttribute; +interface ISchemaElement; +interface ISchemaType; +interface ISchemaComplexType; +interface ISchemaAttributeGroup; +interface ISchemaModelGroup; +interface ISchemaAny; +interface ISchemaIdentityConstraint; +interface ISchemaNotation; + cpp_quote("#define DOMDocument DOMDocument2") cpp_quote("#define CLSID_DOMDocument CLSID_DOMDocument2") @@ -108,6 +124,134 @@ typedef enum tagDOMNodeType } DOMNodeType; cpp_quote("#endif /* __WIDL_XMLDOM_H */") +typedef enum _SOMITEMTYPE +{ + SOMITEM_SCHEMA = 0x1000, + SOMITEM_ATTRIBUTE = 0x1001, + SOMITEM_ATTRIBUTEGROUP = 0x1002, + SOMITEM_NOTATION = 0x1003, + SOMITEM_IDENTITYCONSTRAINT = 0x1100, + SOMITEM_KEY = 0x1101, + SOMITEM_KEYREF = 0x1102, + SOMITEM_UNIQUE = 0x1103, + SOMITEM_ANYTYPE = 0x2000, + SOMITEM_DATATYPE = 0x2100, + SOMITEM_DATATYPE_ANYTYPE = 0x2101, + SOMITEM_DATATYPE_ANYURI = 0x2102, + SOMITEM_DATATYPE_BASE64BINARY = 0x2103, + SOMITEM_DATATYPE_BOOLEAN = 0x2104, + SOMITEM_DATATYPE_BYTE = 0x2105, + SOMITEM_DATATYPE_DATE = 0x2106, + SOMITEM_DATATYPE_DATETIME = 0x2107, + SOMITEM_DATATYPE_DAY = 0x2108, + SOMITEM_DATATYPE_DECIMAL = 0x2109, + SOMITEM_DATATYPE_DOUBLE = 0x210A, + SOMITEM_DATATYPE_DURATION = 0x210B, + SOMITEM_DATATYPE_ENTITIES = 0x210C, + SOMITEM_DATATYPE_ENTITY = 0x210D, + SOMITEM_DATATYPE_FLOAT = 0x210E, + SOMITEM_DATATYPE_HEXBINARY = 0x210F, + SOMITEM_DATATYPE_ID = 0x2110, + SOMITEM_DATATYPE_IDREF = 0x2111, + SOMITEM_DATATYPE_IDREFS = 0x2112, + SOMITEM_DATATYPE_INT = 0x2113, + SOMITEM_DATATYPE_INTEGER = 0x2114, + SOMITEM_DATATYPE_LANGUAGE = 0x2115, + SOMITEM_DATATYPE_LONG = 0x2116, + SOMITEM_DATATYPE_MONTH = 0x2117, + SOMITEM_DATATYPE_MONTHDAY = 0x2118, + SOMITEM_DATATYPE_NAME = 0x2119, + SOMITEM_DATATYPE_NCNAME = 0x211A, + SOMITEM_DATATYPE_NEGATIVEINTEGER = 0x211B, + SOMITEM_DATATYPE_NMTOKEN = 0x211C, + SOMITEM_DATATYPE_NMTOKENS = 0x211D, + SOMITEM_DATATYPE_NONNEGATIVEINTEGER = 0x211E, + SOMITEM_DATATYPE_NONPOSITIVEINTEGER = 0x211F, + SOMITEM_DATATYPE_NORMALIZEDSTRING = 0x2120, + SOMITEM_DATATYPE_NOTATION = 0x2121, + SOMITEM_DATATYPE_POSITIVEINTEGER = 0x2122, + SOMITEM_DATATYPE_QNAME = 0x2123, + SOMITEM_DATATYPE_SHORT = 0x2124, + SOMITEM_DATATYPE_STRING = 0x2125, + SOMITEM_DATATYPE_TIME = 0x2126, + SOMITEM_DATATYPE_TOKEN = 0x2127, + SOMITEM_DATATYPE_UNSIGNEDBYTE = 0x2128, + SOMITEM_DATATYPE_UNSIGNEDINT = 0x2129, + SOMITEM_DATATYPE_UNSIGNEDLONG = 0x212A, + SOMITEM_DATATYPE_UNSIGNEDSHORT = 0x212B, + SOMITEM_DATATYPE_YEAR = 0x212C, + SOMITEM_DATATYPE_YEARMONTH = 0x212D, + SOMITEM_DATATYPE_ANYSIMPLETYPE = 0x21FF, + SOMITEM_SIMPLETYPE = 0x2200, + SOMITEM_COMPLEXTYPE = 0x2400, + SOMITEM_PARTICLE = 0x4000, + SOMITEM_ANY = 0x4001, + SOMITEM_ANYATTRIBUTE = 0x4002, + SOMITEM_ELEMENT = 0x4003, + SOMITEM_GROUP = 0x4100, + SOMITEM_ALL = 0x4101, + SOMITEM_CHOICE = 0x4102, + SOMITEM_SEQUENCE = 0x4103, + SOMITEM_EMPTYPARTICLE = 0x4104, + SOMITEM_NULL = 0x0800, + SOMITEM_NULL_TYPE = 0x2800, + SOMITEM_NULL_ANY = 0x4801, + SOMITEM_NULL_ANYATTRIBUTE = 0x4802, + SOMITEM_NULL_ELEMENT = 0x4803, +} SOMITEMTYPE; + +typedef enum _SCHEMAUSE +{ + SCHEMAUSE_OPTIONAL, + SCHEMAUSE_PROHIBITED, + SCHEMAUSE_REQUIRED, +} SCHEMAUSE; + +typedef enum _SCHEMADERIVATIONMETHOD +{ + SCHEMADERIVATIONMETHOD_EMPTY = 0x0000, + SCHEMADERIVATIONMETHOD_SUBSTITUTION = 0x0001, + SCHEMADERIVATIONMETHOD_EXTENSION = 0x0002, + SCHEMADERIVATIONMETHOD_RESTRICTION = 0x0004, + SCHEMADERIVATIONMETHOD_LIST = 0x0008, + SCHEMADERIVATIONMETHOD_UNION = 0x0010, + SCHEMADERIVATIONMETHOD_ALL = 0x00FF, + SCHEMADERIVATIONMETHOD_NONE = 0x0100, +} SCHEMADERIVATIONMETHOD; + +typedef enum _SCHEMACONTENTTYPE +{ + SCHEMACONTENTTYPE_EMPTY, + SCHEMACONTENTTYPE_TEXTONLY, + SCHEMACONTENTTYPE_ELEMENTONLY, + SCHEMACONTENTTYPE_MIXED, +} SCHEMACONTENTTYPE; + +typedef enum _SCHEMAPROCESSCONTENTS +{ + SCHEMAPROCESSCONTENTS_NONE, + SCHEMAPROCESSCONTENTS_SKIP, + SCHEMAPROCESSCONTENTS_LAX, + SCHEMAPROCESSCONTENTS_STRICT, +} SCHEMAPROCESSCONTENTS; + +typedef enum _SCHEMAWHITESPACE +{ + SCHEMAWHITESPACE_NONE = -1, + SCHEMAWHITESPACE_PRESERVE = 0, + SCHEMAWHITESPACE_REPLACE = 1, + SCHEMAWHITESPACE_COLLAPSE = 2, +} SCHEMAWHITESPACE; + + +typedef enum _SCHEMATYPEVARIETY +{ + SCHEMATYPEVARIETY_NONE = -1, + SCHEMATYPEVARIETY_ATOMIC = 0, + SCHEMATYPEVARIETY_LIST = 1, + SCHEMATYPEVARIETY_UNION = 2, +} SCHEMATYPEVARIETY; + [ local, object, @@ -417,6 +561,35 @@ interface IXMLDOMSchemaCollection : IDispatch HRESULT _newEnum([retval, out] IUnknown **ppUnk); } +[ + local, + object, + uuid(50ea08b0-dd1b-4664-9a50-c2f40f4bd79a), +] +interface IXMLDOMSchemaCollection2 : IXMLDOMSchemaCollection +{ + [id(DISPID_SOM_VALIDATE)] + HRESULT validate(); + + [propput, id(DISPID_SOM_VALIDATEONLOAD)] + HRESULT validateOnLoad( + [in] VARIANT_BOOL validateOnLoad); + + [propget, id(DISPID_SOM_VALIDATEONLOAD)] + HRESULT validateOnLoad( + [out,retval] VARIANT_BOOL* validateOnLoad); + + [id(DISPID_SOM_GETSCHEMA)] + HRESULT getSchema( + [in] BSTR namespaceURI, + [out,retval] ISchema** schema); + + [id(DISPID_SOM_GETDECLARATION)] + HRESULT getDeclaration( + [in] IXMLDOMNode* node, + [out,retval]ISchemaItem** item); +}; + [ local, object, @@ -1106,6 +1279,15 @@ coclass FreeThreadedDOMDocument30 [default, source] dispinterface XMLDOMDocumentEvents; } +[ + uuid(88d969c1-f192-11d4-a65f-0040963251e5), +] +coclass FreeThreadedDOMDocument40 +{ + [default] interface IXMLDOMDocument2; + [default, source] dispinterface XMLDOMDocumentEvents; +}; + [ uuid(373984c9-b845-449b-91e7-45ac83036ade) ] @@ -1130,6 +1312,14 @@ coclass XMLSchemaCache30 [default] interface IXMLDOMSchemaCollection; } +[ + uuid(88d969c2-f192-11d4-a65f-0040963251e5) +] +coclass XMLSchemaCache40 +{ + [default] interface IXMLDOMSchemaCollection2; +}; + [ uuid(2933BF94-7B36-11d2-B20E-00C04F983E60) ] @@ -1959,6 +2149,443 @@ interface IMXWriter : IDispatch HRESULT flush(); }; +[ + local, + object, + uuid(50ea08b1-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaStringCollection : IDispatch +{ + [id(DISPID_VALUE), propget] + HRESULT item( + [in] long index, + [out,retval] BSTR* bstr); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval] long* length); + + [id(DISPID_NEWENUM), hidden, restricted, propget] + HRESULT _newEnum( + [out,retval] IUnknown** ppunk); +}; + +[ + local, + object, + uuid(50ea08b2-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaItemCollection : IDispatch +{ + [id(DISPID_VALUE), propget] + HRESULT item( + [in] long index, + [out,retval]ISchemaItem** item); + + [id(DISPID_SOM_ITEMBYNAME)] + HRESULT itemByName( + [in] BSTR name, + [out,retval] ISchemaItem** item); + + [id(DISPID_SOM_ITEMBYQNAME)] + HRESULT itemByQName( + [in] BSTR name, + [in] BSTR namespaceURI, + [out,retval] ISchemaItem** item); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval]long* length); + + [id(DISPID_NEWENUM), hidden, restricted, propget] + HRESULT _newEnum( + [out,retval]IUnknown** ppunk); +}; + +[ + local, + object, + uuid(50ea08b3-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaItem : IDispatch +{ + [id(DISPID_SOM_NAME), propget] + HRESULT name( + [out,retval] BSTR* name); + + [id(DISPID_SOM_NAMESPACEURI), propget] + HRESULT namespaceURI( + [out,retval] BSTR* namespaceURI); + + [id(DISPID_SOM_SCHEMA), propget] + HRESULT schema( + [out,retval] ISchema** schema); + + [id(DISPID_SOM_ID), propget] + HRESULT id( + [out,retval] BSTR* id); + + [id(DISPID_SOM_ITEMTYPE), propget] + HRESULT itemType( + [out,retval] SOMITEMTYPE* itemType); + + [id(DISPID_SOM_UNHANDLEDATTRS), propget] + HRESULT unhandledAttributes( + [out,retval] IVBSAXAttributes** attributes); + + [id(DISPID_SOM_WRITEANNOTATION)] + HRESULT writeAnnotation( + [in] IUnknown* annotationSink, + [out,retval] VARIANT_BOOL* isWritten); +}; + +[ + local, + object, + uuid(50ea08b4-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchema : ISchemaItem +{ + [id(DISPID_SOM_TARGETNAMESPACE), propget] + HRESULT targetNamespace( + [out,retval] BSTR* targetNamespace); + + [id(DISPID_SOM_VERSION), propget] + HRESULT version( + [out,retval] BSTR* version); + + [id(DISPID_SOM_TYPES), propget] + HRESULT types( + [out,retval] ISchemaItemCollection** types); + + [id(DISPID_SOM_ELEMENTS), propget] + HRESULT elements( + [out,retval] ISchemaItemCollection** elements); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); + + [id(DISPID_SOM_ATTRIBUTEGROUPS), propget] + HRESULT attributeGroups( + [out,retval] ISchemaItemCollection** attributeGroups); + + [id(DISPID_SOM_MODELGROUPS), propget] + HRESULT modelGroups( + [out,retval] ISchemaItemCollection** modelGroups); + + [id(DISPID_SOM_NOTATIONS), propget] + HRESULT notations( + [out,retval] ISchemaItemCollection** notations); + + [id(DISPID_SOM_SCHEMALOCATIONS), propget] + HRESULT schemaLocations( + [out,retval] ISchemaStringCollection** schemaLocations); +}; + +[ + local, + object, + uuid(50ea08b5-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaParticle : ISchemaItem +{ + [id(DISPID_SOM_MINOCCURS), propget] + HRESULT minOccurs( + [out,retval] VARIANT* minOccurs); + + [id(DISPID_SOM_MAXOCCURS), propget] + HRESULT maxOccurs( + [out,retval] VARIANT* maxOccurs); +}; + +[ + object, + uuid(50ea08b6-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaAttribute : ISchemaItem +{ + [id(DISPID_SOM_TYPE), propget] + HRESULT type( + [out,retval] ISchemaType** type); + + [id(DISPID_SOM_SCOPE), propget] + HRESULT scope( + [out,retval] ISchemaComplexType** scope); + + [id(DISPID_SOM_DEFAULTVALUE), propget] + HRESULT defaultValue( + [out,retval]BSTR* defaultValue); + + [id(DISPID_SOM_FIXEDVALUE), propget] + HRESULT fixedValue( + [out,retval] BSTR* fixedValue); + + [id(DISPID_SOM_USE), propget] + HRESULT use( + [out,retval] SCHEMAUSE* use); + + [id(DISPID_SOM_ISREFERENCE), propget] + HRESULT isReference( + [out,retval] VARIANT_BOOL* reference); +}; + +[ + local, + object, + uuid(50ea08b7-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaElement : ISchemaParticle +{ + [id(DISPID_SOM_TYPE), propget] + HRESULT type( + [out,retval] ISchemaType** type); + + [id(DISPID_SOM_SCOPE), propget] + HRESULT scope( + [out,retval] ISchemaComplexType** scope); + + [id(DISPID_SOM_DEFAULTVALUE), propget] + HRESULT defaultValue( + [out,retval] BSTR* defaultValue); + + [id(DISPID_SOM_FIXEDVALUE), propget] + HRESULT fixedValue( + [out,retval] BSTR* fixedValue); + + [id(DISPID_SOM_ISNILLABLE), propget] + HRESULT isNillable( + [out,retval] VARIANT_BOOL* nillable); + + [id(DISPID_SOM_IDCONSTRAINTS), propget] + HRESULT identityConstraints( + [out,retval] ISchemaItemCollection** constraints); + + [id(DISPID_SOM_SUBSTITUTIONGROUP), propget] + HRESULT substitutionGroup( + [out,retval] ISchemaElement** element); + + [id(DISPID_SOM_EXCLUSIONS), propget] + HRESULT substitutionGroupExclusions( + [out,retval] SCHEMADERIVATIONMETHOD* exclusions); + + [id(DISPID_SOM_DISALLOWED), propget] + HRESULT disallowedSubstitutions( + [out,retval] SCHEMADERIVATIONMETHOD* disallowed); + + [id(DISPID_SOM_ISABSTRACT), propget] + HRESULT isAbstract( + [out,retval] VARIANT_BOOL* abstract); + + [id(DISPID_SOM_ISREFERENCE), propget] + HRESULT isReference( + [out,retval] VARIANT_BOOL* reference); +}; + +[ + local, + object, + uuid(50ea08b8-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaType : ISchemaItem +{ + [id(DISPID_SOM_BASETYPES), propget] + HRESULT baseTypes( + [out,retval] ISchemaItemCollection** baseTypes); + + [id(DISPID_SOM_FINAL), propget] + HRESULT final( + [out,retval] SCHEMADERIVATIONMETHOD* final); + + [id(DISPID_SOM_VARIETY), propget] + HRESULT variety( + [out,retval] SCHEMATYPEVARIETY* variety); + + [id(DISPID_SOM_DERIVEDBY), propget] + HRESULT derivedBy( + [out,retval] SCHEMADERIVATIONMETHOD* derivedBy); + + [id(DISPID_SOM_ISVALID)] + HRESULT isValid( + [in] BSTR data, + [out,retval] VARIANT_BOOL* valid); + + [id(DISPID_SOM_MINEXCLUSIVE), propget] + HRESULT minExclusive( + [out,retval]BSTR* minExclusive); + + [id(DISPID_SOM_MININCLUSIVE), propget] + HRESULT minInclusive( + [out,retval] BSTR* minInclusive); + + [id(DISPID_SOM_MAXEXCLUSIVE), propget] + HRESULT maxExclusive( + [out,retval] BSTR* maxExclusive); + + [id(DISPID_SOM_MAXINCLUSIVE), propget] + HRESULT maxInclusive( + [out,retval] BSTR* maxInclusive); + + [id(DISPID_SOM_TOTALDIGITS), propget] + HRESULT totalDigits( + [out,retval] VARIANT* totalDigits); + + [id(DISPID_SOM_FRACTIONDIGITS), propget] + HRESULT fractionDigits( + [out,retval] VARIANT* fractionDigits); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval] VARIANT* length); + + [id(DISPID_SOM_MINLENGTH), propget] + HRESULT minLength( + [out,retval]VARIANT* minLength); + + [id(DISPID_SOM_MAXLENGTH), propget] + HRESULT maxLength( + [out,retval]VARIANT* maxLength); + + [id(DISPID_SOM_ENUMERATION), propget] + HRESULT enumeration( + [out,retval] ISchemaStringCollection** enumeration); + + [id(DISPID_SOM_WHITESPACE), propget] + HRESULT whitespace( + [out,retval]SCHEMAWHITESPACE* whitespace); + + [id(DISPID_SOM_PATTERNS), propget] + HRESULT patterns( + [out,retval] ISchemaStringCollection** patterns); +}; + +[ + local, + object, + uuid(50ea08b9-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaComplexType : ISchemaType +{ + [id(DISPID_SOM_ISABSTRACT), propget] + HRESULT isAbstract( + [out,retval] VARIANT_BOOL* abstract); + + [id(DISPID_SOM_ANYATTRIBUTE), propget] + HRESULT anyAttribute( + [out,retval] ISchemaAny** anyAttribute); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); + + [id(DISPID_SOM_CONTENTTYPE), propget] + HRESULT contentType( + [out,retval] SCHEMACONTENTTYPE* contentType); + + [id(DISPID_SOM_CONTENTMODEL), propget] + HRESULT contentModel( + [out,retval] ISchemaModelGroup** contentModel); + + [id(DISPID_SOM_PROHIBITED), propget] + HRESULT prohibitedSubstitutions( + [out,retval] SCHEMADERIVATIONMETHOD* prohibited); +}; + +[ + local, + object, + uuid(50ea08ba-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaAttributeGroup : ISchemaItem +{ + [id(DISPID_SOM_ANYATTRIBUTE), propget] + HRESULT anyAttribute( + [out,retval] ISchemaAny** anyAttribute); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); +}; + +[ + local, + object, + uuid(50ea08bb-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaModelGroup : ISchemaParticle +{ + [id(DISPID_SOM_PARTICLES), propget] + HRESULT particles( + [out,retval] ISchemaItemCollection** particles); +}; + +[ + local, + object, + uuid(50ea08bc-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaAny : ISchemaParticle +{ + [id(DISPID_SOM_NAMESPACES), propget] + HRESULT namespaces( + [out,retval] ISchemaStringCollection** namespaces); + + [id(DISPID_SOM_PROCESSCONTENTS), propget] + HRESULT processContents( + [out,retval] SCHEMAPROCESSCONTENTS* processContents); +}; + +[ + local, + object, + uuid(50ea08bd-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaIdentityConstraint : ISchemaItem +{ + [id(DISPID_SOM_SELECTOR), propget] + HRESULT selector( + [out,retval] BSTR* selector); + + [id(DISPID_SOM_FIELDS), propget] + HRESULT fields( + [out,retval] ISchemaStringCollection** fields); + + [id(DISPID_SOM_REFERENCEDKEY), propget] + HRESULT referencedKey( + [out,retval] ISchemaIdentityConstraint** key); +}; + +[ + local, + object, + uuid(50ea08be-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaNotation : ISchemaItem +{ + [id(DISPID_SOM_SYSTEMIDENTIFIER), propget] + HRESULT systemIdentifier( + [out,retval] BSTR* uri); + + [id(DISPID_SOM_PUBLICIDENTIFIER), propget] + HRESULT publicIdentifier( + [out,retval] BSTR* uri); +}; + + [ uuid(079aa557-4a18-424a-8eee-e39f0a8d41b9) ] @@ -2028,6 +2655,26 @@ coclass MXXMLWriter30 interface IVBSAXLexicalHandler; }; +[ + uuid(88d969c8-f192-11d4-a65f-0040963251e5), +] +coclass MXXMLWriter40 +{ + [default] interface IMXWriter; + + interface ISAXContentHandler; + interface ISAXDeclHandler; + interface ISAXDTDHandler; + interface ISAXErrorHandler; + interface ISAXLexicalHandler; + + interface IVBSAXContentHandler; + interface IVBSAXDeclHandler; + interface IVBSAXDTDHandler; + interface IVBSAXErrorHandler; + interface IVBSAXLexicalHandler; +}; + [ uuid(4dd441ad-526d-4a77-9f1b-9841ed802fb0) ] @@ -2048,5 +2695,15 @@ coclass SAXAttributes30 interface ISAXAttributes; }; +[ + uuid(88d969ca-f192-11d4-a65f-0040963251e5), +] +coclass SAXAttributes40 +{ + [default] interface IMXAttributes; + interface IVBSAXAttributes; + interface ISAXAttributes; +}; + } /* Library MSXML */ diff --git a/reactos/include/psdk/msxml2did.h b/reactos/include/psdk/msxml2did.h index f2adaaff427..d7489d0524f 100644 --- a/reactos/include/psdk/msxml2did.h +++ b/reactos/include/psdk/msxml2did.h @@ -394,5 +394,87 @@ #define DISPID_MX_READER_CONTROL_RESUME 0x00000577 #define DISPID_MX_READER_CONTROL_SUSPEND 0x00000578 +#define DISPID_MX_SCHEMADECLHANDLER 0x0000057a +#define DISPID_MX_SCHEMADECLHANDLER_SCHEMAELEMENTDECL 0x0000057b + +#define DISPID_MX_NSMGR 0x0000057d +#define DISPID_MX_NSMGR_ALLOWOVERRIDE 0x0000057e +#define DISPID_MX_NSMGR_RESET 0x0000057f +#define DISPID_MX_NSMGR_PUSHCONTEXT 0x00000580 +#define DISPID_MX_NSMGR_PUSHNODECONTEXT 0x00000581 +#define DISPID_MX_NSMGR_POPCONTEXT 0x00000582 +#define DISPID_MX_NSMGR_DECLAREPREFIX 0x00000583 +#define DISPID_MX_NSMGR_GETDECLAREDPREFIXES 0x00000584 +#define DISPID_MX_NSMGR_GETPREFIXES 0x00000585 +#define DISPID_MX_NSMGR_GETURI 0x00000586 +#define DISPID_MX_NSMGR_GETURIFROMNODE 0x00000587 +#define DISPID_MX_NSMGR_LENGTH 0x00000588 + +#define DISPID_SOM_VALIDATE 0x0000058b +#define DISPID_SOM_VALIDATEONLOAD 0x0000058c +#define DISPID_SOM_GETSCHEMA 0x0000058d +#define DISPID_SOM_GETDECLARATION 0x0000058e +#define DISPID_SOM_ITEMBYNAME 0x0000058f +#define DISPID_SOM_ITEMBYQNAME 0x00000590 +#define DISPID_SOM_ANYATTRIBUTE 0x00000591 +#define DISPID_SOM_ATTRIBUTEGROUPS 0x00000592 +#define DISPID_SOM_ATTRIBUTES 0x00000593 +#define DISPID_SOM_BASETYPES 0x00000594 +#define DISPID_SOM_CONTENTMODEL 0x00000595 +#define DISPID_SOM_CONTENTTYPE 0x00000596 +#define DISPID_SOM_DEFAULTVALUE 0x00000597 +#define DISPID_SOM_DERIVEDBY 0x00000598 +#define DISPID_SOM_DISALLOWED 0x00000599 +#define DISPID_SOM_ELEMENTS 0x0000059a +#define DISPID_SOM_ENUMERATION 0x0000059b +#define DISPID_SOM_FIELDS 0x0000059c +#define DISPID_SOM_FINAL 0x0000059d +#define DISPID_SOM_FIXEDVALUE 0x0000059e +#define DISPID_SOM_FRACTIONDIGITS 0x0000059f +#define DISPID_SOM_ID 0x000005a0 +#define DISPID_SOM_IDCONSTRAINTS 0x000005a1 +#define DISPID_SOM_ISABSTRACT 0x000005a2 +#define DISPID_SOM_ISNILLABLE 0x000005a3 +#define DISPID_SOM_ISREFERENCE 0x000005a4 +#define DISPID_SOM_ISVALID 0x000005a5 +#define DISPID_SOM_ITEMTYPE 0x000005a6 +#define DISPID_SOM_LENGTH 0x000005a7 +#define DISPID_SOM_MAXEXCLUSIVE 0x000005a8 +#define DISPID_SOM_MAXINCLUSIVE 0x000005a9 +#define DISPID_SOM_MAXLENGTH 0x000005aa +#define DISPID_SOM_MAXOCCURS 0x000005ab +#define DISPID_SOM_MINEXCLUSIVE 0x000005ac +#define DISPID_SOM_MININCLUSIVE 0x000005ad +#define DISPID_SOM_MINLENGTH 0x000005ae +#define DISPID_SOM_MINOCCURS 0x000005af +#define DISPID_SOM_MODELGROUPS 0x000005b0 +#define DISPID_SOM_NAME 0x000005b1 +#define DISPID_SOM_NAMESPACES 0x000005b2 +#define DISPID_SOM_NAMESPACEURI 0x000005b3 +#define DISPID_SOM_NOTATIONS 0x000005b4 +#define DISPID_SOM_PARTICLES 0x000005b5 +#define DISPID_SOM_PATTERNS 0x000005b6 +#define DISPID_SOM_PROCESSCONTENTS 0x000005b7 +#define DISPID_SOM_PROHIBITED 0x000005b8 +#define DISPID_SOM_PUBLICIDENTIFIER 0x000005b9 +#define DISPID_SOM_REFERENCEDKEY 0x000005ba +#define DISPID_SOM_SCHEMA 0x000005bb +#define DISPID_SOM_SCHEMALOCATIONS 0x000005bc +#define DISPID_SOM_SCOPE 0x000005bd +#define DISPID_SOM_SELECTOR 0x000005be +#define DISPID_SOM_SUBSTITUTIONGROUP 0x000005bf +#define DISPID_SOM_EXCLUSIONS 0x000005c0 +#define DISPID_SOM_SYSTEMIDENTIFIER 0x000005c1 +#define DISPID_SOM_TARGETNAMESPACE 0x000005c2 +#define DISPID_SOM_TOTALDIGITS 0x000005c3 +#define DISPID_SOM_TYPE 0x000005c4 +#define DISPID_SOM_TYPES 0x000005c5 +#define DISPID_SOM_UNHANDLEDATTRS 0x000005c6 +#define DISPID_SOM_USE 0x000005c7 +#define DISPID_SOM_VARIETY 0x000005c8 +#define DISPID_SOM_VERSION 0x000005c9 +#define DISPID_SOM_WHITESPACE 0x000005ca +#define DISPID_SOM_WRITEANNOTATION 0x000005cb + #endif /* __MSXML2DID_H__ */ From def4a5f1f5fd7cc2f4cf47655ccb76687af91615 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:03:59 +0000 Subject: [PATCH 075/292] [RSAENH] sync to wine 1.2 RC2 svn path=/trunk/; revision=47399 --- reactos/dll/win32/rsaenh/implglue.c | 1 + reactos/dll/win32/rsaenh/rsaenh.c | 13 ++----------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/reactos/dll/win32/rsaenh/implglue.c b/reactos/dll/win32/rsaenh/implglue.c index 7ecfc289ecf..c217007221c 100644 --- a/reactos/dll/win32/rsaenh/implglue.c +++ b/reactos/dll/win32/rsaenh/implglue.c @@ -342,6 +342,7 @@ BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContex case CALG_RSA_KEYX: case CALG_RSA_SIGN: + case CALG_SSL3_SHAMD5: outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8; if (enc) { if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { diff --git a/reactos/dll/win32/rsaenh/rsaenh.c b/reactos/dll/win32/rsaenh/rsaenh.c index 8a5be9935c3..d7d63b13676 100644 --- a/reactos/dll/win32/rsaenh/rsaenh.c +++ b/reactos/dll/win32/rsaenh/rsaenh.c @@ -1167,16 +1167,6 @@ static void store_key_container_keys(KEYCONTAINER *pKeyContainer) static void store_key_container_permissions(KEYCONTAINER *pKeyContainer) { HKEY hKey; - DWORD dwFlags; - - /* On WinXP, persistent keys are stored in a file located at: - * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string - */ - - if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) - dwFlags = CRYPTPROTECT_LOCAL_MACHINE; - else - dwFlags = 0; if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) { @@ -1426,7 +1416,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, ALG_ID aiAlgid; DWORD dwLen; CONST BYTE abOID[19]; - } aOIDDescriptor[8] = { + } aOIDDescriptor[] = { { CALG_MD2, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 } }, { CALG_MD4, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, @@ -1444,6 +1434,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, { CALG_SHA_384, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x40 } }, + { CALG_SSL3_SHAMD5, 0, { 0 } }, { 0, 0, { 0 } } }; DWORD dwIdxOID, i, j; From cdabe0cf2112352bb4314617331057ef5fc05403 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:05:43 +0000 Subject: [PATCH 076/292] [QEDIT] sync to wine 1.2 RC2 svn path=/trunk/; revision=47400 --- reactos/dll/directx/qedit/mediadet.c | 6 +++--- reactos/dll/directx/qedit/regsvr.c | 2 +- reactos/dll/directx/qedit/samplegrabber.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/dll/directx/qedit/mediadet.c b/reactos/dll/directx/qedit/mediadet.c index 3a13f717bf6..9aeb9c017cc 100644 --- a/reactos/dll/directx/qedit/mediadet.c +++ b/reactos/dll/directx/qedit/mediadet.c @@ -38,8 +38,8 @@ typedef struct MediaDetImpl { IGraphBuilder *graph; IBaseFilter *source; IBaseFilter *splitter; - long num_streams; - long cur_stream; + LONG num_streams; + LONG cur_stream; IPin *cur_pin; } MediaDetImpl; @@ -168,7 +168,7 @@ static HRESULT WINAPI MediaDet_get_CurrentStream(IMediaDet* iface, LONG *pVal) return S_OK; } -static HRESULT SetCurPin(MediaDetImpl *This, long strm) +static HRESULT SetCurPin(MediaDetImpl *This, LONG strm) { IEnumPins *pins; IPin *pin; diff --git a/reactos/dll/directx/qedit/regsvr.c b/reactos/dll/directx/qedit/regsvr.c index d70c8222ee8..d007311840a 100644 --- a/reactos/dll/directx/qedit/regsvr.c +++ b/reactos/dll/directx/qedit/regsvr.c @@ -326,5 +326,5 @@ HRESULT WINAPI DllUnregisterServer(void) TRACE("\n"); hr = unregister_coclasses(coclass_list); - return S_OK; + return hr; } diff --git a/reactos/dll/directx/qedit/samplegrabber.c b/reactos/dll/directx/qedit/samplegrabber.c index 78a7306e10e..78979fecf28 100644 --- a/reactos/dll/directx/qedit/samplegrabber.c +++ b/reactos/dll/directx/qedit/samplegrabber.c @@ -489,7 +489,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) REFERENCE_TIME tStart, tEnd; if (This->bufferLen >= 0) { BYTE *data = 0; - long size = IMediaSample_GetActualDataLength(sample); + LONG size = IMediaSample_GetActualDataLength(sample); if (size >= 0 && SUCCEEDED(IMediaSample_GetPointer(sample, &data))) { if (!data) size = 0; @@ -527,7 +527,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) case 1: { BYTE *data = 0; - long size = IMediaSample_GetActualDataLength(sample); + LONG size = IMediaSample_GetActualDataLength(sample); if (size && SUCCEEDED(IMediaSample_GetPointer(sample, &data)) && data) ISampleGrabberCB_BufferCB(This->grabberIface, time, data, size); } @@ -535,7 +535,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) case -1: break; default: - FIXME("unsupported method %ld\n", (long int)This->grabberMethod); + FIXME("unsupported method %d\n", This->grabberMethod); /* do not bother us again */ This->grabberMethod = -1; } From b6ed2f2fbf0ad1fd8bc35e7562771f35c074f908 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:07:32 +0000 Subject: [PATCH 077/292] [QUARTZ] sync to wine 1.2 RC2 svn path=/trunk/; revision=47401 --- reactos/dll/directx/quartz/acmwrapper.c | 2 +- reactos/dll/directx/quartz/avidec.c | 2 +- reactos/dll/directx/quartz/avisplit.c | 7 +-- reactos/dll/directx/quartz/dsoundrender.c | 14 +++--- reactos/dll/directx/quartz/enumfilters.c | 3 ++ reactos/dll/directx/quartz/filtergraph.c | 36 +++++++-------- reactos/dll/directx/quartz/filtermapper.c | 2 +- reactos/dll/directx/quartz/memallocator.c | 4 +- reactos/dll/directx/quartz/mpegsplit.c | 3 -- reactos/dll/directx/quartz/pin.c | 2 +- reactos/dll/directx/quartz/pin.h | 2 +- reactos/dll/directx/quartz/videorenderer.c | 54 ++++++++++++++++------ 12 files changed, 73 insertions(+), 58 deletions(-) diff --git a/reactos/dll/directx/quartz/acmwrapper.c b/reactos/dll/directx/quartz/acmwrapper.c index c275d833979..a0323911707 100644 --- a/reactos/dll/directx/quartz/acmwrapper.c +++ b/reactos/dll/directx/quartz/acmwrapper.c @@ -105,7 +105,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample tMed = tStart; - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) diff --git a/reactos/dll/directx/quartz/avidec.c b/reactos/dll/directx/quartz/avidec.c index 8469bbc9f29..b7d45e93890 100644 --- a/reactos/dll/directx/quartz/avidec.c +++ b/reactos/dll/directx/quartz/avidec.c @@ -101,7 +101,7 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) { diff --git a/reactos/dll/directx/quartz/avisplit.c b/reactos/dll/directx/quartz/avisplit.c index 42ec2ae2b34..61078805903 100644 --- a/reactos/dll/directx/quartz/avisplit.c +++ b/reactos/dll/directx/quartz/avisplit.c @@ -178,7 +178,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe { AVISTDINDEX *index = stream->stdindex[stream->index]; AVISTDINDEX_ENTRY *entry = &index->aIndex[stream->pos]; - BOOL keyframe; /* End of file */ if (stream->index >= stream->entries) @@ -189,7 +188,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe } rtSampleStart = index->qwBaseOffset; - keyframe = !(entry->dwSize >> 31); rtSampleStart += entry->dwOffset; rtSampleStart = MEDIATIME_FROM_BYTES(rtSampleStart); @@ -208,7 +206,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe { DWORD flags = This->oldindex->aIndex[stream->pos].dwFlags; DWORD size = This->oldindex->aIndex[stream->pos].dwSize; - BOOL keyframe; /* End of file */ if (stream->index) @@ -218,8 +215,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe return S_FALSE; } - keyframe = !!(flags & AVIIF_KEYFRAME); - rtSampleStart = MEDIATIME_FROM_BYTES(This->offset); rtSampleStart += MEDIATIME_FROM_BYTES(This->oldindex->aIndex[stream->pos].dwOffset); rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(size); @@ -775,7 +770,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE { const AVISUPERINDEX *pIndex = (const AVISUPERINDEX *)pChunk; DWORD x; - long rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY; + UINT rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY; if (pIndex->cb < sizeof(AVISUPERINDEX) - sizeof(RIFFCHUNK)) { diff --git a/reactos/dll/directx/quartz/dsoundrender.c b/reactos/dll/directx/quartz/dsoundrender.c index 1d87a7f0047..b327c00da9b 100644 --- a/reactos/dll/directx/quartz/dsoundrender.c +++ b/reactos/dll/directx/quartz/dsoundrender.c @@ -78,8 +78,8 @@ typedef struct DSoundRenderImpl HANDLE state_change, blocked; - long volume; - long pan; + LONG volume; + LONG pan; } DSoundRenderImpl; /* Seeking is not needed for a renderer, rely on newsegment for the appropriate changes */ @@ -238,7 +238,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) { DSoundRenderImpl *This = iface; LPBYTE pbSrcStream = NULL; - long cbSrcStream = 0; + LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; AM_MEDIA_TYPE *amt; @@ -344,7 +344,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) } cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); #if 0 /* For debugging purpose */ { @@ -677,7 +677,7 @@ static HRESULT WINAPI DSoundRender_GetState(IBaseFilter * iface, DWORD dwMilliSe } LeaveCriticalSection(&This->csFilter); - return S_OK; + return hr; } static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) @@ -877,11 +877,11 @@ static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin { hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume); if (FAILED(hr)) - ERR("Can't set volume to %ld (%x)\n", DSImpl->volume, hr); + ERR("Can't set volume to %d (%x)\n", DSImpl->volume, hr); hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan); if (FAILED(hr)) - ERR("Can't set pan to %ld (%x)\n", DSImpl->pan, hr); + ERR("Can't set pan to %d (%x)\n", DSImpl->pan, hr); DSImpl->write_pos = 0; hr = S_OK; diff --git a/reactos/dll/directx/quartz/enumfilters.c b/reactos/dll/directx/quartz/enumfilters.c index ca6a98941bc..ab1f6ec6a72 100644 --- a/reactos/dll/directx/quartz/enumfilters.c +++ b/reactos/dll/directx/quartz/enumfilters.c @@ -126,6 +126,9 @@ static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched); + if (!ppFilters) + return E_POINTER; + for (i = 0; i < cFetched; i++) { ppFilters[i] = This->ppFilters[This->uIndex + i]; diff --git a/reactos/dll/directx/quartz/filtergraph.c b/reactos/dll/directx/quartz/filtergraph.c index 3e9a1da1b82..18bf97c392b 100644 --- a/reactos/dll/directx/quartz/filtergraph.c +++ b/reactos/dll/directx/quartz/filtergraph.c @@ -45,14 +45,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct { - HWND hWnd; /* Target window */ - long msg; /* User window message */ - long instance; /* User data */ - int disabled; /* Disabled messages posting */ + HWND hWnd; /* Target window */ + UINT msg; /* User window message */ + LONG_PTR instance; /* User data */ + int disabled; /* Disabled messages posting */ } WndNotify; typedef struct { - long lEventCode; /* Event code */ + LONG lEventCode; /* Event code */ LONG_PTR lParam1; /* Param1 */ LONG_PTR lParam2; /* Param2 */ } Event; @@ -120,7 +120,7 @@ static int EventsQueue_PutEvent(EventsQueue* omr, const Event* evt) return TRUE; } -static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut) +static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, LONG msTimeOut) { if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0) return FALSE; @@ -182,7 +182,7 @@ typedef struct _IFilterGraphImpl { LPWSTR * pFilterNames; int nFilters; int filterCapacity; - long nameIndex; + LONG nameIndex; IReferenceClock *refClock; EventsQueue evqueue; HANDLE hEventCompletion; @@ -4970,7 +4970,7 @@ static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface, This->notif.hWnd = (HWND)hwnd; This->notif.msg = lMsg; - This->notif.instance = (long) lInstanceData; + This->notif.instance = lInstanceData; return S_OK; } @@ -5055,30 +5055,26 @@ static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClass static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) { - FIXME("(): stub\n"); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Stop((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) { - FIXME("(): stub\n"); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Pause((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart) { - FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart)); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Run((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState) { - FIXME("(%d, %p): stub\n", dwMsTimeout, pState); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_GetState((IMediaControl*)&This->IMediaControl_vtbl, dwMsTimeout, (OAFilterState*)pState); } static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock) diff --git a/reactos/dll/directx/quartz/filtermapper.c b/reactos/dll/directx/quartz/filtermapper.c index bacb72950d6..aeacfac386e 100644 --- a/reactos/dll/directx/quartz/filtermapper.c +++ b/reactos/dll/directx/quartz/filtermapper.c @@ -1778,7 +1778,7 @@ static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface, prf2 = CoTaskMemAlloc(sizeof(*prf2)); if (!prf2) return E_OUTOFMEMORY; - *ppRegFilter2 = (BYTE *)&prf2; + *ppRegFilter2 = (BYTE *)prf2; hr = FM2_ReadFilterData(pData, prf2); if (FAILED(hr)) diff --git a/reactos/dll/directx/quartz/memallocator.c b/reactos/dll/directx/quartz/memallocator.c index 7f799c93b7d..a1c4473238f 100644 --- a/reactos/dll/directx/quartz/memallocator.c +++ b/reactos/dll/directx/quartz/memallocator.c @@ -534,7 +534,7 @@ static HRESULT WINAPI StdMediaSample2_GetTime(IMediaSample2 * iface, REFERENCE_T hr = S_OK; } - return S_OK; + return hr; } static HRESULT WINAPI StdMediaSample2_SetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd) @@ -785,7 +785,7 @@ static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface) StdMemAllocator *This = (StdMemAllocator *)iface; StdMediaSample2 * pSample = NULL; SYSTEM_INFO si; - long i; + LONG i; assert(list_empty(&This->base.free_list)); diff --git a/reactos/dll/directx/quartz/mpegsplit.c b/reactos/dll/directx/quartz/mpegsplit.c index e44a10fcca1..7eb2d2c213f 100644 --- a/reactos/dll/directx/quartz/mpegsplit.c +++ b/reactos/dll/directx/quartz/mpegsplit.c @@ -246,11 +246,8 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample, BYTE *pbSrcStream; DWORD cbSrcStream = 0; REFERENCE_TIME tStart, tStop, tAviStart = This->position; - Parser_OutputPin * pOutputPin; HRESULT hr; - pOutputPin = (Parser_OutputPin*)This->Parser.ppPins[1]; - hr = IMediaSample_GetTime(pSample, &tStart, &tStop); if (SUCCEEDED(hr)) { diff --git a/reactos/dll/directx/quartz/pin.c b/reactos/dll/directx/quartz/pin.c index ca34d9331c5..fd0d5a2e522 100644 --- a/reactos/dll/directx/quartz/pin.c +++ b/reactos/dll/directx/quartz/pin.c @@ -1834,7 +1834,7 @@ HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinI return E_FAIL; } -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) +HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) { OutputPin * pPinImpl; diff --git a/reactos/dll/directx/quartz/pin.h b/reactos/dll/directx/quartz/pin.h index 2cbaddba0f9..e356ef32f53 100644 --- a/reactos/dll/directx/quartz/pin.h +++ b/reactos/dll/directx/quartz/pin.h @@ -143,7 +143,7 @@ typedef struct PullPin /*** Constructors ***/ HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin ** ppPin); -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); +HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, STOPPROCESSPROC, REQUESTPROC pCustomRequest, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); /**************************/ diff --git a/reactos/dll/directx/quartz/videorenderer.c b/reactos/dll/directx/quartz/videorenderer.c index b31959eed21..268373f1888 100644 --- a/reactos/dll/directx/quartz/videorenderer.c +++ b/reactos/dll/directx/quartz/videorenderer.c @@ -82,8 +82,8 @@ typedef struct VideoRendererImpl RECT SourceRect; RECT DestRect; RECT WindowPos; - long VideoWidth; - long VideoHeight; + LONG VideoWidth; + LONG VideoHeight; IUnknown * pUnkOuter; BOOL bUnkOuterValid; BOOL bAggregatable; @@ -287,7 +287,6 @@ static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, return VFW_E_RUNTIME_ERROR; } - TRACE("biSize = %d\n", bmiHeader->biSize); TRACE("biWidth = %d\n", bmiHeader->biWidth); TRACE("biHeight = %d\n", bmiHeader->biHeight); @@ -344,7 +343,7 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) { VideoRendererImpl *This = iface; LPBYTE pbSrcStream = NULL; - long cbSrcStream = 0; + LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; @@ -396,7 +395,7 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("val %p %ld\n", pbSrcStream, cbSrcStream); + TRACE("val %p %d\n", pbSrcStream, cbSrcStream); #if 0 /* For debugging purpose */ { @@ -483,6 +482,7 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)) { VideoRendererImpl* This = iface; + LONG height; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { @@ -490,7 +490,11 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth; - This->SourceRect.bottom = This->VideoHeight = format->bmiHeader.biHeight; + height = format->bmiHeader.biHeight; + if (height < 0) + This->SourceRect.bottom = This->VideoHeight = -height; + else + This->SourceRect.bottom = This->VideoHeight = height; } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { @@ -499,7 +503,11 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth; - This->SourceRect.bottom = This->VideoHeight = format2->bmiHeader.biHeight; + height = format2->bmiHeader.biHeight; + if (height < 0) + This->SourceRect.bottom = This->VideoHeight = -height; + else + This->SourceRect.bottom = This->VideoHeight = height; } else { @@ -1176,10 +1184,25 @@ static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface, /*** IBasicVideo methods ***/ static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame) { + AM_MEDIA_TYPE *pmt; ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame); + if (!This->pInputPin->pin.pConnectedTo) + return VFW_E_NOT_CONNECTED; + TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); + + pmt = &This->pInputPin->pin.mtCurrent; + if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { + VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat; + *pAvgTimePerFrame = vih->AvgTimePerFrame; + } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { + VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat; + *pAvgTimePerFrame = vih->AvgTimePerFrame; + } else { + ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); + *pAvgTimePerFrame = 0; + } return S_OK; } @@ -1779,9 +1802,6 @@ static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface, TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); - if (WindowStyleEx & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) - return E_INVALIDARG; - if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx)) return E_FAIL; @@ -1805,7 +1825,7 @@ static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface, TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); - This->AutoShow = 1; /* FIXME: Should be AutoShow */; + This->AutoShow = AutoShow; return S_OK; } @@ -1825,16 +1845,20 @@ static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface, LONG WindowState) { ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, WindowState); - + TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); + ShowWindow(This->hWnd, WindowState); return S_OK; } static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface, LONG *WindowState) { + WINDOWPLACEMENT place; ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState); + place.length = sizeof(place); + GetWindowPlacement(This->hWnd, &place); + TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); + *WindowState = place.showCmd; return S_OK; } From e701f228c2d800435e8ca87239ecf708cccbba0c Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:22:07 +0000 Subject: [PATCH 078/292] [MSVCRT_WINETEST] partial sync to wine 1.2 RC2 svn path=/trunk/; revision=47402 --- rostests/winetests/msvcrt/data.c | 9 +- rostests/winetests/msvcrt/environ.c | 11 + rostests/winetests/msvcrt/headers.c | 2 +- rostests/winetests/msvcrt/scanf.c | 42 ++++ rostests/winetests/msvcrt/string.c | 334 ++++++++++++++++++++++++++++ rostests/winetests/msvcrt/time.c | 81 +++++-- 6 files changed, 463 insertions(+), 16 deletions(-) diff --git a/rostests/winetests/msvcrt/data.c b/rostests/winetests/msvcrt/data.c index a27ca27f3a6..7061124ef73 100644 --- a/rostests/winetests/msvcrt/data.c +++ b/rostests/winetests/msvcrt/data.c @@ -74,7 +74,8 @@ static void test_initvar( HMODULE hmsvcrt ) int *pp_winmajor = (int*)GetProcAddress(hmsvcrt, "_winmajor"); int *pp_winminor = (int*)GetProcAddress(hmsvcrt, "_winminor"); int *pp_osver = (int*)GetProcAddress(hmsvcrt, "_osver"); - unsigned int winver, winmajor, winminor, osver; + int *pp_osplatform = (int*)GetProcAddress(hmsvcrt, "_osplatform"); + unsigned int winver, winmajor, winminor, osver, osplatform; if( !( pp_winmajor && pp_winminor && pp_winver)) { win_skip("_winver variables are not available\n"); @@ -91,16 +92,20 @@ static void test_initvar( HMODULE hmsvcrt ) ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion), "Wrong value for _winver %02x expected %02x\n", winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion)); - if( !pp_osver) { + if( !pp_osver || !pp_osplatform ) { win_skip("_osver variables are not available\n"); return; } osver = *pp_osver; + osplatform = *pp_osplatform; ok( osver == (osvi.dwBuildNumber & 0xffff) || ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion && ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */ "Wrong value for _osver %04x expected %04x\n", osver, osvi.dwBuildNumber); + ok(osplatform == osvi.dwPlatformId, + "Wrong value for _osplatform %x exprected %x\n", + osplatform, osvi.dwPlatformId); } START_TEST(data) diff --git a/rostests/winetests/msvcrt/environ.c b/rostests/winetests/msvcrt/environ.c index 6175e14af69..336238ce13f 100644 --- a/rostests/winetests/msvcrt/environ.c +++ b/rostests/winetests/msvcrt/environ.c @@ -42,6 +42,15 @@ static const char *a_very_long_env_string = "/usr/lib/mingw32/3.4.2/;" "/usr/lib/"; +static void test_system(void) +{ + int ret = system(NULL); + ok(ret == 1, "Expected system to return 1, got %d\n", ret); + + ret = system("echo OK"); + ok(ret == 0, "Expected system to return 0, got %d\n", ret); +} + START_TEST(environ) { ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); @@ -54,4 +63,6 @@ START_TEST(environ) ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n"); ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); + + test_system(); } diff --git a/rostests/winetests/msvcrt/headers.c b/rostests/winetests/msvcrt/headers.c index 80c614b2950..c39948d7308 100644 --- a/rostests/winetests/msvcrt/headers.c +++ b/rostests/winetests/msvcrt/headers.c @@ -68,7 +68,7 @@ #define MSVCRT(x) MSVCRT_##x #define OFFSET(T,F) ((unsigned int)((char *)&((struct T *)0L)->F - (char *)0L)) #define CHECK_SIZE(e) ok(sizeof(e) == sizeof(MSVCRT(e)), "Element has different sizes\n") -#define CHECK_TYPE(t) { TYPEOF(t) a = 0; TYPEOF(MSVCRT(t)) b = 0; a = b; CHECK_SIZE(t); } +#define CHECK_TYPE(t) { TYPEOF(t) a = 0; TYPEOF(MSVCRT(t)) b = a; a = b; CHECK_SIZE(t); } #define CHECK_STRUCT(s) ok(sizeof(struct s) == sizeof(struct MSVCRT(s)), "Struct has different sizes\n") #define CHECK_FIELD(s,e) ok(OFFSET(s,e) == OFFSET(MSVCRT(s),e), "Bad offset\n") #define CHECK_DEF(d) ok(d == MSVCRT_##d, "Defines (MSVCRT_)" #d " are different: %d vs. %d\n", d, MSVCRT_##d) diff --git a/rostests/winetests/msvcrt/scanf.c b/rostests/winetests/msvcrt/scanf.c index 0ec89ff5193..e9cb987b7bd 100644 --- a/rostests/winetests/msvcrt/scanf.c +++ b/rostests/winetests/msvcrt/scanf.c @@ -198,7 +198,49 @@ static void test_sscanf( void ) ok(number_so_far == 4, "%%n yielded wrong result: %d\n", number_so_far); } +static void test_sscanf_s(void) +{ + int (__cdecl *psscanf_s)(const char*,const char*,...); + HMODULE hmod = GetModuleHandleA("msvcrt.dll"); + int i, ret; + char buf[100]; + + psscanf_s = (void*)GetProcAddress(hmod, "sscanf_s"); + if(!psscanf_s) { + win_skip("sscanf_s not available\n"); + return; + } + + ret = psscanf_s("123", "%d", &i); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(i == 123, "i = %d\n", i); + + ret = psscanf_s("123", "%s", buf, 100); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(!strcmp("123", buf), "buf = %s\n", buf); + + ret = psscanf_s("123", "%s", buf, 3); + ok(ret == 0, "Wrong number of arguments read: %d\n", ret); + ok(buf[0]=='\0', "buf = %s\n", buf); + + buf[0] = 'a'; + ret = psscanf_s("123", "%3c", buf, 2); + ok(ret == 0, "Wrong number of arguments read: %d\n", ret); + ok(buf[0]=='\0', "buf = %s\n", buf); + + i = 1; + ret = psscanf_s("123 123", "%s %d", buf, 2, &i); + ok(ret == 0, "Wrong number of arguments read: %d\n", ret); + ok(i==1, "i = %d\n", i); + + i = 1; + ret = psscanf_s("123 123", "%d %s", &i, buf, 2); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(i==123, "i = %d\n", i); +} + START_TEST(scanf) { test_sscanf(); + test_sscanf_s(); } diff --git a/rostests/winetests/msvcrt/string.c b/rostests/winetests/msvcrt/string.c index a7b34047afe..f6c0e2cfec1 100644 --- a/rostests/winetests/msvcrt/string.c +++ b/rostests/winetests/msvcrt/string.c @@ -27,6 +27,7 @@ #include #include #include +#include static char *buf_to_string(const unsigned char *bin, int len, int nr) { @@ -52,6 +53,11 @@ static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count); static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc); static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size); +static size_t (__cdecl *p_strnlen)(const char *, size_t); +static __int64 (__cdecl *p_strtoi64)(const char *, char **, int); +static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int); +static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t); +static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t); static int *p__mb_cur_max; static unsigned char *p_mbctype; @@ -911,6 +917,325 @@ static void test_strtol(void) ok(errno == ERANGE, "wrong errno %d\n", errno); } +static void test_strnlen(void) +{ + static const char str[] = "string"; + size_t res; + + if(!p_strnlen) { + win_skip("strnlen not found\n"); + return; + } + + res = p_strnlen(str, 20); + ok(res == 6, "Returned length = %d\n", (int)res); + + res = p_strnlen(str, 3); + ok(res == 3, "Returned length = %d\n", (int)res); + + res = p_strnlen(NULL, 0); + ok(res == 0, "Returned length = %d\n", (int)res); +} + +static void test__strtoi64(void) +{ + static const char no1[] = "31923"; + static const char no2[] = "-213312"; + static const char no3[] = "12aa"; + static const char no4[] = "abc12"; + static const char overflow[] = "99999999999999999999"; + static const char neg_overflow[] = "-99999999999999999999"; + static const char hex[] = "0x123"; + static const char oct[] = "000123"; + static const char blanks[] = " 12 212.31"; + + __int64 res; + unsigned __int64 ures; + char *endpos; + + if(!p_strtoi64 || !p_strtoui64) { + win_skip("_strtoi64 or _strtoui64 not found\n"); + return; + } + + errno = 0xdeadbeef; + res = p_strtoi64(no1, NULL, 10); + ok(res == 31923, "res != 31923\n"); + res = p_strtoi64(no2, NULL, 10); + ok(res == -213312, "res != -213312\n"); + res = p_strtoi64(no3, NULL, 10); + ok(res == 12, "res != 12\n"); + res = p_strtoi64(no4, &endpos, 10); + ok(res == 0, "res != 0\n"); + ok(endpos == no4, "Scanning was not stopped on first character\n"); + res = p_strtoi64(hex, &endpos, 10); + ok(res == 0, "res != 0\n"); + ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); + res = p_strtoi64(oct, &endpos, 10); + ok(res == 123, "res != 123\n"); + ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); + res = p_strtoi64(blanks, &endpos, 10); + ok(res == 12, "res != 12"); + ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); + ok(errno == 0xdeadbeef, "errno = %x\n", errno); + + errno = 0xdeadbeef; + res = p_strtoi64(overflow, &endpos, 10); + ok(res == _I64_MAX, "res != _I64_MAX\n"); + ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos); + ok(errno == ERANGE, "errno = %x\n", errno); + + errno = 0xdeadbeef; + res = p_strtoi64(neg_overflow, &endpos, 10); + ok(res == _I64_MIN, "res != _I64_MIN\n"); + ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos); + ok(errno == ERANGE, "errno = %x\n", errno); + + errno = 0xdeadbeef; + res = p_strtoi64(no1, &endpos, 16); + ok(res == 203043, "res != 203043\n"); + ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); + res = p_strtoi64(no2, &endpos, 16); + ok(res == -2175762, "res != -2175762\n"); + ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); + res = p_strtoi64(no3, &endpos, 16); + ok(res == 4778, "res != 4778\n"); + ok(endpos == no3+strlen(no3), "Incorrect endpos (%p-%p)\n", no3, endpos); + res = p_strtoi64(no4, &endpos, 16); + ok(res == 703506, "res != 703506\n"); + ok(endpos == no4+strlen(no4), "Incorrect endpos (%p-%p)\n", no4, endpos); + res = p_strtoi64(hex, &endpos, 16); + ok(res == 291, "res != 291\n"); + ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos); + res = p_strtoi64(oct, &endpos, 16); + ok(res == 291, "res != 291\n"); + ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); + res = p_strtoi64(blanks, &endpos, 16); + ok(res == 18, "res != 18\n"); + ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); + ok(errno == 0xdeadbeef, "errno = %x\n", errno); + + errno = 0xdeadbeef; + res = p_strtoi64(hex, &endpos, 36); + ok(res == 1541019, "res != 1541019\n"); + ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos); + ok(errno == 0xdeadbeef, "errno = %x\n", errno); + + errno = 0xdeadbeef; + res = p_strtoi64(no1, &endpos, 0); + ok(res == 31923, "res != 31923\n"); + ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); + res = p_strtoi64(no2, &endpos, 0); + ok(res == -213312, "res != -213312\n"); + ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); + res = p_strtoi64(no3, &endpos, 10); + ok(res == 12, "res != 12\n"); + ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos); + res = p_strtoi64(no4, &endpos, 10); + ok(res == 0, "res != 0\n"); + ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos); + res = p_strtoi64(hex, &endpos, 10); + ok(res == 0, "res != 0\n"); + ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); + res = p_strtoi64(oct, &endpos, 10); + ok(res == 123, "res != 123\n"); + ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); + res = p_strtoi64(blanks, &endpos, 10); + ok(res == 12, "res != 12\n"); + ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); + ok(errno == 0xdeadbeef, "errno = %x\n", errno); + + errno = 0xdeadbeef; + ures = p_strtoui64(no1, &endpos, 0); + ok(ures == 31923, "ures != 31923\n"); + ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); + ures = p_strtoui64(no2, &endpos, 0); + ok(ures == -213312, "ures != -213312\n"); + ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); + ures = p_strtoui64(no3, &endpos, 10); + ok(ures == 12, "ures != 12\n"); + ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos); + ures = p_strtoui64(no4, &endpos, 10); + ok(ures == 0, "ures != 0\n"); + ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos); + ures = p_strtoui64(hex, &endpos, 10); + ok(ures == 0, "ures != 0\n"); + ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); + ures = p_strtoui64(oct, &endpos, 10); + ok(ures == 123, "ures != 123\n"); + ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); + ures = p_strtoui64(blanks, &endpos, 10); + ok(ures == 12, "ures != 12\n"); + ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); + ok(errno == 0xdeadbeef, "errno = %x\n", errno); + + errno = 0xdeadbeef; + ures = p_strtoui64(overflow, &endpos, 10); + ok(ures == _UI64_MAX, "ures != _UI64_MAX\n"); + ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos); + ok(errno == ERANGE, "errno = %x\n", errno); + + errno = 0xdeadbeef; + ures = p_strtoui64(neg_overflow, &endpos, 10); + ok(ures == 1, "ures != 1\n"); + ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos); + ok(errno == ERANGE, "errno = %x\n", errno); +} + +static inline BOOL almost_equal(double d1, double d2) { + if(d1-d2>-1e-30 && d1-d2<1e-30) + return TRUE; + return FALSE; +} + +static void test__strtod(void) +{ + const char double1[] = "12.1"; + const char double2[] = "-13.721"; + const char double3[] = "INF"; + const char double4[] = ".21e12"; + const char double5[] = "214353e-3"; + const char overflow[] = "1d9999999999999999999"; + + char *end; + double d; + + d = strtod(double1, &end); + ok(almost_equal(d, 12.1), "d = %lf\n", d); + ok(end == double1+4, "incorrect end (%d)\n", end-double1); + + d = strtod(double2, &end); + ok(almost_equal(d, -13.721), "d = %lf\n", d); + ok(end == double2+7, "incorrect end (%d)\n", end-double2); + + d = strtod(double3, &end); + ok(almost_equal(d, 0), "d = %lf\n", d); + ok(end == double3, "incorrect end (%d)\n", end-double3); + + d = strtod(double4, &end); + ok(almost_equal(d, 210000000000.0), "d = %lf\n", d); + ok(end == double4+6, "incorrect end (%d)\n", end-double4); + + d = strtod(double5, &end); + ok(almost_equal(d, 214.353), "d = %lf\n", d); + ok(end == double5+9, "incorrect end (%d)\n", end-double5); + + d = strtod("12.1d2", NULL); + ok(almost_equal(d, 12.1e2), "d = %lf\n", d); + + /* Set locale with non '.' decimal point (',') */ + if(!setlocale(LC_ALL, "Polish")) { + win_skip("system with limited locales\n"); + return; + } + + d = strtod("12.1", NULL); + ok(almost_equal(d, 12.0), "d = %lf\n", d); + + d = strtod("12,1", NULL); + ok(almost_equal(d, 12.1), "d = %lf\n", d); + + setlocale(LC_ALL, "C"); + + /* Precision tests */ + d = strtod("0.1", NULL); + ok(almost_equal(d, 0.1), "d = %lf\n", d); + d = strtod("-0.1", NULL); + ok(almost_equal(d, -0.1), "d = %lf\n", d); + d = strtod("0.1281832188491894198128921", NULL); + ok(almost_equal(d, 0.1281832188491894198128921), "d = %lf\n", d); + d = strtod("0.82181281288121", NULL); + ok(almost_equal(d, 0.82181281288121), "d = %lf\n", d); + d = strtod("21921922352523587651128218821", NULL); + ok(almost_equal(d, 21921922352523587651128218821.0), "d = %lf\n", d); + d = strtod("0.1d238", NULL); + ok(almost_equal(d, 0.1e238L), "d = %lf\n", d); + d = strtod("0.1D-4736", NULL); + ok(almost_equal(d, 0.1e-4736L), "d = %lf\n", d); + + errno = 0xdeadbeef; + d = strtod(overflow, &end); + ok(errno == ERANGE, "errno = %x\n", errno); + ok(end == overflow+21, "incorrect end (%d)\n", end-overflow); + + errno = 0xdeadbeef; + strtod("-1d309", NULL); + ok(errno == ERANGE, "errno = %x\n", errno); +} + +static void test_mbstowcs(void) +{ + static const wchar_t wSimple[] = { 't','e','x','t',0 }; + static const wchar_t wHiragana[] = { 0x3042,0x3043,0 }; + static const char mSimple[] = "text"; + static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 }; + + wchar_t wOut[6]; + char mOut[6]; + size_t ret; + int err; + + wOut[4] = '!'; wOut[5] = '\0'; + mOut[4] = '!'; mOut[5] = '\0'; + + ret = mbstowcs(NULL, mSimple, 0); + ok(ret == 4, "ret = %d\n", ret); + + ret = mbstowcs(wOut, mSimple, 4); + ok(ret == 4, "ret = %d\n", ret); + ok(!memcmp(wOut, wSimple, 4*sizeof(wchar_t)), "wOut = %s\n", wine_dbgstr_w(wOut)); + ok(wOut[4] == '!', "wOut[4] != \'!\'\n"); + + ret = wcstombs(NULL, wSimple, 0); + ok(ret == 4, "ret = %d\n", ret); + + ret = wcstombs(mOut, wSimple, 6); + ok(ret == 4, "ret = %d\n", ret); + ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut); + + ret = wcstombs(mOut, wSimple, 2); + ok(ret == 2, "ret = %d\n", ret); + ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut); + + if(!setlocale(LC_ALL, "Japanese_Japan.932")) { + win_skip("Japanese_Japan.932 locale not available\n"); + return; + } + + ret = mbstowcs(wOut, mHiragana, 6); + ok(ret == 2, "ret = %d\n", ret); + ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut)); + + ret = wcstombs(mOut, wHiragana, 6); + ok(ret == 4, "ret = %d\n", ret); + ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut); + + if(!pmbstowcs_s || !pwcstombs_s) { + win_skip("mbstowcs_s or wcstombs_s not available\n"); + return; + } + + err = pmbstowcs_s(&ret, wOut, 6, mSimple, -1/*_TRUNCATE*/); + ok(err == 0, "err = %d\n", err); + ok(ret == 5, "ret = %d\n", (int)ret); + ok(!memcmp(wOut, wSimple, sizeof(wSimple)), "wOut = %s\n", wine_dbgstr_w(wOut)); + + err = pmbstowcs_s(&ret, wOut, 6, mHiragana, -1/*_TRUNCATE*/); + ok(err == 0, "err = %d\n", err); + ok(ret == 3, "ret = %d\n", (int)ret); + ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut)); + + err = pwcstombs_s(&ret, mOut, 6, wSimple, -1/*_TRUNCATE*/); + ok(err == 0, "err = %d\n", err); + ok(ret == 5, "ret = %d\n", (int)ret); + ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut); + + err = pwcstombs_s(&ret, mOut, 6, wHiragana, -1/*_TRUNCATE*/); + ok(err == 0, "err = %d\n", err); + ok(ret == 5, "ret = %d\n", (int)ret); + ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut); +} + START_TEST(string) { char mem[100]; @@ -930,6 +1255,11 @@ START_TEST(string) p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" ); p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" ); + p_strnlen = (void *)GetProcAddress( hMsvcrt,"strnlen" ); + p_strtoi64 = (void *) GetProcAddress(hMsvcrt, "_strtoi64"); + p_strtoui64 = (void *) GetProcAddress(hMsvcrt, "_strtoui64"); + pmbstowcs_s = (void *) GetProcAddress(hMsvcrt, "mbstowcs_s"); + pwcstombs_s = (void *) GetProcAddress(hMsvcrt, "wcstombs_s"); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -959,4 +1289,8 @@ START_TEST(string) test_wcscpy_s(); test__wcsupr_s(); test_strtol(); + test_strnlen(); + test__strtoi64(); + test__strtod(); + test_mbstowcs(); } diff --git a/rostests/winetests/msvcrt/time.c b/rostests/winetests/msvcrt/time.c index ac782cab835..7f0a80b7542 100644 --- a/rostests/winetests/msvcrt/time.c +++ b/rostests/winetests/msvcrt/time.c @@ -54,20 +54,75 @@ static void test_ctime(void) } static void test_gmtime(void) { - time_t gmt = 0; - struct tm* gmt_tm = gmtime(&gmt); - if(gmt_tm == 0) - { - ok(0,"gmtime() error\n"); - return; - } + static __time32_t (__cdecl *p_mkgmtime32)(struct tm*); + static struct tm* (__cdecl *p_gmtime32)(__time32_t*); + + HMODULE hmod = GetModuleHandleA("msvcrt.dll"); + __time32_t valid, gmt; + struct tm* gmt_tm; + + p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32"); + if(!p_gmtime32) { + win_skip("Skipping _gmtime32 tests\n"); + return; + } + + gmt = valid = 0; + gmt_tm = p_gmtime32(&gmt); + if(!gmt_tm) { + ok(0, "_gmtime32() failed\n"); + return; + } + ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon == 0) && (gmt_tm->tm_yday == 0) && - (gmt_tm->tm_mday == 1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour == 0) && - (gmt_tm->tm_min == 0) && (gmt_tm->tm_sec == 0) && (gmt_tm->tm_isdst == 0)), - "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n", - gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, - gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); - + (gmt_tm->tm_mday == 1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour == 0) && + (gmt_tm->tm_min == 0) && (gmt_tm->tm_sec == 0) && (gmt_tm->tm_isdst == 0)), + "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n", + gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, + gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); + + p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32"); + if(!p_mkgmtime32) { + win_skip("Skipping _mkgmtime32 tests\n"); + return; + } + + gmt_tm->tm_wday = gmt_tm->tm_yday = 0; + gmt = p_mkgmtime32(gmt_tm); + ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); + ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); + + gmt_tm->tm_wday = gmt_tm->tm_yday = 0; + gmt_tm->tm_isdst = -1; + gmt = p_mkgmtime32(gmt_tm); + ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); + ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); + + gmt_tm->tm_wday = gmt_tm->tm_yday = 0; + gmt_tm->tm_isdst = 1; + gmt = p_mkgmtime32(gmt_tm); + ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); + ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); + + gmt = valid = 173921; + gmt_tm = p_gmtime32(&gmt); + if(!gmt_tm) { + ok(0, "_gmtime32() failed\n"); + return; + } + + gmt_tm->tm_isdst = -1; + gmt = p_mkgmtime32(gmt_tm); + ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt_tm->tm_wday == 6, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); + ok(gmt_tm->tm_yday == 2, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); + + gmt_tm->tm_isdst = 1; + gmt = p_mkgmtime32(gmt_tm); + ok(gmt == valid, "gmt = %u\n", gmt); } static void test_mktime(void) From 1d5afb8039f02dbcabc6b0b0d55bab52e283be29 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 09:23:23 +0000 Subject: [PATCH 079/292] [CRT] fix behavior of _system (fixes msvcrt environ winetest) svn path=/trunk/; revision=47403 --- reactos/lib/sdk/crt/process/_system.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/reactos/lib/sdk/crt/process/_system.c b/reactos/lib/sdk/crt/process/_system.c index f6173db03c6..3f9712b5737 100644 --- a/reactos/lib/sdk/crt/process/_system.c +++ b/reactos/lib/sdk/crt/process/_system.c @@ -35,11 +35,14 @@ int system(const char *command) // system should return 0 if command is null and the shell is found if (command == NULL) { - if (szComSpec == NULL) - return 0; - else - return -1; - } + if (szComSpec == NULL) + return 0; + else + return 1; + } + + if (szComSpec == NULL) + return -1; // should return 127 or 0 ( MS ) if the shell is not found // __set_errno(ENOENT); From c48e118c70ee7acaf7155f831a138b91ebc635ef Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 11:34:57 +0000 Subject: [PATCH 080/292] [OLE32] sync to wine 1.2 RC2 svn path=/trunk/; revision=47405 --- reactos/dll/win32/ole32/clipboard.c | 4 +- reactos/dll/win32/ole32/comcat.c | 22 +- reactos/dll/win32/ole32/compobj.c | 1 - reactos/dll/win32/ole32/compositemoniker.c | 9 +- reactos/dll/win32/ole32/defaulthandler.c | 2 +- reactos/dll/win32/ole32/hglobalstream.c | 19 +- reactos/dll/win32/ole32/ifs.c | 2 +- reactos/dll/win32/ole32/marshal.c | 45 +- reactos/dll/win32/ole32/moniker.c | 8 +- reactos/dll/win32/ole32/ole2.c | 390 +++--- reactos/dll/win32/ole32/stg_prop.c | 7 + reactos/dll/win32/ole32/storage32.c | 1329 ++++++++++++++------ reactos/dll/win32/ole32/storage32.h | 24 +- reactos/dll/win32/ole32/usrmarshal.c | 48 +- 14 files changed, 1258 insertions(+), 652 deletions(-) diff --git a/reactos/dll/win32/ole32/clipboard.c b/reactos/dll/win32/ole32/clipboard.c index 2afc77e35f0..3064bb04156 100644 --- a/reactos/dll/win32/ole32/clipboard.c +++ b/reactos/dll/win32/ole32/clipboard.c @@ -1266,10 +1266,10 @@ static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt, ole_priv_data_entry *entry; TYMED supported; - TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed); - if ( !fmt || !med ) return E_INVALIDARG; + TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed); + if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN; if(!This->data) diff --git a/reactos/dll/win32/ole32/comcat.c b/reactos/dll/win32/ole32/comcat.c index b8060bdefca..fe0f7e5962e 100644 --- a/reactos/dll/win32/ole32/comcat.c +++ b/reactos/dll/win32/ole32/comcat.c @@ -232,18 +232,20 @@ static HRESULT COMCAT_IsClassOfCategories( LPCWSTR string; /* Check that every given category is implemented by class. */ - res = RegOpenKeyExW(key, impl_keyname, 0, KEY_READ, &subkey); - if (res != ERROR_SUCCESS) return S_FALSE; - for (string = categories->impl_strings; *string; string += 39) { - HKEY catkey; - res = RegOpenKeyExW(subkey, string, 0, 0, &catkey); - if (res != ERROR_SUCCESS) { - RegCloseKey(subkey); - return S_FALSE; + if (*categories->impl_strings) { + res = RegOpenKeyExW(key, impl_keyname, 0, KEY_READ, &subkey); + if (res != ERROR_SUCCESS) return S_FALSE; + for (string = categories->impl_strings; *string; string += 39) { + HKEY catkey; + res = RegOpenKeyExW(subkey, string, 0, 0, &catkey); + if (res != ERROR_SUCCESS) { + RegCloseKey(subkey); + return S_FALSE; + } + RegCloseKey(catkey); } - RegCloseKey(catkey); + RegCloseKey(subkey); } - RegCloseKey(subkey); /* Check that all categories required by class are given. */ res = RegOpenKeyExW(key, req_keyname, 0, KEY_READ, &subkey); diff --git a/reactos/dll/win32/ole32/compobj.c b/reactos/dll/win32/ole32/compobj.c index 0fb074dc50c..937f3d8a06c 100644 --- a/reactos/dll/win32/ole32/compobj.c +++ b/reactos/dll/win32/ole32/compobj.c @@ -4156,7 +4156,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) break; case DLL_PROCESS_DETACH: - OLEDD_UnInitialize(); COMPOBJ_UninitProcess(); RPC_UnregisterAllChannelHooks(); COMPOBJ_DllList_Free(); diff --git a/reactos/dll/win32/ole32/compositemoniker.c b/reactos/dll/win32/ole32/compositemoniker.c index 7402b8edbbf..275d875362b 100644 --- a/reactos/dll/win32/ole32/compositemoniker.c +++ b/reactos/dll/win32/ole32/compositemoniker.c @@ -445,7 +445,6 @@ static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar, IMoniker** ppmkToLeft, IMoniker** ppmkReduced) { - HRESULT res; IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk; IEnumMoniker *enumMoniker; @@ -462,8 +461,8 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); IEnumMoniker_Release(enumMoniker); - res=CreateAntiMoniker(&antiMk); - res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + CreateAntiMoniker(&antiMk); + IMoniker_ComposeWith(iface,antiMk,0,&tempMk); IMoniker_Release(antiMk); return IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced); @@ -479,8 +478,8 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); IEnumMoniker_Release(enumMoniker); - res=CreateAntiMoniker(&antiMk); - res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + CreateAntiMoniker(&antiMk); + IMoniker_ComposeWith(iface,antiMk,0,&tempMk); IMoniker_Release(antiMk); /* If any of the components reduces itself, the method returns S_OK and passes back a composite */ diff --git a/reactos/dll/win32/ole32/defaulthandler.c b/reactos/dll/win32/ole32/defaulthandler.c index 5130513d57f..d0a871f17c0 100644 --- a/reactos/dll/win32/ole32/defaulthandler.c +++ b/reactos/dll/win32/ole32/defaulthandler.c @@ -365,7 +365,7 @@ static HRESULT WINAPI DefaultHandler_SetClientSite( if (This->clientSite) IOleClientSite_AddRef(This->clientSite); - return S_OK; + return hr; } /************************************************************************ diff --git a/reactos/dll/win32/ole32/hglobalstream.c b/reactos/dll/win32/ole32/hglobalstream.c index 5742f99619a..ef616defec5 100644 --- a/reactos/dll/win32/ole32/hglobalstream.c +++ b/reactos/dll/win32/ole32/hglobalstream.c @@ -371,12 +371,6 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart, dlibMove.u.LowPart, dwOrigin, plibNewPosition); - if (dlibMove.u.LowPart >= 0x80000000) - { - hr = STG_E_SEEKERROR; - goto end; - } - /* * The file pointer is moved depending on the given "function" * parameter. @@ -405,10 +399,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( newPosition.u.HighPart = 0; newPosition.u.LowPart += dlibMove.QuadPart; -end: - if (plibNewPosition) *plibNewPosition = newPosition; + if (dlibMove.u.LowPart >= 0x80000000 && + newPosition.u.LowPart >= dlibMove.u.LowPart) + { + /* We tried to seek backwards and went past the start. */ + hr = STG_E_SEEKERROR; + goto end; + } + This->currentPosition = newPosition; +end: + if (plibNewPosition) *plibNewPosition = This->currentPosition; + return hr; } diff --git a/reactos/dll/win32/ole32/ifs.c b/reactos/dll/win32/ole32/ifs.c index c6a6962cd72..1a10c3e1f53 100644 --- a/reactos/dll/win32/ole32/ifs.c +++ b/reactos/dll/win32/ole32/ifs.c @@ -501,7 +501,7 @@ HRESULT WINAPI CoRevokeMallocSpy(void) } LeaveCriticalSection(&IMalloc32_SpyCS); - return S_OK; + return hres; } /****************************************************************************** diff --git a/reactos/dll/win32/ole32/marshal.c b/reactos/dll/win32/ole32/marshal.c index 54a3a87b2b6..d14516f6dec 100644 --- a/reactos/dll/win32/ole32/marshal.c +++ b/reactos/dll/win32/ole32/marshal.c @@ -1214,16 +1214,13 @@ StdMarshalImpl_MarshalInterface( RPC_StartRemoting(apt); hres = marshal_object(apt, &stdobjref, riid, pv, mshlflags); - if (hres) + if (hres != S_OK) { ERR("Failed to create ifstub, hres=0x%x\n", hres); return hres; } - hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return hres; - - return S_OK; + return IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); } /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with @@ -1321,10 +1318,10 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v /* read STDOBJREF from wire */ hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return STG_E_READFAULT; + if (hres != S_OK) return STG_E_READFAULT; hres = apartment_getoxid(apt, &oxid); - if (hres) return hres; + if (hres != S_OK) return hres; /* check if we're marshalling back to ourselves */ if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid))) @@ -1374,7 +1371,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v if (stubmgr) stub_manager_int_release(stubmgr); if (stub_apt) apartment_release(stub_apt); - if (hres) WARN("Failed with error 0x%08x\n", hres); + if (hres != S_OK) WARN("Failed with error 0x%08x\n", hres); else TRACE("Successfully created proxy %p\n", *ppv); return hres; @@ -1392,7 +1389,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) TRACE("iface=%p, pStm=%p\n", iface, pStm); hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return STG_E_READFAULT; + if (hres != S_OK) return STG_E_READFAULT; TRACE("oxid = %s, oid = %s, ipid = %s\n", wine_dbgstr_longlong(stdobjref.oxid), @@ -1516,7 +1513,7 @@ static HRESULT get_marshaler(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, if (!pUnk) return E_POINTER; hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (LPVOID*)pMarshal); - if (hr) + if (hr != S_OK) hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, pMarshal); return hr; @@ -1537,7 +1534,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, /* read common OBJREF header */ hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res); - if (hr || (res != FIELD_OFFSET(OBJREF, u_objref))) + if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref))) { ERR("Failed to read common OBJREF header, 0x%08x\n", hr); return STG_E_READFAULT; @@ -1566,7 +1563,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, /* read constant sized OR_CUSTOM data from stream */ hr = IStream_Read(stream, &objref.u_objref.u_custom, custom_header_size, &res); - if (hr || (res != custom_header_size)) + if (hr != S_OK || (res != custom_header_size)) { ERR("Failed to read OR_CUSTOM header, 0x%08x\n", hr); return STG_E_READFAULT; @@ -1583,7 +1580,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, return RPC_E_INVALID_OBJREF; } - if (hr) + if (hr != S_OK) ERR("Failed to create marshal, 0x%08x\n", hr); return hr; @@ -1618,12 +1615,12 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, CLSID marshaler_clsid; hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); - if (hr) + if (hr != S_OK) return hr; hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &marshaler_clsid); - if (hr) + if (hr != S_OK) { ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr); IMarshal_Release(pMarshal); @@ -1711,7 +1708,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* get the marshaler for the specified interface */ hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); - if (hr) + if (hr != S_OK) { ERR("Failed to get marshaller, 0x%08x\n", hr); return hr; @@ -1719,7 +1716,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &marshaler_clsid); - if (hr) + if (hr != S_OK) { ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr); goto cleanup; @@ -1733,7 +1730,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* write the common OBJREF header to the stream */ hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL); - if (hr) + if (hr != S_OK) { ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr); goto cleanup; @@ -1749,7 +1746,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &objref.u_objref.u_custom.size); - if (hr) + if (hr != S_OK) { ERR("Failed to get max size of marshal data, error 0x%08x\n", hr); goto cleanup; @@ -1757,7 +1754,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* write constant sized common header and OR_CUSTOM data into stream */ hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL); - if (hr) + if (hr != S_OK) { ERR("Failed to write OR_CUSTOM header to stream with 0x%08x\n", hr); goto cleanup; @@ -1769,7 +1766,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_MarshalInterface(pMarshal, pStream, riid, pUnk, dwDestContext, pvDestContext, mshlFlags); - if (hr) + if (hr != S_OK) { ERR("Failed to marshal the interface %s, %x\n", debugstr_guid(riid), hr); goto cleanup; @@ -1821,7 +1818,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) /* call the helper object to do the actual unmarshaling */ hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object); - if (hr) + if (hr != S_OK) ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr); if (hr == S_OK) @@ -1831,7 +1828,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) { TRACE("requested interface != marshalled interface, additional QI needed\n"); hr = IUnknown_QueryInterface(object, riid, ppv); - if (hr) + if (hr != S_OK) ERR("Couldn't query for interface %s, hr = 0x%08x\n", debugstr_guid(riid), hr); IUnknown_Release(object); @@ -1885,7 +1882,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream) /* call the helper object to do the releasing of marshal data */ hr = IMarshal_ReleaseMarshalData(pMarshal, pStream); - if (hr) + if (hr != S_OK) ERR("IMarshal::ReleaseMarshalData failed with error 0x%08x\n", hr); IMarshal_Release(pMarshal); diff --git a/reactos/dll/win32/ole32/moniker.c b/reactos/dll/win32/ole32/moniker.c index 2fb03ae6650..b0030dee59b 100644 --- a/reactos/dll/win32/ole32/moniker.c +++ b/reactos/dll/win32/ole32/moniker.c @@ -1109,7 +1109,13 @@ HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk); - if (!(IsValidInterface((LPUNKNOWN) pbc))) + if (!pbc || !IsValidInterface((LPUNKNOWN) pbc)) + return E_INVALIDARG; + + if (!szDisplayName || !*szDisplayName) + return E_INVALIDARG; + + if (!pchEaten || !ppmk) return E_INVALIDARG; *pchEaten = 0; diff --git a/reactos/dll/win32/ole32/ole2.c b/reactos/dll/win32/ole32/ole2.c index 6bf79fdb507..41989f3331b 100644 --- a/reactos/dll/win32/ole32/ole2.c +++ b/reactos/dll/win32/ole32/ole2.c @@ -57,13 +57,6 @@ WINE_DECLARE_DEBUG_CHANNEL(accel); * These are static/global variables and internal data structures that the * OLE module uses to maintain it's state. */ -typedef struct tagDropTargetNode -{ - HWND hwndTarget; - IDropTarget* dropTarget; - struct list entry; -} DropTargetNode; - typedef struct tagTrackerWindowInfo { IDataObject* dataObject; @@ -110,12 +103,25 @@ static LONG OLE_moduleLockCount = 0; /* * Name of our registered window class. */ -static const char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32"; +static const WCHAR OLEDD_DRAGTRACKERCLASS[] = + {'W','i','n','e','D','r','a','g','D','r','o','p','T','r','a','c','k','e','r','3','2',0}; /* - * This is the head of the Drop target container. + * Name of menu descriptor property. */ -static struct list targetListHead = LIST_INIT(targetListHead); +static const WCHAR prop_olemenuW[] = + {'P','R','O','P','_','O','L','E','M','e','n','u','D','e','s','c','r','i','p','t','o','r',0}; + +/* property to store IDropTarget pointer */ +static const WCHAR prop_oledroptarget[] = + {'O','l','e','D','r','o','p','T','a','r','g','e','t','I','n','t','e','r','f','a','c','e',0}; + +static const WCHAR clsidfmtW[] = + {'C','L','S','I','D','\\','{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-', + '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', + '%','0','2','x','%','0','2','x','}','\\',0}; + +static const WCHAR emptyW[] = { 0 }; /****************************************************************************** * These are the prototypes of miscellaneous utility methods @@ -144,22 +150,12 @@ extern void OLEClipbrd_Initialize(void); /****************************************************************************** * These are the prototypes of the utility methods used for OLE Drag n Drop */ -static void OLEDD_Initialize(void); -static DropTargetNode* OLEDD_FindDropTarget( - HWND hwndOfTarget); -static void OLEDD_FreeDropTarget(DropTargetNode*, BOOL); -static LRESULT WINAPI OLEDD_DragTrackerWindowProc( - HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam); -static void OLEDD_TrackMouseMove( - TrackerWindowInfo* trackerInfo); -static void OLEDD_TrackStateChange( - TrackerWindowInfo* trackerInfo); +static void OLEDD_Initialize(void); +static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo); +static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo); static DWORD OLEDD_GetButtonState(void); - /****************************************************************************** * OleBuildVersion [OLE32.@] */ @@ -270,14 +266,22 @@ HRESULT WINAPI OleInitializeWOW(DWORD x, DWORD y) { return 0; } +/*** + * OLEDD_FindDropTarget() + * + * Returns IDropTarget pointer registered for this window. + */ +static inline IDropTarget* OLEDD_FindDropTarget(HWND hwnd) +{ + return GetPropW(hwnd, prop_oledroptarget); +} + /*********************************************************************** * RegisterDragDrop (OLE32.@) */ -HRESULT WINAPI RegisterDragDrop( - HWND hwnd, - LPDROPTARGET pDropTarget) +HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget) { - DropTargetNode* dropTargetInfo; + DWORD pid = 0; TRACE("(%p,%p)\n", hwnd, pDropTarget); @@ -296,32 +300,20 @@ HRESULT WINAPI RegisterDragDrop( return DRAGDROP_E_INVALIDHWND; } - /* - * First, check if the window is already registered. - */ - dropTargetInfo = OLEDD_FindDropTarget(hwnd); + /* block register for other processes windows */ + GetWindowThreadProcessId(hwnd, &pid); + if (pid != GetCurrentProcessId()) + { + FIXME("register for another process windows is disabled\n"); + return DRAGDROP_E_INVALIDHWND; + } - if (dropTargetInfo!=NULL) + /* check if the window is already registered */ + if (OLEDD_FindDropTarget(hwnd)) return DRAGDROP_E_ALREADYREGISTERED; - /* - * If it's not there, we can add it. We first create a node for it. - */ - dropTargetInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode)); - - if (dropTargetInfo==NULL) - return E_OUTOFMEMORY; - - dropTargetInfo->hwndTarget = hwnd; - - /* - * Don't forget that this is an interface pointer, need to nail it down since - * we keep a copy of it. - */ IDropTarget_AddRef(pDropTarget); - dropTargetInfo->dropTarget = pDropTarget; - - list_add_tail(&targetListHead, &dropTargetInfo->entry); + SetPropW(hwnd, prop_oledroptarget, pDropTarget); return S_OK; } @@ -329,10 +321,9 @@ HRESULT WINAPI RegisterDragDrop( /*********************************************************************** * RevokeDragDrop (OLE32.@) */ -HRESULT WINAPI RevokeDragDrop( - HWND hwnd) +HRESULT WINAPI RevokeDragDrop(HWND hwnd) { - DropTargetNode* dropTargetInfo; + IDropTarget* droptarget; TRACE("(%p)\n", hwnd); @@ -342,18 +333,12 @@ HRESULT WINAPI RevokeDragDrop( return DRAGDROP_E_INVALIDHWND; } - /* - * First, check if the window is already registered. - */ - dropTargetInfo = OLEDD_FindDropTarget(hwnd); - - /* - * If it ain't in there, it's an error. - */ - if (dropTargetInfo==NULL) + /* no registration data */ + if (!(droptarget = OLEDD_FindDropTarget(hwnd))) return DRAGDROP_E_NOTREGISTERED; - OLEDD_FreeDropTarget(dropTargetInfo, TRUE); + IDropTarget_Release(droptarget); + RemovePropW(hwnd, prop_oledroptarget); return S_OK; } @@ -371,13 +356,12 @@ HRESULT WINAPI OleRegGetUserType( DWORD dwFormOfType, LPOLESTR* pszUserType) { - char keyName[60]; + WCHAR keyName[60]; DWORD dwKeyType; DWORD cbData; HKEY clsidKey; LONG hres; - LPSTR buffer; - HRESULT retVal; + /* * Initialize the out parameter. */ @@ -386,17 +370,17 @@ HRESULT WINAPI OleRegGetUserType( /* * Build the key name we're looking for */ - sprintf( keyName, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", - clsid->Data1, clsid->Data2, clsid->Data3, - clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], - clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + sprintfW( keyName, clsidfmtW, + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); - TRACE("(%s, %d, %p)\n", keyName, dwFormOfType, pszUserType); + TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwFormOfType, pszUserType); /* * Open the class id Key */ - hres = RegOpenKeyA(HKEY_CLASSES_ROOT, + hres = RegOpenKeyW(HKEY_CLASSES_ROOT, keyName, &clsidKey); @@ -408,8 +392,8 @@ HRESULT WINAPI OleRegGetUserType( */ cbData = 0; - hres = RegQueryValueExA(clsidKey, - "", + hres = RegQueryValueExW(clsidKey, + emptyW, NULL, &dwKeyType, NULL, @@ -424,7 +408,7 @@ HRESULT WINAPI OleRegGetUserType( /* * Allocate a buffer for the registry value. */ - *pszUserType = CoTaskMemAlloc(cbData*2); + *pszUserType = CoTaskMemAlloc(cbData); if (*pszUserType==NULL) { @@ -432,41 +416,24 @@ HRESULT WINAPI OleRegGetUserType( return E_OUTOFMEMORY; } - buffer = HeapAlloc(GetProcessHeap(), 0, cbData); - - if (buffer == NULL) - { - RegCloseKey(clsidKey); - CoTaskMemFree(*pszUserType); - *pszUserType=NULL; - return E_OUTOFMEMORY; - } - - hres = RegQueryValueExA(clsidKey, - "", + hres = RegQueryValueExW(clsidKey, + emptyW, NULL, &dwKeyType, - (LPBYTE) buffer, + (LPBYTE) *pszUserType, &cbData); RegCloseKey(clsidKey); - - if (hres!=ERROR_SUCCESS) + if (hres != ERROR_SUCCESS) { CoTaskMemFree(*pszUserType); - *pszUserType=NULL; + *pszUserType = NULL; - retVal = REGDB_E_READREGDB; + return REGDB_E_READREGDB; } - else - { - MultiByteToWideChar( CP_ACP, 0, buffer, -1, *pszUserType, cbData /*FIXME*/ ); - retVal = S_OK; - } - HeapFree(GetProcessHeap(), 0, buffer); - return retVal; + return S_OK; } /*********************************************************************** @@ -478,17 +445,19 @@ HRESULT WINAPI DoDragDrop ( DWORD dwOKEffect, /* [in] effects allowed by the source */ DWORD *pdwEffect) /* [out] ptr to effects of the source */ { + static const WCHAR trackerW[] = {'T','r','a','c','k','e','r','W','i','n','d','o','w',0}; TrackerWindowInfo trackerInfo; HWND hwndTrackWindow; MSG msg; - TRACE("(DataObject %p, DropSource %p)\n", pDataObject, pDropSource); + TRACE("(%p, %p, %d, %p)\n", pDataObject, pDropSource, dwOKEffect, pdwEffect); + + if (!pDataObject || !pDropSource || !pdwEffect) + return E_INVALIDARG; /* * Setup the drag n drop tracking window. */ - if (!IsValidInterface((LPUNKNOWN)pDropSource)) - return E_INVALIDARG; trackerInfo.dataObject = pDataObject; trackerInfo.dropSource = pDropSource; @@ -500,12 +469,12 @@ HRESULT WINAPI DoDragDrop ( trackerInfo.curTargetHWND = 0; trackerInfo.curDragTarget = 0; - hwndTrackWindow = CreateWindowA(OLEDD_DRAGTRACKERCLASS, "TrackerWindow", + hwndTrackWindow = CreateWindowW(OLEDD_DRAGTRACKERCLASS, trackerW, WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, 0, &trackerInfo); - if (hwndTrackWindow!=0) + if (hwndTrackWindow) { /* * Capture the mouse input @@ -517,7 +486,7 @@ HRESULT WINAPI DoDragDrop ( /* * Pump messages. All mouse input should go to the capture window. */ - while (!trackerInfo.trackingDone && GetMessageA(&msg, 0, 0, 0) ) + while (!trackerInfo.trackingDone && GetMessageW(&msg, 0, 0, 0) ) { trackerInfo.curMousePos.x = msg.pt.x; trackerInfo.curMousePos.y = msg.pt.y; @@ -548,7 +517,7 @@ HRESULT WINAPI DoDragDrop ( /* * Dispatch the messages only when it's not a keyboard message. */ - DispatchMessageA(&msg); + DispatchMessageW(&msg); } } @@ -584,7 +553,9 @@ HRESULT WINAPI OleRegGetMiscStatus( DWORD dwAspect, DWORD* pdwStatus) { - char keyName[60]; + static const WCHAR miscstatusW[] = {'M','i','s','c','S','t','a','t','u','s',0}; + static const WCHAR dfmtW[] = {'%','d',0}; + WCHAR keyName[60]; HKEY clsidKey; HKEY miscStatusKey; HKEY aspectKey; @@ -598,17 +569,17 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Build the key name we're looking for */ - sprintf( keyName, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", - clsid->Data1, clsid->Data2, clsid->Data3, - clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], - clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + sprintfW( keyName, clsidfmtW, + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); - TRACE("(%s, %d, %p)\n", keyName, dwAspect, pdwStatus); + TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwAspect, pdwStatus); /* * Open the class id Key */ - result = RegOpenKeyA(HKEY_CLASSES_ROOT, + result = RegOpenKeyW(HKEY_CLASSES_ROOT, keyName, &clsidKey); @@ -618,8 +589,8 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Get the MiscStatus */ - result = RegOpenKeyA(clsidKey, - "MiscStatus", + result = RegOpenKeyW(clsidKey, + miscstatusW, &miscStatusKey); @@ -637,9 +608,9 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Open the key specific to the requested aspect. */ - sprintf(keyName, "%d", dwAspect); + sprintfW(keyName, dfmtW, dwAspect); - result = RegOpenKeyA(miscStatusKey, + result = RegOpenKeyW(miscStatusKey, keyName, &aspectKey); @@ -1180,7 +1151,7 @@ static void OLEMenu_UnInitialize(void) */ static BOOL OLEMenu_InstallHooks( DWORD tid ) { - OleMenuHookItem *pHookItem = NULL; + OleMenuHookItem *pHookItem; /* Create an entry for the hook table */ if ( !(pHookItem = HeapAlloc(GetProcessHeap(), 0, @@ -1189,15 +1160,16 @@ static BOOL OLEMenu_InstallHooks( DWORD tid ) pHookItem->tid = tid; pHookItem->hHeap = GetProcessHeap(); + pHookItem->CallWndProc_hHook = NULL; /* Install a thread scope message hook for WH_GETMESSAGE */ - pHookItem->GetMsg_hHook = SetWindowsHookExA( WH_GETMESSAGE, OLEMenu_GetMsgProc, + pHookItem->GetMsg_hHook = SetWindowsHookExW( WH_GETMESSAGE, OLEMenu_GetMsgProc, 0, GetCurrentThreadId() ); if ( !pHookItem->GetMsg_hHook ) goto CLEANUP; /* Install a thread scope message hook for WH_CALLWNDPROC */ - pHookItem->CallWndProc_hHook = SetWindowsHookExA( WH_CALLWNDPROC, OLEMenu_CallWndProc, + pHookItem->CallWndProc_hHook = SetWindowsHookExW( WH_CALLWNDPROC, OLEMenu_CallWndProc, 0, GetCurrentThreadId() ); if ( !pHookItem->CallWndProc_hHook ) goto CLEANUP; @@ -1271,7 +1243,7 @@ CLEANUP: */ static OleMenuHookItem * OLEMenu_IsHookInstalled( DWORD tid ) { - OleMenuHookItem *pHookItem = NULL; + OleMenuHookItem *pHookItem; /* Do a simple linear search for an entry whose tid matches ours. * We really need a map but efficiency is not a concern here. */ @@ -1376,7 +1348,7 @@ static BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDes */ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lParam) { - LPCWPSTRUCT pMsg = NULL; + LPCWPSTRUCT pMsg; HOLEMENU hOleMenu = 0; OleMenuDescriptor *pOleMenuDescriptor = NULL; OleMenuHookItem *pHookItem = NULL; @@ -1395,7 +1367,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar * If the window has an OLEMenu property we may need to dispatch * the menu message to its active objects window instead. */ - hOleMenu = GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + hOleMenu = GetPropW( pMsg->hwnd, prop_olemenuW ); if ( !hOleMenu ) goto NEXTHOOK; @@ -1413,7 +1385,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar pOleMenuDescriptor->bIsServerItem = FALSE; /* Send this message to the server as well */ - SendMessageA( pOleMenuDescriptor->hwndActiveObject, + SendMessageW( pOleMenuDescriptor->hwndActiveObject, pMsg->message, pMsg->wParam, pMsg->lParam ); goto NEXTHOOK; } @@ -1454,7 +1426,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar /* If the message was for the server dispatch it accordingly */ if ( pOleMenuDescriptor->bIsServerItem ) { - SendMessageA( pOleMenuDescriptor->hwndActiveObject, + SendMessageW( pOleMenuDescriptor->hwndActiveObject, pMsg->message, pMsg->wParam, pMsg->lParam ); } @@ -1481,7 +1453,7 @@ NEXTHOOK: */ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lParam) { - LPMSG pMsg = NULL; + LPMSG pMsg; HOLEMENU hOleMenu = 0; OleMenuDescriptor *pOleMenuDescriptor = NULL; OleMenuHookItem *pHookItem = NULL; @@ -1500,7 +1472,7 @@ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lPara * If the window has an OLEMenu property we may need to dispatch * the menu message to its active objects window instead. */ - hOleMenu = GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + hOleMenu = GetPropW( pMsg->hwnd, prop_olemenuW ); if ( !hOleMenu ) goto NEXTHOOK; @@ -1671,7 +1643,7 @@ HRESULT WINAPI OleSetMenuDescriptor( pOleMenuDescriptor = NULL; /* Add a menu descriptor windows property to the frame window */ - SetPropA( hwndFrame, "PROP_OLEMenuDescriptor", hOleMenu ); + SetPropW( hwndFrame, prop_olemenuW, hOleMenu ); /* Install thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC */ if ( !OLEMenu_InstallHooks( GetCurrentThreadId() ) ) @@ -1684,7 +1656,7 @@ HRESULT WINAPI OleSetMenuDescriptor( return E_FAIL; /* Remove the menu descriptor property from the frame window */ - RemovePropA( hwndFrame, "PROP_OLEMenuDescriptor" ); + RemovePropW( hwndFrame, prop_olemenuW ); } return S_OK; @@ -1870,9 +1842,9 @@ void WINAPI ReleaseStgMedium( */ static void OLEDD_Initialize(void) { - WNDCLASSA wndClass; + WNDCLASSW wndClass; - ZeroMemory (&wndClass, sizeof(WNDCLASSA)); + ZeroMemory (&wndClass, sizeof(WNDCLASSW)); wndClass.style = CS_GLOBALCLASS; wndClass.lpfnWndProc = OLEDD_DragTrackerWindowProc; wndClass.cbClsExtra = 0; @@ -1881,58 +1853,7 @@ static void OLEDD_Initialize(void) wndClass.hbrBackground = 0; wndClass.lpszClassName = OLEDD_DRAGTRACKERCLASS; - RegisterClassA (&wndClass); -} - -/*** - * OLEDD_FreeDropTarget() - * - * Frees the drag and drop data structure - */ -static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo, BOOL release_drop_target) -{ - list_remove(&dropTargetInfo->entry); - if (release_drop_target) IDropTarget_Release(dropTargetInfo->dropTarget); - HeapFree(GetProcessHeap(), 0, dropTargetInfo); -} - -/*** - * OLEDD_UnInitialize() - * - * Releases the OLE drag and drop data structures. - */ -void OLEDD_UnInitialize(void) -{ - /* - * Simply empty the list. - */ - while (!list_empty(&targetListHead)) - { - DropTargetNode* curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry); - OLEDD_FreeDropTarget(curNode, FALSE); - } -} - -/*** - * OLEDD_FindDropTarget() - * - * Finds information about the drop target. - */ -static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget) -{ - DropTargetNode* curNode; - - /* - * Iterate the list to find the HWND value. - */ - LIST_FOR_EACH_ENTRY(curNode, &targetListHead, DropTargetNode, entry) - if (hwndOfTarget==curNode->hwndTarget) - return curNode; - - /* - * If we get here, the item is not in the list - */ - return NULL; + RegisterClassW (&wndClass); } /*** @@ -1958,7 +1879,7 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( { LPCREATESTRUCTA createStruct = (LPCREATESTRUCTA)lParam; - SetWindowLongPtrA(hwnd, 0, (LONG_PTR)createStruct->lpCreateParams); + SetWindowLongPtrW(hwnd, 0, (LONG_PTR)createStruct->lpCreateParams); SetTimer(hwnd, DRAG_TIMER_ID, 50, NULL); break; @@ -1989,7 +1910,7 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( /* * This is a window proc after all. Let's call the default. */ - return DefWindowProcA (hwnd, uMsg, wParam, lParam); + return DefWindowProcW (hwnd, uMsg, wParam, lParam); } /*** @@ -2038,46 +1959,65 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) } else { - DropTargetNode* newDropTargetNode = 0; - /* * If we changed window, we have to notify our old target and check for * the new one. */ - if (trackerInfo->curDragTarget!=0) - { + if (trackerInfo->curDragTarget) IDropTarget_DragLeave(trackerInfo->curDragTarget); - } /* * Make sure we're hovering over a window. */ - if (hwndNewTarget!=0) + if (hwndNewTarget) { /* * Find-out if there is a drag target under the mouse */ - HWND nexttar = hwndNewTarget; + HWND next_target_wnd = hwndNewTarget; + IDropTarget *new_target; + DWORD pid; + trackerInfo->curTargetHWND = hwndNewTarget; do { - newDropTargetNode = OLEDD_FindDropTarget(nexttar); - } while (!newDropTargetNode && (nexttar = GetParent(nexttar)) != 0); - if(nexttar) hwndNewTarget = nexttar; + new_target = OLEDD_FindDropTarget(next_target_wnd); + } while (!new_target && (next_target_wnd = GetParent(next_target_wnd))); - trackerInfo->curDragTargetHWND = hwndNewTarget; - trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0; + if (next_target_wnd) hwndNewTarget = next_target_wnd; + + GetWindowThreadProcessId(hwndNewTarget, &pid); + if (pid != GetCurrentProcessId()) + { + FIXME("drop to another process window is unsupported\n"); + trackerInfo->curDragTargetHWND = 0; + trackerInfo->curTargetHWND = 0; + trackerInfo->curDragTarget = 0; + } + else + { + trackerInfo->curDragTargetHWND = hwndNewTarget; + trackerInfo->curDragTarget = new_target; + } /* * If there is, notify it that we just dragged-in */ - if (trackerInfo->curDragTarget!=0) + if (trackerInfo->curDragTarget) { - IDropTarget_DragEnter(trackerInfo->curDragTarget, - trackerInfo->dataObject, - trackerInfo->dwKeyState, - trackerInfo->curMousePos, - trackerInfo->pdwEffect); + hr = IDropTarget_DragEnter(trackerInfo->curDragTarget, + trackerInfo->dataObject, + trackerInfo->dwKeyState, + trackerInfo->curMousePos, + trackerInfo->pdwEffect); + + /* failed DragEnter() means invalid target */ + if (hr != S_OK) + { + trackerInfo->curDragTargetHWND = 0; + trackerInfo->curTargetHWND = 0; + trackerInfo->curDragTarget = 0; + } } } else @@ -2110,24 +2050,28 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) * when that's the case, we must display the standard drag and drop * cursors. */ - if (hr==DRAGDROP_S_USEDEFAULTCURSORS) + if (hr == DRAGDROP_S_USEDEFAULTCURSORS) { + HCURSOR hCur; + if (*trackerInfo->pdwEffect & DROPEFFECT_MOVE) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(1))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(1)); } else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(2))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(2)); } else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(3))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(3)); } else { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(0))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(0)); } + + SetCursor(hCur); } } @@ -2174,7 +2118,7 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) * If we end-up over a target, drop the object in the target or * inform the target that the operation was cancelled. */ - if (trackerInfo->curDragTarget!=0) + if (trackerInfo->curDragTarget) { switch (trackerInfo->returnValue) { @@ -2183,14 +2127,16 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) * the drop target that we just dropped the object in it. */ case DRAGDROP_S_DROP: - { - IDropTarget_Drop(trackerInfo->curDragTarget, - trackerInfo->dataObject, - trackerInfo->dwKeyState, - trackerInfo->curMousePos, - trackerInfo->pdwEffect); - break; - } + if (*trackerInfo->pdwEffect != DROPEFFECT_NONE) + IDropTarget_Drop(trackerInfo->curDragTarget, + trackerInfo->dataObject, + trackerInfo->dwKeyState, + trackerInfo->curMousePos, + trackerInfo->pdwEffect); + else + IDropTarget_DragLeave(trackerInfo->curDragTarget); + break; + /* * If the source told us that we should cancel, fool the drop * target by telling it that the mouse left it's window. @@ -2256,13 +2202,13 @@ static void OLEUTL_ReadRegistryDWORDValue( HKEY regKey, DWORD* pdwValue) { - char buffer[20]; + WCHAR buffer[20]; + DWORD cbData = sizeof(buffer); DWORD dwKeyType; - DWORD cbData = 20; LONG lres; - lres = RegQueryValueExA(regKey, - "", + lres = RegQueryValueExW(regKey, + emptyW, NULL, &dwKeyType, (LPBYTE)buffer, @@ -2278,7 +2224,7 @@ static void OLEUTL_ReadRegistryDWORDValue( case REG_EXPAND_SZ: case REG_MULTI_SZ: case REG_SZ: - *pdwValue = (DWORD)strtoul(buffer, NULL, 10); + *pdwValue = (DWORD)strtoulW(buffer, NULL, 10); break; } } diff --git a/reactos/dll/win32/ole32/stg_prop.c b/reactos/dll/win32/ole32/stg_prop.c index b3362bc21de..f887d10c0cf 100644 --- a/reactos/dll/win32/ole32/stg_prop.c +++ b/reactos/dll/win32/ole32/stg_prop.c @@ -1314,6 +1314,13 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This) hr = PropertyStorage_ReadFmtIdOffsetFromStream(This->stm, &fmtOffset); if (FAILED(hr)) goto end; + if (!IsEqualGUID(&fmtOffset.fmtid, &FMTID_DocSummaryInformation) && + !IsEqualGUID(&fmtOffset.fmtid, &FMTID_SummaryInformation)) + { + WARN("not reading unknown fmtid %s\n", debugstr_guid(&fmtOffset.fmtid)); + hr = S_FALSE; + goto end; + } if (fmtOffset.dwOffset > stat.cbSize.u.LowPart) { WARN("invalid offset %d (stream length is %d)\n", fmtOffset.dwOffset, diff --git a/reactos/dll/win32/ole32/storage32.c b/reactos/dll/win32/ole32/storage32.c index 434d8b24606..98df144976c 100644 --- a/reactos/dll/win32/ole32/storage32.c +++ b/reactos/dll/win32/ole32/storage32.c @@ -118,17 +118,61 @@ static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This, static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEntry); static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry); +typedef struct TransactedDirEntry +{ + /* If applicable, a reference to the original DirEntry in the transacted + * parent. If this is a newly-created entry, DIRENTRY_NULL. */ + DirRef transactedParentEntry; + + /* True if this entry is being used. */ + int inuse; + + /* True if data is up to date. */ + int read; + + /* True if this entry has been modified. */ + int dirty; + + /* True if this entry's stream has been modified. */ + int stream_dirty; + + /* True if this entry has been deleted in the transacted storage, but the + * delete has not yet been committed. */ + int deleted; + + /* If this entry's stream has been modified, a reference to where the stream + * is stored in the snapshot file. */ + DirRef stream_entry; + + /* This directory entry's data, including any changes that have been made. */ + DirEntry data; + + /* A reference to the parent of this node. This is only valid while we are + * committing changes. */ + DirRef parent; + + /* A reference to a newly-created entry in the transacted parent. This is + * always equal to transactedParentEntry except when committing changes. */ + DirRef newTransactedParentEntry; +} TransactedDirEntry; + /**************************************************************************** - * Transacted storage object that reads/writes a snapshot file. + * Transacted storage object. */ typedef struct TransactedSnapshotImpl { struct StorageBaseImpl base; /* - * Changes are temporarily saved to the snapshot. + * Modified streams are temporarily saved to the scratch file. */ - StorageBaseImpl *snapshot; + StorageBaseImpl *scratch; + + /* The directory structure is kept here, so that we can track how these + * entries relate to those in the parent storage. */ + TransactedDirEntry *entries; + ULONG entries_size; + ULONG firstFreeEntry; /* * Changes are committed to the transacted parent. @@ -1296,46 +1340,6 @@ static HRESULT StorageImpl_DestroyDirEntry( } -/*************************************************************************** - * - * Internal Method - * - * Destroy an entry, its attached data, and all entries reachable from it. - */ -static HRESULT DestroyReachableEntries( - StorageBaseImpl *base, - DirRef index) -{ - HRESULT hr = S_OK; - DirEntry data; - ULARGE_INTEGER zero; - - zero.QuadPart = 0; - - if (index != DIRENTRY_NULL) - { - hr = StorageBaseImpl_ReadDirEntry(base, index, &data); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.dirRootEntry); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.leftChild); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.rightChild); - - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_StreamSetSize(base, index, zero); - - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_DestroyDirEntry(base, index); - } - - return hr; -} - - /**************************************************************************** * * Internal Method @@ -2347,6 +2351,21 @@ static BlockChainStream **StorageImpl_GetCachedBlockChainStream(StorageImpl *Thi return &This->blockChainCache[free_index]; } +static void StorageImpl_DeleteCachedBlockChainStream(StorageImpl *This, DirRef index) +{ + int i; + + for (i=0; iblockChainCache[i] && This->blockChainCache[i]->ownerDirEntry == index) + { + BlockChainStream_Destroy(This->blockChainCache[i]); + This->blockChainCache[i] = NULL; + return; + } + } +} + static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) { @@ -2538,6 +2557,30 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, } } +static HRESULT StorageImpl_StreamLink(StorageBaseImpl *base, DirRef dst, + DirRef src) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry dst_data, src_data; + HRESULT hr; + + hr = StorageImpl_ReadDirEntry(This, dst, &dst_data); + + if (SUCCEEDED(hr)) + hr = StorageImpl_ReadDirEntry(This, src, &src_data); + + if (SUCCEEDED(hr)) + { + StorageImpl_DeleteCachedBlockChainStream(This, src); + dst_data.startingBlock = src_data.startingBlock; + dst_data.size = src_data.size; + + hr = StorageImpl_WriteDirEntry(This, dst, &dst_data); + } + + return hr; +} + /* * Virtual function table for the IStorage32Impl class. */ @@ -2573,7 +2616,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl = StorageImpl_DestroyDirEntry, StorageImpl_StreamReadAt, StorageImpl_StreamWriteAt, - StorageImpl_StreamSetSize + StorageImpl_StreamSetSize, + StorageImpl_StreamLink }; static HRESULT StorageImpl_Construct( @@ -3540,6 +3584,9 @@ HRESULT StorageImpl_ReadRawDirEntry(StorageImpl *This, ULONG index, BYTE *buffer buffer, &bytesRead); + if (bytesRead != RAW_DIRENTRY_SIZE) + return STG_E_READFAULT; + return hr; } @@ -3885,6 +3932,11 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( offset.u.LowPart += cbRead; } + else + { + resRead = STG_E_READFAULT; + break; + } } while (cbTotalRead.QuadPart < size.QuadPart); HeapFree(GetProcessHeap(),0,buffer); @@ -3983,6 +4035,11 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( offset.u.LowPart += cbRead; } + else + { + resRead = STG_E_READFAULT; + break; + } }while(cbTotalRead.QuadPart < size.QuadPart); HeapFree(GetProcessHeap(), 0, buffer); @@ -4011,40 +4068,384 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( return SmallBlockChainStream_Construct(This, NULL, streamEntryRef); } -static HRESULT CreateSnapshotFile(StorageBaseImpl* original, StorageBaseImpl **snapshot) +static HRESULT StorageBaseImpl_CopyStream( + StorageBaseImpl *dst, DirRef dst_entry, + StorageBaseImpl *src, DirRef src_entry) { HRESULT hr; - DirEntry parentData, snapshotData; + BYTE data[4096]; + DirEntry srcdata; + ULARGE_INTEGER bytes_copied; + ULONG bytestocopy, bytesread, byteswritten; - hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DELETEONRELEASE, - 0, (IStorage**)snapshot); + hr = StorageBaseImpl_ReadDirEntry(src, src_entry, &srcdata); if (SUCCEEDED(hr)) { - hr = StorageBaseImpl_ReadDirEntry(original, - original->storageDirEntry, &parentData); + hr = StorageBaseImpl_StreamSetSize(dst, dst_entry, srcdata.size); - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_ReadDirEntry((*snapshot), - (*snapshot)->storageDirEntry, &snapshotData); - - if (SUCCEEDED(hr)) + bytes_copied.QuadPart = 0; + while (bytes_copied.QuadPart < srcdata.size.QuadPart && SUCCEEDED(hr)) { - memcpy(snapshotData.name, parentData.name, sizeof(snapshotData.name)); - snapshotData.sizeOfNameString = parentData.sizeOfNameString; - snapshotData.stgType = parentData.stgType; - snapshotData.clsid = parentData.clsid; - snapshotData.ctime = parentData.ctime; - snapshotData.mtime = parentData.mtime; - hr = StorageBaseImpl_WriteDirEntry((*snapshot), - (*snapshot)->storageDirEntry, &snapshotData); + bytestocopy = min(4096, srcdata.size.QuadPart - bytes_copied.QuadPart); + + hr = StorageBaseImpl_StreamReadAt(src, src_entry, bytes_copied, bytestocopy, + data, &bytesread); + if (SUCCEEDED(hr) && bytesread != bytestocopy) hr = STG_E_READFAULT; + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_StreamWriteAt(dst, dst_entry, bytes_copied, bytestocopy, + data, &byteswritten); + if (SUCCEEDED(hr)) + { + if (byteswritten != bytestocopy) hr = STG_E_WRITEFAULT; + bytes_copied.QuadPart += byteswritten; + } + } + } + + return hr; +} + +static DirRef TransactedSnapshotImpl_FindFreeEntry(TransactedSnapshotImpl *This) +{ + DirRef result=This->firstFreeEntry; + + while (result < This->entries_size && This->entries[result].inuse) + result++; + + if (result == This->entries_size) + { + ULONG new_size = This->entries_size * 2; + TransactedDirEntry *new_entries; + + new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedDirEntry) * new_size); + if (!new_entries) return DIRENTRY_NULL; + + memcpy(new_entries, This->entries, sizeof(TransactedDirEntry) * This->entries_size); + HeapFree(GetProcessHeap(), 0, This->entries); + + This->entries = new_entries; + This->entries_size = new_size; + } + + This->entries[result].inuse = 1; + + This->firstFreeEntry = result+1; + + return result; +} + +static DirRef TransactedSnapshotImpl_CreateStubEntry( + TransactedSnapshotImpl *This, DirRef parentEntryRef) +{ + DirRef stubEntryRef; + TransactedDirEntry *entry; + + stubEntryRef = TransactedSnapshotImpl_FindFreeEntry(This); + + if (stubEntryRef != DIRENTRY_NULL) + { + entry = &This->entries[stubEntryRef]; + + entry->newTransactedParentEntry = entry->transactedParentEntry = parentEntryRef; + + entry->read = 0; + } + + return stubEntryRef; +} + +static HRESULT TransactedSnapshotImpl_EnsureReadEntry( + TransactedSnapshotImpl *This, DirRef entry) +{ + HRESULT hr=S_OK; + DirEntry data; + + if (!This->entries[entry].read) + { + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + This->entries[entry].transactedParentEntry, + &data); + + if (SUCCEEDED(hr) && data.leftChild != DIRENTRY_NULL) + { + data.leftChild = TransactedSnapshotImpl_CreateStubEntry(This, data.leftChild); + + if (data.leftChild == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr) && data.rightChild != DIRENTRY_NULL) + { + data.rightChild = TransactedSnapshotImpl_CreateStubEntry(This, data.rightChild); + + if (data.rightChild == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr) && data.dirRootEntry != DIRENTRY_NULL) + { + data.dirRootEntry = TransactedSnapshotImpl_CreateStubEntry(This, data.dirRootEntry); + + if (data.dirRootEntry == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) - hr = IStorage_CopyTo((IStorage*)original, 0, NULL, NULL, - (IStorage*)(*snapshot)); + { + memcpy(&This->entries[entry].data, &data, sizeof(DirEntry)); + This->entries[entry].read = 1; + } + } - if (FAILED(hr)) IStorage_Release((IStorage*)(*snapshot)); + return hr; +} + +static HRESULT TransactedSnapshotImpl_MakeStreamDirty( + TransactedSnapshotImpl *This, DirRef entry) +{ + HRESULT hr = S_OK; + + if (!This->entries[entry].stream_dirty) + { + DirEntry new_entrydata; + + memset(&new_entrydata, 0, sizeof(DirEntry)); + new_entrydata.name[0] = 'S'; + new_entrydata.sizeOfNameString = 1; + new_entrydata.stgType = STGTY_STREAM; + new_entrydata.startingBlock = BLOCK_END_OF_CHAIN; + new_entrydata.leftChild = DIRENTRY_NULL; + new_entrydata.rightChild = DIRENTRY_NULL; + new_entrydata.dirRootEntry = DIRENTRY_NULL; + + hr = StorageBaseImpl_CreateDirEntry(This->scratch, &new_entrydata, + &This->entries[entry].stream_entry); + + if (SUCCEEDED(hr) && This->entries[entry].transactedParentEntry != DIRENTRY_NULL) + { + hr = StorageBaseImpl_CopyStream( + This->scratch, This->entries[entry].stream_entry, + This->transactedParent, This->entries[entry].transactedParentEntry); + + if (FAILED(hr)) + StorageBaseImpl_DestroyDirEntry(This->scratch, This->entries[entry].stream_entry); + } + + if (SUCCEEDED(hr)) + This->entries[entry].stream_dirty = 1; + + if (This->entries[entry].transactedParentEntry != DIRENTRY_NULL) + { + /* Since this entry is modified, and we aren't using its stream data, we + * no longer care about the original entry. */ + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[entry].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[entry].transactedParentEntry = This->entries[entry].newTransactedParentEntry = DIRENTRY_NULL; + } + } + + return hr; +} + +/* Find the first entry in a depth-first traversal. */ +static DirRef TransactedSnapshotImpl_FindFirstChild( + TransactedSnapshotImpl* This, DirRef parent) +{ + DirRef cursor, prev; + TransactedDirEntry *entry; + + cursor = parent; + entry = &This->entries[cursor]; + while (entry->read) + { + if (entry->data.leftChild != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.leftChild; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else if (entry->data.rightChild != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.rightChild; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else if (entry->data.dirRootEntry != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.dirRootEntry; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else + break; + } + + return cursor; +} + +/* Find the next entry in a depth-first traversal. */ +static DirRef TransactedSnapshotImpl_FindNextChild( + TransactedSnapshotImpl* This, DirRef current) +{ + DirRef parent; + TransactedDirEntry *parent_entry; + + parent = This->entries[current].parent; + parent_entry = &This->entries[parent]; + + if (parent != DIRENTRY_NULL && parent_entry->data.dirRootEntry != current) + { + if (parent_entry->data.rightChild != current && parent_entry->data.rightChild != DIRENTRY_NULL) + { + This->entries[parent_entry->data.rightChild].parent = parent; + return TransactedSnapshotImpl_FindFirstChild(This, parent_entry->data.rightChild); + } + + if (parent_entry->data.dirRootEntry != DIRENTRY_NULL) + { + This->entries[parent_entry->data.dirRootEntry].parent = parent; + return TransactedSnapshotImpl_FindFirstChild(This, parent_entry->data.dirRootEntry); + } + } + + return parent; +} + +/* Return TRUE if we've made a copy of this entry for committing to the parent. */ +static inline BOOL TransactedSnapshotImpl_MadeCopy( + TransactedSnapshotImpl* This, DirRef entry) +{ + return entry != DIRENTRY_NULL && + This->entries[entry].newTransactedParentEntry != This->entries[entry].transactedParentEntry; +} + +/* Destroy the entries created by CopyTree. */ +static void TransactedSnapshotImpl_DestroyTemporaryCopy( + TransactedSnapshotImpl* This, DirRef stop) +{ + DirRef cursor; + TransactedDirEntry *entry; + ULARGE_INTEGER zero; + + zero.QuadPart = 0; + + if (!This->entries[This->base.storageDirEntry].read) + return; + + cursor = This->entries[This->base.storageDirEntry].data.dirRootEntry; + + if (cursor == DIRENTRY_NULL) + return; + + cursor = TransactedSnapshotImpl_FindFirstChild(This, cursor); + + while (cursor != DIRENTRY_NULL && cursor != stop) + { + if (TransactedSnapshotImpl_MadeCopy(This, cursor)) + { + entry = &This->entries[cursor]; + + if (entry->stream_dirty) + StorageBaseImpl_StreamSetSize(This->transactedParent, + entry->newTransactedParentEntry, zero); + + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->newTransactedParentEntry); + + entry->newTransactedParentEntry = entry->transactedParentEntry; + } + + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + } +} + +/* Make a copy of our edited tree that we can use in the parent. */ +static HRESULT TransactedSnapshotImpl_CopyTree(TransactedSnapshotImpl* This) +{ + DirRef cursor; + TransactedDirEntry *entry; + HRESULT hr = S_OK; + + cursor = This->base.storageDirEntry; + entry = &This->entries[cursor]; + entry->parent = DIRENTRY_NULL; + entry->newTransactedParentEntry = entry->transactedParentEntry; + + if (entry->data.dirRootEntry == DIRENTRY_NULL) + return S_OK; + + This->entries[entry->data.dirRootEntry].parent = DIRENTRY_NULL; + + cursor = TransactedSnapshotImpl_FindFirstChild(This, entry->data.dirRootEntry); + entry = &This->entries[cursor]; + + while (cursor != DIRENTRY_NULL) + { + /* Make a copy of this entry in the transacted parent. */ + if (!entry->read || + (!entry->dirty && !entry->stream_dirty && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.leftChild) && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.rightChild) && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.dirRootEntry))) + entry->newTransactedParentEntry = entry->transactedParentEntry; + else + { + DirEntry newData; + + memcpy(&newData, &entry->data, sizeof(DirEntry)); + + newData.size.QuadPart = 0; + newData.startingBlock = BLOCK_END_OF_CHAIN; + + if (newData.leftChild != DIRENTRY_NULL) + newData.leftChild = This->entries[newData.leftChild].newTransactedParentEntry; + + if (newData.rightChild != DIRENTRY_NULL) + newData.rightChild = This->entries[newData.rightChild].newTransactedParentEntry; + + if (newData.dirRootEntry != DIRENTRY_NULL) + newData.dirRootEntry = This->entries[newData.dirRootEntry].newTransactedParentEntry; + + hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &newData, + &entry->newTransactedParentEntry); + if (FAILED(hr)) + { + TransactedSnapshotImpl_DestroyTemporaryCopy(This, cursor); + return hr; + } + + if (entry->stream_dirty) + { + hr = StorageBaseImpl_CopyStream( + This->transactedParent, entry->newTransactedParentEntry, + This->scratch, entry->stream_entry); + } + else if (entry->data.size.QuadPart) + { + hr = StorageBaseImpl_StreamLink( + This->transactedParent, entry->newTransactedParentEntry, + entry->transactedParentEntry); + } + + if (FAILED(hr)) + { + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + TransactedSnapshotImpl_DestroyTemporaryCopy(This, cursor); + return hr; + } + } + + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + entry = &This->entries[cursor]; } return hr; @@ -4055,10 +4456,13 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit( DWORD grfCommitFlags) /* [in] */ { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + TransactedDirEntry *root_entry; + DirRef i, dir_root_ref; + DirEntry data; + ULARGE_INTEGER zero; HRESULT hr; - DirEntry data, tempStorageData, snapshotRootData; - DirRef tempStorageEntry, oldDirRoot; - StorageInternalImpl *tempStorage; + + zero.QuadPart = 0; TRACE("(%p,%x)\n", iface, grfCommitFlags); @@ -4072,75 +4476,71 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit( * needed in the rare situation where we have just enough free disk space to * overwrite the existing data. */ - /* Create an orphaned storage in the parent for the new directory structure. */ - memset(&data, 0, sizeof(data)); - data.name[0] = 'D'; - data.sizeOfNameString = 1; - data.stgType = STGTY_STORAGE; - data.leftChild = DIRENTRY_NULL; - data.rightChild = DIRENTRY_NULL; - data.dirRootEntry = DIRENTRY_NULL; - hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &data, &tempStorageEntry); + root_entry = &This->entries[This->base.storageDirEntry]; + if (!root_entry->read) + return S_OK; + + hr = TransactedSnapshotImpl_CopyTree(This); if (FAILED(hr)) return hr; - tempStorage = StorageInternalImpl_Construct(This->transactedParent, - STGM_READWRITE|STGM_SHARE_EXCLUSIVE, tempStorageEntry); - if (tempStorage) - { - hr = IStorage_CopyTo((IStorage*)This->snapshot, 0, NULL, NULL, - (IStorage*)tempStorage); - - list_init(&tempStorage->ParentListEntry); - - IStorage_Release((IStorage*) tempStorage); - } + if (root_entry->data.dirRootEntry == DIRENTRY_NULL) + dir_root_ref = DIRENTRY_NULL; else - hr = E_OUTOFMEMORY; - - if (FAILED(hr)) - { - DestroyReachableEntries(This->transactedParent, tempStorageEntry); - return hr; - } + dir_root_ref = This->entries[root_entry->data.dirRootEntry].newTransactedParentEntry; /* Update the storage to use the new data in one step. */ hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, - This->transactedParent->storageDirEntry, &data); + root_entry->transactedParentEntry, &data); if (SUCCEEDED(hr)) { - hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, - tempStorageEntry, &tempStorageData); - } - - if (SUCCEEDED(hr)) - { - hr = StorageBaseImpl_ReadDirEntry(This->snapshot, - This->snapshot->storageDirEntry, &snapshotRootData); - } - - if (SUCCEEDED(hr)) - { - oldDirRoot = data.dirRootEntry; - data.dirRootEntry = tempStorageData.dirRootEntry; - data.clsid = snapshotRootData.clsid; - data.ctime = snapshotRootData.ctime; - data.mtime = snapshotRootData.mtime; + data.dirRootEntry = dir_root_ref; + data.clsid = root_entry->data.clsid; + data.ctime = root_entry->data.ctime; + data.mtime = root_entry->data.mtime; hr = StorageBaseImpl_WriteDirEntry(This->transactedParent, - This->transactedParent->storageDirEntry, &data); + root_entry->transactedParentEntry, &data); } if (SUCCEEDED(hr)) { /* Destroy the old now-orphaned data. */ - DestroyReachableEntries(This->transactedParent, oldDirRoot); - StorageBaseImpl_DestroyDirEntry(This->transactedParent, tempStorageEntry); + for (i=0; ientries_size; i++) + { + TransactedDirEntry *entry = &This->entries[i]; + if (entry->inuse) + { + if (entry->deleted) + { + StorageBaseImpl_StreamSetSize(This->transactedParent, + entry->transactedParentEntry, zero); + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->transactedParentEntry); + memset(entry, 0, sizeof(TransactedDirEntry)); + This->firstFreeEntry = min(i, This->firstFreeEntry); + } + else if (entry->read && entry->transactedParentEntry != entry->newTransactedParentEntry) + { + if (entry->transactedParentEntry != DIRENTRY_NULL) + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->transactedParentEntry); + if (entry->stream_dirty) + { + StorageBaseImpl_StreamSetSize(This->scratch, entry->stream_entry, zero); + StorageBaseImpl_DestroyDirEntry(This->scratch, entry->stream_entry); + entry->stream_dirty = 0; + } + entry->dirty = 0; + entry->transactedParentEntry = entry->newTransactedParentEntry; + } + } + } } else { - DestroyReachableEntries(This->transactedParent, tempStorageEntry); + TransactedSnapshotImpl_DestroyTemporaryCopy(This, DIRENTRY_NULL); } return hr; @@ -4150,21 +4550,31 @@ static HRESULT WINAPI TransactedSnapshotImpl_Revert( IStorage* iface) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; - StorageBaseImpl *newSnapshot; - HRESULT hr; + ULARGE_INTEGER zero; + ULONG i; TRACE("(%p)\n", iface); - /* Create a new copy of the parent data. */ - hr = CreateSnapshotFile(This->transactedParent, &newSnapshot); - if (FAILED(hr)) return hr; - /* Destroy the open objects. */ StorageBaseImpl_DeleteAll(&This->base); - /* Replace our current snapshot. */ - IStorage_Release((IStorage*)This->snapshot); - This->snapshot = newSnapshot; + /* Clear out the scratch file. */ + zero.QuadPart = 0; + for (i=0; ientries_size; i++) + { + if (This->entries[i].stream_dirty) + { + StorageBaseImpl_StreamSetSize(This->scratch, This->entries[i].stream_entry, + zero); + + StorageBaseImpl_DestroyDirEntry(This->scratch, This->entries[i].stream_entry); + } + } + + memset(This->entries, 0, sizeof(TransactedDirEntry) * This->entries_size); + + This->firstFreeEntry = 0; + This->base.storageDirEntry = TransactedSnapshotImpl_CreateStubEntry(This, This->transactedParent->storageDirEntry); return S_OK; } @@ -4185,11 +4595,13 @@ static void TransactedSnapshotImpl_Destroy( StorageBaseImpl *iface) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; - TransactedSnapshotImpl_Invalidate(iface); + TransactedSnapshotImpl_Revert((IStorage*)iface); IStorage_Release((IStorage*)This->transactedParent); - IStorage_Release((IStorage*)This->snapshot); + IStorage_Release((IStorage*)This->scratch); + + HeapFree(GetProcessHeap(), 0, This->entries); HeapFree(GetProcessHeap(), 0, This); } @@ -4198,27 +4610,76 @@ static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base, const DirEntry *newData, DirRef *index) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + DirRef new_ref; + TransactedDirEntry *new_entry; - return StorageBaseImpl_CreateDirEntry(This->snapshot, - newData, index); + new_ref = TransactedSnapshotImpl_FindFreeEntry(This); + if (new_ref == DIRENTRY_NULL) + return E_OUTOFMEMORY; + + new_entry = &This->entries[new_ref]; + + new_entry->newTransactedParentEntry = new_entry->transactedParentEntry = DIRENTRY_NULL; + new_entry->read = 1; + new_entry->dirty = 1; + memcpy(&new_entry->data, newData, sizeof(DirEntry)); + + *index = new_ref; + + TRACE("%s l=%x r=%x d=%x <-- %x\n", debugstr_w(newData->name), newData->leftChild, newData->rightChild, newData->dirRootEntry, *index); + + return S_OK; } static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, DirRef index, const DirEntry *data) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_WriteDirEntry(This->snapshot, - index, data); + TRACE("%x %s l=%x r=%x d=%x\n", index, debugstr_w(data->name), data->leftChild, data->rightChild, data->dirRootEntry); + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + memcpy(&This->entries[index].data, data, sizeof(DirEntry)); + + if (index != This->base.storageDirEntry) + { + This->entries[index].dirty = 1; + + if (data->size.QuadPart == 0 && + This->entries[index].transactedParentEntry != DIRENTRY_NULL) + { + /* Since this entry is modified, and we aren't using its stream data, we + * no longer care about the original entry. */ + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; + } + } + + return S_OK; } static HRESULT TransactedSnapshotImpl_ReadDirEntry(StorageBaseImpl *base, DirRef index, DirEntry *data) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_ReadDirEntry(This->snapshot, - index, data); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + memcpy(data, &This->entries[index].data, sizeof(DirEntry)); + + TRACE("%x %s l=%x r=%x d=%x\n", index, debugstr_w(data->name), data->leftChild, data->rightChild, data->dirRootEntry); + + return S_OK; } static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, @@ -4226,8 +4687,21 @@ static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; - return StorageBaseImpl_DestroyDirEntry(This->snapshot, - index); + if (This->entries[index].transactedParentEntry == DIRENTRY_NULL || + This->entries[index].data.size.QuadPart != 0) + { + /* If we deleted this entry while it has stream data. We must have left the + * data because some other entry is using it, and we need to leave the + * original entry alone. */ + memset(&This->entries[index], 0, sizeof(TransactedDirEntry)); + This->firstFreeEntry = min(index, This->firstFreeEntry); + } + else + { + This->entries[index].deleted = 1; + } + + return S_OK; } static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, @@ -4235,26 +4709,122 @@ static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; - return StorageBaseImpl_StreamReadAt(This->snapshot, - index, offset, size, buffer, bytesRead); + if (This->entries[index].stream_dirty) + { + return StorageBaseImpl_StreamReadAt(This->scratch, + This->entries[index].stream_entry, offset, size, buffer, bytesRead); + } + else if (This->entries[index].transactedParentEntry == DIRENTRY_NULL) + { + /* This stream doesn't live in the parent, and we haven't allocated storage + * for it yet */ + *bytesRead = 0; + return S_OK; + } + else + { + return StorageBaseImpl_StreamReadAt(This->transactedParent, + This->entries[index].transactedParentEntry, offset, size, buffer, bytesRead); + } } static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_StreamWriteAt(This->snapshot, - index, offset, size, buffer, bytesWritten); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + hr = TransactedSnapshotImpl_MakeStreamDirty(This, index); + if (FAILED(hr)) return hr; + + hr = StorageBaseImpl_StreamWriteAt(This->scratch, + This->entries[index].stream_entry, offset, size, buffer, bytesWritten); + + if (SUCCEEDED(hr) && size != 0) + This->entries[index].data.size.QuadPart = max( + This->entries[index].data.size.QuadPart, + offset.QuadPart + size); + + return hr; } static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER newsize) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_StreamSetSize(This->snapshot, - index, newsize); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + if (This->entries[index].data.size.QuadPart == newsize.QuadPart) + return S_OK; + + if (newsize.QuadPart == 0) + { + /* Destroy any parent references or entries in the scratch file. */ + if (This->entries[index].stream_dirty) + { + ULARGE_INTEGER zero; + zero.QuadPart = 0; + StorageBaseImpl_StreamSetSize(This->scratch, + This->entries[index].stream_entry, zero); + StorageBaseImpl_DestroyDirEntry(This->scratch, + This->entries[index].stream_entry); + This->entries[index].stream_dirty = 0; + } + else if (This->entries[index].transactedParentEntry != DIRENTRY_NULL) + { + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; + } + } + else + { + hr = TransactedSnapshotImpl_MakeStreamDirty(This, index); + if (FAILED(hr)) return hr; + + hr = StorageBaseImpl_StreamSetSize(This->scratch, + This->entries[index].stream_entry, newsize); + } + + if (SUCCEEDED(hr)) + This->entries[index].data.size = newsize; + + return hr; +} + +static HRESULT TransactedSnapshotImpl_StreamLink(StorageBaseImpl *base, + DirRef dst, DirRef src) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; + TransactedDirEntry *dst_entry, *src_entry; + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, src); + if (FAILED(hr)) return hr; + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, dst); + if (FAILED(hr)) return hr; + + dst_entry = &This->entries[dst]; + src_entry = &This->entries[src]; + + dst_entry->stream_dirty = src_entry->stream_dirty; + dst_entry->stream_entry = src_entry->stream_entry; + dst_entry->transactedParentEntry = src_entry->transactedParentEntry; + dst_entry->newTransactedParentEntry = src_entry->newTransactedParentEntry; + dst_entry->data.size = src_entry->data.size; + + return S_OK; } static const IStorageVtbl TransactedSnapshotImpl_Vtbl = @@ -4289,7 +4859,8 @@ static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl = TransactedSnapshotImpl_DestroyDirEntry, TransactedSnapshotImpl_StreamReadAt, TransactedSnapshotImpl_StreamWriteAt, - TransactedSnapshotImpl_StreamSetSize + TransactedSnapshotImpl_StreamSetSize, + TransactedSnapshotImpl_StreamLink }; static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, @@ -4317,17 +4888,35 @@ static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, (*result)->base.filename = parentStorage->filename; - /* Create a new temporary storage to act as the snapshot */ - hr = CreateSnapshotFile(parentStorage, &(*result)->snapshot); + /* Create a new temporary storage to act as the scratch file. */ + hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, + 0, (IStorage**)&(*result)->scratch); if (SUCCEEDED(hr)) { - (*result)->base.storageDirEntry = (*result)->snapshot->storageDirEntry; + ULONG num_entries = 20; - /* parentStorage already has 1 reference, which we take over here. */ - (*result)->transactedParent = parentStorage; + (*result)->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedDirEntry) * num_entries); - parentStorage->transactedChild = (StorageBaseImpl*)*result; + (*result)->entries_size = num_entries; + + (*result)->firstFreeEntry = 0; + + if ((*result)->entries) + { + /* parentStorage already has 1 reference, which we take over here. */ + (*result)->transactedParent = parentStorage; + + parentStorage->transactedChild = (StorageBaseImpl*)*result; + + (*result)->base.storageDirEntry = TransactedSnapshotImpl_CreateStubEntry(*result, parentStorage->storageDirEntry); + } + else + { + IStorage_Release((IStorage*)(*result)->scratch); + + hr = E_OUTOFMEMORY; + } } if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, (*result)); @@ -4474,6 +5063,15 @@ static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base, index, newsize); } +static HRESULT StorageInternalImpl_StreamLink(StorageBaseImpl *base, + DirRef dst, DirRef src) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamLink(This->parentStorage, + dst, src); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit @@ -4833,7 +5431,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = StorageInternalImpl_DestroyDirEntry, StorageInternalImpl_StreamReadAt, StorageInternalImpl_StreamWriteAt, - StorageInternalImpl_StreamSetSize + StorageInternalImpl_StreamSetSize, + StorageInternalImpl_StreamLink }; /****************************************************************************** @@ -5026,38 +5625,134 @@ void StorageUtl_CopyDirEntryToSTATSTG( ** BlockChainStream implementation */ +/* Read and save the index of all blocks in this stream. */ +HRESULT BlockChainStream_UpdateIndexCache(BlockChainStream* This) +{ + ULONG next_sector, next_offset; + HRESULT hr; + struct BlockChainRun *last_run; + + if (This->indexCacheLen == 0) + { + last_run = NULL; + next_offset = 0; + next_sector = BlockChainStream_GetHeadOfChain(This); + } + else + { + last_run = &This->indexCache[This->indexCacheLen-1]; + next_offset = last_run->lastOffset+1; + hr = StorageImpl_GetNextBlockInChain(This->parentStorage, + last_run->firstSector + last_run->lastOffset - last_run->firstOffset, + &next_sector); + if (FAILED(hr)) return hr; + } + + while (next_sector != BLOCK_END_OF_CHAIN) + { + if (!last_run || next_sector != last_run->firstSector + next_offset - last_run->firstOffset) + { + /* Add the current block to the cache. */ + if (This->indexCacheSize == 0) + { + This->indexCache = HeapAlloc(GetProcessHeap(), 0, sizeof(struct BlockChainRun)*16); + if (!This->indexCache) return E_OUTOFMEMORY; + This->indexCacheSize = 16; + } + else if (This->indexCacheSize == This->indexCacheLen) + { + struct BlockChainRun *new_cache; + ULONG new_size; + + new_size = This->indexCacheSize * 2; + new_cache = HeapAlloc(GetProcessHeap(), 0, sizeof(struct BlockChainRun)*new_size); + if (!new_cache) return E_OUTOFMEMORY; + memcpy(new_cache, This->indexCache, sizeof(struct BlockChainRun)*This->indexCacheLen); + + HeapFree(GetProcessHeap(), 0, This->indexCache); + This->indexCache = new_cache; + This->indexCacheSize = new_size; + } + + This->indexCacheLen++; + last_run = &This->indexCache[This->indexCacheLen-1]; + last_run->firstSector = next_sector; + last_run->firstOffset = next_offset; + } + + last_run->lastOffset = next_offset; + + /* Find the next block. */ + next_offset++; + hr = StorageImpl_GetNextBlockInChain(This->parentStorage, next_sector, &next_sector); + if (FAILED(hr)) return hr; + } + + if (This->indexCacheLen) + { + This->tailIndex = last_run->firstSector + last_run->lastOffset - last_run->firstOffset; + This->numBlocks = last_run->lastOffset+1; + } + else + { + This->tailIndex = BLOCK_END_OF_CHAIN; + This->numBlocks = 0; + } + + return S_OK; +} + +/* Locate the nth block in this stream. */ +ULONG BlockChainStream_GetSectorOfOffset(BlockChainStream *This, ULONG offset) +{ + ULONG min_offset = 0, max_offset = This->numBlocks-1; + ULONG min_run = 0, max_run = This->indexCacheLen-1; + + if (offset >= This->numBlocks) + return BLOCK_END_OF_CHAIN; + + while (min_run < max_run) + { + ULONG run_to_check = min_run + (offset - min_offset) * (max_run - min_run) / (max_offset - min_offset); + if (offset < This->indexCache[run_to_check].firstOffset) + { + max_offset = This->indexCache[run_to_check].firstOffset-1; + max_run = run_to_check-1; + } + else if (offset > This->indexCache[run_to_check].lastOffset) + { + min_offset = This->indexCache[run_to_check].lastOffset+1; + min_run = run_to_check+1; + } + else + /* Block is in this run. */ + min_run = max_run = run_to_check; + } + + return This->indexCache[min_run].firstSector + offset - This->indexCache[min_run].firstOffset; +} + BlockChainStream* BlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, DirRef dirEntry) { BlockChainStream* newStream; - ULONG blockIndex; newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); newStream->parentStorage = parentStorage; newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; newStream->ownerDirEntry = dirEntry; - newStream->lastBlockNoInSequence = 0xFFFFFFFF; - newStream->tailIndex = BLOCK_END_OF_CHAIN; - newStream->numBlocks = 0; + newStream->indexCache = NULL; + newStream->indexCacheLen = 0; + newStream->indexCacheSize = 0; - blockIndex = BlockChainStream_GetHeadOfChain(newStream); - - while (blockIndex != BLOCK_END_OF_CHAIN) + if (FAILED(BlockChainStream_UpdateIndexCache(newStream))) { - newStream->numBlocks++; - newStream->tailIndex = blockIndex; - - if(FAILED(StorageImpl_GetNextBlockInChain( - parentStorage, - blockIndex, - &blockIndex))) - { - HeapFree(GetProcessHeap(), 0, newStream); - return NULL; - } + HeapFree(GetProcessHeap(), 0, newStream->indexCache); + HeapFree(GetProcessHeap(), 0, newStream); + return NULL; } return newStream; @@ -5065,6 +5760,8 @@ BlockChainStream* BlockChainStream_Construct( void BlockChainStream_Destroy(BlockChainStream* This) { + if (This) + HeapFree(GetProcessHeap(), 0, This->indexCache); HeapFree(GetProcessHeap(), 0, This); } @@ -5105,27 +5802,10 @@ static ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This) * * Returns the number of blocks that comprises this chain. * This is not the size of the stream as the last block may not be full! - * */ static ULONG BlockChainStream_GetCount(BlockChainStream* This) { - ULONG blockIndex; - ULONG count = 0; - - blockIndex = BlockChainStream_GetHeadOfChain(This); - - while (blockIndex != BLOCK_END_OF_CHAIN) - { - count++; - - if(FAILED(StorageImpl_GetNextBlockInChain( - This->parentStorage, - blockIndex, - &blockIndex))) - return 0; - } - - return count; + return This->numBlocks; } /****************************************************************************** @@ -5146,44 +5826,26 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, ULONG bytesToReadInBuffer; ULONG blockIndex; BYTE* bufferWalker; + ULARGE_INTEGER stream_size; TRACE("(%p)-> %i %p %i %p\n",This, offset.u.LowPart, buffer, size, bytesRead); /* * Find the first block in the stream that contains part of the buffer. */ - if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || - (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || - (blockNoInSequence < This->lastBlockNoInSequence) ) - { - blockIndex = BlockChainStream_GetHeadOfChain(This); - This->lastBlockNoInSequence = blockNoInSequence; - } + blockIndex = BlockChainStream_GetSectorOfOffset(This, blockNoInSequence); + + *bytesRead = 0; + + stream_size = BlockChainStream_GetSize(This); + if (stream_size.QuadPart > offset.QuadPart) + size = min(stream_size.QuadPart - offset.QuadPart, size); else - { - ULONG temp = blockNoInSequence; - - blockIndex = This->lastBlockNoInSequenceIndex; - blockNoInSequence -= This->lastBlockNoInSequence; - This->lastBlockNoInSequence = temp; - } - - while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) - { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex))) - return STG_E_DOCFILECORRUPT; - blockNoInSequence--; - } - - if ((blockNoInSequence > 0) && (blockIndex == BLOCK_END_OF_CHAIN)) - return STG_E_DOCFILECORRUPT; /* We failed to find the starting block */ - - This->lastBlockNoInSequenceIndex = blockIndex; + return S_OK; /* * Start reading the buffer. */ - *bytesRead = 0; bufferWalker = buffer; while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) @@ -5221,7 +5883,7 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, break; } - return (size == 0) ? S_OK : STG_E_READFAULT; + return S_OK; } /****************************************************************************** @@ -5245,31 +5907,7 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, /* * Find the first block in the stream that contains part of the buffer. */ - if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || - (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || - (blockNoInSequence < This->lastBlockNoInSequence) ) - { - blockIndex = BlockChainStream_GetHeadOfChain(This); - This->lastBlockNoInSequence = blockNoInSequence; - } - else - { - ULONG temp = blockNoInSequence; - - blockIndex = This->lastBlockNoInSequenceIndex; - blockNoInSequence -= This->lastBlockNoInSequence; - This->lastBlockNoInSequence = temp; - } - - while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) - { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &blockIndex))) - return STG_E_DOCFILECORRUPT; - blockNoInSequence--; - } - - This->lastBlockNoInSequenceIndex = blockIndex; + blockIndex = BlockChainStream_GetSectorOfOffset(This, blockNoInSequence); /* BlockChainStream_SetSize should have already been called to ensure we have * enough blocks in the chain to write into */ @@ -5330,15 +5968,8 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, static BOOL BlockChainStream_Shrink(BlockChainStream* This, ULARGE_INTEGER newSize) { - ULONG blockIndex, extraBlock; + ULONG blockIndex; ULONG numBlocks; - ULONG count = 1; - - /* - * Reset the last accessed block cache. - */ - This->lastBlockNoInSequence = 0xFFFFFFFF; - This->lastBlockNoInSequenceIndex = BLOCK_END_OF_CHAIN; /* * Figure out how many blocks are needed to contain the new size @@ -5348,43 +5979,62 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This, if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0) numBlocks++; - blockIndex = BlockChainStream_GetHeadOfChain(This); - - /* - * Go to the new end of chain - */ - while (count < numBlocks) + if (numBlocks) { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &blockIndex))) - return FALSE; - count++; + /* + * Go to the new end of chain + */ + blockIndex = BlockChainStream_GetSectorOfOffset(This, numBlocks-1); + + /* Mark the new end of chain */ + StorageImpl_SetNextBlockInChain( + This->parentStorage, + blockIndex, + BLOCK_END_OF_CHAIN); + + This->tailIndex = blockIndex; + } + else + { + if (This->headOfStreamPlaceHolder != 0) + { + *This->headOfStreamPlaceHolder = BLOCK_END_OF_CHAIN; + } + else + { + DirEntry chainEntry; + assert(This->ownerDirEntry != DIRENTRY_NULL); + + StorageImpl_ReadDirEntry( + This->parentStorage, + This->ownerDirEntry, + &chainEntry); + + chainEntry.startingBlock = BLOCK_END_OF_CHAIN; + + StorageImpl_WriteDirEntry( + This->parentStorage, + This->ownerDirEntry, + &chainEntry); + } + + This->tailIndex = BLOCK_END_OF_CHAIN; } - /* Get the next block before marking the new end */ - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &extraBlock))) - return FALSE; - - /* Mark the new end of chain */ - StorageImpl_SetNextBlockInChain( - This->parentStorage, - blockIndex, - BLOCK_END_OF_CHAIN); - - This->tailIndex = blockIndex; This->numBlocks = numBlocks; /* * Mark the extra blocks as free */ - while (extraBlock != BLOCK_END_OF_CHAIN) + while (This->indexCacheLen && This->indexCache[This->indexCacheLen-1].lastOffset >= numBlocks) { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock, - &blockIndex))) - return FALSE; - StorageImpl_FreeBigBlock(This->parentStorage, extraBlock); - extraBlock = blockIndex; + struct BlockChainRun *last_run = &This->indexCache[This->indexCacheLen-1]; + StorageImpl_FreeBigBlock(This->parentStorage, + last_run->firstSector + last_run->lastOffset - last_run->firstOffset); + if (last_run->lastOffset == last_run->firstOffset) + This->indexCacheLen--; + else + last_run->lastOffset--; } return TRUE; @@ -5498,6 +6148,9 @@ static BOOL BlockChainStream_Enlarge(BlockChainStream* This, This->numBlocks = newNumBlocks; } + if (FAILED(BlockChainStream_UpdateIndexCache(This))) + return FALSE; + return TRUE; } @@ -5663,6 +6316,9 @@ static HRESULT SmallBlockChainStream_GetNextBlockInChain( &buffer, &bytesRead); + if (SUCCEEDED(res) && bytesRead != sizeof(DWORD)) + res = STG_E_READFAULT; + if (SUCCEEDED(res)) { StorageUtl_ReadDWord((BYTE *)&buffer, 0, nextBlockInChain); @@ -5734,6 +6390,9 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( ULONG nextBlockIndex = BLOCK_END_OF_CHAIN; HRESULT res = S_OK; ULONG smallBlocksPerBigBlock; + DirEntry rootEntry; + ULONG blocksRequired; + ULARGE_INTEGER old_size, size_required; offsetOfBlockInDepot.u.HighPart = 0; @@ -5754,7 +6413,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( /* * If we run out of space for the small block depot, enlarge it */ - if (SUCCEEDED(res)) + if (SUCCEEDED(res) && bytesRead == sizeof(DWORD)) { StorageUtl_ReadDWord((BYTE *)&buffer, 0, &nextBlockIndex); @@ -5766,76 +6425,22 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( ULONG count = BlockChainStream_GetCount(This->parentStorage->smallBlockDepotChain); - ULONG sbdIndex = This->parentStorage->smallBlockDepotStart; - ULONG nextBlock, newsbdIndex; BYTE smallBlockDepot[MAX_BIG_BLOCK_SIZE]; + ULARGE_INTEGER newSize, offset; + ULONG bytesWritten; - nextBlock = sbdIndex; - while (nextBlock != BLOCK_END_OF_CHAIN) - { - sbdIndex = nextBlock; - StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock); - } - - newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); - if (sbdIndex != BLOCK_END_OF_CHAIN) - StorageImpl_SetNextBlockInChain( - This->parentStorage, - sbdIndex, - newsbdIndex); - - StorageImpl_SetNextBlockInChain( - This->parentStorage, - newsbdIndex, - BLOCK_END_OF_CHAIN); + newSize.QuadPart = (count + 1) * This->parentStorage->bigBlockSize; + BlockChainStream_Enlarge(This->parentStorage->smallBlockDepotChain, newSize); /* * Initialize all the small blocks to free */ memset(smallBlockDepot, BLOCK_UNUSED, This->parentStorage->bigBlockSize); - StorageImpl_WriteBigBlock(This->parentStorage, newsbdIndex, smallBlockDepot); + offset.QuadPart = count * This->parentStorage->bigBlockSize; + BlockChainStream_WriteAt(This->parentStorage->smallBlockDepotChain, + offset, This->parentStorage->bigBlockSize, smallBlockDepot, &bytesWritten); - if (count == 0) - { - /* - * We have just created the small block depot. - */ - DirEntry rootEntry; - ULONG sbStartIndex; - - /* - * Save it in the header - */ - This->parentStorage->smallBlockDepotStart = newsbdIndex; - StorageImpl_SaveFileHeader(This->parentStorage); - - /* - * And allocate the first big block that will contain small blocks - */ - sbStartIndex = - StorageImpl_GetNextFreeBigBlock(This->parentStorage); - - StorageImpl_SetNextBlockInChain( - This->parentStorage, - sbStartIndex, - BLOCK_END_OF_CHAIN); - - StorageImpl_ReadDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - - rootEntry.startingBlock = sbStartIndex; - rootEntry.size.u.HighPart = 0; - rootEntry.size.u.LowPart = This->parentStorage->bigBlockSize; - - StorageImpl_WriteDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - } - else - StorageImpl_SaveFileHeader(This->parentStorage); + StorageImpl_SaveFileHeader(This->parentStorage); } } @@ -5847,30 +6452,29 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( /* * Verify if we have to allocate big blocks to contain small blocks */ - if (blockIndex % smallBlocksPerBigBlock == 0) + blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; + + size_required.QuadPart = blocksRequired * This->parentStorage->bigBlockSize; + + old_size = BlockChainStream_GetSize(This->parentStorage->smallBlockRootChain); + + if (size_required.QuadPart > old_size.QuadPart) { - DirEntry rootEntry; - ULONG blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; + BlockChainStream_SetSize( + This->parentStorage->smallBlockRootChain, + size_required); StorageImpl_ReadDirEntry( This->parentStorage, This->parentStorage->base.storageDirEntry, &rootEntry); - if (rootEntry.size.u.LowPart < - (blocksRequired * This->parentStorage->bigBlockSize)) - { - rootEntry.size.u.LowPart += This->parentStorage->bigBlockSize; + rootEntry.size = size_required; - BlockChainStream_SetSize( - This->parentStorage->smallBlockRootChain, - rootEntry.size); - - StorageImpl_WriteDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - } + StorageImpl_WriteDirEntry( + This->parentStorage, + This->parentStorage->base.storageDirEntry, + &rootEntry); } return blockIndex; @@ -5900,12 +6504,21 @@ HRESULT SmallBlockChainStream_ReadAt( ULONG blockIndex; ULONG bytesReadFromBigBlockFile; BYTE* bufferWalker; + ULARGE_INTEGER stream_size; /* * This should never happen on a small block file. */ assert(offset.u.HighPart==0); + *bytesRead = 0; + + stream_size = SmallBlockChainStream_GetSize(This); + if (stream_size.QuadPart > offset.QuadPart) + size = min(stream_size.QuadPart - offset.QuadPart, size); + else + return S_OK; + /* * Find the first block in the stream that contains part of the buffer. */ @@ -5922,7 +6535,6 @@ HRESULT SmallBlockChainStream_ReadAt( /* * Start reading the buffer. */ - *bytesRead = 0; bufferWalker = buffer; while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) @@ -5956,6 +6568,9 @@ HRESULT SmallBlockChainStream_ReadAt( if (FAILED(rc)) return rc; + if (!bytesReadFromBigBlockFile) + return STG_E_DOCFILECORRUPT; + /* * Step to the next big block. */ @@ -5969,7 +6584,7 @@ HRESULT SmallBlockChainStream_ReadAt( offsetInBlock = (offsetInBlock + bytesReadFromBigBlockFile) % This->parentStorage->smallBlockSize; } - return (size == 0) ? S_OK : STG_E_READFAULT; + return S_OK; } /****************************************************************************** diff --git a/reactos/dll/win32/ole32/storage32.h b/reactos/dll/win32/ole32/storage32.h index 36a7d679af6..19f3f2d682c 100644 --- a/reactos/dll/win32/ole32/storage32.h +++ b/reactos/dll/win32/ole32/storage32.h @@ -263,6 +263,7 @@ struct StorageBaseImplVtbl { HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); + HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef); }; static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) @@ -320,6 +321,16 @@ static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, return This->baseVtbl->StreamSetSize(This, index, newsize); } +/* Make dst point to the same stream that src points to. Other stream operations + * will not work properly for entries that point to the same stream, so this + * must be a very temporary state, and only one entry pointing to a given stream + * may be reachable at any given time. */ +static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This, + DirRef dst, DirRef src) +{ + return This->baseVtbl->StreamLink(This, dst, src); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ @@ -513,13 +524,22 @@ void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destinat * The BlockChainStream class is a utility class that is used to create an * abstraction of the big block chains in the storage file. */ +struct BlockChainRun +{ + /* This represents a range of blocks that happen reside in consecutive sectors. */ + ULONG firstSector; + ULONG firstOffset; + ULONG lastOffset; +}; + struct BlockChainStream { StorageImpl* parentStorage; ULONG* headOfStreamPlaceHolder; DirRef ownerDirEntry; - ULONG lastBlockNoInSequence; - ULONG lastBlockNoInSequenceIndex; + struct BlockChainRun* indexCache; + ULONG indexCacheLen; + ULONG indexCacheSize; ULONG tailIndex; ULONG numBlocks; }; diff --git a/reactos/dll/win32/ole32/usrmarshal.c b/reactos/dll/win32/ole32/usrmarshal.c index ed316201f69..2d238e6ccc3 100644 --- a/reactos/dll/win32/ole32/usrmarshal.c +++ b/reactos/dll/win32/ole32/usrmarshal.c @@ -2761,7 +2761,8 @@ void CALLBACK IAdviseSink_OnDataChange_Proxy( FORMATETC *pFormatetc, STGMEDIUM *pStgmed) { - FIXME(":stub\n"); + TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed); + IAdviseSink_RemoteOnDataChange_Proxy(This, pFormatetc, pStgmed); } HRESULT __RPC_STUB IAdviseSink_OnDataChange_Stub( @@ -2769,8 +2770,9 @@ HRESULT __RPC_STUB IAdviseSink_OnDataChange_Stub( FORMATETC *pFormatetc, ASYNC_STGMEDIUM *pStgmed) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed); + IAdviseSink_OnDataChange(This, pFormatetc, pStgmed); + return S_OK; } void CALLBACK IAdviseSink_OnViewChange_Proxy( @@ -2778,7 +2780,8 @@ void CALLBACK IAdviseSink_OnViewChange_Proxy( DWORD dwAspect, LONG lindex) { - FIXME(":stub\n"); + TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex); + IAdviseSink_RemoteOnViewChange_Proxy(This, dwAspect, lindex); } HRESULT __RPC_STUB IAdviseSink_OnViewChange_Stub( @@ -2786,64 +2789,73 @@ HRESULT __RPC_STUB IAdviseSink_OnViewChange_Stub( DWORD dwAspect, LONG lindex) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex); + IAdviseSink_OnViewChange(This, dwAspect, lindex); + return S_OK; } void CALLBACK IAdviseSink_OnRename_Proxy( IAdviseSink* This, IMoniker *pmk) { - FIXME(":stub\n"); + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink_RemoteOnRename_Proxy(This, pmk); } HRESULT __RPC_STUB IAdviseSink_OnRename_Stub( IAdviseSink* This, IMoniker *pmk) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink_OnRename(This, pmk); + return S_OK; } void CALLBACK IAdviseSink_OnSave_Proxy( IAdviseSink* This) { - FIXME(":stub\n"); + TRACE("(%p)\n", This); + IAdviseSink_RemoteOnSave_Proxy(This); } HRESULT __RPC_STUB IAdviseSink_OnSave_Stub( IAdviseSink* This) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)\n", This); + IAdviseSink_OnSave(This); + return S_OK; } void CALLBACK IAdviseSink_OnClose_Proxy( IAdviseSink* This) { - FIXME(":stub\n"); + TRACE("(%p)\n", This); + IAdviseSink_RemoteOnClose_Proxy(This); } HRESULT __RPC_STUB IAdviseSink_OnClose_Stub( IAdviseSink* This) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)\n", This); + IAdviseSink_OnClose(This); + return S_OK; } void CALLBACK IAdviseSink2_OnLinkSrcChange_Proxy( IAdviseSink2* This, IMoniker *pmk) { - FIXME(":stub\n"); + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink2_RemoteOnLinkSrcChange_Proxy(This, pmk); } HRESULT __RPC_STUB IAdviseSink2_OnLinkSrcChange_Stub( IAdviseSink2* This, IMoniker *pmk) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink2_OnLinkSrcChange(This, pmk); + return S_OK; } HRESULT CALLBACK IDataObject_GetData_Proxy( From 24dd4301ad8133e97f0ffaf6ec860cecad435134 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 29 May 2010 12:29:26 +0000 Subject: [PATCH 081/292] [KERNEL32] WaitNamedPipeW: Free Unicode buffer when leaving the function svn path=/trunk/; revision=47406 --- reactos/dll/win32/kernel32/file/npipe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/dll/win32/kernel32/file/npipe.c b/reactos/dll/win32/kernel32/file/npipe.c index d62527e12a5..55aeed952fc 100644 --- a/reactos/dll/win32/kernel32/file/npipe.c +++ b/reactos/dll/win32/kernel32/file/npipe.c @@ -496,6 +496,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName, if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); + RtlFreeUnicodeString(&NamedPipeName); return FALSE; } @@ -538,9 +539,11 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName, if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); + RtlFreeUnicodeString(&NamedPipeName); return FALSE; } + RtlFreeUnicodeString(&NamedPipeName); return TRUE; } #endif From c8e90e9d05d69c8f86e2e26e84c697d383510234 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 29 May 2010 12:31:48 +0000 Subject: [PATCH 082/292] [KERNEL32] ReplaceFileW: - Initialize Unicode string structure, so that only allocated buffers are freed when leaving the function - Fixes several heap warnings in kernel32:file test svn path=/trunk/; revision=47407 --- reactos/dll/win32/kernel32/file/file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/kernel32/file/file.c b/reactos/dll/win32/kernel32/file/file.c index 66046621821..cdbafd08839 100644 --- a/reactos/dll/win32/kernel32/file/file.c +++ b/reactos/dll/win32/kernel32/file/file.c @@ -1906,7 +1906,8 @@ ReplaceFileW( ) { HANDLE hReplaced = NULL, hReplacement = NULL; - UNICODE_STRING NtReplacedName, NtReplacementName; + UNICODE_STRING NtReplacedName = { 0, 0, NULL }; + UNICODE_STRING NtReplacementName = { 0, 0, NULL }; DWORD Error = ERROR_SUCCESS; NTSTATUS Status; BOOL Ret = FALSE; @@ -2029,8 +2030,10 @@ Cleanup: if (hReplacement) NtClose(hReplacement); if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); - RtlFreeUnicodeString(&NtReplacementName); - RtlFreeUnicodeString(&NtReplacedName); + if (NtReplacementName.Buffer) + RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer); + if (NtReplacedName.Buffer) + RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer); /* If there was an error, set the error code */ if(!Ret) From f435dab493c9ca02880e2d8eabd19ca5f016087d Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Sat, 29 May 2010 12:47:30 +0000 Subject: [PATCH 083/292] Update: DejaVu Fonts 2.30 -> 2.31 Liberation Fonts 1.04 -> 1.05.2 svn path=/trunk/; revision=47408 --- .../applications/rapps/rapps/mirandaim.txt | 6 +++--- reactos/media/fonts/DejaVuSans-Bold.ttf | Bin 573136 -> 584396 bytes .../media/fonts/DejaVuSans-BoldOblique.ttf | Bin 524056 -> 524624 bytes reactos/media/fonts/DejaVuSans-Oblique.ttf | Bin 523804 -> 524396 bytes reactos/media/fonts/DejaVuSans.ttf | Bin 622280 -> 633604 bytes reactos/media/fonts/DejaVuSansMono-Bold.ttf | Bin 301928 -> 302868 bytes .../fonts/DejaVuSansMono-BoldOblique.ttf | Bin 223408 -> 224160 bytes .../media/fonts/DejaVuSansMono-Oblique.ttf | Bin 229284 -> 230244 bytes reactos/media/fonts/DejaVuSansMono.ttf | Bin 321524 -> 322524 bytes reactos/media/fonts/DejaVuSerif-Bold.ttf | Bin 306532 -> 307596 bytes .../media/fonts/DejaVuSerif-BoldItalic.ttf | Bin 294244 -> 295360 bytes reactos/media/fonts/DejaVuSerif-Italic.ttf | Bin 301828 -> 303004 bytes reactos/media/fonts/DejaVuSerif.ttf | Bin 328908 -> 330052 bytes reactos/media/fonts/LiberationMono-Bold.ttf | Bin 104980 -> 105116 bytes .../media/fonts/LiberationMono-BoldItalic.ttf | Bin 117192 -> 117800 bytes reactos/media/fonts/LiberationMono-Italic.ttf | Bin 123228 -> 123804 bytes .../media/fonts/LiberationMono-Regular.ttf | Bin 107920 -> 107696 bytes reactos/media/fonts/LiberationSans-Bold.ttf | Bin 133000 -> 139008 bytes .../media/fonts/LiberationSans-BoldItalic.ttf | Bin 128828 -> 134548 bytes reactos/media/fonts/LiberationSans-Italic.ttf | Bin 155304 -> 161020 bytes .../media/fonts/LiberationSans-Regular.ttf | Bin 133088 -> 139280 bytes reactos/media/fonts/LiberationSerif-Bold.ttf | Bin 141132 -> 146184 bytes .../fonts/LiberationSerif-BoldItalic.ttf | Bin 144184 -> 149804 bytes .../media/fonts/LiberationSerif-Italic.ttf | Bin 138328 -> 143432 bytes .../media/fonts/LiberationSerif-Regular.ttf | Bin 146036 -> 151480 bytes 25 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/base/applications/rapps/rapps/mirandaim.txt b/reactos/base/applications/rapps/rapps/mirandaim.txt index aadc724e326..5845bf7eb97 100644 --- a/reactos/base/applications/rapps/rapps/mirandaim.txt +++ b/reactos/base/applications/rapps/rapps/mirandaim.txt @@ -2,13 +2,13 @@ [Section] Name = Miranda IM -Version = 0.8.22 +Version = 0.8.24 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. -Size = 1.6MB +Size = 1.7MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.22-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.24-unicode.exe CDPath = none [Section.0407] diff --git a/reactos/media/fonts/DejaVuSans-Bold.ttf b/reactos/media/fonts/DejaVuSans-Bold.ttf index ec1a2ebaf247e5d2a547a5ec406f6831dabe26bd..7b29accc1319396989cd62666c21943e311b489e 100644 GIT binary patch delta 74385 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 Mn6%DobwA?ze{)@r&Hw-a delta 63715 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 Xd`I{GUV2vZDN>Jq-rxSKwT%6LU9V7J delta 24255 zcmbt+349bq+J04cSN9AgFw?mR1PBm0BmycRA}YEO5II5;5-uS?K#l;BGs-at5m69X z25AJu$VNbnd|AThu*f3oA|SHBx_~Ty)*q{gh=@^xqGIwrRXsgdCX?V_e@|C+)qB5h zRaZ}#Ik_ZxeN{^rp@fhaTolr!PoJ!TnV1j!-^-y&MF`p{wMPk+($i;|J1|> zpY8Kc+&c(6nKx;|*u2Wt?Y9!O?`+I>pM-%%KP8^QeJSo!CQX}N`22qoU%~xJLi(3Z zoiKCyjkkVSPSiCE2)Vr|f5!N+-QN9Y9#Q`a^8RJh#*Qc~NJvueAevT&k>u%Pr%i}I z-ZmBY5ODvFf*G@BUu_P7+9MFKyK}+J2?YzjDp^OgpP`UV1rLuOIW)m@RJ8m0C0T9x zFgk_iJE{qF5@$mqIis9W=tn!FiR^6TY=VBG^InYiboNL8G3R3#AK)B-{y^tI^atsK z3Dwi}5k%HU>Pyit(u>f4R^I`wjQ|x;2(32IQs=$po#drbTvW{TR@;dLGiZ+IVOjTX9q4oepO#NpQwH6G#$F zZAw}=n>$;OWM?<1TGi-1DXuZ5T3{-Pv~#v}CX`P$7HIZ6KDbnpy7pc3{ zOL|!9Ck>Laq!CiCG*QZzW=e(9BB@AvL0T=XlQv0Pr0vp9X}7djIv^dAj+Lj!x2Eob z_$Ka|2`$~PCLDUKAxR$c3 zxZ?PpJnE=)TqhZhUmR5=OJA+8Cc}9Qklumr-A(4ZiW}S@H0m6QqK`}ar1zyG(sAjO zbWXY;U6QU!-%B^7Dp`>m$PPJPPLf;8?d48#SGlL$TkazdkTc|A@@P3vo+1~>bL9o{ z5_!42N?t2(kc;K5a;dya-Xrgq56Va7lkyq)y!@GbS-vJ$%D*T?QI#k~cPUMj7D|e8 zyV6DJuJlqKR{AM}lq_Y0lB-Nq@|BrNp|VIRQeIG2E9;a^$`)n2vQycu>{SjZhm>Q= z$I4mdQ{|#^MX6AJRBkef*;peM%bK!e)|RERyI2qQ083;2Svt#Rqu4k$iA`s-+0$$> zTgFy0*BZ8-ZDu8G2Pgr`S1mfn8!(+4t-Qt5OxUf$C7>)g-mG+FtFX zc2#?-z12SI05wA$rjAzg)G2C#I#*qwE>V}OtJJmX2DMn-s+Ov|)II8c^`LrGJ*l2i z&#RxQm(^=(rTPoD6;+FJX}Z=#YoVoRw`*Or?piPHVXdDwNXybjXt~-%Enl0d6>5vL zBJBljwYE;%q;1i*Ydf{w+FtE|c1Sy>eXO0;KGiO2SF{T4NA0Ffve|5nY_Ybcwq#pd zTdM6YTMydaVHp({6Hpw>KHrw{JZLw{c&9&0D#7iy}iAYy{o;ay|=xOeSkf~KFmJa zo@bw8FR;(GFR(AMFSoC$Dj!Y1+=&%GrvhI(InVqIWpocJ8O0oqu;8qz^d{I}g)8I6riLMAMwdohN8t=Rcii z=%e~0dLKGi@23x-L-axVAeya@(jTWe`fPm;9j-6Z7txV?nMib0`Q_VQrP1$Wi=nYL z5+$`#(#lu2tCr&WL=TA0h#nR_Iyx^pKYC_#Vf3QtW$u#OuWM5r1&+Cn1@7XGUECEN z+m%;$yt6@hukLnQ{@6VQlopil>p>;gFk0%^<|w6m96KF5>3&CDaO#mtwe^ z$x^&ts2562^!fS%DUtguHPaXCOQj^?d9r)befNnSxVzYaOYiFtBWLMZ2O&zD8e1h`wImM3}x=-$EMbCHi*Kn2_?yjQ`r@HTui${%6CpXuHQOsxPIl-aQ#J4G;oj3ZI-BlHwX8WWCMPF=3bNg zR&)iQVa;(>8&?-Egc?jn zQ5-SA{cj-&c_J-Hl%A;%!Q(zd&(?EroG8+V=|lD5`UrQ6aqZ#?rB-4={!D(LKl1|B zpVFUpj~Lfxa^@wXxOl_B>(hul{M+)D)KH+_fozx(XCdF|3575_Cp zfY|e1D%u8wsA)t|n?U6f3~FRa`P}jMQ8puWUg|>k?!4RR%JOr0BPo5dyz9gzH0|^M zeD;UWdVY4-`>#)Ve9G`CIa7vCd2C9TDYsAFGkN#qos)M=E}6V#^32K8CRI1<8BgLW z<3X7B zBrp&C!DycX7NVa`NGI6J;TVawHEOmQiF z(UxGC{Ho$`&)XOv0ezg`e{BwQM;{^mwFl4(eHioW116j>>et@DLl{p*`v(A#!OADU z!nj{ykP`-1K|iT#jGLZllYutq_a~(KXW%#V2NC)&RLj4z(a$9GbPoV;98T<&r|$!x z&{>MMH^3E?q3t6;od1g!XYbPpz4INk8NgKZ|B9ELUce0W6F(vJ6RfmPKE#IG5basu zzvw?wetG6$DpRLazH4@?(TSNXjn1jAuAYw%V46G}C?HbOIg1ukLS8H*_C89Zl2S6{iytGv#-rdMnQEHhPX8nUvKQkz#9j7DQY-}Zul`(Js&UKi5`r?sbb9%bPckL=HBD$+ z0irA+5BU_@2ApfzA#^m|OZ^O1@>7Bundj8y3(oyd1E@^>q6403*<9G~2!EOU|rgL?bbVdPHlLryQ ze`)!ScF5CR*ZL+7W-F?v2hJ+n)L6_8E?;x)Jqr6XDqukQ9$X>3#rK`*u<}9Q=SY~@ zTFFg|y50f(?$J2Vo)Q!$D>8vH^t^Npwb=7O?<{RDM)hW;nEmwYiD~S#@%Hk;Qj0c3A7b#>6t(~C+5=ou!K~;M4+=x_2+^WN13FVj6ei|9P;44z$o zq%nHSOg3K7;mH9y>=0~}ScUCHxuqKy|3qJd??okO(mg3}&f7um$bQi?=rGk-;wn=XTPl`E&#G+ptJ=cRR)5Je{TOYhL;AW; z>3a%IH?lvcgK4(0l{e|ekDnu?=|IcyT0YX(i-&mCp|@doYSENKj=lAo61jh?fm@6b=3 zBh8~Zo{~AzyE1Nbp9&Db5UKTCfNJ*&IPeq~;DLZADAX>WFU3%BZCW7BLgQE{CBVY= z3#Anx+PzSkOzA>T3zzg~PIPjyG%qnn-6L#E!6v*yh|&Cig$_N+}tI# z;@e4!%hF49h_Umsgy*C2>1B}S8OOhp5)$*s=T+}wlf|}g?FBZzQI9vOFipoB@mEm9 z*~Y3XJg>&_E21VkeJ!=5bgVJxDnyK}o>uh%MEqchPeeQ3jVaBK53WFL|h~|L`o_(XLLKC)e$Dl6t)~pbMTO&*G!~ zcyo+AYtr+vQ2M|*$QQDtjV7Nfa58`~h{&Xoi6`=&zgSb%~4IcbBS50F)3 z&Sf!%B_hxI1(0Wh6$j2KWu{k=XyCEX5lrKvso?~LCzgx2M`nu9_oc{hBn;7bbOPss zLmoV*y8O8fihw168)pfyEDxLuO<6b^i$ByUF2}_SuRaklm6{PSmGWHH^fuU_$TTpB z=RY!$m0Q#LnzVt&!~3xE0%*U-BUV(x(S#JMi&tcw0wD-A{t(tfFkb}`c&s9Hnaa(4h7VJ)#Ug*T z8f?*;%IiUEKL1Ti>&+ApiTWGvk6s`T@*jRP2@PK$Q*AsZja4Jz6$bKF6-cgq;;j`P zRTY>^5rZ{OFoAPck-uBKmk3?(<42?#uf)Ul) zA{fXc&VN2@%%_tmj6fp(g!I!`fYW1PDBI4)q z?*EazH9e?pHw*8zrKnC`mv7e-he8p0SXZOMEpII^!_frS2;bK0l0#EnR(`?}2W*w~ zG|V5RaPoo;6tw2~KOAwe$5u^5R$%h@i>+?C=J~%)@2n_A3V(Qm>oCT8|AVE%h+9!` zD?GIoBF_JH7fEf*;dsp)izQoURN<_de=EGT3$*fIZ^2MrA0C%~@3+Dk$(Ya_*M}!e z)r-goJuY$ly7d&)ZKS{OBGI~nJ*pp*#bXJ!iq^Uhmqv@nr1hmny#M*bQAaeaaQ_~K z;d!zCBUx*DVoBI??#5 z()Xc6V2CZH0fiJsp!q6iRe7DX{QMWDKzv2Q2`A<|66$vcgXZFy+{I0rIBgF8;bLPfHeWe)F{GQqZBMSXa^0D7wnvA zFlb#7!XGTys+0ODu$+pNUM^pJ{$u5?zD)i{t3P^mDdIeqo`7`uKK~69UNZ&e#$;{N zk!mG8O=uCr$$+$Y-~Vb0buh7+!+@Pq7#)r#RGt;t8npcVKiEQlNNW)LcEzxv3}a0A zA`X=6+y8?t_7_E>U@HzzQ{ekwXbPr0ROJVp`VDkFTf007wt5*J$49;JeV@OUuvyfrrdc3xkM5XhS`=46U2TDrkKE6D~}_g8jsiXieqy zqcu}44m5$!|H$DBF4V}hmV&x@@cwUk8yvn{_CyqB-3qP8y?4vz=l@7y4PF)DX@hIV zdKQGIwVbsg3@;;m~mIBMWNVK5}>fkXy|FslYg6m+4@R_lHQ?g`*bI3H3r`Z4b zZ#_2_t1jvnX48lWJhean!=Cr+G}4M(ed>lsp|10PoeHfm->PEo`+)iW|9gZ4ycg7I zq!kU*$iS81{rf-vz#+H@#mhuJ1^ZJ~Q-S~Eo8V`KSAPB0zrU&@DF}9;emo(c|5={Y zkJ-PBe5ay%M$ES&#QDEYrqE>+DGH$*P-I@5{{kPs7PG0qXC;40snbYnOT8st>+}EG zR=}+&{yj2WX3E$TGRwKg^W8CaO7{HspKLMZ|CaD(cl`Te@ox&r zj;ej?5_TFJ*Glg=TKqd?|M+t6IKJ&0G>&^AXGO@kB|n(HE!T%N`~tr8bF+I`LBWdK z>JR`1VO9{mrQms=;-zrFQm|~@S(ZSbHM*Q;iFXJ4XpuZu!vsqtW{kYE?6x*=Iz%_u z(N4F5u?&POPqCIRa~QWG7NIV{#1JuNtSvFn7vNf39kB#`sD0LW%}^}I$s~+ozn!50 zFck=Q!zdPJdB@F|!Z8>GH-d6z<>m!^Av$CNwug8SCWfDrm z&jF*yY39rf4I=^-VgwI+Tkc25xM`eev`C^A732ITtQpRoR+U3ne91L7s=D|s~=t}`skTWOX(&}^A1^qPyM7CB)m%5*u9-VBi$-$47#@fAkX zGtB7MTzRX+fXcv7P-}zo_wlZP{Nx6;Gr@(uzkvgA2epRy3DMoG52(uQo3aZ78)pi{r z!nDgP6n1e25JFuD!^e%)+hVxA$-GYe3`PTodQWpP!PT2Tq!2aLny|rkfElUi`tWHpw@u9Bv1Faq-GPEj2?TEX*F={)cuh`L+$I56Cqqc~F2|Oj< z*a?G-_hQv}klz)nc0;o-R!!td=P`z9FT|>MdPf_W5#-X084xB)!=zH<)HV+9v{1nV zWjv#+O+rS&%16yCS%Ea;!rh58evVcf8l`b+Lnz%7Cn9hmPHhzxkQ2#xrm-4hB*&{U zyn3W!BPm*K)(k$;#b$n`;*ji4k4Nce8aw0FX3=IucpiD^`OrPSAX)6eN%sZ~EWF@M zYdPh*1Yuu$vq?_~V`h`ardej;aD^a?H5NxBX@5;n8^I_HB*vLk0kVZ(d{snQ=@#a; zXd>#fIIN)-yOm#mffY1STi$8r2R3lo!2#lH#$0;{p(q!j?LZSX@jjEylI>*=3XqtC z0MkjK-OPmPY+0N5f z84Sx*sPSA#RR0-67kPHwq2fmi=6IHLR@*d=OIO(v&rsUa%o=Kki{GdistgPf&G}5Ly?iifxHMkK9I1{|y4m>m zadVVxX&%fSs&wGrr{sTa<%~_dzSxCOAwV!X)bVVyn9Bmg954=H?@8uoRG3pfHT`5? z2tGk$@hL;ZwOJ?bv!=+K(j;l4oB|PltX}@xdLj01+EqF%#@1M4)dx|PKZ`N9 zF`^$tY=nrTf_x~*SBR-~7CD)Qu`#qlh#hbEe0HG@zMi{V;c9mPFmVfb@(06ef<_%t+D)3 z^&a|`=fI=t{SO&*h1%KEV}-gv^6Yt0eY=Y*i*&E{=vg#LTw921vbeSu*K@e8(RWlI z)!n$R*Vp2@RDT)QLVcYWUoWn&;EEq-!*!{?QS>*7@y+7;niwg@b*cWk=x-6@B~3;1 z2CjwrR$Q0r+i+d4Z`XHts`jgoJme}QZ0JS8veSVBz*WL>ngDAF8)gF*1G|AEKm}pL zM*$ccUIJijIOs>@0Sf@|j3@;T0_TBB!bU~`DL^kE3&;nGfK348x<(#D=OS>Euu-u< zDv$<@0%ij%ff8UJa0<9e*y9S21at)k0C~UyU@cGz90bk-m4uCs0#blpKo*b>6akxn z-NeO4A4BINaFehxu|O)228;q`11o_NU>|S_xJp>A0we)lfdN1s0NUIlU@ZXpvEUzv z-!mK69_S5#cRc9ELrxy%@(}F_$u3;-f!)AO!X~Bxn4Abn8}RNPO6;Hj&DeZXbH@}W4t7cdEcLHVG~$M`fG&;=LRcdAE4>(2Gidf`- zMJhVWfeOM_CIJP&5yD;s(~B_X#bUx%LC7l5tx5w%0keUXKnVb0s~~LERl;6U0LXZ$ zD=+}a0~P>lfl}Zga2}{6Y;_cnVid_*XIB|vfBgRi#IAwJHCe!>ns9d^%smMx0^pK+ zAAlIUVTx;Q5@Bo80QkOkJ#YZHO4!S>KraA(yu1?F4O}2>9pbSL0@sZKAaGqNa0<9d zn2`dc1BCz-8OH!9Sq~lSp<{hMuoi%h^_K~I#epQe0wu3N$tzIu3Y5HZp0EuH03{oS z0gC}B*#IRQpkyPIY#ad02B2i)5uk#wO;EB4N;W~sCMemo54cF!s}7(CkPAS^tI+W( zbZmx>&8b*~o3j8Y*}NS%2|&qfQ1Tj-yapw&Z2}GgP*U6k=nX(gF_aWTNimeX-W5Q* zWfTDVEoTY)Qyzf+pDGC}fdM7BFF8Qi8(D;Hg&h30AKU6WM%cC}U^W0xw!_-(dkA~8 z7f^=Z*MZ<2Xy1wjAha|WfY8!P!rlhW+eL)!1nC3qS>7?-Ia)I)67A9R&8>8-(p!K-gbnfm{HD`wIcs z`W^yy0R9}n_yGj$Z#@WmAIW(izP%5jfA0-|<{*N6uqyz%gX@8-gnf_7E&#~f;U)kC9!>}H0c7cL32*>758NQ^2#h&`xg#+C z2xJ_={E<_HeV79D0wDjx#lRi_<3|SokaM(xu#d7(=O0Z1!1z%a0D_Mo^jH$m8^{Ad zd<@M0PyjIh<0NpEu;UJ(D=-Ww1U3PXar_`~768o&(42rFCwc(jJ&_9(0qcQMpbb1Z z0i`Ey;Ah&SfMftdPxb@y_|JRlZ+Q;cwPs3VoYt}@%$zlO#`NU7I^EsHQxUEG^Mzw8?ny- diff --git a/reactos/media/fonts/DejaVuSans-Oblique.ttf b/reactos/media/fonts/DejaVuSans-Oblique.ttf index becc54992732780a54a3843eea37884768d36c97..e233295c46426361a21458a4d2cc23704562456e 100644 GIT binary patch delta 25254 zcmbt-4V+EY{{C9~?3eR?&fb_AVrI;Y86@OoC@QyHQ7(S2yft|#l_t4ENaZ?{CMM*n zgEQ9*CL@OArNI$GB}tOJHMvL#At9tN^MBUbXP-G|=FE%!`aFBBz1H)6S>N?tYp;Dc zr@WhS=QHCygc3q(;UbcjUApx7N54BRBojhAqP70Ro&VltOm4)ze$Lzq~||dw946k=@CNGa8LR^^}^7M21T{rA>@fZ zgs5|#8aF0>-hx%oKk_{Ejd&*GSv}cFDm_Zc$M>0<0-u~=}m!FyK znD7VgFB0iY+VH1`4!g4Og)2lJ&>j7$!_i=08nYJnS-4Lc{=%5?PyL`K;=YiOM~k0- zdi2P)C&vyX@_U(t)VVg|Ur!BfH*Hi7kvEP<|KS&g4ji8m^|)*yiUJQw{K%m%JiVpm zSM_i|hLHQ7%=p)fV@7q{wu&g7iwW^h&KUi4#yf8d2}HR$1R=9ShQ*I;-{1VdtlW|K z!*-)A>QA4iLtiIU%~JnE1a+o56ZN;%w~0x8N6kZhp1Kt6%hYA4zprjaeT(`H>U-2Z z;C!ooi~3%5FY5cWxrA!D+Iz&LE!K9U{*Cqx>U*@SMMO^qviR z*=1(YHOV8^$<=a6b8VhBkF?MhKu1d^?VW0U$iXx=vc@2U$)yt+Z%?47AT?eeLM)D`L) z1V@k>sBagE+G^3(Mz}zzsUxwIH18|s{zK@ebO+r{_tQi47(GSL)64WaEfGY)D!7Fx zp}vqHG!~i*ZG?M;PC^%MnK{llJbz?jz(LwVyhWbWn$=>Er?R1$8`mM4hNkB7L?0Y5yaSv!P+4_Iiu! ze%qv29i@&|U(=SLl?uhU5+W0N3rR?*eY(ww>vm$NLyGp-TQ8WcXRQ~l*Q__as~Xhv z<~K+x+S$M%o9-$->D`~$-bxRb^oAB|N$(Ma6FK!mMi95wT;z9AScw9UqUJ$Q{e@aA>CA*|aF;c9QBsG;|^c_hB8Z;tK=(-mF3EZ%6et9vQ62k>`@LXhn3^X z8RddHSaXuOskx;&)!fnipt-BLhq;e=pm~V-8S@D9X!CgUM01vT zs(Ge)jycclS!gaauQ0DMZ!m8)Z#VBU?==^jkD5=K&zdiqubFRJ1dG|?wA8lLv&37H zEzK;gEbT4#TRK}FvGlU^wWL{|v<$b5w2ZO5V#%~jwoJFYW6811w=A+Ov#heLvuv__ zYT04gZP{-*WI1LzWjSxTY`JbJv5Ho!)oqQk*7sNwtc|VBt!=FLT02?0Si4($Tl-rF zS%+EEtr^yF)(O^0)@n!VBYrb`{b-DFJ>w4>E>o)67>mKVt>tXA0>ly0>>lN#t zHe!=)cAI94vBlbwY)x$~ZK<}7wg+upZ9Qy#Yy)jWY|q$6*hbsN+a}twY*TGBZF6j% zJljHBp>2h2jctQ%t8Keμ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 delta 24593 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 aLqC4hEzWg$jFUEYRBXI+-A3)qHUAGOgAk7Z delta 22210 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 Og=U*?^eXevS^p1Jr$LYa diff --git a/reactos/media/fonts/DejaVuSansMono-BoldOblique.ttf b/reactos/media/fonts/DejaVuSansMono-BoldOblique.ttf index 5e2ee0339c9b8366b84b9081a3baf4ea2600aaf4..42bbcdee97493014108fbe79f34e84759a9ec23d 100644 GIT binary patch delta 16929 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 delta 15093 zcmb80eOy#k{`f!V&M=ozQc_YeP*egRP!Ld1QOU@tu*}HF$VW6(Br+^Ca?seaqBKD- z6_zRa6sd(ZZc&ku>+ZU{?k??Gv8~lGQn8!6i>(#H?|ttKiuT<RsLdi%gH z-|ESEnTU4mhTHF$_QulRy^V7wvgBKDkB$H0Gsk$50Q53@(TW8H-!=WUfpd>Y;MPSC z7DiN0+0Y@c-r~3v#}De|WrTZ$=Ped@h0>o7L-_ zXK@~xyP~jYQ5a16kD%0DjZR;a=8M-*!>%8UzZ+! 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 K&5JEI+y4U#rilgs delta 14236 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 diff --git a/reactos/media/fonts/DejaVuSansMono.ttf b/reactos/media/fonts/DejaVuSansMono.ttf index 6bc854ddae97bf5ab2c4c19058306a2d8f96fd49..b464c52ade0f8827d69920fe11e700ea28f7e0ed 100644 GIT binary patch delta 28593 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%0Ae5kW5fBe4pkM#a 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 delta 28027 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 A4gdfE delta 16510 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 ezme`vb2Fr6)mWc2X+tt=W<6!PF8x2O1tw?! delta 16928 zcmb_k4R{pQxjtuRXLfdGcXpcw2tPuK0RqG%je^leid=-qrAQGm<#GiiKtzNTf~Gu_ zK?vLwkpwoEjfhBX3eigy4Z6t9RW6s(lu}BS(iB6AkV1--Qlyw7lD;#Olik^!-E4R+ zJn#IR^L{_)`@VDL%;<7pO;XE^uW5u5LcWfJgJh2zH}yM@Hs=e3&^)yE8$b4;ah2Q4 z4&%N6_ch}uKk{hb`;xxE{Y^rK9vuJZV`F+AT5=yD!w(Q5j(z0OtehuLCUJ!1IKZDa z=b72X6Gyz*i2E6Y_?FLkwj_1kXSEfCj6oZ%nO8htd*(v<-wqKnb_E1pm_K`IF>&HA zc}T*&d;Y>7%#*ywUcr4b;fI$O&7EEN`Ex^0625pF`bQR_L47h=!2Jo_rxiU@QhM&h z6F$0r@l!ERXBwsyn?^Db|^C86h+yH>k8#1v~N{j#q|!Q2JJspYU{4j z-jw#MbMwP#4_z_^yb97=*`#bDeH6bE@K1CMaOpjLbPaVSjx|&p<|`yzQXz5Ep^lx7 z-Hvx0`y3xQ4mplEjyp~|njB{xt&Yo%YmOTN5k$c)Bnc@(e<4j6CS(gEg*;)5kS|OU zrV7)AS;9PFp|C_K6;=vm!g`@n*dlBbUK47CH-){ze&K*{SU4(tBs2=mLW^)wxFTE^ zZfYVYN}?(zi+#jYaj=*n=7_oCC~>SfL7Xg36K9A|ibdigu|!-ht`gUY8^q0GwYXiZ z5#JE^i0_H@;z6-NJSLtHPl;#5^Wr7(s@Nvpayp!{)936-h_jz_pferkOyC~ieqgk7 zoO2@1Q=D3X^9fuOIu|&Laemgh!nqpfa_2^8m2<0ehjXWMxAPt6KD2!Rpx&HFm-9Gq z5@>Rsb++Ps8Mp@AAVe=eNd(+L5|9G)2T%smFd!QkDdkCHqOh(bOb2EG^Q48+ z5~);LDV0gR9hE+k8l`5bMYerMd>YGF&;XT-PYqSl0yCWY;v;4A+ycBG)2UiEFuQm1~`AgKM*^+O^%K)wtep z?Qy;5s&^f9HMowsPPk6F&bZFIF1fC{+FZ9}hb+rJxu@Ju9w?{FnesjI{qkseoIFvU zA{WR{$c6F(xmbQyULmiR%jJ!7mAqBnA@7uT%kRkh{a$F2b9CgQRO40QE66Ml#9w0<+^gy&ABDF>P~j|ai_WmyEEK5?p*gM_gMD? z_hk1p_YC)w?jrXhcZqwsdzE{gdxLwkyV|X7ch|VzaPM)y=dQ=HaS&(#jsaK~+^2vu zzSc{Fg05psphF;)O>Z4I#r#n&Qj;83)LlRsk&0t%GC90rMgAkroN`u zs&A@$)&1%L^{{$W{YY(8o7EQeqIyNWuHN)=UdgL^lf8Yssouff3~!D%*E`BP);qyF z**ncU!~3MS$h*i};$7}t(rT<#DyXVVv$QmlkYvpyc2P(0g_LAR~KcFdCCSRrll~wLI2;`~KHS+?LwGtBt*;qhLMSifQE^BBiepqD4(eO*l5$$IyqY2LsA}gCQEB$!3Y*7LTW3^JH zyyWkhbEg;KR$igk$mjH$vR!%ApP#d4NDCzKM=izx^s5YSx|R1 z=UeoSg&B)8p37LC@x!|YWu{~f%FNt3e&=_0KEA8xt^vC?)aBpvT}l_#RgZX@4)-*> zo0Zc)Y6>)MY+6_N{lcdT=g$ewshgAE^LIT@B;S|(&Ezbf!=oqz39b9)y@k}jqp#EJ z);*Cn=tul{x2`7lai_MB5P3QLS_CY{^(vf~0ngzYQ!?WR0Q%*%IAfY-{1DgwLC9Uu zaMvJQ{|I}66ch4WIAa~i)Z6#qoM}SdOUTZ#z<9L3i}PgQySRRz5N+pF+&qq(|0ZOY z1fcrm4{`1b48Zj

    OoxBM|7*I@YCU|jzW=X4YDO+v080vgc%70$mkfkG$OPnf_? zf_w?tFGWI7r390X-13qkL{SK7{|5j;r7xi;ih!4Kol5BM`vH&PdTL$rgTJ809BCf& zX%^k=Kd_`1tu&5)|CJ@ZdT$aY(q--K?O5N0kDY6LgGm~ut5d0{OI`YH3V~TAx`2N4 z`zuR&^{x;~4FQagzv_G%0vUz?RHL`jk>1&RGprZJprOJqEqg)RBwW!sl%+qPH6X!l#%7sC@%&n8Q|J|wffLT@M3pY-fMW^WeS3|j}=&pBrsKI9rcRK{rc zTiSJlQFNd3xZ;j|(CH65q!n_yUM&c%&);+57r|tQ^F0iLUAMM+} zgxHn0PwN9bR+ok2EgWC+XYQSe<3{6n**H#mS8sV!Kh~-5eM~Xti*#8MOApo&VW5$o zs=6D&&neu${Ql2rplZCYdn@@kelm-F^ zKcW8#hYOmZAP`vHM8Be&1FKHcZ=>-5iVB9OG(!@7&2(nq!9UXef%axP28zf0k^a1Q zrI=|{fS#F5=hI1p$)t9@0xE;4XXw3pEDAm~ReuU^0)exi(ht3rViNaN=Zdl^u;(nO zn**(94YTRza90_ab%kMEvH)a#-RKs`WSUpiW7JTOl}Gkou|*y zO@TA#>Gz=S{tF;g1{PeP9|peH3cts<(j@pjz10w2-%9_&fmZq%Lbxf=_8I*>-4r~2 ziT(x)c3{V4T7lc_ztUeN(JjH7l$(jU8l1s%uAgeVXodrixb}9M!ENR09m8QAZ5$pP ztW6w^@-TSTKC+gp=X#iJ1dmmnueU|=!~3A$(8axM%4y-9VS*Nt$>GZ!dxT_g;GlkO z8tiBbb1>A$Z8i8|x}y3tCTL3{YeNdiTC3skKF1z&RPi_%v0=l?(e#joj4(y^WWG!v zk(nY~cc#c9@6@9c-e(QDwNKPSxwS-qDbSr`3Yh2NeUT}%<1qQiLFsxlvuG?MV2)VA zWg0ajU>enPX{LlZ6rOK0lJPlkNY8(Kk~JmK-0<{a^tSrKIZU6))#57*3t7U7QM{_vsIE6PpI1C zIb~DzhJHgvGqzvdPeD9`W)woRARbqOnv(Pe@JK}$x>k5#j>d2 z98(b+aXc=o5jGXU)%X8aqme}tMvme#g{IL^xD$62`+s`_QAHRtN>+z0D`=F%jLV|r z(Bg!jkt0JJFJ(-I4XP`y@%@JxNK`2Fu_6?`t_q%rn!+A{)ik-~X*1hC&)e?tD$N4W*4U_C*}7 zw{!isMj%wh;pE8YL1z_r6mdK*i$sKs*75kY&npxfqcVl<(_wWy6um@bxR*QD|JyMX zR>g6gG*e)vIC3M3zVP=y>qu%60TvmSw?uNBh)jom zE$Zpl9Yc{Ru$Q%;1tzz1|7Tx-tccjz-hg$N#5f7bu=hWc9Lh~X!X58}EZp6ZVfOU* zKTGv8@8jj!1!yR3)kyUQTVMWabaI0ABT2Y7`&9y!Y z5_8Oqcn4SC|Hs(J8zZ%lBe;6`T}CA`?1>ugcpos||8GZ0*n2^jPBN#==!8eGpM_rKdwVmcc==Mx^p1NNWA zPy>lXByf2=*DE;t1ecc+xWmae1UI?(C%E9f9{&6w`rAPNyZH&h(!2TVqx(-hI(qzu znwj3bzmoy@aSZ+(uFtPw=fH*%{$Bd}u0tjKFiHA^OcO_tF9T<`^ZkO3SNUuj%-z9% z$vcJiCX%Lz!TW3Yp>E@DwIT)yhv=C1F{VKvWg3wq` zxIdurR4(B@NdYbquBn!Ar&kcJxtwr+Oa-9y%nZVPnoPK}_&M3xLqIFx&bfhXU@Fi6 zGy-}%9Bz>S$hI^Q?oTlMC$yh007HqP-P{ zS}zgq&oKPwJYW`32^=8YMFNZlVEiKVT&yPCXW(3d;Y-kUxgT(XaDN5&${E7_4cAw} z`@Dc~*N$q0`};P+U9TeC7dr^oRz|pglo0O5Zo+*D12>No4nJ<<+H>(!GdF%ChhKry z6NKlE5}vOnJpK=GUYJUF5pXsTUfM=@IU7H!o<(@~KEiu85MEtHcrSRq9fbcHkW>#q z$Ja{%tsIA&ginUD2%iEaz4Hm*2R|GC|Ay8#o$!5g0T}38 z02BeGKsiti)B^i}2A~mW1= z8h}Qi6=);;00~IZa7YJofqb9a-bTh1@-|AKqJr!v=Kg40#bl;u}N&$Yl?z!o_aF4+e&e1sVvSew^?_ zaUPbBfAaus!;64&{U?{o>%p8$d@=9M#=ovGcgfPH7B5Q8$-Fx|`1W7<9sQlJV=<+K z^FQ(6hrwQ6$3s1m$pP}eic694FAlgBkD@AG#TP72bKFCNdj~m2e8=^WbJ?P&a{guH XxImw!jt7GCmpW#0!DGuDSCxMP(q7&e diff --git a/reactos/media/fonts/DejaVuSerif-Italic.ttf b/reactos/media/fonts/DejaVuSerif-Italic.ttf index 4464868f7536612758568a1d90efcb415a00cf90..b2ed04a1230757a3cb2482f3c4f987c51619cc3f 100644 GIT binary patch delta 26706 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 STQi+IJ29m`=0Q`N{r>@`WM0?+ delta 25471 zcmb`P4_s7b_W#dw@5}%*lZ{G&Mn*~gixicVii(PgS}H0sw`B_pjf#pjEo!MDB_pMx zV1tT`HCI_fmx6*^wy3D3;_Fh8u`Lx9t7KSIq->G?-ZR6M85sW9>sPP$+z=eq`x_#_?BVPmZ$D8q`!xH^s_)e# zrPfy2^{MJehutBe_6hb0GRYon4=p^?bexV?RjMgVIgfbBwo9}ly2UQL^e6Q)eUo0H zzo6IZujmc>J9@LeQ*YD1&^z^S^d9{ulb9?fyJ>`PcuiF=b2;7XPV>97nzgHi_9tJ>&)rqTg@xXcbjv}Ys~rP z$IK<>_2!M{E#^w|OXfQB>*hxD4s(n7V{^NCm$}RQy}8$Xz+$pkSx^qk(UvgF2^JQQ zWi~`xPP4?ZJ>QaOx!h@4Y`MmgX1U3dX}QCaZCOP}9y|<1mM1M`mQ9ul_FsTncm-H! zmUk@8mYr-_V3seS6Ifst7L4U5ajiWGuz(#VKxn{}fQW!u0a5HP2#5_hCm0 z&JRiqx;$tx``17k+yt3HcLZeztqRHudN`;k=*gh6piMy)K`#W=2E7v05cEz^bI{J9 zwxBP9I)lCm>IwSEDprftZk=EawN9}{SZ7(IoYn=_SnD~~1nVW%Wb4(|RO>QphIP3$ z%X+Uh*SgkPV13+LYTaNhw{EjmTen;5t#4VItnXV}t)E&utb458)_vAKn`R5Njk5*Y zCfmYo(`=EpdA1nanYMV_MYbf{B3p{>IvdrrQB51wwA~FkKt*k?OP-CA+9;`wlG-S# zZHukaMmcSi(?&UMl+(7u)>2gvbhc9ORlRS$#!{F(es1B@5ZzdPO3FI z@3q}ybJ}uj_t|H1Ewbo$=vn$*danL}UgA2oP3Bc8JFi!Bl^Z9s`}+N89q) zyHGA=L>jNTyk2PZaYfQqvRrDP>gux}FB(TmO!#o@+H+mAoSt2|P$k=PF;a4oJIo2P zK;kg8$T-^r?jVV_`#DbZwAmxv;)(VX+-)w|2aG-XTz0g1sZOEID#7jqxP;18?!5=) zT+gm1i`3aPS!}L%G$rNW8gn4m*6IB%noJg}eWHCl*U}005PK*Uon$}CKDqFVxl@mH zS6%hU530vi`@-OPtEYG1$$#TqRdVe`vSrbmJH%wJ<jRA5~)hqK(SI1^V-WGXh zp1tXUO_y!DYV*;XkK3GI6&!t;Qnyy6opQ4}>7h^aKVA1}&?h0E zjQhlr_FdXnX}i-Frp>>;G33gStck*oBQVc~d-G!2T(0x!i2JjQvx&25m~_;3^JI7ug<ncPwu{{Qk zWB(Gi>%eugTp`j!;2th!wkz3ksc>NAi0}Ae+Jk-CU2-0K$3VM&ky|Iytus;oyP>ZadbN+&KXbLu zI!IvsNw1DzPlvnx@c>r|#zn#bPJ-@cUcb-8t7Jvvp{ zcODl&LZ$c4RKbOB-8)Bx7Vf+E6m?W#q;t-sqs&q6@G}U%+7gT$Yn5RfS-8TvSA`T_ zm*cX3EN3b9y*Vz06Ye{O_Qm(jqvHzok|>EOHVn>7X$4rVPSQw+C1Kbl*g! zCKQfaeJu{Ru3m~m%jz4EI5YQeB=k+Lt4@~tFHlDoUUGj3ugmWL4=v}cAy`%Un)?)P zv-0MsNmWdIZ6O*)%PUWrc$9gWJ0ngh)6#$% zRF5j$UU?_I^PYbMx7VM41BW#)Jm(tPyy`i;UdQX?!pEww<@I~_>*X)H_Fr(nPI!s^ zs^u@etI#;JHiXO;)qbQ%bN2RERcO^W+y5J=mQ}U9@rylxTWN>I9#+-byf-xHSmE^L za7xvVuL4dOueoRHewO=Jrs)ogO|RKyQ*#2QJM>1^Olse_`#lROg|r=}1MYU$wc?;G zD~_G0?sP6YxZ8ZD>0C~5R!c4j#&sI$zjrUAiRM?_lX*JlNqoTTw5Pk;ZL4ac=d0UwwW_9kfqKHK zR@aN)=lCWV`wkLy7tvfzaZs zKUcpn%*9`*vuG^&LOn|0SzqEw-$T_rI6?2s-uKbQff@?aza~)1B&iO$-LaU=k9jBHRNA;+XN$wSE z+2ELNaY~Nse9+DP3p&-edx<>m(_P@(eVx?%bl20ZmesWOsAGcqgQOAUcHxcND~SDo zI_O+>;41T(mJJi8nTuVW+Rjqmja?_zq4ttt+MgJv{mEh4pYqo}i@-!295|qd_NRT@ zYpM^bk95yzZb@)V*RsW(no%^@>2KcWm@a>i0+*-J?jA@Qdfamij$=A^!ZerN;C9P0 z+9`y0yG!4)Z~}!)kRtB@HDM-g@2k!kD$*S6s+~Gk+o9cHn#7`_P5We^&631|b=&#& zNr`rY`qI-Tn?3ffw!!w^edxQjv`;*KPVY`HM;{}PjlR-sHob}s3F^5<(*12-2@dpW zJKXkOT0{DrhNE92DH#xu&Ax%X`^>?fQH^B7h}|)KZJg>@e?tC^^_8v>d8SCu9hjnl zBuON|RUPj>-;(?GS)2oN>r(+kz?GaKU}WyyH+ahY*%XhGTb6Eg#77vRl-Zp zQ-S_9Xoi3QWPEM4h9benXuO zdP?Y-64wP~=zROG3I8@Of2Zfo#&gYMHKcKhofhC&rhJzKZ)vF>8WO`0T8i(A$c=s8Lj08vWbI-j$8{aFT zbJ)Oc0T$mKpYLiH6mWpw;^UbTgzmo)pOqzx=TcMLsqzNgNV?6&M=uTop<3Z1ghvPH2dPW?c|A#K5(MoSP`}6g>6pva}bUgEK zly`W+fpU&y>pyY#1!|aNoCDW>qnw8mU@Shqr{%yI;*R5V-+mqb6pWtaz*#Vot<$$; zV{$?B*vp_}_9@)oJL9a{kuzIfh|LLy9gy0Y(-#PVf<2x0`VEo$}dPY@< z>AL?n=6%@3HpT=8PE&t_@t-Kqe_q*mB{O6Z4x5Cpu+J6LOV4+3p6SEZIYRk;g$GJI z(v%rK#-K*Cb$|ZjXSI$xTF(dusyA97*EPY2tjRW(MEk`md&M;vS#=&;Ptn3C{{P0vMGUDH-3y2P!g> zPrtr%$h+T2PJ;t^Y)1>||19wM9=iVf3_9Q&I_e}Dh;S@9z}_dgFB zQ#7W4gPtK>&wqy<(38|a*?&#oevN_8|HmT2T`|eJK9m}|UTRVHU@AY(>c1( zfbmdU-}i#CCFZGkzpd;3-}@GMaE3m{gKP(n*hqAAA7erD`H#Oc`3eshk7Vl!J~ms= zRJ(6zyx;#vE}!p09og0hFuD)V|Hf#2%Xio#aWBl#0~&Al{g-Ul{r^a1^*t;6+xo5< zX9?8e|y~6!$G2K44^MBy2cBBBqokb)04Ep@f zSaf3x=sDL1R`*DOe6I_KeBAf{qt2gE-r?tQ^r`Xh%l)7C+pm$OXC#NRbUmbunxwH7 z4$Ifse?K zU&&#f|HtO+`=m6u{38eM|D3>>e`E3dDiQY@8d$7j3f#Z$4t@S-oF0ecY}o!9-~Is` z&wsxzdt;h@eF9#e|NR<~!P9lv8mIdISd5F!Xcej1^R4#AyyCN`>WwvTpQta_Y95%W zub-qYE1q_)eo;-%x%%Hu=bv*&IrTeiQxcoB=MEmY_Q=>D<+wopg|ho=%9X~pxM8in zP|d38TdUjn=0#0lp}t=~YMJRb5^Z`{Ue>3|)22`4Y4Z(yX`*ero?5e_Sl=CV>@ruw za1_Tqs~=zU#Gm!cmDz1n+`U1cKf2GelZKVt-1n?L(GoaUg3SLcKDtJqQWIOFN2!|3 zTK#5?v`MW{1>AqIO(JY-YVN4hPqw*_R@v4RZ~3Qwv-@B*2Vsr<2e}+PY#i_%u*cu- z?^uJt^0)P4L!40}|7sFx=G#flEh6t_L6^w;d@Jew3g{I1APMS4TKJM!3;$UD!%*N$ zTp#kc{SVtkcGADIPUIsK(X0xotSN zVbF%bCk|*8`Ls>sGul4GussnPf%eaF`n(7lM7~IXN|7%ML^@)C_KuAr|BVEa-G%Kg zlG@GjZUXP_6X`^&vqj{qctCGY24C^rL*P9ae2vK0B=dDG5b$dZzU~(35}8E zz4Yy6)O&kHzDa=$;P@MCzs2U;azLY-1iESaj_r5Yd`IB#;~)uAArtDjKl{E3+JHzu z(D_53NRJ)T0H+_LfsyTV00H(DiR`C;KYqQ5Kob8mK@Q;i6a7D7|8qKYK#xct_I;(m z{x1aoh5lcvq4^k66H9%$qigPw!6d<`@f`uIw1r6`SkjjbLAeB;m*4l$4f&Cn^z z%)U7lG9d>FL|OQjqNR>+97RGrq`(Tu7Zo@I8bt-A1O85HHoqGX0epp#-vdzY-wViP z+bZe^1dgZ_HIAU;2r!N$#&wH2l70tCIq(^uC~5-z6OsVY3HVJUP;emNdlYs@)rvYg z0?I{&IDmvh=?^UvrwXMrv{}?73@3F$uc*nffblUV$PyJMfYY%!9m`0j*dYV5fnZZe zWJ;Z=Y)|7MV%N3*q#^z&Lm!nL`~yh z8vE1I0mo?=PG@w}dqvGC6E!mwW&n0G6JW8ZS+vcn5Oq?ds7O1|7TG51WU4WnkXcm>wC+b3U zF2e3N>7p*?d;aR;c2Sqqi@LNyR8p;|%NWt+v|YjemGPn$Wr?~9p~d;4ev8o69RIFV zR0<>feTJxO!bM%nNR|Xbuc+%uCap)*GJJ2KFFi`sjf?pW{HNj6XU%MP;Xpx`#mbklnrP-%Fcw1$2wb$rN>8Bp|$s z{#Ep?jslX)WmLJ1qVA6d?CvLlHQ27nhb~bMBto~Syac&q8`f?RcHqi zENtPYSm^%~mH1PcsK+CrTvRc7#g)u|F&UPSL`j>dCkXyTov0@xfc+;kpa4kh$u3b( zg+VkV0-{f414%tq0S$o0Q$3^9^>1vEjIsAo+O z2GPv_vx)4aK{gZthR-%Y8}x|UXom=hg=ENpTquQVXo3#t6ZMy1h=h1ZffbMs8=($b zpi9&yJ7Bjdk@?@0!486(5Zr{|rY1me6M~x&+>GI71UDnN89~16uQnsN8Ntm6ZtfCQ zZh|m~hD1n%Y$$>XXn;285%pI)L_jPgGyi|h5VeKIEeLEuU`rw(umyoFrBDZL&?oA- zFo=Z|$c9p=gEr_BRS^u45DzJ^0`j2(nxF%)+lt**?6x{F+=}5=47Xyq6~nCXXn;20^sMBRt(*az!p=(0 z(MnFg$~@rwtgMA*=oIz50HV*wKr&NJ>fof<1 z?5eP!LX_l8lfF}MO6m_g4K+sn$c8aSB+gYg4NA{;EM>p7z)_E zNZ=P!AqxtCQNPHjUqtUk^j>nn42XlpkO_Ir|4U_13oXzks>TH25Cch&4mnT)mCy+7 z&?~AI(b`Cehg8UdBEYT|yV_Rh7WJ|~D3HL*agYS)zU;)|w=c00D)o1s(G-vvS;3KAd{vY-IUp&nYHTU1>jghLD@G5>Yx?BqZRR6--P zL$9cRIA8|E!D7gSJSc-&XogNvuLy)f6eK_@WI+LxLp`)Yx2RVGAsk{Lf%$(G<5x2w z2bzFY`f87;dOJiwEF?n)s zkO(P|1$j^gB+}3~2Ig40S&|P&I(cQV*73bv_YS!rcj82B%r^EQ8qD!O`W3tFB5X19Ps%+ z>~};1mD!O7B(|f0`QJgd|B8SZpz&X&P%o-E4B~$U6{6lV0ZF|_GVdotuBZI5BR+xvd50{3ILlp;XkTp%4pcP$Y`y za`hQ~pCSHP6Lg7cw?iZ(LI&hR1vEjIsLxG6u+NhK&Cf~b3xUN@$K%?UQKG)Y;Y$uW zqM@$X@tq#xB)R{_LkeU-E^GvJ|JwmQqITIK5@I0{u-%m*YIh)D+gT~`vvlKBCfAM&9A`b70`+(Um4h56AA+0ezh+!rirADQe+ zgIZpLj3ZY#%BjwP_t-O0fepm zWS0#a8#a7|pxKk42)g+JL6SQn5lW!~`a~NS2WX6=?MU{Iq}{=Ybj5O_R^ObCQzC=+cW0VhTS#}f;nQ?%f0AizBN0f!jcV`z^-=v0JG zjRx#brTx@uXcg@=6GXvc$bkx={d57^PecvA9mr&JKn+SOFV>q|U+r9CXjg zfqLL`3GLhnNCUDwmq77>kOW20E!uhXpNIH)`GC`T?Lg4;V_`86;QRup0Q}GI5bXj1 zf?W^?>45JA)jc>1dI~Op#cbzK#&VVAsR^N!VJg}?IMnULsGwK z0_=X%BU+*ZXiG#d5xqog6Z2pr)Iu|KiFR=y;D0fF7nd>r7x#*G$zstiEfOt>jFND; zJPinRc?C2A0j?mx6|s;41wh{wEzm7maws60oC?`c4h=xxm3D}MWI*%EQb6;{4$&4l znEyqQ?2rJTKWU2)U4+wB7+zH^+Tt+Lej5xpT%8N`qWz9wzsm&LQX(K9+C=-k3DEj| zI<$*+4GCS72k2bG@wIk{1+=ei09PBIOK7PCNX0RA1(ZP(^oX{E;7dqs$wp{~UeT^g z1CFoj5bgR1;P`s>)7Yl5UCMT8J`i*%Ni7S62uOkqC=%_4T+z}Q&^?PiQJ zFv=jKTT-A!v|9;$DlP50o~Q~uWo{F(Q-*FHxAOE0QlpCmP^O| zc8G#x$bpT}3<$2FeGTnvXkSwS?V>$^{R0R+umUQ91Rij;W1kleB#@U1B#=jc9tq@i zi}oN1Jc!?eB=BGXxJvRM9cvL>8wCVfn*$`UwiysyNBcV3*U`R?1lF~SmXCctLir?+ zUkL=r?-uPL0z5?fLj-uJ0MLJk_J?VInD&P=pbW5oM3{<4qS?uWBB+Nh(F(#L5ptj! z5O_2Ul7JCCiru3RETjVVh4dE^u&`USqF{&v5-ciU{)@=4 zh>kzmAqtWq2R1@8Aow`#kJJ7*?T=SLyJ*GO7b8@>0xE$3#oeNn5TJzi5(1PI0Qx1g zKSBEwv_FvnWq|#Y{BcZsG8!_W2E(_H+~=_;e*8 z_%wFwgCPz`V0{6Qzlo=Ws}b9H<5aHju!E zBp`te*lp+$?b#?m@Yzae5pAPDB&0$Y~DLN5@kii=T|Yuh4Pbs#K; za_AE6#VE)I>|Y9oR3Jc&Koa0r>wp~S7VTyFU)~5^%>VWjXcF!35rD|w5v-%Fj)dy^ zMEge^FsgrG^GY~mL9=MDV*hF$U{g;r_0^)i77Gocy&ejgKtgY@|3*5{-oUn@L$o(Z z^38bQb1Ci3a%dIptw2EFtqdpy0=|X#KO-Rp@}Um8L~9I#L|{aXmC!EQ+lao6=-Vrx z04ksn2>1?(zk|j*CD0<;yTp1ohWURtot;vs1v;ASuo&t^`@b20(2hvRh9=Se6$)9< zD_S#l%>;iBvG-D;7FtDnUm#z!5AgdS7SQ;hU9^^H$b(MNJ`4rd_5VY%<Mon?&1}2n61b4^PwD{xm>) ze=YOBpP;=Chy^n4rK7hJT1ESxzzjg(f7wt0-J<=32#?m|eZuIGww+9@A6qT@ao8OnDEbNPPt6xSqEhr}4$-H_ zi#{VmbROCCnGw(o=*&unPSH=I?W8oP=#f!?)5(aR+#~wzI??B3iXKIV|G$}=DEizK zAhEgG;LPWx6e@tgbDN+Ix}Z<=d3FecNQi|*NP!Hwq6vzW+@iZh(XGTwtf>NN3$45OD&PW4hkEcQX zEJDO(h<-M0XBPk;+KAX^X+it~aEY+m#UXJLP_xKvny()jC9-Jg^4o8`?bh&lv*$N;^LDFO5M<~%t$T7I*PaQ8zzg_}Kj{GyVG0zQp!Pjl#rE1o=i+OpO0 zC-J!xAst4P%$ZmE$}7adfH_M1$jNg_o0Rrc$G@M{ z+w#ZhQ=K;uDmf)5VWo}IM%-_benl8*yL1irmC}FFe^Y9xxI$wn(=z=XHjTDWq+4OE zlC+kprE1bfs+De(59Qj2DI=|wSrsMRN-8(Y3V)n1%@zoB6pelk*neAxjQ_=TX+W_#kc0;_yj(YPvtZD zY(9q{#*gC1^7;G}eg+;?MHu_;2}3 z{1yHhf1SU{y9G|L3K2rI&{l{Sx(Z1`FQKn6P{|_XrIsa@6_!<&HI{Xjjh1cb-Ki`W%Rb8i%VEoL%PHKS1JGU4bN^7l1_;HW0`K@_>hd#{pDn*i>L9Py#FfmH{h)7Xhs2 zu=T)ZU^}o2*bBS^90ZO4CxFwy=KxX@c7ezw?0ei?1**d8!fsiKRj}Huk=7V%EFsoT zKzAU;nr_Xq4zdolj#cVrMzTl_DN1TB#YqWLqLeCS%2KwJBMp;ANn@paX^J#M zDway6CDICMm9$1$hxN8i+9|yy?UN2jho$4vDe0_qPWo25BwdlNN!PLN+&0c;wME#X zZEbDwwyw4$TQ6H*+dx~cEzkC_?QvUyZK`dit;Dv#w#>HD_M+`o+j`q(+jiS7+g{r{ zHu<3Khz((}AuKk8#fGrhE&zy%4NGFLhQsY*lqSmdyGBS-pStGo?=h8XW0kY zhuTNj$Joc)C)o?_MfSP&MfTBwGxjg-=j|8m zm+e2=YwY#1{f>iiSR4*Vl%usH&XM3qbfh{m9odc?$1ukz$5=&J!;`{$g`>8@QCs1tEkcjv2(|pkt8I&BdY{SLL3aqx7?L%CjT; zg&%Q`h0G_)DDw#+6(x}`GjvqNov1(1vglN zG?rYD-j)7At{`1M)8^7`$xU07e;%EzZifBT&Ct^Frg8q@v z%it3w9QyGYcleB6O1k3CN@8&ph(p?{&dQTE<8z)WztwZ6%g1J^6Qa~Xd<~Gt)Vpn- zJBEy<_v5}bu}U>k6`ZM->ZBX+u^#36-*To;$8bbJx=riIPqa?DBmGj|tIu;?>YxSx zbDRSKYS9cYsjwAyB^ye zy}SMHS1PjlJw_|u$SR@Tc3k}R#SY&kf0yuG?6k0HbZW!Yky9Uf@>0v>34(#yzlW4DcB4AHnvx z+d{~0?3EHacEjNA_P8%Z`!etf?q?B#-2Ltb-?FVGz9&!6>AOJ6<_tEC6 zAks0k!vJ_BeSr3103@YTgnn}#_y_L4uUIqmW6GkkE5;7{>l3u5JY`QyTBTlV%O~w= z*{YiRfzEGeXn=40-^BdL1cI$NLX;{i*6#U%k!!eX$}o8v!)f9y48v~>R|V;>HS{a$ zH2F$zKXXvklc?&cVK?ad4gFPGe|H3iFkkshsP#;ki2l!1zM7)S^0s^bELZc-s_N!7 z{2;VbXQgUp_@So#RYCe|4gCdhL(@}j=vUm+`YV-w)c4FkyiOSXWHIZ#ZnU<%@V#VuqkO}Az3KJxGw&t0 zy3YMeHDB291AkSBf;!YbQg*E(>QGNg>&kQAS0*fYe;OuScwbQ=9PW+&ti#>VUwC+8 zt6KgUIzLh%_n|f$8a~8nze=1H(FObB#lsDhR+nEqG7%H9k50pcoku^QwH1ZOG8j2nRGOe!|^l@`##@J639)~~ahWjg@ zB!f-#X{Be`>4|XVx2h}s8h&8A2*cqD%0YFd?(}GdNA4Mg$1Ys!%Z1M-D$)2%QL*8( z-pwnyo$BO#gl~XY1o~Cw7cqLH+;JAMs>nI}`*yHX^Pgl~Z~Emg22N z%BS0|oG$c(cpBpphS872R+a1~#YazxpmZ2)C(7z|T^>zaIcTNJJ&|VETdB)9Qeej` z3H2=Id_<(uHDWeh2-?n*#q=kLAHx33W~j>o;#g#wxbTvi{~CV2QWxwKYJUt0Y@fI% zB7vQu8g(9+N8jhE({*?eeKUe?bd7(BIwR3u-$K7>PU~E!|47HNw9?tBf<8#=oW&J% zBt9Lfpvh>ev?g{xmGNoYe%c$&x&5k0r*~;Ld>ZjCorvb`cQK*fc~NO9osI)^H;5lN zKqnT`8_wu<%o}iLZ#xFX?EJbN^9!wUo{MD$pfjpH^E&MAYR{kwoL{$RCZb7?LsRM8 z5XXGfs*2B}%iwW8RQ$ihKcU`6sGe21N;@!EJ5|nI@!H&YZEi>AXc&UUR3nzvPIpJ< z0a(lFq*^QMgeg_d1D(_vSF|R&GlK*>zwWHfPf*5Og$c|^3Oz4*^c?BJJVUFUSzVcN zP`9BggpeSmsdUyW%?)QlH&wx^ZffTNrMcm}qBOOx=CxcCAcdZbZ^L*P_A9U%!(ZXd)k_B$~Ek&N9=v zR;VlVG2eOngi-KY?bF6|d9sn2PJht)$Zkzu>C@%O?m&6yS9R%QvTn$4qKQFvKF@PU zp&SI+GM$8{5AsT%(I9hHl{bv(_B>;Ft)G(&b*S*ro`OP=TXhdY% zE{Ko`A$GpPT1ydI=I06Il|G{b9(luLYSSe%+Z!DTZR*{zHYr9n-S7;sE?Tuz?g|aEkZD;I-<|l zBP08IpexXYe3y|A0o8~u6N-qg4=EIt^lJLF2zVkamuZTWu$e|eW$nMQ1d>+6t{MqW z$eS83Aw2B(uK*2`EStcB1gC8DorLo!dCyAmb%usz)V{ z^Phi+O@&1z=iW$}%BTwU`e?)nT~<~VH-%}?5F!G`noyQ;@CX_m#`#YPp^pME)As>y zm79ebic~L*3PbA)h#>ZVrIK}{szS36nh-R|HsY}^tG2#`)$?Bv??kQOLWU9wn^u%s zw7jw&!m=8EZPW3Ogen}sSoyjRLfAkiAk+boR`jd;zxP}hs%m{aP)X@&YCQB_M*@mi z_F3!3ok{sx4jy{lxG!P<8qsA!5tIWMnG;e&t1E1Tm?1ii5LC|p-tdQFsuR^)-zpAP z6B=P9{J|nAdrv?9hfK2~(~PV66n(!18XH`;4 z{_oinjimpP%6#Y3^atINwdX(GYqJoUR5h44ZHxBNt9l!#Uk=>+eI}`qX-W#9ST&$| z>pf8^brHgWE|RkU>ysL8CQeszxDbE!+^Kan^II-6ufhq;E;a) z_f~OWjzW55AldX(>GouA`0vp}Jq==0_W_^i=ySFF8$D*{D@CK7irF&nsaTJK(ieDS z(~8VH78rVUOf~Fl@9y`%{sV!oJTR1A1$x2yM$CtR?p=_`81!iSzb_-@>DIfQ>K-Zi z^54UCMc#sIii|Nbp65UP2o~(o%a0H|^coEwDZR)-)R^-8=WkpOuaT*CMl_KP$f+Jd zpOhdKW?L{@ChH1~De&FPy##fcP{bf(LMW&{?ff4qgt|gKD!w`P@lZ{Pzii_~we@ep zIG_l11EQAu;Kits@YaVfVg2d)Zq#KpTwdYE8GDNghCs&nWfNe)PrrYp)!%>avhfP5 z5itvS2m^*WO?2e$`A?l}^hisAabq$&6?+TRjIe)==rS5X&-0(ZR}eBGq*bvGA;_pl zDp5Pc2CoTSpKknaO(@U*CJa^Mx^Spa`Y1LbY+l5gUZsvazyF)E=bHeO3FU#4yL;knH*QKmY30qHuSa+|w%YnJYH7F?pW<^#=>D zL45_>qlaqv^|=O5%^eLq|7&40FG`$>)lec@s%Jq?$0`Y3#@7MkGE|8t_WZAJ zyQo|>e7+I!XRNOj{pXs-LmjH9@%$gcfLch6SF^!ueU93iIbYG(l zYQ`%YO0VzvziEs$!Ui%;NrAR01w099zyBISVl<$Vx|bCA7z*l;H|3t+fAyl$^3}A} zpc%TiRpCE}3I6@>Eh?W$P4GzDFMJ$QQx$Br_?-WP8`Q(!lx68pR-YTB2(|OS30pny zK|MC#dP6-QcpcP9;rD;cT-hPzmY|K=xh;E5H9V2`b^l8qs3!elY@ zk;*@UDoNF#UPrzu6J*1&sPW1FA5TLSr5vJY;HmN@;$0z)MF(qNjgGH}A@n0Eta|=a zC*7kVOg2A~HDXZtuOL)=+LxB;^M7C(v|TOW+so(Qj)Scr{bcQ(YjCu&{QDRV>T%Q3 zV!j+b-~Yip_AW8soHoHA$a?1*JT?}*eD`0!^);<|>|Hi`zWx^i!4D`{|Hi#r&zF~g z>AE#~(PSL~k?4akX#|=?#HR*asl(YVJ!OXAEe!rDUqfO@8eS|)jc(byLyL~h(pq%r z?O;2`cS&g0E3#Ab)NH0d?UlrIjCZgtqGCnncfa}bV7heQQTKv2_ZPlV@bj;>t)a|k zMQ`TccVGUtSrgWb%WT=KU1D-p`ruT)rnL04S-0t|)5#AG?efi6bi!pi@xxmM6Lx>~ zeDf7$=k`n(T)Ovzg@t?N!kpAL5uEeWFT@0+-`GX?Mh2Ooy9fGI-~J&|Ms%`*B|mb6kaRj zKwfwsh&JHA_veRm{ShtFp(9nubPS{E8R=;VT#JrLv}3#=GS9x?Uc8w8`z?AOwWekD zpOgG#YJt!vD`RkH_VBD(zjS7vUzXG(BK*^we*N?DdKX^o3bXQG5xglCMxjp8E31mr z!l>e_uG+zf&$zelbid_(Yo~khdZxo6nnB0xpyO$DWY&-&orljEFi{*bCN{N03+_L+ zTX08i58`Lensxh6+@afj*zX1w^or@w;cpWsw7w7TjKDAqie+%7o#KpU7iOE&G}?Sv zHbQ#WBi^>jearoGx%;Dq^dEbxXymgr;xBEop3Hk09)wv#Q_MPL* zGb6_(xBqnDfI)Z_#8oD<6Buc)do1@))Y(8n%16)X7SSb^PfJbDNNeFh(31ErX07>G+X3*$;Lu-!>;+wzhpVb5NJo(;wQCI=IKM2~)=A z;`J=Wk9_x7{xt-!8zE`EsZzcjTF|uAShhWlZW+sIW&~Kle|e7-<+D5P+*!(Py;IOJ zVOVNTo4AFX*gih1$AGwD&qfrj{H)LP2}8OU4O*Eul#l#79Y6F|RdlP2)^W`juwq?UlhUf%+2h!M`B0j zPdGZY$Hefg8>GEOVT@PG|9w+$opqILI%6ZQ#40u?v8^zO%(L_)h5W}2b;>sxavloOIklS zZ>8F|QrhBNejoRR+Vz~;^&GnL6FpsJYF8P$`u6a2J+F2>kFJ;`PuD87Yn8OcRiDJY z$*IbYt9{2Iwmr=wc0%nsfv)AfJY6T%u9KLV- zauqfaC$3vb0-rN7%u6z)r&EZ~&C$oFVK3=z9QdZVG_0 zA&?&egF`+i?9fDDD`6iT2pj`05q1~>;(&nw2oF05oC3}RSBcC%1c8T22#fb7**vhz zyGGdIYk>X01;UPi@exowVhpehfYA|W01zA*17rgEzzP6kBToPr8`TMz3ZQS)LEt=L zM{__Fu#d10!{#G-GGWKeAnc=U2|E@99*Y1l`SBMCI}S?6LvTV7Ve>~3_K7^g7GQG0 z9l}nE18N961xB94*i^_&OC)SzR{(~l!{Ce(!ah|>*qN9!6FQ3)5q5SCVT&&iw!}i% zr+Wc12IgKRY$=SFV&eQWgk3NdK>xyxgk3a{u!~`MNeW??LS`A-XVCY|3BoSl_rF8- zS0cj;8Q!m$0o)|)v!j5Wgk3oXSOZ)m>~oWV?Sw6h0U-1I8N#lL0@ed?<^{}s;SynA zgtsqZ{3Xm^-4*zpurE&q&JlJE`d;aU{J#P(Ud;oJ0d<6Z?L1-ELc!}60AuT5Y#qkR z4-$5LB7i=;0?WR!2mqN4NYjQrgmuE0vy8ACV}KgMZW;<)ChTU6ZAQBVeOvbfnDgdN z!fuNo?5|35alzpBWrY1T2V??=3A+PIcH{u1z#8BbaEGwJ83PmnW%zR+E0jO^fi0V0 z!~4F7YtDxE#2*!zHh11rbBg0qlhS&+xDswgtg;^#zshxL86|DN-`d!Szp;VWW2LQl zU;7yOz`5(U+`$Ox7G5343)7NYYOvuCX1EG=asM3MGe?|X{8Z}T^ang`uGVIxc-o$x mHr3OnIrDCE{iVSfo(UPbuCkllREE1hBQwW!`4)FI?Ee4;I3sre delta 16776 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 diff --git a/reactos/media/fonts/LiberationMono-Bold.ttf b/reactos/media/fonts/LiberationMono-Bold.ttf index 95de75300f71b3ce012f6984ded74e5d5badf0b7..c11a84dba71e2a78fb7bee467a9ebe24ba9dcd31 100644 GIT binary patch delta 4693 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 XFBNcOL;o$d{Ho-DJ6jHNJs15GF4g~b delta 4559 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 diff --git a/reactos/media/fonts/LiberationMono-Italic.ttf b/reactos/media/fonts/LiberationMono-Italic.ttf index 08f55d6367d2dfaf52a7d503c04a4ee80752c977..ce27ca7c250619400adcb86a76e3dd92a4adf181 100644 GIT binary patch delta 4976 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 delta 4500 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 diff --git a/reactos/media/fonts/LiberationMono-Regular.ttf b/reactos/media/fonts/LiberationMono-Regular.ttf index e3024a09d8ce2bd144f00948228f5d76253e6226..a74d22776828dbab819564b6050e5e2ebfefaedc 100644 GIT binary patch delta 4718 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 UN$dTZZLb&ZvuE4eT;uis0cI)c)&Kwi delta 4968 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 V4uu_h$_iJC4!W}KP*J+#zW{~dErS36 diff --git a/reactos/media/fonts/LiberationSans-Bold.ttf b/reactos/media/fonts/LiberationSans-Bold.ttf index 53200d956c9582d7797f54e872a9e2fcec5e8b3f..f9ad862c37efa91b88f657c17c4eaa74c80108a2 100644 GIT binary patch delta 14173 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 diff --git a/reactos/media/fonts/LiberationSans-BoldItalic.ttf b/reactos/media/fonts/LiberationSans-BoldItalic.ttf index d06deca60d1eceaf5458f225876c5f863c52e45c..b7b5b5b447669890dca4bc1031664c7e1b5f3efb 100644 GIT binary patch delta 13987 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�@(;b|L;)u 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 diff --git a/reactos/media/fonts/LiberationSans-Regular.ttf b/reactos/media/fonts/LiberationSans-Regular.ttf index 09fac2ff94ae92033266d8e021c22c382bea19b5..9d557bbb7b823474d9fb153b6eaece2806282c43 100644 GIT binary patch delta 14984 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

    kC}yy^GuY4>D48T)M@c+T2aHm=I*O}j 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 Hes2E*a@32W delta 8760 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 delta 7455 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 bTZ2y)@neQny6t-=ju%FSKbPjoN#FbzzyMxh diff --git a/reactos/media/fonts/LiberationSerif-BoldItalic.ttf b/reactos/media/fonts/LiberationSerif-BoldItalic.ttf index dc75de89c0f11c877687ce17a8db2a214baee814..b0ca8c6dc76117495ea12bd77e386632ef233dbe 100644 GIT binary patch delta 13408 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 ODgJ4UQm4%)rT-5?G5%Hn delta 7760 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 diff --git a/reactos/media/fonts/LiberationSerif-Italic.ttf b/reactos/media/fonts/LiberationSerif-Italic.ttf index d92b5e39292482c40634e85294bff9ccd50a5107..006db7e16e16db4bc62e6bbdbd83e7eb88a1b2cf 100644 GIT binary patch delta 12765 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 Avj6}9 delta 7549 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 delta 8318 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 Date: Sat, 29 May 2010 12:57:29 +0000 Subject: [PATCH 084/292] [BOOTVID] Don't increment an uninitialized and unused variable, bug #5103 svn path=/trunk/; revision=47409 --- reactos/drivers/base/bootvid/i386/bootvid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/base/bootvid/i386/bootvid.c b/reactos/drivers/base/bootvid/i386/bootvid.c index 3d0ae503167..08d0dc10b8e 100644 --- a/reactos/drivers/base/bootvid/i386/bootvid.c +++ b/reactos/drivers/base/bootvid/i386/bootvid.c @@ -155,7 +155,7 @@ VgaInterpretCmdStream(IN PUSHORT CmdStream) if (!ShortValue) continue; /* Loop the cmd array */ - for (; Count; Count--, CmdStream++, Value++) + for (; Count; Count--, CmdStream++) { /* Get the byte we're writing */ ShortValue += (*CmdStream) << 8; From c5d6cf73b08b2e57ab894c34a23e688b6aa8be82 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 13:14:05 +0000 Subject: [PATCH 085/292] [CRYPT32] sync to wine 1.2 RC2 svn path=/trunk/; revision=47410 --- reactos/dll/win32/crypt32/cert.c | 18 +++++++++-- reactos/dll/win32/crypt32/chain.c | 48 ++++++++++++++++++++++++++-- reactos/dll/win32/crypt32/regstore.c | 4 +++ reactos/dll/win32/crypt32/store.c | 21 +++++++++--- reactos/include/psdk/wincrypt.h | 2 ++ 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/reactos/dll/win32/crypt32/cert.c b/reactos/dll/win32/crypt32/cert.c index c25e612574f..12c013e7a4a 100644 --- a/reactos/dll/win32/crypt32/cert.c +++ b/reactos/dll/win32/crypt32/cert.c @@ -113,9 +113,21 @@ BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext) { - FIXME("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, - ppCertContext); - return FALSE; + static int calls; + PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore; + + if (!(calls++)) + FIXME("(%p, %p, %08x, %p): semi-stub\n", hCertStore, pCertContext, + dwAddDisposition, ppCertContext); + if (store->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) + return FALSE; + if (store->type == StoreTypeCollection) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + return CertAddCertificateContextToStore(hCertStore, pCertContext, + dwAddDisposition, ppCertContext); } PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, diff --git a/reactos/dll/win32/crypt32/chain.c b/reactos/dll/win32/crypt32/chain.c index 1724f4254fe..e951ef8e9c5 100644 --- a/reactos/dll/win32/crypt32/chain.c +++ b/reactos/dll/win32/crypt32/chain.c @@ -152,6 +152,20 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, return engine; } +typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT +{ + DWORD cbSize; + HCERTSTORE hRestrictedRoot; + HCERTSTORE hRestrictedTrust; + HCERTSTORE hRestrictedOther; + DWORD cAdditionalStore; + HCERTSTORE *rghAdditionalStore; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; +} CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT; + BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTCHAINENGINE *phChainEngine) { @@ -159,7 +173,8 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, TRACE("(%p, %p)\n", pConfig, phChainEngine); - if (pConfig->cbSize != sizeof(*pConfig)) + if (pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT) + && pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG)) { SetLastError(E_INVALIDARG); return FALSE; @@ -171,7 +186,10 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTSTORE root; HCERTCHAINENGINE engine; - if (pConfig->hRestrictedRoot) + if (pConfig->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && + pConfig->hExclusiveRoot) + root = CertDuplicateStore(pConfig->hExclusiveRoot); + else if (pConfig->hRestrictedRoot) root = CertDuplicateStore(pConfig->hRestrictedRoot); else root = CertOpenSystemStoreW(0, rootW); @@ -3017,7 +3035,31 @@ static BOOL match_dns_to_subject_alt_name(PCERT_EXTENSION ext, { TRACE_(chain)("dNSName: %s\n", debugstr_w( subjectName->rgAltEntry[i].u.pwszDNSName)); - if (!strcmpiW(server_name, + if (subjectName->rgAltEntry[i].u.pwszDNSName[0] == '*') + { + LPCWSTR server_name_dot; + + /* Matching a wildcard: a wildcard matches a single name + * component, which is terminated by a dot. RFC 1034 + * doesn't define whether multiple wildcards are allowed, + * but I will assume that they are not until proven + * otherwise. RFC 1034 also states that 'the "*" label + * always matches at least one whole label and sometimes + * more, but always whole labels.' Native crypt32 does not + * match more than one label with a wildcard, so I do the + * same here. Thus, a wildcard only accepts the first + * label, then requires an exact match of the remaining + * string. + */ + server_name_dot = strchrW(server_name, '.'); + if (server_name_dot) + { + if (!strcmpiW(server_name_dot, + subjectName->rgAltEntry[i].u.pwszDNSName + 1)) + matches = TRUE; + } + } + else if (!strcmpiW(server_name, subjectName->rgAltEntry[i].u.pwszDNSName)) matches = TRUE; } diff --git a/reactos/dll/win32/crypt32/regstore.c b/reactos/dll/win32/crypt32/regstore.c index 296b0c9a5b9..f4b4295835a 100644 --- a/reactos/dll/win32/crypt32/regstore.c +++ b/reactos/dll/win32/crypt32/regstore.c @@ -479,6 +479,10 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, ret = CRYPT_RegFlushStore(store, dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG); break; + case CERT_STORE_CTRL_AUTO_RESYNC: + FIXME("CERT_STORE_CTRL_AUTO_RESYNC: stub\n"); + ret = TRUE; + break; default: FIXME("%d: stub\n", dwCtrlType); ret = FALSE; diff --git a/reactos/dll/win32/crypt32/store.c b/reactos/dll/win32/crypt32/store.c index a8923949974..da3de5650db 100644 --- a/reactos/dll/win32/crypt32/store.c +++ b/reactos/dll/win32/crypt32/store.c @@ -855,7 +855,16 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); - if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) + switch (dwAddDisposition) + { + case CERT_STORE_ADD_ALWAYS: + break; + case CERT_STORE_ADD_NEW: + case CERT_STORE_ADD_REPLACE_EXISTING: + case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: + case CERT_STORE_ADD_USE_EXISTING: + case CERT_STORE_ADD_NEWER: + case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: { BYTE hashToAdd[20]; DWORD size = sizeof(hashToAdd); @@ -870,6 +879,12 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, NULL); } + break; + } + default: + FIXME("Unimplemented add disposition %d\n", dwAddDisposition); + SetLastError(E_INVALIDARG); + ret = FALSE; } switch (dwAddDisposition) @@ -940,10 +955,6 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, else toAdd = CertDuplicateCertificateContext(pCertContext); break; - default: - FIXME("Unimplemented add disposition %d\n", dwAddDisposition); - SetLastError(E_INVALIDARG); - ret = FALSE; } if (toAdd) diff --git a/reactos/include/psdk/wincrypt.h b/reactos/include/psdk/wincrypt.h index 3f7f4ed6e5b..540169b266d 100644 --- a/reactos/include/psdk/wincrypt.h +++ b/reactos/include/psdk/wincrypt.h @@ -3389,6 +3389,8 @@ typedef struct _CERT_CHAIN_ENGINE_CONFIG DWORD dwUrlRetrievalTimeout; DWORD MaximumCachedCertificates; DWORD CycleDetectionModulus; + HCERTSTORE hExclusiveRoot; + HCERTSTORE hExclusiveRootTrustedPeople; } CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG; /* message-related definitions */ From 85122dfdc473b1e543d24470c4415a991beead64 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Sat, 29 May 2010 13:22:48 +0000 Subject: [PATCH 086/292] Update zlib from 1.2.3 to 1.2.5 svn path=/trunk/; revision=47411 --- reactos/lib/3rdparty/zlib/ChangeLog | 355 ++++++- reactos/lib/3rdparty/zlib/FAQ | 261 ++--- reactos/lib/3rdparty/zlib/INDEX | 30 +- reactos/lib/3rdparty/zlib/Makefile.host | 46 - reactos/lib/3rdparty/zlib/Makefile.in | 219 +++-- reactos/lib/3rdparty/zlib/README | 86 +- reactos/lib/3rdparty/zlib/adler32.c | 38 +- reactos/lib/3rdparty/zlib/algorithm.txt | 2 +- reactos/lib/3rdparty/zlib/compress.c | 5 +- reactos/lib/3rdparty/zlib/configure | 347 ++++--- reactos/lib/3rdparty/zlib/crc32.c | 35 +- reactos/lib/3rdparty/zlib/deflate.c | 268 ++++-- reactos/lib/3rdparty/zlib/deflate.h | 27 +- reactos/lib/3rdparty/zlib/example.c | 4 +- reactos/lib/3rdparty/zlib/gzclose.c | 25 + reactos/lib/3rdparty/zlib/gzguts.h | 132 +++ reactos/lib/3rdparty/zlib/gzio.c | 1026 -------------------- reactos/lib/3rdparty/zlib/gzlib.c | 537 +++++++++++ reactos/lib/3rdparty/zlib/gzread.c | 653 +++++++++++++ reactos/lib/3rdparty/zlib/gzwrite.c | 531 +++++++++++ reactos/lib/3rdparty/zlib/infback.c | 93 +- reactos/lib/3rdparty/zlib/inffast.c | 78 +- reactos/lib/3rdparty/zlib/inffast.h | 2 +- reactos/lib/3rdparty/zlib/inflate.c | 282 ++++-- reactos/lib/3rdparty/zlib/inflate.h | 31 +- reactos/lib/3rdparty/zlib/inftrees.c | 61 +- reactos/lib/3rdparty/zlib/inftrees.h | 27 +- reactos/lib/3rdparty/zlib/minigzip.c | 134 ++- reactos/lib/3rdparty/zlib/trees.c | 87 +- reactos/lib/3rdparty/zlib/uncompr.c | 4 +- reactos/lib/3rdparty/zlib/zconf.h | 206 ++-- reactos/lib/3rdparty/zlib/zconf.in.h | 332 ------- reactos/lib/3rdparty/zlib/zlib.h | 1152 ++++++++++++++--------- reactos/lib/3rdparty/zlib/zlib.rbuild | 34 +- reactos/lib/3rdparty/zlib/zutil.c | 18 +- reactos/lib/3rdparty/zlib/zutil.h | 63 +- 36 files changed, 4570 insertions(+), 2661 deletions(-) delete mode 100755 reactos/lib/3rdparty/zlib/Makefile.host create mode 100644 reactos/lib/3rdparty/zlib/gzclose.c create mode 100644 reactos/lib/3rdparty/zlib/gzguts.h delete mode 100644 reactos/lib/3rdparty/zlib/gzio.c create mode 100644 reactos/lib/3rdparty/zlib/gzlib.c create mode 100644 reactos/lib/3rdparty/zlib/gzread.c create mode 100644 reactos/lib/3rdparty/zlib/gzwrite.c delete mode 100644 reactos/lib/3rdparty/zlib/zconf.in.h diff --git a/reactos/lib/3rdparty/zlib/ChangeLog b/reactos/lib/3rdparty/zlib/ChangeLog index 7f6869d3235..f310bb0fcdb 100644 --- a/reactos/lib/3rdparty/zlib/ChangeLog +++ b/reactos/lib/3rdparty/zlib/ChangeLog @@ -1,6 +1,359 @@ ChangeLog file for zlib +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling error in zlib.h [Willem] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + Changes in 1.2.3 (18 July 2005) - Apply security vulnerability fixes to contrib/infback9 as well - Clean up some text files (carriage returns, trailing space) @@ -13,7 +366,7 @@ Changes in 1.2.2.4 (11 July 2005) compile - Fix some spelling errors in comments [Betts] - Correct inflateInit2() error return documentation in zlib.h -- Added zran.c example of compressed data random access to examples +- Add zran.c example of compressed data random access to examples directory, shows use of inflatePrime() - Fix cast for assignments to strm->state in inflate.c and infback.c - Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] diff --git a/reactos/lib/3rdparty/zlib/FAQ b/reactos/lib/3rdparty/zlib/FAQ index 441d910daa1..1a22750a58e 100644 --- a/reactos/lib/3rdparty/zlib/FAQ +++ b/reactos/lib/3rdparty/zlib/FAQ @@ -3,8 +3,8 @@ If your question is not there, please check the zlib home page -http://www.zlib.org which may have more recent information. -The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html +http://zlib.net/ which may have more recent information. +The lastest zlib FAQ is at http://zlib.net/zlib_faq.html 1. Is zlib Y2K-compliant? @@ -13,54 +13,51 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 2. Where can I get a Windows DLL version? - The zlib sources can be compiled without change to produce a DLL. - See the file win32/DLL_FAQ.txt in the zlib distribution. - Pointers to the precompiled DLL are found in the zlib web site at - http://www.zlib.org. + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at http://zlib.net/ . 3. Where can I get a Visual Basic interface to zlib? See - * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm - * contrib/visual-basic.txt in the zlib distribution + * http://marknelson.us/1997/01/01/zlib-engine/ * win32/DLL_FAQ.txt in the zlib distribution 4. compress() returns Z_BUF_ERROR. - Make sure that before the call of compress, the length of the compressed - buffer is equal to the total size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference ("as any"), not by value ("as long"). 5. deflate() or inflate() returns Z_BUF_ERROR. - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a + heavily annotated example. 6. Where's the zlib documentation (man pages, etc.)? - It's in zlib.h for the moment, and Francis S. Lin has converted it to a - web page zlib.html. Volunteers to transform this to Unix-style man pages, - please contact us (zlib@gzip.org). Examples of zlib usage are in the files - example.c and minigzip.c. + It's in zlib.h . Examples of zlib usage are in the files example.c and + minigzip.c, with more in examples/ . 7. Why don't you use GNU autoconf or libtool or ...? - Because we would like to keep zlib as a very small and simple - package. zlib is rather portable and doesn't need much configuration. + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. 8. I found a bug in zlib. - Most of the time, such problems are due to an incorrect usage of - zlib. Please try to reproduce the problem with a small program and send - the corresponding source to us at zlib@gzip.org . Do not send - multi-megabyte data files without prior agreement. + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. 9. Why do I get "undefined reference to gzputc"? @@ -82,7 +79,7 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 12. Can zlib handle .Z files? - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt the code of uncompress on your own. 13. How can I make a Unix shared library? @@ -99,8 +96,10 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html However, many flavors of Unix come with a shared zlib already installed. Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to it. + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . 15. I have a question about OttoPDF. @@ -109,8 +108,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 16. Can zlib decode Flate data in an Adobe PDF file? - Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . - To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + Yes. See http://www.pdflib.com/ . To modify PDF forms, see + http://sourceforge.net/projects/acroformtool/ . 17. Why am I getting this "register_frame_info not found" error on Solaris? @@ -121,67 +120,67 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html symbol __register_frame_info: referenced symbol not found The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See http://www.sunfreeware.com for Solaris versions of zlib and applications using zlib. 18. Why does gzip give an error on a file I make with compress/deflate? The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip - formats use the same compressed data format internally, but have different - headers and trailers around the compressed data. + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. 19. Ok, so why are there two different formats? - The gzip format was designed to retain the directory information about - a single file, such as the name and last modification date. The zlib - format on the other hand was designed for in-memory and communication - channel applications, and has a much more compact header and trailer and - uses a faster integrity check than gzip. + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. 20. Well that's nice, but how do I make a gzip file in memory? You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode - the gzip format using inflateInit2(). Read zlib.h for more details. + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. 21. Is zlib thread-safe? - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's Init functions allow - for the application to provide custom memory allocation routines. + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. Of course, you should only operate on any given zlib or gzip stream from a single thread at a time. 22. Can I use zlib in my commercial application? - Yes. Please read the license in zlib.h. + Yes. Please read the license in zlib.h. 23. Is zlib under the GNU license? - No. Please read the license in zlib.h. + No. Please read the license in zlib.h. 24. The license says that altered source versions must be "plainly marked". So what exactly do I need to do to meet that requirement? - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers + identification string should be appended to ZLIB_VERSION. Version numbers x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering + maintainers. For example, if the version of the base zlib you are altering is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also update the version strings in deflate.c and inftrees.c. For altered source distributions, you should also note the origin and nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your + with the dates of the alterations. The origin should include at least your name (or your company's name), and an email address to contact for help or issues with the library. @@ -197,105 +196,112 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 26. Will zlib work on a 64-bit machine? - It should. It has been tested on 64-bit machines, and has no dependence - on any data types being limited to 32-bits in length. If you have any + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any difficulties, please provide a complete problem report to zlib@gzip.org 27. Will zlib decompress data from the PKWare Data Compression Library? - No. The PKWare DCL uses a completely different compressed data format - than does PKZIP and zlib. However, you can look in zlib's contrib/blast + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast directory for a possible solution to your problem. 28. Can I access data randomly in a compressed stream? - No, not without some preparation. If when compressing you periodically - use Z_FULL_FLUSH, carefully write all the pending data at those points, - and keep an index of those locations, then you can start decompression - at those points. You have to be careful to not use Z_FULL_FLUSH too - often, since it can significantly degrade compression. + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . 29. Does zlib work on MVS, OS/390, CICS, etc.? - We don't know for sure. We have heard occasional reports of success on - these systems. If you do use it on one of these, please provide us with - a report, instructions, and patches that we can reference when we get - these questions. Thanks. + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. -30. Is there some simpler, easier to read version of inflate I can look at - to understand the deflate format? +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? - First off, you should read RFC 1951. Second, yes. Look in zlib's + First off, you should read RFC 1951. Second, yes. Look in zlib's contrib/puff directory. 31. Does zlib infringe on any patents? - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: http://www.gzip.org/#faq11 32. Can zlib work with greater than 4 GB of data? - Yes. inflate() and deflate() will process any amount of data correctly. + Yes. inflate() and deflate() will process any amount of data correctly. Each call of inflate() or deflate() is limited to input and output chunks of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters + inflate() or deflate(). The application can easily set up its own counters updated after each call of inflate() or deflate() to count beyond 4 GB. compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. - The word "may" appears several times above since there is a 4 GB limit - only if the compiler's "long" type is 32 bits. If the compiler's "long" - type is 64 bits, then the limit is 16 exabytes. + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. 33. Does zlib have any security vulnerabilities? - The only one that we are aware of is potentially in gzprintf(). If zlib - is compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of a 4K string space, other than the caller of - gzprintf() assuring that the output will not exceed 4K. On the other - hand, if zlib is compiled to use snprintf() or vsnprintf(), which should - normally be the case, then there is no vulnerability. The ./configure - script will display warnings if an insecure variation of sprintf() will - be used by gzprintf(). Also the zlibCompileFlags() function will return - information on what variant of sprintf() is used by gzprintf(). + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). If you don't have snprintf() or vsnprintf() and would like one, you can find a portable implementation here: http://www.ijs.si/software/snprintf/ - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability. + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. 34. Is there a Java version of zlib? Probably what you want is to use zlib in Java. zlib is already included as part of the Java SDK in the java.util.zip package. If you really want a version of zlib written in the Java language, look on the zlib home - page for links: http://www.zlib.org/ + page for links: http://zlib.net/ . 35. I get this or that compiler or source-code scanner warning when I crank it up to maximally-pedantic. Can't you guys write proper code? Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly. So now, we simply make sure that the code always - works. + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. 36. Valgrind (or some similar memory access checker) says that deflate is performing a conditional jump that depends on an uninitialized value. Isn't that a bug? - No. That is intentional for performance reasons, and the output of - deflate is not affected. This only started showing up recently since - zlib 1.2.x uses malloc() by default for allocations, whereas earlier - versions used calloc(), which zeros out the allocated memory. + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. 37. Will zlib read the (insert any ancient or arcane format here) compressed data format? @@ -305,20 +311,21 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 38. How can I encrypt/decrypt zip files with zlib? - zlib doesn't support encryption. The original PKZIP encryption is very weak - and can be broken with freely available programs. To get strong encryption, - use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. - For PKZIP compatible "encryption", look at http://www.info-zip.org/ + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://www.info-zip.org/ 39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion - with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 correctly points to the zlib specification in RFC 1950 for the "deflate" transfer encoding, there have been reports of servers and browsers that incorrectly produce or expect raw deflate data per the deflate - specficiation in RFC 1951, most notably Microsoft. So even though the + specficiation in RFC 1951, most notably Microsoft. So even though the "deflate" transfer encoding using the zlib format would be the more efficient approach (and in fact exactly what the zlib format was designed for), using the "gzip" transfer encoding is probably more reliable due to @@ -328,12 +335,32 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 40. Does zlib support the new "Deflate64" format introduced by PKWare? - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. - In any case, the compression improvements are so modest compared to other - more modern approaches, that it's not worth the effort to implement. + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. -41. Can you please sign these lengthy legal documents and fax them back to us +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us so that we can use your software in our product? No. Go away. Shoo. diff --git a/reactos/lib/3rdparty/zlib/INDEX b/reactos/lib/3rdparty/zlib/INDEX index 0587e5902bd..f6c51ca1759 100644 --- a/reactos/lib/3rdparty/zlib/INDEX +++ b/reactos/lib/3rdparty/zlib/INDEX @@ -1,23 +1,32 @@ +CMakeLists.txt cmake build file ChangeLog history of changes FAQ Frequently Asked Questions about zlib INDEX this file -Makefile makefile for Unix (generated by configure) -Makefile.in makefile for Unix (template for configure) +Makefile dummy Makefile that tells you to ./configure +Makefile.in template for Unix Makefile README guess what -algorithm.txt description of the (de)compression algorithm configure configure script for Unix -zconf.in.h template for zconf.h (used by configure) +make_vms.com makefile for VMS +treebuild.xml XML description of source file dependencies +zconf.h.cmakein zconf.h template for cmake +zconf.h.in zconf.h template for configure +zlib.3 Man page for zlib +zlib.3.pdf Man page in PDF format +zlib.map Linux symbol information +zlib.pc.in Template for pkg-config descriptor +zlib2ansi perl script to convert source files for C++ compilation amiga/ makefiles for Amiga SAS C -as400/ makefiles for IBM AS/400 +doc/ documentation for formats and algorithms msdos/ makefiles for MSDOS +nintendods/ makefile for Nintendo DS old/ makefiles for various architectures and zlib documentation files that have not yet been updated for zlib 1.2.x -projects/ projects for various Integrated Development Environments qnx/ makefiles for QNX +watcom/ makefiles for OpenWatcom win32/ makefiles for Windows - zlib public header files (must be kept): + zlib public header files (required for library use): zconf.h zlib.h @@ -28,7 +37,11 @@ crc32.c crc32.h deflate.c deflate.h -gzio.c +gzclose.c +gzguts.h +gzlib.c +gzread.c +gzwrite.c infback.c inffast.c inffast.h @@ -46,6 +59,7 @@ zutil.h source files for sample programs: example.c minigzip.c +See examples/README.examples for more unsupported contribution by third parties See contrib/README.contrib diff --git a/reactos/lib/3rdparty/zlib/Makefile.host b/reactos/lib/3rdparty/zlib/Makefile.host deleted file mode 100755 index 6a2a9b38267..00000000000 --- a/reactos/lib/3rdparty/zlib/Makefile.host +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ -PATH_TO_TOP = ../.. - -TARGET = zlib.host.a - -CFLAGS = \ - -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -OBJECTS = \ - adler32.o \ - compress.o \ - crc32.o \ - gzio.o \ - uncompr.o \ - deflate.o \ - trees.o \ - zutil.o \ - inflate.o \ - infblock.o \ - inftrees.o \ - infcodes.o \ - infutil.o \ - inffast.o - -OBJECTS := $(OBJECTS:%=hostobjs/%) - -all: hostobjs $(TARGET) - -hostobjs: - - $(RMKDIR) hostobjs - -hostobjs/%.o: %.c - $(HOST_CC) $(CFLAGS) -c $< -o $@ - -$(TARGET): $(OBJECTS) - $(HOST_AR) -r $(TARGET) $^ - -clean: - - $(RM) hostobjs/* - - $(RM) $(TARGET) - - $(RMDIR) hostobjs - -.phony: clean - -include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/lib/3rdparty/zlib/Makefile.in b/reactos/lib/3rdparty/zlib/Makefile.in index 2fd6e45c48d..5b15bd00d73 100644 --- a/reactos/lib/3rdparty/zlib/Makefile.in +++ b/reactos/lib/3rdparty/zlib/Makefile.in @@ -1,11 +1,11 @@ # Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. +# Copyright (C) 1995-2010 Jean-loup Gailly. # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: # ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static # To use the asm code, type: # cp contrib/asm?86/match.S ./match.S @@ -24,17 +24,22 @@ CFLAGS=-O #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ # -Wstrict-prototypes -Wmissing-prototypes -LDFLAGS=libz.a +SFLAGS=-O +LDFLAGS= +TEST_LDFLAGS=-L. libz.a LDSHARED=$(CC) CPP=$(CC) -E -LIBS=libz.a +STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 +SHAREDLIBV=libz.so.1.2.5 SHAREDLIBM=libz.so.1 +LIBS=$(STATICLIB) $(SHAREDLIBV) AR=ar rc RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC=-lc TAR=tar SHELL=/bin/sh EXE= @@ -42,33 +47,68 @@ EXE= prefix = /usr/local exec_prefix = ${prefix} libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} includedir = ${prefix}/include mandir = ${prefix}/share/man man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o +OBJC = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o +PIC_OBJC = adler32.lo compress.lo crc32.lo deflate.lo gzclose.lo gzlib.lo gzread.lo \ + gzwrite.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo + +# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo OBJA = -# to use the asm code: make OBJA=match.o +PIC_OBJA = -TEST_OBJS = example.o minigzip.o +OBJS = $(OBJC) $(OBJA) -all: example$(EXE) minigzip$(EXE) +PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + +all: static shared + +static: example$(EXE) minigzip$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +all64: example64$(EXE) minigzip64$(EXE) check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ + +test: all teststatic testshared + +teststatic: static + @if echo hello world | ./minigzip | ./minigzip -d && ./example; then \ echo ' *** zlib test OK ***'; \ else \ - echo ' *** zlib test FAILED ***'; \ + echo ' *** zlib test FAILED ***'; false; \ fi + -@rm -f foo.gz -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) +testshared: shared + @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +test64: all64 + @if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 match.o: match.S @@ -77,58 +117,116 @@ match.o: match.S mv _match.o match.o rm -f _match.s -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) +match.lo: match.S + $(CPP) match.S > _match.s + $(CC) -c -fPIC _match.s + mv _match.o match.lo + rm -f _match.s + +example64.o: example.c zlib.h zconf.h + $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ example.c + +minigzip64.o: minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ minigzip.c + +.SUFFIXES: .lo + +.c.lo: + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $< + -@mv objs/$*.o $@ + +$(SHAREDLIBV): $(PIC_OBJS) + $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) rm -f $(SHAREDLIB) $(SHAREDLIBM) ln -s $@ $(SHAREDLIB) ln -s $@ $(SHAREDLIBM) + -@rmdir objs -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) +example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) +minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ +examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) + +minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) + +example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +minigzip64$(EXE): minigzip64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + +install-libs: $(LIBS) + -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + cp $(STATICLIB) $(DESTDIR)$(libdir) + cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir) + cd $(DESTDIR)$(libdir); chmod u=rw,go=r $(STATICLIB) + -@(cd $(DESTDIR)$(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + -@cd $(DESTDIR)$(sharedlibdir); if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ + chmod 755 $(SHAREDLIBV); \ rm -f $(SHAREDLIB) $(SHAREDLIBM); \ ln -s $(SHAREDLIBV) $(SHAREDLIB); \ ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ + ($(LDCONFIG) || true) >/dev/null 2>&1; \ fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 + cp zlib.3 $(DESTDIR)$(man3dir) + chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + cp zlib.pc $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc # The ranlib in install is needed on NeXTSTEP which checks file times # ldconfig is for Linux +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + cp zlib.h zconf.h $(DESTDIR)$(includedir) + chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ + cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir); rm -f libz.a; \ + if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ fi - cd $(man3dir); rm -f zlib.3 + cd $(DESTDIR)$(man3dir); rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc + +docs: zlib.3.pdf + +zlib.3.pdf: zlib.3 + groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf + +zconf.h.in: zconf.h.cmakein + sed "/^#cmakedefine/D" < zconf.h.cmakein > zconf.h.in + touch -r zconf.h.cmakein zconf.h.in + +zconf: zconf.h.in + cp -p zconf.h.in zconf.h mostlyclean: clean clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ + example64$(EXE) minigzip64$(EXE) \ libz.* foo.gz so_locations \ _match.s maketree contrib/infback9/*.o + rm -rf objs maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store +distclean: clean zconf docs + rm -f Makefile zlib.pc + -@rm -f .DS_Store + -@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile + -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile + -@touch -r Makefile.in Makefile tags: etags *.[ch] @@ -138,17 +236,22 @@ depend: # DO NOT DELETE THIS LINE -- make depend depends on it. -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h +adler32.o zutil.o: zutil.h zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h +compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h crc32.h deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h +infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h + +adler32.lo zutil.lo: zutil.h zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h +crc32.lo: zutil.h zlib.h zconf.h crc32.h +deflate.lo: deflate.h zutil.h zlib.h zconf.h +infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.lo: zutil.h zlib.h zconf.h inftrees.h +trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h diff --git a/reactos/lib/3rdparty/zlib/README b/reactos/lib/3rdparty/zlib/README index 758cc50020d..d4219bf889f 100644 --- a/reactos/lib/3rdparty/zlib/README +++ b/reactos/lib/3rdparty/zlib/README @@ -1,56 +1,52 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.3 is a general purpose data compression library. All the code is +zlib 1.2.5 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +and rfc1952.txt (gzip format). All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The +is working correctly. Another example is given in the file minigzip.c. The compression library itself is composed of all source files except example.c and minigzip.c. To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install". For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use one +of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.3 are documented in the file ChangeLog. +The changes made in version 1.2.5 are documented in the file ChangeLog. -Unsupported third party contributions are provided in directory "contrib". +Unsupported third party contributions are provided in directory contrib/ . -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . -A Perl interface to zlib written by Paul Marquess is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html +http://www.python.org/doc/lib/module-zlib.html . -A zlib binding for TCL written by Andreas Kupries is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html +zlib is built into tcl: http://wiki.tcl.tk/4610 . An experimental package to read and write files in .zip format, written on top of zlib by Gilles Vollant , is available in the @@ -74,25 +70,21 @@ Notes for some targets: - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with other compilers. Use "make test" to check your compiler. -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. +- gzdopen is not supported on RISCOS or BEOS. - For PalmOs, see http://palmzlib.sourceforge.net/ -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - Acknowledgments: - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. Copyright notice: - (C) 1995-2004 Jean-loup Gailly and Mark Adler + (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,13 +105,11 @@ Copyright notice: Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/reactos/lib/3rdparty/zlib/adler32.c b/reactos/lib/3rdparty/zlib/adler32.c index 007ba26277c..65ad6a5adc4 100644 --- a/reactos/lib/3rdparty/zlib/adler32.c +++ b/reactos/lib/3rdparty/zlib/adler32.c @@ -1,12 +1,15 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2007 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ -#define ZLIB_INTERNAL -#include "zlib.h" +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 @@ -125,10 +128,10 @@ uLong ZEXPORT adler32(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) +local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; uLong adler2; - z_off_t len2; + z_off64_t len2; { unsigned long sum1; unsigned long sum2; @@ -141,9 +144,26 @@ uLong ZEXPORT adler32_combine(adler1, adler2, len2) MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/reactos/lib/3rdparty/zlib/algorithm.txt b/reactos/lib/3rdparty/zlib/algorithm.txt index b022dde312a..34960bddacc 100644 --- a/reactos/lib/3rdparty/zlib/algorithm.txt +++ b/reactos/lib/3rdparty/zlib/algorithm.txt @@ -121,7 +121,7 @@ At least for deflate's output that generates new trees every several 10's of kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code would take too long if you're only decoding several thousand symbols. At the other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend two much time +that's essentially a Huffman tree. But then you spend too much time traversing the tree while decoding, even for short symbols. So the number of bits for the first lookup table is a trade of the time to diff --git a/reactos/lib/3rdparty/zlib/compress.c b/reactos/lib/3rdparty/zlib/compress.c index df04f0148e6..ea4dfbe9d7b 100644 --- a/reactos/lib/3rdparty/zlib/compress.c +++ b/reactos/lib/3rdparty/zlib/compress.c @@ -1,5 +1,5 @@ /* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. + * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -75,5 +75,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen) uLong ZEXPORT compressBound (sourceLen) uLong sourceLen; { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; } diff --git a/reactos/lib/3rdparty/zlib/configure b/reactos/lib/3rdparty/zlib/configure index d7ffdc3458d..bd9edd26cdd 100644 --- a/reactos/lib/3rdparty/zlib/configure +++ b/reactos/lib/3rdparty/zlib/configure @@ -1,37 +1,61 @@ #!/bin/sh -# configure script for zlib. This script is needed only if -# you wish to build a shared library and your system supports them, -# of if you need special compiler, flags or install directory. -# Otherwise, you can just use directly "make test; make install" +# configure script for zlib. # -# To create a shared library, use "configure --shared"; by default a static -# library is created. If the primitive shared library support provided here -# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static # # To impose specific compiler or flags or install directory, use for example: # prefix=$HOME CC=cc CFLAGS="-O4" ./configure # or for csh/tcsh users: # (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) -# LDSHARED is the command to be used to create a shared library # Incorrect settings of CC or CFLAGS may prevent creating a shared library. # If you have problems, try without defining CC and CFLAGS before reporting # an error. -LIBS=libz.a -LDFLAGS="-L. ${LIBS}" +if [ -n "${CHOST}" ]; then + uname="$(echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')" + CROSS_PREFIX="${CHOST}-" +fi + +STATICLIB=libz.a +LDFLAGS="${LDFLAGS} -L. ${STATICLIB}" VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h` VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` -AR=${AR-"ar rc"} -RANLIB=${RANLIB-"ranlib"} +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} +fi +AR_RC="${AR} rc" +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} +else + RANLIB=${RANLIB-"ranlib"} +fi +if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then + NM=${NM-"${CROSS_PREFIX}nm"} + test -n "${CROSS_PREFIX}" && echo Using ${NM} +else + NM=${NM-"nm"} +fi +LDCONFIG=${LDCONFIG-"ldconfig"} +LDSHAREDLIBC="${LDSHAREDLIBC--lc}" prefix=${prefix-/usr/local} exec_prefix=${exec_prefix-'${prefix}'} libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} includedir=${includedir-'${prefix}/include'} mandir=${mandir-'${prefix}/share/man'} shared_ext='.so' -shared=0 +shared=1 +zprefix=0 +build64=0 gcc=0 old_cc="$CC" old_cflags="$CFLAGS" @@ -39,21 +63,29 @@ old_cflags="$CFLAGS" while test $# -ge 1 do case "$1" in - -h* | --h*) + -h* | --help) echo 'usage:' - echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' - echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' - exit 0;; - -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; - -p* | --p*) prefix="$2"; shift; shift;; - -e* | --e*) exec_prefix="$2"; shift; shift;; - -l* | --l*) libdir="$2"; shift; shift;; - -i* | --i*) includedir="$2"; shift; shift;; - -s* | --s*) shared=1; shift;; - *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;; + echo ' configure [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' + echo ' [--includedir=INCLUDEDIR]' + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; + --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; + -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + -z* | --zprefix) zprefix=1; shift ;; + -6* | --64) build64=1; shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir"; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir"; shift ;; + *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;; esac done @@ -63,46 +95,68 @@ extern int getchar(); int hello() {return getchar();} EOF -test -z "$CC" && echo Checking for gcc... -cc=${CC-gcc} +test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... +cc=${CC-${CROSS_PREFIX}gcc} cflags=${CFLAGS-"-O3"} # to force the asm version use: CFLAGS="-O3 -DASMV" ./configure case "$cc" in - *gcc*) gcc=1;; + *gcc*) gcc=1 ;; esac if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then CC="$cc" - SFLAGS=${CFLAGS-"-fPIC -O3"} - CFLAGS="$cflags" - case `(uname -s || echo unknown) 2>/dev/null` in - Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};; - CYGWIN* | Cygwin* | cygwin* | OS/2* ) - EXE='.exe';; + SFLAGS="${CFLAGS--O3} -fPIC" + CFLAGS="${CFLAGS--O3}" + if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + fi + if test "${ZLIBGCCWARN}" = "YES"; then + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi + if test -z "$uname"; then + uname=`(uname -s || echo unknown) 2>/dev/null` + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | *BSD | DragonFly) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;; + CYGWIN* | Cygwin* | cygwin* | OS/2*) + EXE='.exe' ;; + MINGW*|mingw*) +# temporary bypass + rm -f $test.[co] $test $test$shared_ext + echo "Please use win32/Makefile.gcc instead." + exit 1 + LDSHARED=${LDSHARED-"$cc -shared"} + LDSHAREDLIBC="" + EXE='.exe' ;; QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 # (alain.bonnefoy@icbt.com) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};; + LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; HP-UX*) LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} case `(uname -m || echo unknown) 2>/dev/null` in ia64) shared_ext='.so' - SHAREDLIB='libz.so';; + SHAREDLIB='libz.so' ;; *) shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; + SHAREDLIB='libz.sl' ;; + esac ;; Darwin*) shared_ext='.dylib' SHAREDLIB=libz$shared_ext SHAREDLIBV=libz.$VER$shared_ext SHAREDLIBM=libz.$VER1$shared_ext - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};; - *) LDSHARED=${LDSHARED-"$cc -shared"};; + LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} ;; + *) LDSHARED=${LDSHARED-"$cc -shared"} ;; esac else # find system name and corresponding cc options CC=${CC-cc} - case `(uname -sr || echo unknown) 2>/dev/null` in + gcc=0 + if test -z "$uname"; then + uname=`(uname -sr || echo unknown) 2>/dev/null` + fi + case "$uname" in HP-UX*) SFLAGS=${CFLAGS-"-O +z"} CFLAGS=${CFLAGS-"-O"} # LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} @@ -110,57 +164,64 @@ else case `(uname -m || echo unknown) 2>/dev/null` in ia64) shared_ext='.so' - SHAREDLIB='libz.so';; + SHAREDLIB='libz.so' ;; *) shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; + SHAREDLIB='libz.sl' ;; + esac ;; IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} CFLAGS=${CFLAGS-"-ansi -O2"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; + LDFLAGS="${LDFLAGS} -Wl,-rpath,." + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; OSF1*) SFLAGS=${CFLAGS-"-O -std1"} CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; QNX*) SFLAGS=${CFLAGS-"-4 -O"} CFLAGS=${CFLAGS-"-4 -O"} LDSHARED=${LDSHARED-"cc"} RANLIB=${RANLIB-"true"} - AR="cc -A";; + AR_RC="cc -A" ;; SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} CFLAGS=${CFLAGS-"-O3"} - LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; - SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} - CFLAGS=${CFLAGS-"-fast -xcg89"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; + SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"} + case `(uname -m || echo unknown) 2>/dev/null` in + i86*) + SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."} + CFLAGS=${CFLAGS-"-xpentium -fast"} ;; + *) + SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg92"} ;; + esac ;; SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} CFLAGS=${CFLAGS-"-O2"} - LDSHARED=${LDSHARED-"ld"};; - SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} - CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"} - LDSHARED=${LDSHARED-"cc -xarch=v9b"};; + LDSHARED=${LDSHARED-"ld"} ;; + SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} + CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} + LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; UNIX_System_V\ 4.2.0) SFLAGS=${CFLAGS-"-KPIC -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; UNIX_SV\ 4.2MP) SFLAGS=${CFLAGS-"-Kconform_pic -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; OpenUNIX\ 5) SFLAGS=${CFLAGS-"-KPIC -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; AIX*) # Courtesy of dbakker@arrayasolutions.com SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"};; - # send working options for other systems to support@gzip.org + LDSHARED=${LDSHARED-"xlc -G"} ;; + # send working options for other systems to zlib@gzip.org *) SFLAGS=${CFLAGS-"-O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared"} ;; esac fi @@ -171,38 +232,83 @@ SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} if test $shared -eq 1; then echo Checking for shared library support... # we must test in two steps (cc then ld), required at least on SunOS 4.x - if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && - test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then - CFLAGS="$SFLAGS" - LIBS="$SHAREDLIBV" + if test "`($CC -w -c $SFLAGS $test.c) 2>&1`" = "" && + test "`($LDSHARED $SFLAGS -o $test$shared_ext $test.o) 2>&1`" = ""; then echo Building shared library $SHAREDLIBV with $CC. elif test -z "$old_cc" -a -z "$old_cflags"; then echo No shared library support. shared=0; else + echo Tested $CC -w -c $SFLAGS $test.c + $CC -w -c $SFLAGS $test.c + echo Tested $LDSHARED $SFLAGS -o $test$shared_ext $test.o + $LDSHARED $SFLAGS -o $test$shared_ext $test.o echo 'No shared library support; try without defining CC and CFLAGS' shared=0; fi fi if test $shared -eq 0; then LDSHARED="$CC" - echo Building static library $LIBS version $VER with $CC. + ALL="static" + TEST="all teststatic" + SHAREDLIB="" + SHAREDLIBV="" + SHAREDLIBM="" + echo Building static library $STATICLIB version $VER with $CC. else - LDFLAGS="-L. ${SHAREDLIBV}" + ALL="static shared" + TEST="all teststatic testshared" fi +cat > $test.c < +off64_t dummy = 0; +EOF +if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + ALL="${ALL} all64" + TEST="${TEST} test64" + echo "Checking for off64_t... Yes." + echo "Checking for fseeko... Yes." +else + echo "Checking for off64_t... No." + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then + echo "Checking for fseeko... Yes." + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." + fi +fi + +cp -p zconf.h.in zconf.h + cat > $test.c < int main() { return 0; } EOF if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h + sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h echo "Checking for unistd.h... Yes." else - cp -p zconf.in.h zconf.h echo "Checking for unistd.h... No." fi +if test $zprefix -eq 1; then + sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Using z_ prefix on all symbols." +fi + cat > $test.c < #include @@ -219,13 +325,13 @@ int main() EOF if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()" + echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." cat > $test.c < #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { char buf[20]; va_list ap; @@ -249,7 +355,7 @@ EOF #include #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { int n; char buf[20]; @@ -271,6 +377,7 @@ EOF echo "Checking for return value of vsnprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_vsnprintf_void" + SFLAGS="$SFLAGS -DHAS_vsnprintf_void" echo "Checking for return value of vsnprintf()... No." echo " WARNING: apparently vsnprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -278,6 +385,7 @@ EOF fi else CFLAGS="$CFLAGS -DNO_vsnprintf" + SFLAGS="$SFLAGS -DNO_vsnprintf" echo "Checking for vsnprintf() in stdio.h... No." echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" echo " can build but will be open to possible buffer-overflow security" @@ -287,7 +395,7 @@ EOF #include #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { int n; char buf[20]; @@ -309,6 +417,7 @@ EOF echo "Checking for return value of vsprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_vsprintf_void" + SFLAGS="$SFLAGS -DHAS_vsprintf_void" echo "Checking for return value of vsprintf()... No." echo " WARNING: apparently vsprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -316,7 +425,7 @@ EOF fi fi else - echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()" + echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." cat >$test.c < @@ -358,6 +467,7 @@ EOF echo "Checking for return value of snprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_snprintf_void" + SFLAGS="$SFLAGS -DHAS_snprintf_void" echo "Checking for return value of snprintf()... No." echo " WARNING: apparently snprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -365,6 +475,7 @@ EOF fi else CFLAGS="$CFLAGS -DNO_snprintf" + SFLAGS="$SFLAGS -DNO_snprintf" echo "Checking for snprintf() in stdio.h... No." echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" echo " can build but will be open to possible buffer-overflow security" @@ -390,6 +501,7 @@ EOF echo "Checking for return value of sprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_sprintf_void" + SFLAGS="$SFLAGS -DHAS_sprintf_void" echo "Checking for return value of sprintf()... No." echo " WARNING: apparently sprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -398,41 +510,37 @@ EOF fi fi -cat >$test.c < -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for errno.h... Yes." -else - echo "Checking for errno.h... No." - CFLAGS="$CFLAGS -DNO_ERRNO_H" -fi - -cat > $test.c < -#include -#include -caddr_t hello() { - return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); +if test "$gcc" -eq 1; then + cat > $test.c <= 33) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif +int ZLIB_INTERNAL foo; +int main() +{ + return 0; } EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - CFLAGS="$CFLAGS -DUSE_MMAP" - echo Checking for mmap support... Yes. -else - echo Checking for mmap support... No. + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + echo "Checking for attribute(visibility) support... Yes." + else + CFLAGS="$CFLAGS -DNO_VIZ" + SFLAGS="$SFLAGS -DNO_VIZ" + echo "Checking for attribute(visibility) support... No." + fi fi CPP=${CPP-"$CC -E"} case $CFLAGS in *ASMV*) - if test "`nm $test.o | grep _hello`" = ""; then + if test "`$NM $test.o | grep _hello`" = ""; then CPP="$CPP -DNO_UNDERLINE" echo Checking for underline in external names... No. else echo Checking for underline in external names... Yes. - fi;; + fi ;; esac rm -f $test.[co] $test $test$shared_ext @@ -441,19 +549,48 @@ rm -f $test.[co] $test $test$shared_ext sed < Makefile.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# -/^CPP *=/s#=.*#=$CPP# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# /^LDSHARED *=/s#=.*#=$LDSHARED# -/^LIBS *=/s#=.*#=$LIBS# +/^CPP *=/s#=.*#=$CPP# +/^STATICLIB *=/s#=.*#=$STATICLIB# /^SHAREDLIB *=/s#=.*#=$SHAREDLIB# /^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# /^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# +/^AR *=/s#=.*#=$AR_RC# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^all: */s#:.*#: $ALL# +/^test: */s#:.*#: $TEST# +" > Makefile + +sed < zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^CPP *=/s#=.*#=$CPP# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR_RC# /^RANLIB *=/s#=.*#=$RANLIB# /^EXE *=/s#=.*#=$EXE# /^prefix *=/s#=.*#=$prefix# /^exec_prefix *=/s#=.*#=$exec_prefix# /^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# /^includedir *=/s#=.*#=$includedir# /^mandir *=/s#=.*#=$mandir# /^LDFLAGS *=/s#=.*#=$LDFLAGS# -" > Makefile +" | sed -e " +s/\@VERSION\@/$VER/g; +" > zlib.pc diff --git a/reactos/lib/3rdparty/zlib/crc32.c b/reactos/lib/3rdparty/zlib/crc32.c index f658a9ef55e..91be372d224 100644 --- a/reactos/lib/3rdparty/zlib/crc32.c +++ b/reactos/lib/3rdparty/zlib/crc32.c @@ -1,5 +1,5 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2006, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster @@ -53,7 +53,7 @@ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); @@ -68,6 +68,8 @@ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + #ifdef DYNAMIC_CRC_TABLE @@ -219,7 +221,7 @@ const unsigned long FAR * ZEXPORT get_crc_table() unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - unsigned len; + uInt len; { if (buf == Z_NULL) return 0UL; @@ -367,22 +369,22 @@ local void gf2_matrix_square(square, mat) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) +local uLong crc32_combine_(crc1, crc2, len2) uLong crc1; uLong crc2; - z_off_t len2; + z_off64_t len2; { int n; unsigned long row; unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - /* degenerate case */ - if (len2 == 0) + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) return crc1; /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; @@ -421,3 +423,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2) crc1 ^= crc2; return crc1; } + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/reactos/lib/3rdparty/zlib/deflate.c b/reactos/lib/3rdparty/zlib/deflate.c index 29ce1f64a57..5c4022f3d47 100644 --- a/reactos/lib/3rdparty/zlib/deflate.c +++ b/reactos/lib/3rdparty/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -79,19 +79,18 @@ local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, @@ -110,11 +109,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be @@ -288,6 +282,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + s->high_water = 0; /* nothing written to s->window yet */ + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); @@ -332,8 +328,8 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); + if (length > s->w_size) { + length = s->w_size; dictionary += dictLength - length; /* use the tail of the dictionary */ } zmemcpy(s->window, dictionary, length); @@ -435,9 +431,10 @@ int ZEXPORT deflateParams(strm, level, strategy) } func = configuration_table[s->level].func; - if (func != configuration_table[level].func && strm->total_in != 0) { + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); + err = deflate(strm, Z_BLOCK); } if (s->level != level) { s->level = level; @@ -481,33 +478,66 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; - uLong destLen; + uLong complen, wraplen; + Bytef *str; - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - /* if can't get parameters, return conservative bound */ + /* if can't get parameters, return conservative bound plus zlib wrapper */ if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } /* if not default parameters, return conservative bound */ - s = strm->state; if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; + return complen + wraplen; /* default settings: return tight bound for that case */ - return compressBound(sourceLen); + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= @@ -557,7 +587,7 @@ int ZEXPORT deflate (strm, flush) deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { + flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; @@ -581,7 +611,7 @@ int ZEXPORT deflate (strm, flush) put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); - if (s->gzhead == NULL) { + if (s->gzhead == Z_NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); @@ -608,7 +638,7 @@ int ZEXPORT deflate (strm, flush) (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { + if (s->gzhead->extra != Z_NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } @@ -650,7 +680,7 @@ int ZEXPORT deflate (strm, flush) } #ifdef GZIP if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { + if (s->gzhead->extra != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { @@ -678,7 +708,7 @@ int ZEXPORT deflate (strm, flush) s->status = NAME_STATE; } if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { + if (s->gzhead->name != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; @@ -709,7 +739,7 @@ int ZEXPORT deflate (strm, flush) s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { + if (s->gzhead->comment != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; @@ -787,7 +817,9 @@ int ZEXPORT deflate (strm, flush) (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; - bstate = (*(configuration_table[s->level].func))(s, flush); + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; @@ -808,13 +840,17 @@ int ZEXPORT deflate (strm, flush) if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } } } flush_pending(strm); @@ -1167,12 +1203,13 @@ local uInt longest_match(s, cur_match) return s->lookahead; } #endif /* ASMV */ -#endif /* FASTEST */ + +#else /* FASTEST */ /* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only + * Optimized version for FASTEST only */ -local uInt longest_match_fast(s, cur_match) +local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { @@ -1225,6 +1262,8 @@ local uInt longest_match_fast(s, cur_match) return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } +#endif /* FASTEST */ + #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. @@ -1303,7 +1342,6 @@ local void fill_window(s) later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ - /* %%% avoid this when Z_RLE */ n = s->hash_size; p = &s->head[n]; do { @@ -1355,27 +1393,61 @@ local void fill_window(s) */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ +#define FLUSH_BLOCK_ONLY(s, last) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ + (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } /* =========================================================================== @@ -1449,7 +1521,7 @@ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { - IPos hash_head = NIL; /* head of the hash chain */ + IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { @@ -1469,6 +1541,7 @@ local block_state deflate_fast(s, flush) /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ + hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } @@ -1481,19 +1554,8 @@ local block_state deflate_fast(s, flush) * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); @@ -1555,7 +1617,7 @@ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { - IPos hash_head = NIL; /* head of hash chain */ + IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ @@ -1576,6 +1638,7 @@ local block_state deflate_slow(s, flush) /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ + hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } @@ -1591,12 +1654,8 @@ local block_state deflate_slow(s, flush) * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 @@ -1674,7 +1733,6 @@ local block_state deflate_slow(s, flush) } #endif /* FASTEST */ -#if 0 /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of @@ -1684,11 +1742,9 @@ local block_state deflate_rle(s, flush) deflate_state *s; int flush; { - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ for (;;) { /* Make sure that we always have enough lookahead, except @@ -1704,23 +1760,33 @@ local block_state deflate_rle(s, flush) } /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); @@ -1733,4 +1799,36 @@ local block_state deflate_rle(s, flush) FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } -#endif + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/reactos/lib/3rdparty/zlib/deflate.h b/reactos/lib/3rdparty/zlib/deflate.h index 05a5ab3a2c1..e970d73baad 100644 --- a/reactos/lib/3rdparty/zlib/deflate.h +++ b/reactos/lib/3rdparty/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly + * Copyright (C) 1995-2010 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -260,6 +260,13 @@ typedef struct internal_state { * are always zero. */ + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + } FAR deflate_state; /* Output a byte on the stream. @@ -278,14 +285,18 @@ typedef struct internal_state { * distances are limited to MAX_DIST instead of WSIZE. */ +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) diff --git a/reactos/lib/3rdparty/zlib/example.c b/reactos/lib/3rdparty/zlib/example.c index 6c8a0ee7633..604736f15f6 100644 --- a/reactos/lib/3rdparty/zlib/example.c +++ b/reactos/lib/3rdparty/zlib/example.c @@ -1,12 +1,12 @@ /* example.c -- usage example of the zlib compression library - * Copyright (C) 1995-2004 Jean-loup Gailly. + * Copyright (C) 1995-2006 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ -#include #include "zlib.h" +#include #ifdef STDC # include diff --git a/reactos/lib/3rdparty/zlib/gzclose.c b/reactos/lib/3rdparty/zlib/gzclose.c new file mode 100644 index 00000000000..caeb99a3177 --- /dev/null +++ b/reactos/lib/3rdparty/zlib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/reactos/lib/3rdparty/zlib/gzguts.h b/reactos/lib/3rdparty/zlib/gzguts.h new file mode 100644 index 00000000000..055455af860 --- /dev/null +++ b/reactos/lib/3rdparty/zlib/gzguts.h @@ -0,0 +1,132 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifdef _MSC_VER +# include +# define vsnprintf _vsnprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifdef STDC +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + z_off64_t pos; /* current position in uncompressed data */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + unsigned char *next; /* next output data to deliver or write */ + /* just for reading */ + unsigned have; /* amount of output data unused at next */ + int eof; /* true if end of input file reached */ + z_off64_t start; /* where the gzip data started, for rewinding */ + z_off64_t raw; /* where the raw data started, for seeking */ + int how; /* 0: get header, 1: copy, 2: decompress */ + int direct; /* true if last read direct, false if gzip */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/reactos/lib/3rdparty/zlib/gzio.c b/reactos/lib/3rdparty/zlib/gzio.c deleted file mode 100644 index 7e90f4928fc..00000000000 --- a/reactos/lib/3rdparty/zlib/gzio.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* gzio.c -- IO on .gz files - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. - */ - -/* @(#) $Id$ */ - -#include - -#include "zutil.h" - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef Z_BUFSIZE -# ifdef MAXSEG_64K -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ -# else -# define Z_BUFSIZE 16384 -# endif -#endif -#ifndef Z_PRINTF_BUFSIZE -# define Z_PRINTF_BUFSIZE 4096 -#endif - -#ifdef __MVS__ -# pragma map (fdopen , "\174\174FDOPEN") - FILE *fdopen(int, const char *); -#endif - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern void free OF((voidpf ptr)); -#endif - -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} - -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - z_off_t start; /* start of compressed data in file (header skipped) */ - z_off_t in; /* bytes into deflate or inflate */ - z_off_t out; /* bytes out of deflate or inflate */ - int back; /* one character push-back */ - int last; /* true if push-back is last character */ -} gz_stream; - - -local gzFile gz_open OF((const char *path, const char *mode, int fd)); -local int do_flush OF((gzFile file, int flush)); -local int get_byte OF((gz_stream *s)); -local void check_header OF((gz_stream *s)); -local int destroy OF((gz_stream *s)); -local void putLong OF((FILE *file, uLong x)); -local uLong getLong OF((gz_stream *s)); - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb"). The file is given either by file descriptor - or path name (if fd == -1). - gz_open returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ -local gzFile gz_open (path, mode, fd) - const char *path; - const char *mode; - int fd; -{ - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - gz_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; - - if (!path || !mode) return Z_NULL; - - s = (gz_stream *)ALLOC(sizeof(gz_stream)); - if (!s) return Z_NULL; - - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->file = NULL; - s->z_err = Z_OK; - s->z_eof = 0; - s->in = 0; - s->out = 0; - s->back = EOF; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - - s->path = (char*)ALLOC(strlen(path)+1); - if (s->path == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - strcpy(s->path, path); /* do this early for debugging */ - - s->mode = '\0'; - do { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') { - level = *p - '0'; - } else if (*p == 'f') { - strategy = Z_FILTERED; - } else if (*p == 'h') { - strategy = Z_HUFFMAN_ONLY; - } else if (*p == 'R') { - strategy = Z_RLE; - } else { - *m++ = *p; /* copy the mode */ - } - } while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ - - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); -#endif - if (err != Z_OK || s->outbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } else { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); - - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; - - errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); - - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - if (s->mode == 'w') { - /* Write a very simple .gz header: - */ - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->start = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = ftell(s->file) - s->stream.avail_in; - } - - return (gzFile)s; -} - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. -*/ -gzFile ZEXPORT gzopen (path, mode) - const char *path; - const char *mode; -{ - return gz_open (path, mode, -1); -} - -/* =========================================================================== - Associate a gzFile with the file descriptor fd. fd is not dup'ed here - to mimic the behavio(u)r of fdopen. -*/ -gzFile ZEXPORT gzdopen (fd, mode) - int fd; - const char *mode; -{ - char name[46]; /* allow for up to 128-bit integers */ - - if (fd < 0) return (gzFile)Z_NULL; - sprintf(name, "", fd); /* for debugging */ - - return gz_open (name, mode, fd); -} - -/* =========================================================================== - * Update the compression level and strategy - */ -int ZEXPORT gzsetparams (file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - /* Make room to allow flushing */ - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - } - s->stream.avail_out = Z_BUFSIZE; - } - - return deflateParams (&(s->stream), level, strategy); -} - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ -local int get_byte(s) - gz_stream *s; -{ - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) { - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; - } - s->stream.avail_in--; - return *(s->stream.next_in)++; -} - -/* =========================================================================== - Check the gzip header of a gz_stream opened for reading. Set the stream - mode to transparent if the gzip magic header is not present; set s->err - to Z_DATA_ERROR if the magic header is present but the rest of the header - is incorrect. - IN assertion: the stream s has already been created sucessfully; - s->stream.avail_in is zero for the first time, but may be non-zero - for concatenated .gz files. -*/ -local void check_header(s) - gz_stream *s; -{ - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; - - /* Assure two bytes in the buffer so we can peek ahead -- handle case - where first byte of header is at the end of the buffer after the last - gzip segment */ - len = s->stream.avail_in; - if (len < 2) { - if (len) s->inbuf[0] = s->stream.next_in[0]; - errno = 0; - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; - s->stream.avail_in += len; - s->stream.next_in = s->inbuf; - if (s->stream.avail_in < 2) { - s->transparent = s->stream.avail_in; - return; - } - } - - /* Peek ahead to check the gzip magic header */ - if (s->stream.next_in[0] != gz_magic[0] || - s->stream.next_in[1] != gz_magic[1]) { - s->transparent = 1; - return; - } - s->stream.avail_in -= 2; - s->stream.next_in += 2; - - /* Check the rest of the gzip header */ - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - s->z_err = Z_DATA_ERROR; - return; - } - - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); - - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; - } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); - } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; -} - - /* =========================================================================== - * Cleanup then free the given gz_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. - */ -local int destroy (s) - gz_stream *s; -{ - int err = Z_OK; - - if (!s) return Z_STREAM_ERROR; - - TRYFREE(s->msg); - - if (s->stream.state != NULL) { - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateEnd(&(s->stream)); -#endif - } else if (s->mode == 'r') { - err = inflateEnd(&(s->stream)); - } - } - if (s->file != NULL && fclose(s->file)) { -#ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ -#endif - err = Z_ERRNO; - } - if (s->z_err < 0) err = s->z_err; - - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s->path); - TRYFREE(s); - return err; -} - -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ -int ZEXPORT gzread (file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; - - if (s->stream.avail_out && s->back != EOF) { - *next_out++ = s->back; - s->stream.next_out++; - s->stream.avail_out--; - s->back = EOF; - s->out++; - start++; - if (s->last) { - s->z_err = Z_STREAM_END; - return 1; - } - } - - while (s->stream.avail_out != 0) { - - if (s->transparent) { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; - } - if (s->stream.avail_out > 0) { - s->stream.avail_out -= - (uInt)fread(next_out, 1, s->stream.avail_out, s->file); - } - len -= s->stream.avail_out; - s->in += len; - s->out += len; - if (len == 0) s->z_eof = 1; - return (int)len; - } - if (s->stream.avail_in == 0 && !s->z_eof) { - - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - - if (s->z_err == Z_STREAM_END) { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; - - if (getLong(s) != s->crc) { - s->z_err = Z_DATA_ERROR; - } else { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may be - * different from s->out in case of concatenated .gz files. - * Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) { - inflateReset(&(s->stream)); - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; - } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - - if (len == s->stream.avail_out && - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) - return -1; - return (int)(len - s->stream.avail_out); -} - - -/* =========================================================================== - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ -int ZEXPORT gzgetc(file) - gzFile file; -{ - unsigned char c; - - return gzread(file, &c, 1) == 1 ? c : -1; -} - - -/* =========================================================================== - Push one byte back onto the stream. -*/ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; - s->back = c; - s->out--; - s->last = (s->z_err == Z_STREAM_END); - if (s->last) s->z_err = Z_OK; - s->z_eof = 0; - return c; -} - - -/* =========================================================================== - Reads bytes from the compressed file until len-1 characters are - read, or a newline character is read and transferred to buf, or an - end-of-file condition is encountered. The string is then terminated - with a null character. - gzgets returns buf, or Z_NULL in case of error. - - The current implementation is not optimized at all. -*/ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - char *b = buf; - if (buf == Z_NULL || len <= 0) return Z_NULL; - - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; - *buf = '\0'; - return b == buf && len > 0 ? Z_NULL : b; -} - - -#ifndef NO_GZCOMPRESS -/* =========================================================================== - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of bytes actually written (0 in case of error). -*/ -int ZEXPORT gzwrite (file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; - - while (s->stream.avail_in != 0) { - - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - break; - } - s->stream.avail_out = Z_BUFSIZE; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - if (s->z_err != Z_OK) break; - } - s->crc = crc32(s->crc, (const Bytef *)buf, len); - - return (int)(len - s->stream.avail_in); -} - - -/* =========================================================================== - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ -#ifdef STDC -#include - -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) -{ - char buf[Z_PRINTF_BUFSIZE]; - va_list va; - int len; - - buf[sizeof(buf) - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(buf, format, va); - va_end(va); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = vsprintf(buf, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(buf, sizeof(buf), format, va); - va_end(va); - len = strlen(buf); -# else - len = vsnprintf(buf, sizeof(buf), format, va); - va_end(va); -# endif -#endif - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, (unsigned)len); -} -#else /* not ANSI C */ - -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - char buf[Z_PRINTF_BUFSIZE]; - int len; - - buf[sizeof(buf) - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(buf); -# else - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, len); -} -#endif - -/* =========================================================================== - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char cc = (unsigned char) c; /* required for big endian systems */ - - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; -} - - -/* =========================================================================== - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ - return gzwrite(file, (char*)s, (unsigned)strlen(s)); -} - - -/* =========================================================================== - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. -*/ -local int do_flush (file, flush) - gzFile file; - int flush; -{ - uInt len; - int done = 0; - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.avail_in = 0; /* should be zero already anyway */ - - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; - - if (len != 0) { - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { - s->z_err = Z_ERRNO; - return Z_ERRNO; - } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; - } - if (done) break; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), flush); - s->out -= s->stream.avail_out; - - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; - } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} - -int ZEXPORT gzflush (file, flush) - gzFile file; - int flush; -{ - gz_stream *s = (gz_stream*)file; - int err = do_flush (file, flush); - - if (err) return err; - fflush(s->file); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} -#endif /* NO_GZCOMPRESS */ - -/* =========================================================================== - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error. - SEEK_END is not implemented, returns error. - In this version of the library, gzseek can be extremely slow. -*/ -z_off_t ZEXPORT gzseek (file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || whence == SEEK_END || - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { - return -1L; - } - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { - offset -= s->in; - } - if (offset < 0) return -1L; - - /* At this point, offset is the number of zero bytes to write. */ - if (s->inbuf == Z_NULL) { - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ - if (s->inbuf == Z_NULL) return -1L; - zmemzero(s->inbuf, Z_BUFSIZE); - } - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; - - size = gzwrite(file, s->inbuf, size); - if (size == 0) return -1L; - - offset -= size; - } - return s->in; -#endif - } - /* Rest of function is for reading only */ - - /* compute absolute position */ - if (whence == SEEK_CUR) { - offset += s->out; - } - if (offset < 0) return -1L; - - if (s->transparent) { - /* map to fseek */ - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; - - s->in = s->out = offset; - return offset; - } - - /* For a negative seek, rewind and use positive seek */ - if (offset >= s->out) { - offset -= s->out; - } else if (gzrewind(file) < 0) { - return -1L; - } - /* offset is now the number of bytes to skip. */ - - if (offset != 0 && s->outbuf == Z_NULL) { - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); - if (s->outbuf == Z_NULL) return -1L; - } - if (offset && s->back != EOF) { - s->back = EOF; - s->out++; - offset--; - if (s->last) s->z_err = Z_STREAM_END; - } - while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; - - size = gzread(file, s->outbuf, (uInt)size); - if (size <= 0) return -1L; - offset -= size; - } - return s->out; -} - -/* =========================================================================== - Rewinds input file. -*/ -int ZEXPORT gzrewind (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return -1; - - s->z_err = Z_OK; - s->z_eof = 0; - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); - if (!s->transparent) (void)inflateReset(&s->stream); - s->in = 0; - s->out = 0; - return fseek(s->file, s->start, SEEK_SET); -} - -/* =========================================================================== - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. -*/ -z_off_t ZEXPORT gztell (file) - gzFile file; -{ - return gzseek(file, 0L, SEEK_CUR); -} - -/* =========================================================================== - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ -int ZEXPORT gzeof (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - /* With concatenated compressed files that can have embedded - * crc trailers, z_eof is no longer the only/best indicator of EOF - * on a gz_stream. Handle end-of-stream error explicitly here. - */ - if (s == NULL || s->mode != 'r') return 0; - if (s->z_eof) return 1; - return s->z_err == Z_STREAM_END; -} - -/* =========================================================================== - Returns 1 if reading and doing so transparently, otherwise zero. -*/ -int ZEXPORT gzdirect (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return 0; - return s->transparent; -} - -/* =========================================================================== - Outputs a long in LSB order to the given file -*/ -local void putLong (file, x) - FILE *file; - uLong x; -{ - int n; - for (n = 0; n < 4; n++) { - fputc((int)(x & 0xff), file); - x >>= 8; - } -} - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets z_err in case - of error. -*/ -local uLong getLong (s) - gz_stream *s; -{ - uLong x = (uLong)get_byte(s); - int c; - - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; -} - -/* =========================================================================== - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. -*/ -int ZEXPORT gzclose (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return Z_STREAM_ERROR; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return Z_STREAM_ERROR; -#else - if (do_flush (file, Z_FINISH) != Z_OK) - return destroy((gz_stream*)file); - - putLong (s->file, s->crc); - putLong (s->file, (uLong)(s->in & 0xffffffff)); -#endif - } - return destroy((gz_stream*)file); -} - -#ifdef STDC -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -/* =========================================================================== - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ -const char * ZEXPORT gzerror (file, errnum) - gzFile file; - int *errnum; -{ - char *m; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) { - *errnum = Z_STREAM_ERROR; - return (const char*)ERR_MSG(Z_STREAM_ERROR); - } - *errnum = s->z_err; - if (*errnum == Z_OK) return (const char*)""; - - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); - - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); - - TRYFREE(s->msg); - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); - strcpy(s->msg, s->path); - strcat(s->msg, ": "); - strcat(s->msg, m); - return (const char*)s->msg; -} - -/* =========================================================================== - Clear the error and end-of-file flags, and do the same for the real file. -*/ -void ZEXPORT gzclearerr (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return; - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; - s->z_eof = 0; - clearerr(s->file); -} diff --git a/reactos/lib/3rdparty/zlib/gzlib.c b/reactos/lib/3rdparty/zlib/gzlib.c new file mode 100644 index 00000000000..e9eef783fe1 --- /dev/null +++ b/reactos/lib/3rdparty/zlib/gzlib.c @@ -0,0 +1,537 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const char *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + if (state->mode == GZ_READ) { /* for reading ... */ + state->have = 0; /* no output data available */ + state->eof = 0; /* not at end of file */ + state->how = LOOK; /* look for gzip header */ + state->direct = 1; /* default for empty file */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gz_statep state; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* save the path name for error messages */ + state->path = malloc(strlen(path) + 1); + if (state->path == NULL) { + free(state); + return NULL; + } + strcpy(state->path, path); + + /* open the file with the appropriate mode (or just use fd) */ + state->fd = fd != -1 ? fd : + open(path, +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | ( + state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))), + 0666); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size == 0) + return -1; + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->pos + offset >= state->raw) { + ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); + if (ret == -1) + return -1; + state->have = 0; + state->eof = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->pos += offset; + return state->pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? + (unsigned)offset : state->have; + state->have -= n; + state->next += n; + state->pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? + (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) + state->eof = 0; + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/reactos/lib/3rdparty/zlib/gzread.c b/reactos/lib/3rdparty/zlib/gzread.c new file mode 100644 index 00000000000..548201ab009 --- /dev/null +++ b/reactos/lib/3rdparty/zlib/gzread.c @@ -0,0 +1,653 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_next4 OF((gz_statep, unsigned long *)); +local int gz_head OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_make OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + gz_avail() assumes that strm->avail_in == 0. */ +local int gz_avail(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->err != Z_OK) + return -1; + if (state->eof == 0) { + if (gz_load(state, state->in, state->size, + (unsigned *)&(strm->avail_in)) == -1) + return -1; + strm->next_in = state->in; + } + return 0; +} + +/* Get next byte from input, or -1 if end or error. */ +#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ + (strm->avail_in == 0 ? -1 : \ + (strm->avail_in--, *(strm->next_in)++))) + +/* Get a four-byte little-endian integer and return 0 on success and the value + in *ret. Otherwise -1 is returned and *ret is not modified. */ +local int gz_next4(state, ret) + gz_statep state; + unsigned long *ret; +{ + int ch; + unsigned long val; + z_streamp strm = &(state->strm); + + val = NEXT(); + val += (unsigned)NEXT() << 8; + val += (unsigned long)NEXT() << 16; + ch = NEXT(); + if (ch == -1) + return -1; + val += (unsigned long)ch << 24; + *ret = val; + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->have must be zero. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression, and the gzip header will be skipped so + that the next available input data is the raw deflate stream. If direct + copying, then leftover input data from the input buffer will be copied to + the output buffer. In that case, all further file reads will be directly to + either the output buffer or a user buffer. If decompressing, the inflate + state and the check value will be initialized. gz_head() will return 0 on + success or -1 on failure. Failures may include read errors or gzip header + errors. */ +local int gz_head(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + int flags; + unsigned len; + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get some data in the input buffer */ + if (strm->avail_in == 0) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for the gzip magic header bytes 31 and 139 */ + if (strm->next_in[0] == 31) { + strm->avail_in--; + strm->next_in++; + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in && strm->next_in[0] == 139) { + /* we have a gzip header, woo hoo! */ + strm->avail_in--; + strm->next_in++; + + /* skip rest of header */ + if (NEXT() != 8) { /* compression method */ + gz_error(state, Z_DATA_ERROR, "unknown compression method"); + return -1; + } + flags = NEXT(); + if (flags & 0xe0) { /* reserved flag bits */ + gz_error(state, Z_DATA_ERROR, "unknown header flags set"); + return -1; + } + NEXT(); /* modification time */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); /* extra flags */ + NEXT(); /* operating system */ + if (flags & 4) { /* extra field */ + len = (unsigned)NEXT(); + len += (unsigned)NEXT() << 8; + while (len--) + if (NEXT() < 0) + break; + } + if (flags & 8) /* file name */ + while (NEXT() > 0) + ; + if (flags & 16) /* comment */ + while (NEXT() > 0) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + /* an unexpected end of file is not checked for here -- it will be + noticed on the first request for uncompressed data */ + + /* set up for decompression */ + inflateReset(strm); + strm->adler = crc32(0L, Z_NULL, 0); + state->how = GZIP; + state->direct = 0; + return 0; + } + else { + /* not a gzip file -- save first byte (31) and fall to raw i/o */ + state->out[0] = 31; + state->have = 1; + } + } + + /* doing raw i/o, save start of raw data for seeking, copy any leftover + input to output -- this assumes that the output buffer is larger than + the input buffer, which also assures space for gzungetc() */ + state->raw = state->pos; + state->next = state->out; + if (strm->avail_in) { + memcpy(state->next + state->have, strm->next_in, strm->avail_in); + state->have += strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + If the end of the compressed data is reached, then verify the gzip trailer + check value and length (modulo 2^32). state->have and state->next are set + to point to the just decompressed data, and the crc is updated. If the + trailer is verified, state->how is reset to LOOK to look for the next gzip + stream or raw data, once state->have is depleted. Returns 0 on success, -1 + on failure. Failures may include invalid compressed data or a failed gzip + trailer verification. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret; + unsigned had; + unsigned long crc, len; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output and crc check value */ + state->have = had - strm->avail_out; + state->next = strm->next_out - state->have; + strm->adler = crc32(strm->adler, state->next, state->have); + + /* check gzip trailer if at end of deflate stream */ + if (ret == Z_STREAM_END) { + if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + if (crc != strm->adler) { + gz_error(state, Z_DATA_ERROR, "incorrect data check"); + return -1; + } + if (len != (strm->total_out & 0xffffffffL)) { + gz_error(state, Z_DATA_ERROR, "incorrect length check"); + return -1; + } + state->how = LOOK; /* ready for next stream, once have is 0 (leave + state->direct unchanged to remember how) */ + } + + /* good decompression */ + return 0; +} + +/* Make data and put in the output buffer. Assumes that state->have == 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for (and skipped if found) to determine wither to copy or decompress. + Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY + or GZIP unless the end of the input file has been reached and all data has + been processed. */ +local int gz_make(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->how == LOOK) { /* look for gzip header */ + if (gz_head(state) == -1) + return -1; + if (state->have) /* got some data from gz_head() */ + return 0; + } + if (state->how == COPY) { /* straight copy */ + if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) + return -1; + state->next = state->out; + } + else if (state->how == GZIP) { /* decompress */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->have) { + n = GT_OFF(state->have) || (z_off64_t)state->have > len ? + (unsigned)len : state->have; + state->have -= n; + state->next += n; + state->pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->have) { + n = state->have > len ? len : state->have; + memcpy(buf, state->next, n); + state->next += n; + state->have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) + break; + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + continue; /* no progress yet -- go back to memcpy() above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->have; + state->have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->have) { + state->have--; + state->pos++; + return *(state->next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->have == 0) { + state->have = 1; + state->next = state->out + (state->size << 1) - 1; + state->next[0] = c; + state->pos--; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->have == (state->size << 1)) { + gz_error(state, Z_BUF_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->next == state->out) { + unsigned char *src = state->out + state->have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->next = dest; + } + state->have++; + state->next--; + state->next[0] = c; + state->pos--; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->have == 0) { + if (gz_make(state) == -1) + return NULL; /* error */ + if (state->have == 0) { /* end of file */ + if (buf == str) /* got bupkus */ + return NULL; + break; /* got something -- return it */ + } + } + + /* look for end-of-line in current output buffer */ + n = state->have > left ? left : state->have; + eol = memchr(state->next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->next, n); + state->have -= n; + state->next += n; + state->pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* found end-of-line or out of space -- terminate string and return it */ + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return 0; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->how == LOOK && state->have == 0) + (void)gz_head(state); + + /* return 1 if reading direct, 0 if decompressing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/reactos/lib/3rdparty/zlib/gzwrite.c b/reactos/lib/3rdparty/zlib/gzwrite.c new file mode 100644 index 00000000000..e8defc6887a --- /dev/null +++ b/reactos/lib/3rdparty/zlib/gzwrite.c @@ -0,0 +1,531 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input and output buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + 15 + 16, 8, state->strategy); + if (ret != Z_OK) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer */ + strm->avail_out = state->size; + strm->next_out = state->out; + state->next = strm->next_out; + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->next); + if (have && ((got = write(state->fd, state->next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->pos++; + return c; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#ifdef STDC +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(state->in, format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf(state->in, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(state->in, size, format, va); + va_end(va); + len = strlen(state->in); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#else /* !STDC */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(state->in); +# else + len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = 0; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + ret += gz_zero(state, state->skip); + } + + /* flush, free memory, and close file */ + ret += gz_comp(state, Z_FINISH); + (void)deflateEnd(&(state->strm)); + free(state->out); + free(state->in); + gz_error(state, Z_OK, NULL); + free(state->path); + ret += close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/reactos/lib/3rdparty/zlib/infback.c b/reactos/lib/3rdparty/zlib/infback.c index 455dbc9ee84..af3a8c965d5 100644 --- a/reactos/lib/3rdparty/zlib/infback.c +++ b/reactos/lib/3rdparty/zlib/infback.c @@ -1,5 +1,5 @@ /* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -55,7 +55,7 @@ int stream_size; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; - state->write = 0; + state->wnext = 0; state->whave = 0; return Z_OK; } @@ -253,7 +253,7 @@ void FAR *out_desc; unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ + code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ @@ -389,19 +389,19 @@ void FAR *out_desc; state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; } else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; @@ -411,16 +411,16 @@ void FAR *out_desc; copy = 3 + BITS(2); DROPBITS(2); } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); @@ -438,7 +438,16 @@ void FAR *out_desc; /* handle error breaks in while */ if (state->mode == BAD) break; - /* build code tables */ + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; @@ -474,28 +483,28 @@ void FAR *out_desc; /* get a literal, length, or end-of-block code */ for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.op && (this.op & 0xf0) == 0) { - last = this; + if (here.op && (here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->lencode[last.val + + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } - DROPBITS(this.bits); - state->length = (unsigned)this.val; + DROPBITS(here.bits); + state->length = (unsigned)here.val; /* process literal */ - if (this.op == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); + "inflate: literal 0x%02x\n", here.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; @@ -504,21 +513,21 @@ void FAR *out_desc; } /* process end of block */ - if (this.op & 32) { + if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ - if (this.op & 64) { + if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); @@ -528,30 +537,30 @@ void FAR *out_desc; /* get distance code */ for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if ((this.op & 0xf0) == 0) { - last = this; + if ((here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->distcode[last.val + + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } - DROPBITS(this.bits); - if (this.op & 64) { + DROPBITS(here.bits); + if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } - state->offset = (unsigned)this.val; + state->offset = (unsigned)here.val; /* get distance extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); diff --git a/reactos/lib/3rdparty/zlib/inffast.c b/reactos/lib/3rdparty/zlib/inffast.c index bbee92ed1e6..a9e584fbd25 100644 --- a/reactos/lib/3rdparty/zlib/inffast.c +++ b/reactos/lib/3rdparty/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2008, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -79,7 +79,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ + unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ @@ -87,7 +87,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ + code here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ @@ -106,7 +106,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #endif wsize = state->wsize; whave = state->whave; - write = state->write; + wnext = state->wnext; window = state->window; hold = state->hold; bits = state->bits; @@ -124,20 +124,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(PUP(in)) << bits; bits += 8; } - this = lcode[hold & lmask]; + here = lcode[hold & lmask]; dolen: - op = (unsigned)(this.bits); + op = (unsigned)(here.bits); hold >>= op; bits -= op; - op = (unsigned)(this.op); + op = (unsigned)(here.op); if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); } else if (op & 16) { /* length base */ - len = (unsigned)(this.val); + len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { @@ -155,14 +155,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(PUP(in)) << bits; bits += 8; } - this = dcode[hold & dmask]; + here = dcode[hold & dmask]; dodist: - op = (unsigned)(this.bits); + op = (unsigned)(here.bits); hold >>= op; bits -= op; - op = (unsigned)(this.op); + op = (unsigned)(here.op); if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); + dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; @@ -187,12 +187,34 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif } from = window - OFF; - if (write == 0) { /* very common case */ + if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; @@ -202,17 +224,17 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ from = out - dist; /* rest from output */ } } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; + if (wnext < len) { /* some from start of window */ + op = wnext; len -= op; do { PUP(out) = PUP(from); @@ -222,7 +244,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else { /* contiguous in window */ - from += write - op; + from += wnext - op; if (op < len) { /* some from window */ len -= op; do { @@ -259,7 +281,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; + here = dcode[here.val + (hold & ((1U << op) - 1))]; goto dodist; } else { @@ -269,7 +291,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; + here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ @@ -305,7 +327,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 + - Three separate decoding do-loops for direct, window, and wnext == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes diff --git a/reactos/lib/3rdparty/zlib/inffast.h b/reactos/lib/3rdparty/zlib/inffast.h index 1e88d2d97b5..4d5c03abdd5 100644 --- a/reactos/lib/3rdparty/zlib/inffast.h +++ b/reactos/lib/3rdparty/zlib/inffast.h @@ -1,5 +1,5 @@ /* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler + * Copyright (C) 1995-2003, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/reactos/lib/3rdparty/zlib/inflate.c b/reactos/lib/3rdparty/zlib/inflate.c index 792fdee8e9c..a8431abeacf 100644 --- a/reactos/lib/3rdparty/zlib/inflate.c +++ b/reactos/lib/3rdparty/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -45,7 +45,7 @@ * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() + * - Pull out common wnext == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() @@ -117,28 +117,52 @@ z_streamp strm; state->head = Z_NULL; state->wsize = 0; state->whave = 0; - state->write = 0; + state->wnext = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } -int ZEXPORT inflatePrime(strm, bits, value) +int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; -int bits; -int value; +int windowBits; { + int wrap; struct inflate_state FAR *state; + /* get the state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) @@ -147,6 +171,7 @@ int windowBits; const char *version; int stream_size; { + int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -164,24 +189,13 @@ int stream_size; if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { ZFREE(strm, state); strm->state = Z_NULL; - return Z_STREAM_ERROR; } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); + return ret; } int ZEXPORT inflateInit_(strm, version, stream_size) @@ -192,6 +206,27 @@ int stream_size; return inflateInit2_(strm, DEF_WBITS, version, stream_size); } +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. @@ -340,7 +375,7 @@ unsigned out; /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; - state->write = 0; + state->wnext = 0; state->whave = 0; } @@ -348,22 +383,22 @@ unsigned out; copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; + state->wnext = 0; state->whave = state->wsize; } else { - dist = state->wsize - state->write; + dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; + state->wnext = copy; state->whave = state->wsize; } else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; if (state->whave < state->wsize) state->whave += dist; } } @@ -564,7 +599,7 @@ int flush; unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ + code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ @@ -619,7 +654,9 @@ int flush; } DROPBITS(4); len = BITS(4) + 8; - if (len > state->wbits) { + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -771,7 +808,7 @@ int flush; strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: - if (flush == Z_BLOCK) goto inf_leave; + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); @@ -791,7 +828,11 @@ int flush; fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", @@ -816,6 +857,9 @@ int flush; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: state->mode = COPY; case COPY: copy = state->length; @@ -876,19 +920,19 @@ int flush; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; } else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; @@ -898,16 +942,16 @@ int flush; copy = 3 + BITS(2); DROPBITS(2); } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); @@ -925,7 +969,16 @@ int flush; /* handle error breaks in while */ if (state->mode == BAD) break; - /* build code tables */ + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; @@ -946,88 +999,102 @@ int flush; break; } Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); + if (state->mode == TYPE) + state->back = -1; break; } + state->back = 0; for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.op && (this.op & 0xf0) == 0) { - last = this; + if (here.op && (here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->lencode[last.val + + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); + state->back += last.bits; } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); + "inflate: literal 0x%02x\n", here.val)); state->mode = LIT; break; } - if (this.op & 32) { + if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; state->mode = TYPE; break; } - if (this.op & 64) { + if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); + state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; state->mode = DIST; case DIST: for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if ((this.op & 0xf0) == 0) { - last = this; + if ((here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->distcode[last.val + + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); + state->back += last.bits; } - DROPBITS(this.bits); - if (this.op & 64) { + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); + state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { @@ -1036,11 +1103,6 @@ int flush; break; } #endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: @@ -1048,12 +1110,32 @@ int flush; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; from = state->window + (state->wsize - copy); } else - from = state->window + (state->write - copy); + from = state->window + (state->wnext - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ @@ -1146,7 +1228,8 @@ int flush; strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; @@ -1366,3 +1449,32 @@ z_streamp source; dest->state = (struct internal_state FAR *)copy; return Z_OK; } + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/reactos/lib/3rdparty/zlib/inflate.h b/reactos/lib/3rdparty/zlib/inflate.h index 07bd3e78a7c..95f4986d400 100644 --- a/reactos/lib/3rdparty/zlib/inflate.h +++ b/reactos/lib/3rdparty/zlib/inflate.h @@ -1,5 +1,5 @@ /* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -32,11 +32,13 @@ typedef enum { TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ @@ -53,19 +55,21 @@ typedef enum { /* State transitions between above modes - - (most modes can go to the BAD or MEM mode -- not shown for clarity) + (most modes can go to BAD or MEM on error -- not shown for clarity) Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE + (raw) -> TYPEDO Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN @@ -73,7 +77,7 @@ typedef enum { CHECK -> LENGTH -> DONE */ -/* state maintained between inflate() calls. Approximately 7K bytes. */ +/* state maintained between inflate() calls. Approximately 10K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ @@ -88,7 +92,7 @@ struct inflate_state { unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ + unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ @@ -112,4 +116,7 @@ struct inflate_state { unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ }; diff --git a/reactos/lib/3rdparty/zlib/inftrees.c b/reactos/lib/3rdparty/zlib/inftrees.c index 8a9c13ff03d..6f7afcb306d 100644 --- a/reactos/lib/3rdparty/zlib/inftrees.c +++ b/reactos/lib/3rdparty/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -50,7 +50,7 @@ unsigned short FAR *work; unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ + code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -115,15 +115,15 @@ unsigned short FAR *work; if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)1; - this.val = (unsigned short)0; - *(*table)++ = this; /* make a table to force an error */ - *(*table)++ = this; + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } - for (min = 1; min <= MAXBITS; min++) + for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min; @@ -166,11 +166,10 @@ unsigned short FAR *work; entered in the tables. used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This @@ -209,24 +208,25 @@ unsigned short FAR *work; mask = used - 1; /* mask for comparing low */ /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ - this.bits = (unsigned char)(len - drop); + here.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; + here.op = (unsigned char)0; + here.val = work[sym]; } else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; } else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; } /* replicate for those indices with low len bits equal to huff */ @@ -235,7 +235,7 @@ unsigned short FAR *work; min = fill; /* save offset to next table */ do { fill -= incr; - next[(huff >> drop) + fill] = this; + next[(huff >> drop) + fill] = here; } while (fill != 0); /* backwards increment the len-bit code huff */ @@ -277,7 +277,8 @@ unsigned short FAR *work; /* check for enough space */ used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ @@ -295,20 +296,20 @@ unsigned short FAR *work; through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; - this.bits = (unsigned char)len; + here.bits = (unsigned char)len; } /* put invalid code marker in table */ - next[huff >> drop] = this; + next[huff >> drop] = here; /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); diff --git a/reactos/lib/3rdparty/zlib/inftrees.h b/reactos/lib/3rdparty/zlib/inftrees.h index b1104c87e76..3098b6513a6 100644 --- a/reactos/lib/3rdparty/zlib/inftrees.h +++ b/reactos/lib/3rdparty/zlib/inftrees.h @@ -1,5 +1,5 @@ /* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2005, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -35,21 +35,28 @@ typedef struct { 01000000 - invalid code */ -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) -/* Type of code to build for inftable() */ +/* Type of code to build for inflate_table() */ typedef enum { CODES, LENS, DISTS } codetype; -extern int inflate_table OF((codetype type, unsigned short FAR *lens, +int inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); diff --git a/reactos/lib/3rdparty/zlib/minigzip.c b/reactos/lib/3rdparty/zlib/minigzip.c index 4524b96a1d6..9825ccc3a71 100644 --- a/reactos/lib/3rdparty/zlib/minigzip.c +++ b/reactos/lib/3rdparty/zlib/minigzip.c @@ -1,5 +1,5 @@ /* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2006, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -15,8 +15,8 @@ /* @(#) $Id$ */ -#include #include "zlib.h" +#include #ifdef STDC # include @@ -32,6 +32,9 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include # include +# ifdef UNDER_CE +# include +# endif # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) @@ -50,9 +53,75 @@ # include /* for fileno */ #endif +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ extern int unlink OF((const char *)); #endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ #ifndef GZ_SUFFIX # define GZ_SUFFIX ".gz" @@ -198,6 +267,11 @@ void file_compress(file, mode) FILE *in; gzFile out; + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + strcpy(outfile, file); strcat(outfile, GZ_SUFFIX); @@ -227,7 +301,12 @@ void file_uncompress(file) char *infile, *outfile; FILE *out; gzFile in; - uInt len = (uInt)strlen(file); + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } strcpy(buf, file); @@ -258,7 +337,8 @@ void file_uncompress(file) /* =========================================================================== - * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output * -d : decompress * -f : compress with Z_FILTERED * -h : compress with Z_HUFFMAN_ONLY @@ -270,17 +350,30 @@ int main(argc, argv) int argc; char *argv[]; { + int copyout = 0; int uncompr = 0; gzFile file; - char outmode[20]; + char *bname, outmode[20]; strcpy(outmode, "wb6 "); prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; argc--, argv++; + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + while (argc > 0) { - if (strcmp(*argv, "-d") == 0) + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) uncompr = 1; else if (strcmp(*argv, "-f") == 0) outmode[3] = 'f'; @@ -310,11 +403,36 @@ int main(argc, argv) gz_compress(stdin, file); } } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } do { if (uncompr) { - file_uncompress(*argv); + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } } else { - file_compress(*argv, outmode); + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } } } while (argv++, --argc); } diff --git a/reactos/lib/3rdparty/zlib/trees.c b/reactos/lib/3rdparty/zlib/trees.c index 395e4e16814..a05ec378b3a 100644 --- a/reactos/lib/3rdparty/zlib/trees.c +++ b/reactos/lib/3rdparty/zlib/trees.c @@ -1,5 +1,6 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -152,7 +153,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); +local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); @@ -203,12 +204,12 @@ local void send_bits(s, value, length) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); + s->bi_buf |= (ush)value << s->bi_valid; put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { - s->bi_buf |= value << s->bi_valid; + s->bi_buf |= (ush)value << s->bi_valid; s->bi_valid += length; } } @@ -218,12 +219,12 @@ local void send_bits(s, value, length) { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ + s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ - s->bi_buf |= (value) << s->bi_valid;\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ s->bi_valid += len;\ }\ } @@ -250,11 +251,13 @@ local void tr_static_init() if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; +#endif /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; @@ -348,13 +351,14 @@ void gen_trees_header() static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); @@ -864,13 +868,13 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -void _tr_stored_block(s, buf, stored_len, eof) +void _tr_stored_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ + int last; /* one if this is the last block for a file */ { - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; @@ -918,11 +922,11 @@ void _tr_align(s) * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ -void _tr_flush_block(s, buf, stored_len, eof) +void _tr_flush_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ + int last; /* one if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ @@ -931,8 +935,8 @@ void _tr_flush_block(s, buf, stored_len, eof) if (s->level > 0) { /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); @@ -978,20 +982,20 @@ void _tr_flush_block(s, buf, stored_len, eof) * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ - _tr_stored_block(s, buf, stored_len, eof); + _tr_stored_block(s, buf, stored_len, last); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); + send_bits(s, (STATIC_TREES<<1)+last, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); + send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); @@ -1005,14 +1009,14 @@ void _tr_flush_block(s, buf, stored_len, eof) */ init_block(s); - if (eof) { + if (last) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); + s->compressed_len-7*last)); } /* =========================================================================== @@ -1118,24 +1122,45 @@ local void compress_block(s, ltree, dtree) } /* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */ -local void set_data_type(s) +local int detect_data_type(s) deflate_state *s; { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; int n; - for (n = 0; n < 9; n++) + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; } /* =========================================================================== diff --git a/reactos/lib/3rdparty/zlib/uncompr.c b/reactos/lib/3rdparty/zlib/uncompr.c index b59e3d0defb..ad98be3a5d8 100644 --- a/reactos/lib/3rdparty/zlib/uncompr.c +++ b/reactos/lib/3rdparty/zlib/uncompr.c @@ -1,5 +1,5 @@ /* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -16,8 +16,6 @@ been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output diff --git a/reactos/lib/3rdparty/zlib/zconf.h b/reactos/lib/3rdparty/zlib/zconf.h index 03a9431c8be..02ce56c4313 100644 --- a/reactos/lib/3rdparty/zlib/zconf.h +++ b/reactos/lib/3rdparty/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -11,52 +11,124 @@ /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 # define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress # define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func +/* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong # define Bytef z_Bytef +# define alloc_func z_alloc_func # define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func # define intf z_intf +# define out_func z_out_func +# define uInt z_uInt # define uIntf z_uIntf +# define uLong z_uLong # define uLongf z_uLongf -# define voidpf z_voidpf # define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + #endif #if defined(__MSDOS__) && !defined(MSDOS) @@ -284,49 +356,73 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H #endif + +#ifdef STDC +# include /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif + #ifndef z_off_t # define z_off_t long #endif +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ diff --git a/reactos/lib/3rdparty/zlib/zconf.in.h b/reactos/lib/3rdparty/zlib/zconf.in.h deleted file mode 100644 index 03a9431c8be..00000000000 --- a/reactos/lib/3rdparty/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/reactos/lib/3rdparty/zlib/zlib.h b/reactos/lib/3rdparty/zlib/zlib.h index 022817927ce..bfbba83e8ee 100644 --- a/reactos/lib/3rdparty/zlib/zlib.h +++ b/reactos/lib/3rdparty/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 + version 1.2.5, April 19th, 2010 - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,41 +37,44 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 /* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output (providing more output space) before each call. - The compressed data format used by default by the in-memory functions is + The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. - The library also supports reading and writing files in gzip (.gz) format + The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - This library can optionally read and write gzip streams in memory as well. + This library can optionally read and write gzip streams in memory as well. - The zlib format was designed to be compact and fast for use in memory + The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); @@ -126,45 +129,45 @@ typedef struct gz_header_s { typedef gz_header FAR *gz_headerp; /* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the opaque value. - zalloc must return Z_NULL if there is not enough memory for the object. + zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_PARTIAL_FLUSH 1 #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 +#define Z_TREES 6 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 @@ -176,8 +179,8 @@ typedef gz_header FAR *gz_headerp; #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 @@ -207,119 +210,140 @@ typedef gz_header FAR *gz_headerp; #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ + /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when forced to flush. - The detailed semantics are as follows. deflate performs one or both of the + The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not + accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. + accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to + decide how much data to accumulate before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ @@ -328,13 +352,13 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. + This function discards any unprocessed input and does not flush any pending + output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be deallocated). */ @@ -342,10 +366,10 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - Initializes the internal stream state for decompression. The fields + Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to @@ -353,95 +377,108 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce + buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. - The detailed semantics are as follows. inflate performs one or both of the + The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation + first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. + because Z_BLOCK or Z_TREES is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 + below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has @@ -449,27 +486,28 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. + This function discards any unprocessed input and does not flush any pending + output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a + was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ + /* Advanced functions */ /* @@ -484,55 +522,57 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int memLevel, int strategy)); - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. - The method parameter is the compression method. It must be Z_DEFLATED in + The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. - windowBits can also be greater than 15 for optional gzip encoding. Add + windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. - The strategy parameter is used to tune the compression algorithm. Use the + The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, @@ -540,37 +580,37 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a + used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value + which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not + or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ @@ -581,26 +621,26 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed + data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and + (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, @@ -610,18 +650,18 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, @@ -645,9 +685,10 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, @@ -655,21 +696,21 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* - deflateSetHeader() provides gzip header information for when a gzip + deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information @@ -682,11 +723,11 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. - If deflateSetHeader is not used, the default gzip header has text false, + If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ @@ -694,43 +735,50 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); - This is another version of inflateInit with an extra parameter. The + This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window + deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This + looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom + such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments + most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. - windowBits can also be greater than 15 for optional gzip decoding. Add + windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, @@ -738,8 +786,8 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called @@ -748,26 +796,26 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not + expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, @@ -782,18 +830,30 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and + (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, @@ -801,54 +861,87 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int value)); /* This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* - inflateGetHeader() requests that gzip header information be stored in the + inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. - The text, time, xflags, and os fields are filled in with the gzip header + The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max + was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. - If inflateGetHeader is not used, then the header information is simply + If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ @@ -869,9 +962,9 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); @@ -891,15 +984,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then @@ -925,7 +1018,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These @@ -935,15 +1028,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); @@ -999,23 +1092,22 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* utility functions */ /* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. @@ -1025,11 +1117,11 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* - Compresses the source buffer into the destination buffer. The level + Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the + length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough @@ -1040,22 +1132,20 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1063,136 +1153,199 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, */ -typedef voidp gzFile; + /* gzip file access functions */ -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* - Dynamically update the compression level or strategy. See the description + Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. */ -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); /* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* - Writes the given null-terminated string to the compressed file, excluding + Writes the given null-terminated string to the compressed file, excluding the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. + + gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. */ -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); /* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are + extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. - gzseek returns the resulting offset location as measured in bytes from + gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. @@ -1202,68 +1355,127 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* - Returns 1 if file is being read directly without decompression, otherwise - zero. + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ + /* checksum functions */ /* These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. + anyway because they might be useful in applications using the compression + library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: uLong adler = adler32(0L, Z_NULL, 0); @@ -1273,9 +1485,10 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ +/* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); -/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of @@ -1285,9 +1498,11 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + Usage example: uLong crc = crc32(0L, Z_NULL, 0); @@ -1298,9 +1513,9 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ +/* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); -/* Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 @@ -1339,16 +1554,57 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) + ZLIB_VERSION, sizeof(z_stream)) - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); #ifdef __cplusplus } diff --git a/reactos/lib/3rdparty/zlib/zlib.rbuild b/reactos/lib/3rdparty/zlib/zlib.rbuild index 27082adfacb..c10e794ee05 100644 --- a/reactos/lib/3rdparty/zlib/zlib.rbuild +++ b/reactos/lib/3rdparty/zlib/zlib.rbuild @@ -1,34 +1,40 @@ - + . adler32.c compress.c crc32.c - gzio.c - uncompr.c deflate.c - trees.c - zutil.c - inflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c infback.c - inftrees.c inffast.c + inflate.c + inftrees.c + trees.c + uncompr.c + zutil.c - + . adler32.c compress.c crc32.c - gzio.c - uncompr.c deflate.c - trees.c - zutil.c - inflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c infback.c - inftrees.c inffast.c + inflate.c + inftrees.c + trees.c + uncompr.c + zutil.c diff --git a/reactos/lib/3rdparty/zlib/zutil.c b/reactos/lib/3rdparty/zlib/zutil.c index d55f5948a37..e2880ea35d0 100644 --- a/reactos/lib/3rdparty/zlib/zutil.c +++ b/reactos/lib/3rdparty/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -34,25 +34,25 @@ uLong ZEXPORT zlibCompileFlags() uLong flags; flags = 0; - switch (sizeof(uInt)) { + switch ((int)(sizeof(uInt))) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } - switch (sizeof(uLong)) { + switch ((int)(sizeof(uLong))) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } - switch (sizeof(voidpf)) { + switch ((int)(sizeof(voidpf))) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } - switch (sizeof(z_off_t)) { + switch ((int)(sizeof(z_off_t))) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; @@ -237,7 +237,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) return buf; } -void zcfree (voidpf opaque, voidpf ptr) +void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ @@ -272,13 +272,13 @@ void zcfree (voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +voidpf zcalloc (voidpf opaque, uInt items, uInt size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } -void zcfree (voidpf opaque, voidpf ptr) +void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); @@ -307,7 +307,7 @@ voidpf zcalloc (opaque, items, size) (voidpf)calloc(items, size); } -void zcfree (opaque, ptr) +void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { diff --git a/reactos/lib/3rdparty/zlib/zutil.h b/reactos/lib/3rdparty/zlib/zutil.h index b7d5eff81b6..69f84f17ccd 100644 --- a/reactos/lib/3rdparty/zlib/zutil.h +++ b/reactos/lib/3rdparty/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -13,31 +13,21 @@ #ifndef ZUTIL_H #define ZUTIL_H -#define ZLIB_INTERNAL +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + #include "zlib.h" #ifdef STDC -# ifndef _WIN32_WCE +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif # include # include #endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include -# endif -#endif #ifndef local # define local static @@ -89,7 +79,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); @@ -118,7 +108,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 - #include +# include # endif #endif @@ -151,7 +141,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define fdopen(fd,mode) NULL /* No fdopen() */ #endif -#if (defined(_MSC_VER) && (_MSC_VER > 600)) +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED @@ -163,6 +153,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif +#if defined(__BORLANDC__) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + /* common defaults */ #ifndef OS_CODE @@ -197,7 +199,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif # endif # endif # ifdef __SASC @@ -232,16 +236,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); + void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include - extern int z_verbose; - extern void z_error OF((char *m)); + extern int _verbose; + extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} @@ -258,8 +262,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); +voidpf zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) From e2a40983d06424552423e3f038907a05213b44b2 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 13:41:35 +0000 Subject: [PATCH 087/292] [WININET] -sync to wine 1.2 RC2 -enable http compression with zlib svn path=/trunk/; revision=47412 --- reactos/dll/win32/wininet/ftp.c | 6 +-- reactos/dll/win32/wininet/http.c | 40 +++++++++----- reactos/dll/win32/wininet/internet.c | 63 +++++++++++++++++++---- reactos/dll/win32/wininet/internet.h | 3 +- reactos/dll/win32/wininet/netconnection.c | 12 ++++- reactos/dll/win32/wininet/urlcache.c | 2 - reactos/dll/win32/wininet/utility.c | 2 + reactos/dll/win32/wininet/wininet.rbuild | 2 + reactos/dll/win32/wininet/wininet_Si.rc | 30 +++++++++-- reactos/include/psdk/wininet.h | 3 ++ reactos/include/reactos/wine/config.h | 6 +++ 11 files changed, 135 insertions(+), 34 deletions(-) diff --git a/reactos/dll/win32/wininet/ftp.c b/reactos/dll/win32/wininet/ftp.c index 1f031996811..80cc6f0e60a 100644 --- a/reactos/dll/win32/wininet/ftp.c +++ b/reactos/dll/win32/wininet/ftp.c @@ -1176,7 +1176,7 @@ static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read) @@ -2395,7 +2395,7 @@ static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *bu return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static const object_vtbl_t FTPSESSIONVtbl = { @@ -3476,7 +3476,7 @@ static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *b return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data) diff --git a/reactos/dll/win32/wininet/http.c b/reactos/dll/win32/wininet/http.c index 57b73729a10..d14a52281e7 100644 --- a/reactos/dll/win32/wininet/http.c +++ b/reactos/dll/win32/wininet/http.c @@ -1756,7 +1756,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) @@ -3464,6 +3464,10 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, * for all the data */ HTTP_DrainContent(lpwhr); lpwhr->dwContentRead = 0; + if(redirected) { + lpwhr->dwContentLength = ~0u; + lpwhr->dwBytesToWrite = 0; + } if (TRACE_ON(wininet)) { @@ -3670,7 +3674,7 @@ lend: HTTP_ReceiveRequestData(lpwhr, TRUE); else { - iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; + iar.dwResult = 0; iar.dwError = res; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, @@ -4164,7 +4168,7 @@ static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *b return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) @@ -4261,11 +4265,8 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if(hIC->lpszProxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (lpszServerName && lpszServerName[0]) - { - lpwhs->lpszServerName = heap_strdupW(lpszServerName); - lpwhs->lpszHostName = heap_strdupW(lpszServerName); - } + lpwhs->lpszServerName = heap_strdupW(lpszServerName); + lpwhs->lpszHostName = heap_strdupW(lpszServerName); if (lpszUserName && lpszUserName[0]) lpwhs->lpszUserName = heap_strdupW(lpszUserName); if (lpszPassword && lpszPassword[0]) @@ -4362,6 +4363,10 @@ static DWORD HTTP_OpenConnection(http_request_t *lpwhr) if(res != ERROR_SUCCESS) goto lend; + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CONNECTED_TO_SERVER, + szaddr, strlen(szaddr)+1); + if (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE) { /* Note: we differ from Microsoft's WinINet here. they seem to have @@ -4370,20 +4375,31 @@ static DWORD HTTP_OpenConnection(http_request_t *lpwhr) * behaviour to be more correct and to not cause any incompatibilities * because using a secure connection through a proxy server is a rare * case that would be hard for anyone to depend on */ - if (hIC->lpszProxy && (res = HTTP_SecureProxyConnect(lpwhr)) != ERROR_SUCCESS) + if (hIC->lpszProxy && (res = HTTP_SecureProxyConnect(lpwhr)) != ERROR_SUCCESS) { + HTTPREQ_CloseConnection(&lpwhr->hdr); goto lend; + } res = NETCON_secure_connect(&lpwhr->netConnection, lpwhs->lpszHostName); if(res != ERROR_SUCCESS) { WARN("Couldn't connect securely to host\n"); + + if((lpwhr->hdr.ErrorMask&INTERNET_ERROR_MASK_COMBINED_SEC_CERT) && ( + res == ERROR_INTERNET_SEC_CERT_DATE_INVALID + || res == ERROR_INTERNET_INVALID_CA + || res == ERROR_INTERNET_SEC_CERT_NO_REV + || res == ERROR_INTERNET_SEC_CERT_REV_FAILED + || res == ERROR_INTERNET_SEC_CERT_REVOKED + || res == ERROR_INTERNET_SEC_INVALID_CERT + || res == ERROR_INTERNET_SEC_CERT_CN_INVALID)) + res = ERROR_INTERNET_SEC_CERT_ERRORS; + + HTTPREQ_CloseConnection(&lpwhr->hdr); goto lend; } } - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_CONNECTED_TO_SERVER, - szaddr, strlen(szaddr)+1); lend: lpwhr->read_pos = lpwhr->read_size = 0; diff --git a/reactos/dll/win32/wininet/internet.c b/reactos/dll/win32/wininet/internet.c index 6fc8a212c89..001736001a4 100644 --- a/reactos/dll/win32/wininet/internet.c +++ b/reactos/dll/win32/wininet/internet.c @@ -812,7 +812,7 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static const object_vtbl_t APPINFOVtbl = { @@ -1447,7 +1447,7 @@ BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, lpUrlComponents->nScheme = UCW.nScheme; lpUrlComponents->nPort = UCW.nPort; - TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", lpszUrl, + TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_a(lpszUrl), debugstr_an(lpUrlComponents->lpszScheme, lpUrlComponents->dwSchemeLength), debugstr_an(lpUrlComponents->lpszHostName, lpUrlComponents->dwHostNameLength), debugstr_an(lpUrlComponents->lpszUrlPath, lpUrlComponents->dwUrlPathLength), @@ -1860,7 +1860,7 @@ BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer, DWORD dwURLFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE; TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_a(lpszUrl), lpszBuffer, - lpdwBufferLength, lpdwBufferLength ? *lpdwBufferLength : -1, dwFlags); + lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1); if(dwFlags & ICU_DECODE) { @@ -2194,7 +2194,7 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, return res == ERROR_SUCCESS; } -DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) +DWORD INET_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { static BOOL warn = TRUE; @@ -2357,6 +2357,25 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; case INTERNET_OPTION_POLICY: return ERROR_INVALID_PARAMETER; + case INTERNET_OPTION_CONTEXT_VALUE: + { + if (!hdr) + return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; + if (!size) + return ERROR_INVALID_PARAMETER; + + if (*size < sizeof(DWORD_PTR)) + { + *size = sizeof(DWORD_PTR); + return ERROR_INSUFFICIENT_BUFFER; + } + if (!buffer) + return ERROR_INVALID_PARAMETER; + + *(DWORD_PTR *)buffer = hdr->dwContext; + *size = sizeof(DWORD_PTR); + return ERROR_SUCCESS; + } } FIXME("Stub for %d\n", option); @@ -2388,7 +2407,7 @@ BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, WININET_Release(hdr); } }else { - res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, TRUE); + res = INET_QueryOption(NULL, dwOption, lpBuffer, lpdwBufferLength, TRUE); } if(res != ERROR_SUCCESS) @@ -2421,7 +2440,7 @@ BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, WININET_Release(hdr); } }else { - res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, FALSE); + res = INET_QueryOption(NULL, dwOption, lpBuffer, lpdwBufferLength, FALSE); } if(res != ERROR_SUCCESS) @@ -2484,8 +2503,19 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, break; case INTERNET_OPTION_ERROR_MASK: { - ULONG flags = *(ULONG *)lpBuffer; - FIXME("Option INTERNET_OPTION_ERROR_MASK(%d): STUB\n", flags); + if(!lpwhh) { + SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); + return FALSE; + } else if(*(ULONG*)lpBuffer & (~(INTERNET_ERROR_MASK_INSERT_CDROM| + INTERNET_ERROR_MASK_COMBINED_SEC_CERT| + INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY))) { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } else if(dwBufferLength != sizeof(ULONG)) { + SetLastError(ERROR_INTERNET_BAD_OPTION_LENGTH); + ret = FALSE; + } else + lpwhh->ErrorMask = *(ULONG*)lpBuffer; } break; case INTERNET_OPTION_CODEPAGE: @@ -2550,8 +2580,21 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, break; } case INTERNET_OPTION_CONTEXT_VALUE: - FIXME("Option INTERNET_OPTION_CONTEXT_VALUE; STUB\n"); - break; + { + if (!lpwhh) + { + SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); + return FALSE; + } + if (!lpBuffer || dwBufferLength != sizeof(DWORD_PTR)) + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + else + lpwhh->dwContext = *(DWORD_PTR *)lpBuffer; + break; + } case INTERNET_OPTION_SECURITY_FLAGS: FIXME("Option INTERNET_OPTION_SECURITY_FLAGS; STUB\n"); break; diff --git a/reactos/dll/win32/wininet/internet.h b/reactos/dll/win32/wininet/internet.h index 8fcc0cf3565..a531ccd752f 100644 --- a/reactos/dll/win32/wininet/internet.h +++ b/reactos/dll/win32/wininet/internet.h @@ -160,6 +160,7 @@ struct _object_header_t DWORD dwFlags; DWORD_PTR dwContext; DWORD dwError; + ULONG ErrorMask; DWORD dwInternalFlags; LONG refs; INTERNET_STATUS_CALLBACK lpfnStatusCB; @@ -392,7 +393,7 @@ object_header_t *WININET_AddRef( object_header_t *info ); BOOL WININET_Release( object_header_t *info ); BOOL WININET_FreeHandle( HINTERNET hinternet ); -DWORD INET_QueryOption(DWORD,void*,DWORD*,BOOL); +DWORD INET_QueryOption( object_header_t *, DWORD, void *, DWORD *, BOOL ); time_t ConvertTimeString(LPCWSTR asctime); diff --git a/reactos/dll/win32/wininet/netconnection.c b/reactos/dll/win32/wininet/netconnection.c index c2560b5da37..5aa647a7a49 100644 --- a/reactos/dll/win32/wininet/netconnection.c +++ b/reactos/dll/win32/wininet/netconnection.c @@ -134,6 +134,7 @@ MAKE_FUNCPTR(SSL_shutdown); MAKE_FUNCPTR(SSL_write); MAKE_FUNCPTR(SSL_read); MAKE_FUNCPTR(SSL_pending); +MAKE_FUNCPTR(SSL_get_error); MAKE_FUNCPTR(SSL_get_ex_new_index); MAKE_FUNCPTR(SSL_get_ex_data); MAKE_FUNCPTR(SSL_set_ex_data); @@ -330,7 +331,9 @@ static int netconn_secure_verify(int preverify_ok, X509_STORE_CTX *ctx) CertFreeCertificateContext(endCert); CertCloseStore(store, 0); } - } + } else + pSSL_set_ex_data(ssl, error_idx, (void *)ERROR_INTERNET_SEC_CERT_ERRORS); + return ret; } @@ -392,6 +395,7 @@ DWORD NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) DYNSSL(SSL_write); DYNSSL(SSL_read); DYNSSL(SSL_pending); + DYNSSL(SSL_get_error); DYNSSL(SSL_get_ex_new_index); DYNSSL(SSL_get_ex_data); DYNSSL(SSL_set_ex_data); @@ -772,6 +776,12 @@ DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int { #ifdef SONAME_LIBSSL *recvd = pSSL_read(connection->ssl_s, buf, len); + + /* Check if EOF was received */ + if(!*recvd && (pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_ZERO_RETURN + || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL)) + return ERROR_SUCCESS; + return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED; #else return ERROR_NOT_SUPPORTED; diff --git a/reactos/dll/win32/wininet/urlcache.c b/reactos/dll/win32/wininet/urlcache.c index 6a39c691475..c617a93299f 100644 --- a/reactos/dll/win32/wininet/urlcache.c +++ b/reactos/dll/win32/wininet/urlcache.c @@ -2435,7 +2435,6 @@ static BOOL CommitUrlCacheEntryInternal( DWORD dwFileSizeLow = 0; DWORD dwFileSizeHigh = 0; BYTE cDirectory = 0; - int len; char achFile[MAX_PATH]; LPSTR lpszUrlNameA = NULL; LPSTR lpszFileExtensionA = NULL; @@ -2556,7 +2555,6 @@ static BOOL CommitUrlCacheEntryInternal( dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlNameA) + 1); if (lpszLocalFileName) { - len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL); dwOffsetLocalFileName = dwBytesNeeded; dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(pchLocalFileName) + 1); } diff --git a/reactos/dll/win32/wininet/utility.c b/reactos/dll/win32/wininet/utility.c index 66fbecdd653..0639f40385e 100644 --- a/reactos/dll/win32/wininet/utility.c +++ b/reactos/dll/win32/wininet/utility.c @@ -307,6 +307,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, case INTERNET_STATUS_CONNECTING_TO_SERVER: case INTERNET_STATUS_CONNECTED_TO_SERVER: lpvNewInfo = heap_strdupAtoW(lpvStatusInfo); + dwStatusInfoLength *= sizeof(WCHAR); break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: @@ -325,6 +326,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: lpvNewInfo = heap_strdupWtoA(lpvStatusInfo); + dwStatusInfoLength /= sizeof(WCHAR); break; } } diff --git a/reactos/dll/win32/wininet/wininet.rbuild b/reactos/dll/win32/wininet/wininet.rbuild index 45b87b18665..ac2c43f7945 100644 --- a/reactos/dll/win32/wininet/wininet.rbuild +++ b/reactos/dll/win32/wininet/wininet.rbuild @@ -6,6 +6,7 @@ . include/reactos/wine + . @@ -22,6 +23,7 @@ secur32 crypt32 ws2_32 + zlib pseh cookie.c dialogs.c diff --git a/reactos/dll/win32/wininet/wininet_Si.rc b/reactos/dll/win32/wininet/wininet_Si.rc index b5bf2914328..488104ec9dc 100644 --- a/reactos/dll/win32/wininet/wininet_Si.rc +++ b/reactos/dll/win32/wininet/wininet_Si.rc @@ -27,11 +27,11 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vnos omrežnega gesla" FONT 8, "MS Shell Dlg" { - LTEXT "Vnesite uporabniÅ¡ko ime in geslo:", -1, 40, 6, 150, 15 - LTEXT "Proksi", -1, 40, 26, 50, 10 - LTEXT "Kraljestvo", -1, 40, 46, 50, 10 - LTEXT "UporabniÅ¡ko ime", -1, 40, 66, 50, 10 - LTEXT "Geslo", -1, 40, 86, 50, 10 + LTEXT "Vnesite uporabniÅ¡ko ime in geslo:", -1, 20, 6, 150, 15 + LTEXT "Proksi", -1, 20, 26, 50, 10 + LTEXT "PodroÄje", -1, 20, 46, 50, 10 + LTEXT "UporabniÅ¡ko ime", -1, 20, 66, 55, 10 + LTEXT "Geslo", -1, 20, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP @@ -42,6 +42,26 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "PrekliÄi", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } +IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Authentication Required" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Vnesite uporabniÅ¡ko ime in geslo:", -1, 20, 6, 150, 15 + LTEXT "Server", -1, 20, 26, 50, 10 + LTEXT "PodroÄje", -1, 20, 46, 50, 10 + LTEXT "UporabniÅ¡ko ime", -1, 20, 66, 55, 10 + LTEXT "Geslo", -1, 20, 86, 50, 10 + LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Shrani geslo (nezaÅ¡Äiteno)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "V redu", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "PrekliÄi", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} + STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN povezava" diff --git a/reactos/include/psdk/wininet.h b/reactos/include/psdk/wininet.h index 1cb0508ead3..a0ec4082d12 100644 --- a/reactos/include/psdk/wininet.h +++ b/reactos/include/psdk/wininet.h @@ -122,6 +122,9 @@ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP) ) #define INTERNET_ERROR_MASK_INSERT_CDROM 0x1 +#define INTERNET_ERROR_MASK_COMBINED_SEC_CERT 0x2 +#define INTERNET_ERROR_MASK_NEED_MSN_SSPI_PKG 0x4 +#define INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY 0x8 #define INTERNET_OPTIONS_MASK (~INTERNET_FLAGS_MASK) #define WININET_API_FLAG_ASYNC 0x00000001 diff --git a/reactos/include/reactos/wine/config.h b/reactos/include/reactos/wine/config.h index 406b5fb895d..404783b1d26 100644 --- a/reactos/include/reactos/wine/config.h +++ b/reactos/include/reactos/wine/config.h @@ -442,6 +442,12 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_OPENSSL_SSL_H */ +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_ZLIB 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ZLIB_H 1 + /* Define to 1 if you have the `pclose' function. */ #define HAVE_PCLOSE 1 From b2caf487eea56f50d4476a6f6ebc23a9832d2847 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 14:21:43 +0000 Subject: [PATCH 088/292] [JSCRIPT] sync to wine 1.2 RC2 svn path=/trunk/; revision=47413 --- reactos/dll/win32/jscript/dispex.c | 15 +++ reactos/dll/win32/jscript/function.c | 11 ++- reactos/dll/win32/jscript/global.c | 3 +- reactos/dll/win32/jscript/jscript.c | 1 + reactos/dll/win32/jscript/jscript.h | 11 ++- reactos/dll/win32/jscript/jscript_Nl.rc | 4 + reactos/dll/win32/jscript/jscript_Si.rc | 49 ++++++++++ reactos/dll/win32/jscript/regexp.c | 119 ++++++++++++++++++++++-- reactos/dll/win32/jscript/rsrc.rc | 1 + reactos/dll/win32/jscript/string.c | 27 ++++-- 10 files changed, 222 insertions(+), 19 deletions(-) create mode 100644 reactos/dll/win32/jscript/jscript_Si.rc diff --git a/reactos/dll/win32/jscript/dispex.c b/reactos/dll/win32/jscript/dispex.c index 6894eae0515..07880bcff5b 100644 --- a/reactos/dll/win32/jscript/dispex.c +++ b/reactos/dll/win32/jscript/dispex.c @@ -358,6 +358,9 @@ static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, VARIANT *val, { HRESULT hres; + if(prop->flags & PROPF_CONST) + return S_OK; + switch(prop->type) { case PROP_BUILTIN: if(!(prop->flags & PROPF_METHOD)) { @@ -974,6 +977,18 @@ HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, VARIANT *val, js return prop_put(obj, prop, val, ei, caller); } +HRESULT jsdisp_propput_const(DispatchEx *obj, const WCHAR *name, VARIANT *val) +{ + dispex_prop_t *prop; + HRESULT hres; + + hres = ensure_prop_name(obj, name, FALSE, PROPF_ENUM|PROPF_CONST, &prop); + if(FAILED(hres)) + return hres; + + return VariantCopy(&prop->u.var, val); +} + HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { WCHAR buf[12]; diff --git a/reactos/dll/win32/jscript/function.c b/reactos/dll/win32/jscript/function.c index c7494cfce6c..df46f1d996d 100644 --- a/reactos/dll/win32/jscript/function.c +++ b/reactos/dll/win32/jscript/function.c @@ -606,7 +606,16 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, if(FAILED(hres)) return hres; - hres = set_prototype(ctx, &function->dispex, prototype); + if(builtin_info) { + VARIANT var; + + V_VT(&var) = VT_I4; + V_I4(&var) = function->length; + hres = jsdisp_propput_const(&function->dispex, lengthW, &var); + } + + if(SUCCEEDED(hres)) + hres = set_prototype(ctx, &function->dispex, prototype); if(FAILED(hres)) { jsdisp_release(&function->dispex); return hres; diff --git a/reactos/dll/win32/jscript/global.c b/reactos/dll/win32/jscript/global.c index af142ed4db3..92a0cbecd61 100644 --- a/reactos/dll/win32/jscript/global.c +++ b/reactos/dll/win32/jscript/global.c @@ -550,7 +550,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { LONGLONG d = 0, hlp; - int exp = 0, length; + int exp = 0; VARIANT *arg; WCHAR *str; BSTR val_str = NULL; @@ -569,7 +569,6 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag return hres; str = val_str; - length = SysStringLen(val_str); while(isspaceW(*str)) str++; diff --git a/reactos/dll/win32/jscript/jscript.c b/reactos/dll/win32/jscript/jscript.c index 9a516aa5d71..c7c77e3aa39 100644 --- a/reactos/dll/win32/jscript/jscript.c +++ b/reactos/dll/win32/jscript/jscript.c @@ -71,6 +71,7 @@ void script_release(script_ctx_t *ctx) return; jsheap_free(&ctx->tmp_heap); + SysFreeString(ctx->last_match); heap_free(ctx); } diff --git a/reactos/dll/win32/jscript/jscript.h b/reactos/dll/win32/jscript/jscript.h index c1c8e60f35b..901f25d8b08 100644 --- a/reactos/dll/win32/jscript/jscript.h +++ b/reactos/dll/win32/jscript/jscript.h @@ -68,6 +68,7 @@ extern HINSTANCE jscript_hinstance; #define PROPF_METHOD 0x0100 #define PROPF_ENUM 0x0200 #define PROPF_CONSTR 0x0400 +#define PROPF_CONST 0x0800 /* NOTE: Keep in sync with names in Object.toString implementation */ typedef enum { @@ -203,6 +204,7 @@ HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServi HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propget(DispatchEx*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propput_const(DispatchEx*,const WCHAR*,VARIANT*); HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_get_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*); @@ -270,6 +272,10 @@ struct _script_ctx_t { IDispatch *host_global; + BSTR last_match; + DWORD last_match_index; + DWORD last_match_length; + DispatchEx *global; DispatchEx *function_constr; DispatchEx *activex_constr; @@ -318,8 +324,9 @@ typedef struct { DWORD len; } match_result_t; -#define REM_CHECK_GLOBAL 0x0001 -#define REM_RESET_INDEX 0x0002 +#define REM_CHECK_GLOBAL 0x0001 +#define REM_RESET_INDEX 0x0002 +#define REM_NO_CTX_UPDATE 0x0004 HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,DWORD,const WCHAR*,DWORD,const WCHAR**,match_result_t**, DWORD*,DWORD*,match_result_t*); HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*); diff --git a/reactos/dll/win32/jscript/jscript_Nl.rc b/reactos/dll/win32/jscript/jscript_Nl.rc index c4f761a3922..fec11a08000 100644 --- a/reactos/dll/win32/jscript/jscript_Nl.rc +++ b/reactos/dll/win32/jscript/jscript_Nl.rc @@ -20,10 +20,13 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +#pragma code_page(65001) + STRINGTABLE DISCARDABLE { IDS_TO_PRIMITIVE "Fout bij het omzetten van het object naar een primitief type" IDS_INVALID_CALL_ARG "Ongeldige procedure-aanroep of argument" + IDS_CREATE_OBJ_ERROR "Automatiseringsserver kan het object niet creëren" IDS_NO_PROPERTY "Dit object ondersteunt deze eigenschap of methode niet" IDS_ARG_NOT_OPT "Argument is niet optioneel" IDS_SYNTAX_ERROR "Syntax fout" @@ -40,6 +43,7 @@ STRINGTABLE DISCARDABLE IDS_NOT_BOOL "Boolean object verwacht" IDS_JSCRIPT_EXPECTED "JScript object verwacht" IDS_REGEXP_SYNTAX_ERROR "Syntax fout in reguliere expressie" + IDS_URI_INVALID_CHAR "De te coderen URI bevat ongeldige tekens" IDS_INVALID_LENGTH "Array lengte moet een eindig, positief geheel getal zijn" IDS_ARRAY_EXPECTED "Array object verwacht" } diff --git a/reactos/dll/win32/jscript/jscript_Si.rc b/reactos/dll/win32/jscript/jscript_Si.rc new file mode 100644 index 00000000000..0ddeab117e6 --- /dev/null +++ b/reactos/dll/win32/jscript/jscript_Si.rc @@ -0,0 +1,49 @@ +/* + * Copyright 2010 Matej Spindler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" + +#pragma code_page(65001) + +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TO_PRIMITIVE "Napaka med spreminjanjem v primitivni tip" + IDS_INVALID_CALL_ARG "NapaÄen klic postopka ali argument" + IDS_CREATE_OBJ_ERROR "Avtomatizacijski server ne more ustvariti objekta" + IDS_NO_PROPERTY "Objekt ne podpira atributa ali metode" + IDS_ARG_NOT_OPT "Argument je obvezen" + IDS_SYNTAX_ERROR "NapaÄna sintaksa" + IDS_SEMICOLON "PriÄakujem ';'" + IDS_LBRACKET "PriÄakujem '('" + IDS_RBRACKET "PriÄakujem ')'" + IDS_UNTERMINATED_STR "NezakljuÄen niz" + IDS_NOT_FUNC "PriÄakujem funkcijo" + IDS_NOT_DATE "'[object]' ni date objekt" + IDS_NOT_NUM "PriÄakujem Å¡tevilo" + IDS_OBJECT_EXPECTED "PriÄakujem objekt" + IDS_ILLEGAL_ASSIGN "NapaÄna prireditev" + IDS_UNDEFINED "'|' je nedifiniran" + IDS_NOT_BOOL "PriÄakujem Boolean objekt" + IDS_JSCRIPT_EXPECTED "PriÄakujem JScript objekt" + IDS_REGEXP_SYNTAX_ERROR "NapaÄna sintaksa v regularnem izrazu" + IDS_URI_INVALID_CHAR "URI vsebuje neveljavne znake" + IDS_INVALID_LENGTH "Dožina polja mora bit pozitivno celo Å¡tevilo" + IDS_ARRAY_EXPECTED "PriÄakujem Array objekt" +} diff --git a/reactos/dll/win32/jscript/regexp.c b/reactos/dll/win32/jscript/regexp.c index 7861d229826..fb541891a56 100644 --- a/reactos/dll/win32/jscript/regexp.c +++ b/reactos/dll/win32/jscript/regexp.c @@ -96,6 +96,12 @@ static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR execW[] = {'e','x','e','c',0}; static const WCHAR testW[] = {'t','e','s','t',0}; +static const WCHAR leftContextW[] = + {'l','e','f','t','C','o','n','t','e','x','t',0}; +static const WCHAR rightContextW[] = + {'r','i','g','h','t','C','o','n','t','e','x','t',0}; + +static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0}; static const WCHAR emptyW[] = {0}; /* FIXME: Better error handling */ @@ -1977,7 +1983,7 @@ PushBackTrackState(REGlobalData *gData, REOp op, ptrdiff_t btincr = ((char *)result + sz) - ((char *)gData->backTrackStack + btsize); - TRACE("\tBT_Push: %lu,%lu\n", (unsigned long) parenIndex, (unsigned long) parenCount); + TRACE("\tBT_Push: %lu,%lu\n", (ULONG_PTR)parenIndex, (ULONG_PTR)parenCount); JS_COUNT_OPERATION(gData->cx, JSOW_JUMP * (1 + parenCount)); if (btincr > 0) { @@ -2729,7 +2735,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x) case REOP_LPAREN: pc = ReadCompactIndex(pc, &parenIndex); - TRACE("[ %lu ]\n", (unsigned long) parenIndex); + TRACE("[ %lu ]\n", (ULONG_PTR)parenIndex); assert(parenIndex < gData->regexp->parenCount); if (parenIndex + 1 > parenSoFar) parenSoFar = parenIndex + 1; @@ -3093,8 +3099,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x) } TRACE("\tBT_Pop: %ld,%ld\n", - (unsigned long) backTrackData->parenIndex, - (unsigned long) backTrackData->parenCount); + (ULONG_PTR)backTrackData->parenIndex, + (ULONG_PTR)backTrackData->parenCount); continue; } x = result; @@ -3342,8 +3348,6 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D } if(parens) { - DWORD i; - if(regexp->jsregexp->parenCount > *parens_size) { match_result_t *new_parens; @@ -3356,6 +3360,22 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D *parens = new_parens; } + } + + /* FIXME: We often already have a copy of input string that we could use to store last match */ + if(!(rem_flags & REM_NO_CTX_UPDATE) && + (!ctx->last_match || len != SysStringLen(ctx->last_match) || strncmpW(ctx->last_match, str, len))) { + BSTR last_match; + + last_match = SysAllocStringLen(str, len); + if(!last_match) + return E_OUTOFMEMORY; + SysFreeString(ctx->last_match); + ctx->last_match = last_match; + } + + if(parens) { + DWORD i; *parens_cnt = regexp->jsregexp->parenCount; @@ -3376,6 +3396,11 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D ret->len = matchlen; set_last_index(regexp, result->cp-str); + if(!(rem_flags & REM_NO_CTX_UPDATE)) { + ctx->last_match_index = ret->str-str; + ctx->last_match_length = matchlen; + } + return S_OK; } @@ -3712,12 +3737,24 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPP VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { match_result_t match; + VARIANT undef_var; VARIANT_BOOL b; + DWORD argc; HRESULT hres; TRACE("\n"); - hres = run_exec(ctx, jsthis, arg_cnt(dp) ? get_arg(dp,0) : NULL, ei, NULL, &match, NULL, NULL, &b); + argc = arg_cnt(dp); + if(!argc) { + V_VT(&undef_var) = VT_BSTR; + V_BSTR(&undef_var) = SysAllocString(undefinedW); + if(!V_BSTR(&undef_var)) + return E_OUTOFMEMORY; + } + + hres = run_exec(ctx, jsthis, argc ? get_arg(dp,0) : &undef_var, ei, NULL, &match, NULL, NULL, &b); + if(!argc) + SysFreeString(V_BSTR(&undef_var)); if(FAILED(hres)) return hres; @@ -3959,6 +3996,58 @@ HRESULT regexp_string_match(script_ctx_t *ctx, DispatchEx *re, BSTR str, return hres; } +static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + BSTR ret; + + ret = SysAllocStringLen(ctx->last_match, ctx->last_match_index); + if(!ret) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + } + case DISPATCH_PROPERTYPUT: + return S_OK; + default: + FIXME("unsupported flags\n"); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + BSTR ret; + + ret = SysAllocString(ctx->last_match+ctx->last_match_index+ctx->last_match_length); + if(!ret) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + } + case DISPATCH_PROPERTYPUT: + return S_OK; + default: + FIXME("unsupported flags\n"); + return E_NOTIMPL; + } + + return S_OK; +} + static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -4019,6 +4108,20 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags return S_OK; } +static const builtin_prop_t RegExpConstr_props[] = { + {leftContextW, RegExpConstr_leftContext, 0}, + {rightContextW, RegExpConstr_rightContext, 0} +}; + +static const builtin_info_t RegExpConstr_info = { + JSCLASS_FUNCTION, + {NULL, Function_value, 0}, + sizeof(RegExpConstr_props)/sizeof(*RegExpConstr_props), + RegExpConstr_props, + NULL, + NULL +}; + HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret) { RegExpInstance *regexp; @@ -4030,7 +4133,7 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di if(FAILED(hres)) return hres; - hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL, + hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, &RegExpConstr_info, PROPF_CONSTR|2, ®exp->dispex, ret); jsdisp_release(®exp->dispex); diff --git a/reactos/dll/win32/jscript/rsrc.rc b/reactos/dll/win32/jscript/rsrc.rc index d23ea33a2f3..db7e0ff2fa3 100644 --- a/reactos/dll/win32/jscript/rsrc.rc +++ b/reactos/dll/win32/jscript/rsrc.rc @@ -30,3 +30,4 @@ REGINST REGINST jscript.inf #include "jscript_Nl.rc" #include "jscript_Pt.rc" #include "jscript_Ru.rc" +#include "jscript_Si.rc" diff --git a/reactos/dll/win32/jscript/string.c b/reactos/dll/win32/jscript/string.c index 510dcc272c6..05b9eba26e1 100644 --- a/reactos/dll/win32/jscript/string.c +++ b/reactos/dll/win32/jscript/string.c @@ -779,9 +779,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI DWORD parens_cnt = 0, parens_size=0, rep_len=0, length; BSTR rep_str = NULL, match_str = NULL, ret_str, val_str; DispatchEx *rep_func = NULL, *regexp = NULL; - match_result_t *parens = NULL, match, **parens_ptr = &parens; + match_result_t *parens = NULL, match = {NULL,0}, **parens_ptr = &parens; strbuf_t ret = {NULL,0,0}; - DWORD re_flags = 0; + DWORD re_flags = REM_NO_CTX_UPDATE; VARIANT *arg_var; HRESULT hres = S_OK; @@ -860,7 +860,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI if(regexp) { hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr, &parens_size, &parens_cnt, &match); - re_flags = REM_CHECK_GLOBAL; + re_flags |= REM_CHECK_GLOBAL; if(hres == S_FALSE) { hres = S_OK; @@ -969,13 +969,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI if(rep_func) jsdisp_release(rep_func); - if(regexp) - jsdisp_release(regexp); - SysFreeString(val_str); SysFreeString(rep_str); SysFreeString(match_str); heap_free(parens); + if(SUCCEEDED(hres) && match.str && regexp) { + if(!val_str) + val_str = SysAllocStringLen(str, length); + if(val_str) { + SysFreeString(ctx->last_match); + ctx->last_match = val_str; + val_str = NULL; + ctx->last_match_index = match.str-str; + ctx->last_match_length = match.len; + }else { + hres = E_OUTOFMEMORY; + } + } + + if(regexp) + jsdisp_release(regexp); + SysFreeString(val_str); + if(SUCCEEDED(hres) && retv) { ret_str = SysAllocStringLen(ret.buf, ret.len); if(!ret_str) From da3904b159b7a48aa3c6dedd8bd9309e7cd6b1df Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 14:42:39 +0000 Subject: [PATCH 089/292] [BOOTDATA] revert 47055 svn path=/trunk/; revision=47414 --- reactos/boot/bootdata/hivedef_arm.inf | 3 +-- reactos/boot/bootdata/hivedef_i386.inf | Bin 314636 -> 314522 bytes 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/reactos/boot/bootdata/hivedef_arm.inf b/reactos/boot/bootdata/hivedef_arm.inf index 086ee67f4fa..8d8c48935d1 100644 --- a/reactos/boot/bootdata/hivedef_arm.inf +++ b/reactos/boot/bootdata/hivedef_arm.inf @@ -1530,8 +1530,7 @@ HKCU,"Control Panel\Accessibility\Keyboard Preference","On",2,"0" ; Internet Explorer HKCU,Software\Wine\MSHTML,"GeckoUrl",,"http://source.winehq.org/winegecko.php" -;HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\" -HKCU,Software\Wine\MSHTML,"GeckoCabDir",,"C:\ReactOS\" +HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\" ; Sound Schemes HKCU,"AppEvents",,0x00000012 diff --git a/reactos/boot/bootdata/hivedef_i386.inf b/reactos/boot/bootdata/hivedef_i386.inf index 905f5ef3daff1b1d91a02000819e52a8f03b898b..8fdc4bb0828808f211aa4ff7afae06740850d351 100644 GIT binary patch delta 38 ucmeB~B|K}Ua6=1Y3sVd87M5)Z)5Q{49HuuUvItD)NMy0tz9Eq%CK~_=3=Iqb delta 61 zcmbO=Q@CfAa6=1Y3sVd87M5)ZlW!#OOh1soQa62D0!x6n4ucYdGlLaF3_}n@DnlYe RGD8W2KSS_#(?pikYygDO5@7%U From bc9b61ca215dd54467ead588571f6febd1747db7 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 14:44:13 +0000 Subject: [PATCH 090/292] [MSHTML] restore local mshtml changes lost by last wine sync svn path=/trunk/; revision=47415 --- reactos/dll/win32/mshtml/install.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/reactos/dll/win32/mshtml/install.c b/reactos/dll/win32/mshtml/install.c index 4122194a7cc..e47c28423d0 100644 --- a/reactos/dll/win32/mshtml/install.c +++ b/reactos/dll/win32/mshtml/install.c @@ -60,6 +60,11 @@ static const WCHAR mshtml_keyW[] = '\\','W','i','n','e', '\\','M','S','H','T','M','L',0}; +static const CHAR mshtml_keyA[] = + {'S','o','f','t','w','a','r','e', + '\\','W','i','n','e', + '\\','M','S','H','T','M','L',0}; + static HWND install_dialog = NULL; static LPWSTR tmp_file_name = NULL; static HANDLE tmp_file = INVALID_HANDLE_VALUE; @@ -225,23 +230,18 @@ static BOOL install_from_unix_file(const char *file_name) static BOOL install_from_registered_dir(void) { char *file_name; - HKEY hkey; DWORD res, type, size = MAX_PATH; BOOL ret; - /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ - res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey); - if(res != ERROR_SUCCESS) - return FALSE; - file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); - res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); + /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ + res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); if(res == ERROR_MORE_DATA) { file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME)); - res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); + res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); } - RegCloseKey(hkey); - if(res != ERROR_SUCCESS || type != REG_SZ) { + + if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { heap_free(file_name); return FALSE; } From 7f10ebad54e91cc6aea0e713bdf9d9822cd68b3d Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 14:54:55 +0000 Subject: [PATCH 091/292] [MSHTML] -sync to wine 1.2 RC2 -add ros_diff.patch svn path=/trunk/; revision=47416 --- reactos/dll/win32/mshtml/Nl.rc | 6 +- reactos/dll/win32/mshtml/Ru.rc | 10 +- reactos/dll/win32/mshtml/htmlbody.c | 6 +- reactos/dll/win32/mshtml/htmldoc.c | 21 +++- reactos/dll/win32/mshtml/htmldoc3.c | 12 +- reactos/dll/win32/mshtml/htmlelem.c | 10 +- reactos/dll/win32/mshtml/htmlevent.c | 20 ++-- reactos/dll/win32/mshtml/htmlevent.h | 1 + reactos/dll/win32/mshtml/htmlform.c | 136 +++++++++++++++++----- reactos/dll/win32/mshtml/htmlinput.c | 45 +++++-- reactos/dll/win32/mshtml/htmloption.c | 28 ++++- reactos/dll/win32/mshtml/htmlselect.c | 131 ++++++++++++++++++++- reactos/dll/win32/mshtml/htmltextarea.c | 52 +++++++-- reactos/dll/win32/mshtml/htmlwindow.c | 22 +++- reactos/dll/win32/mshtml/mshtml_private.h | 3 + reactos/dll/win32/mshtml/nsembed.c | 32 ++--- reactos/dll/win32/mshtml/nsiface.idl | 15 ++- reactos/dll/win32/mshtml/nsio.c | 20 ++-- reactos/dll/win32/mshtml/ros_diff.patch | 43 +++++++ reactos/dll/win32/mshtml/secmgr.c | 19 ++- reactos/dll/win32/mshtml/task.c | 2 - 21 files changed, 509 insertions(+), 125 deletions(-) create mode 100644 reactos/dll/win32/mshtml/ros_diff.patch diff --git a/reactos/dll/win32/mshtml/Nl.rc b/reactos/dll/win32/mshtml/Nl.rc index 33baf39b518..d32980ba9fb 100644 --- a/reactos/dll/win32/mshtml/Nl.rc +++ b/reactos/dll/win32/mshtml/Nl.rc @@ -35,9 +35,9 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Wine-Gecko-Installatie" FONT 8, "MS Shell Dlg" { - LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ - "to work correctly. Wine can automatically download and install it for you.\n\n" \ - "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + LTEXT "Wine kon geen Gecko pakket vinden. Gecko is nodig voor programma's die gebruik maken " \ + "van embedded HTML. Wine kan het automatisch voor u downloaden en installeren.\n\n" \ + "Noot: het is aanbevolen om distro pakketten te gebruiken. Zie http://wiki.winehq.org/Gecko voor details.", ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Voortgang", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Installeren", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Ru.rc b/reactos/dll/win32/mshtml/Ru.rc index 8d3a4c3cc0a..6722ddc5dfc 100644 --- a/reactos/dll/win32/mshtml/Ru.rc +++ b/reactos/dll/win32/mshtml/Ru.rc @@ -36,10 +36,12 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "УÑтановка Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Wine не может найти пакет Gecko который нужен Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹ Ñо вÑтроенным HTML " \ - "Ð´Ð»Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ð¹ работы. Wine может автоматичеÑки загрузить и уÑтановить его Ð´Ð»Ñ Ð’Ð°Ñ.\n\n" \ - "Примечание: Рекомендовано иÑпользовать пакет из Вашего диÑтрибутива. ПоÑетите http://wiki.winehq.org/Gecko Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÐµÐ¹.", - ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT + LTEXT "Wine не может найти пакет Gecko, который необходим Ð´Ð»Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ð¹ работы приложений"\ + "Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ HTML. " \ + "Wine может автоматичеÑки загрузить и уÑтановить его Ð´Ð»Ñ Ð²Ð°Ñ.\n\n" \ + "Примечание: рекомендуетÑÑ Ð¸Ñпользовать пакет, предоÑтавлÑемый вашим диÑтрибутивом. "\ + "ПоÑетите http://wiki.winehq.org/Gecko Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации.", + ID_DWL_STATUS, 10, 10, 240, 70, SS_LEFT CONTROL "ПрогреÑÑ", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 65, 240, 12 DEFPUSHBUTTON "&УÑтановить", ID_DWL_INSTALL, 180, 85, 70, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Отмена", IDCANCEL, 100, 85, 70, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/htmlbody.c b/reactos/dll/win32/mshtml/htmlbody.c index 5c66e65a44a..18a60418cee 100644 --- a/reactos/dll/win32/mshtml/htmlbody.c +++ b/reactos/dll/win32/mshtml/htmlbody.c @@ -434,6 +434,10 @@ static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text); nsAString_Finish(&text); + if(NS_FAILED(nsres)) { + ERR("SetText failed: %08x\n", nsres); + return E_FAIL; + } return S_OK; } @@ -462,7 +466,7 @@ static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT nsAString_Finish(&text); - return S_OK; + return hres; } static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v) diff --git a/reactos/dll/win32/mshtml/htmldoc.c b/reactos/dll/win32/mshtml/htmldoc.c index 12aa8c002dc..61476328dd1 100644 --- a/reactos/dll/win32/mshtml/htmldoc.c +++ b/reactos/dll/win32/mshtml/htmldoc.c @@ -889,8 +889,25 @@ static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface) static HRESULT WINAPI HTMLDocument_clear(IHTMLDocument2 *iface) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + nsIDOMNSHTMLDocument *nsdoc; + nsresult nsres; + + TRACE("(%p)\n", This); + + nsres = nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMNSHTMLDocument iface: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMNSHTMLDocument_Clear(nsdoc); + nsIDOMNSHTMLDocument_Release(nsdoc); + if(NS_FAILED(nsres)) { + ERR("Clear failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLDocument_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID, diff --git a/reactos/dll/win32/mshtml/htmldoc3.c b/reactos/dll/win32/mshtml/htmldoc3.c index e28297fce14..f4ea0962cee 100644 --- a/reactos/dll/win32/mshtml/htmldoc3.c +++ b/reactos/dll/win32/mshtml/htmldoc3.c @@ -308,15 +308,19 @@ static HRESULT WINAPI HTMLDocument3_get_dir(IHTMLDocument3 *iface, BSTR *p) static HRESULT WINAPI HTMLDocument3_put_oncontextmenu(IHTMLDocument3 *iface, VARIANT v) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; + + TRACE("(%p)->()\n", This); + + return set_doc_event(This, EVENTID_CONTEXTMENU, &v); } static HRESULT WINAPI HTMLDocument3_get_oncontextmenu(IHTMLDocument3 *iface, VARIANT *p) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_doc_event(This, EVENTID_CONTEXTMENU, p); } static HRESULT WINAPI HTMLDocument3_put_onstop(IHTMLDocument3 *iface, VARIANT v) diff --git a/reactos/dll/win32/mshtml/htmlelem.c b/reactos/dll/win32/mshtml/htmlelem.c index b0cb791a1e8..5bf29159aed 100644 --- a/reactos/dll/win32/mshtml/htmlelem.c +++ b/reactos/dll/win32/mshtml/htmlelem.c @@ -1803,13 +1803,11 @@ static HRESULT WINAPI HTMLFiltersCollection_get_length(IHTMLFiltersCollection *i { HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + if(!p) + return E_POINTER; + FIXME("(%p)->(%p) Always returning 0\n", This, p); - - if(!p) - return E_POINTER; - - if(p) - *p = 0; + *p = 0; return S_OK; } diff --git a/reactos/dll/win32/mshtml/htmlevent.c b/reactos/dll/win32/mshtml/htmlevent.c index eef006c962c..6925a0cf2ac 100644 --- a/reactos/dll/win32/mshtml/htmlevent.c +++ b/reactos/dll/win32/mshtml/htmlevent.c @@ -56,6 +56,9 @@ static const WCHAR onchangeW[] = {'o','n','c','h','a','n','g','e',0}; static const WCHAR clickW[] = {'c','l','i','c','k',0}; static const WCHAR onclickW[] = {'o','n','c','l','i','c','k',0}; +static const WCHAR contextmenuW[] = {'c','o','n','t','e','x','t','m','e','n','u',0}; +static const WCHAR oncontextmenuW[] = {'o','n','c','o','n','t','e','x','t','m','e','n','u',0}; + static const WCHAR dblclickW[] = {'d','b','l','c','l','i','c','k',0}; static const WCHAR ondblclickW[] = {'o','n','d','b','l','c','l','i','c','k',0}; @@ -141,6 +144,8 @@ static const event_info_t event_info[] = { EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {clickW, onclickW, EVENTT_MOUSE, DISPID_EVMETH_ONCLICK, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {contextmenuW, oncontextmenuW, EVENTT_MOUSE, DISPID_EVMETH_ONCONTEXTMENU, + EVENT_BUBBLE}, {dblclickW, ondblclickW, EVENTT_MOUSE, DISPID_EVMETH_ONDBLCLICK, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {dragW, ondragW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAG, @@ -283,16 +288,14 @@ static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface) static HRESULT WINAPI HTMLEventObj_GetTypeInfoCount(IHTMLEventObj *iface, UINT *pctinfo) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLEventObj_GetTypeInfo(IHTMLEventObj *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID riid, @@ -300,9 +303,7 @@ static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID ri LCID lcid, DISPID *rgDispId) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMember, @@ -310,9 +311,8 @@ static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMem VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLElement **p) diff --git a/reactos/dll/win32/mshtml/htmlevent.h b/reactos/dll/win32/mshtml/htmlevent.h index 6ba2fe29dc7..3a8619a068f 100644 --- a/reactos/dll/win32/mshtml/htmlevent.h +++ b/reactos/dll/win32/mshtml/htmlevent.h @@ -21,6 +21,7 @@ typedef enum { EVENTID_BLUR, EVENTID_CHANGE, EVENTID_CLICK, + EVENTID_CONTEXTMENU, EVENTID_DBLCLICK, EVENTID_DRAG, EVENTID_DRAGSTART, diff --git a/reactos/dll/win32/mshtml/htmlform.c b/reactos/dll/win32/mshtml/htmlform.c index 68860560148..8e169170a4b 100644 --- a/reactos/dll/win32/mshtml/htmlform.c +++ b/reactos/dll/win32/mshtml/htmlform.c @@ -41,6 +41,41 @@ struct HTMLFormElement { #define HTMLFORM(x) (&(x)->lpHTMLFormElementVtbl) +static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret) +{ + nsIDOMHTMLCollection *elements; + nsIDOMNode *item; + HTMLDOMNode *node; + nsresult nsres; + + nsres = nsIDOMHTMLFormElement_GetElements(This->nsform, &elements); + if(NS_FAILED(nsres)) { + FIXME("GetElements failed: 0x%08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMHTMLCollection_Item(elements, i, &item); + nsIDOMHTMLCollection_Release(elements); + if(NS_FAILED(nsres)) { + FIXME("Item failed: 0x%08x\n", nsres); + return E_FAIL; + } + + if(item) { + node = get_node(This->element.node.doc, item, TRUE); + if(!node) + return E_OUTOFMEMORY; + + IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); + nsIDOMNode_Release(item); + *ret = (IDispatch*)HTMLDOMNODE(node); + }else { + *ret = NULL; + } + + return S_OK; +} + #define HTMLFORM_THIS(iface) DEFINE_THIS(HTMLFormElement, HTMLFormElement, iface) static HRESULT WINAPI HTMLFormElement_QueryInterface(IHTMLFormElement *iface, @@ -98,15 +133,43 @@ static HRESULT WINAPI HTMLFormElement_Invoke(IHTMLFormElement *iface, DISPID dis static HRESULT WINAPI HTMLFormElement_put_action(IHTMLFormElement *iface, BSTR v) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%s)\n", This, wine_dbgstr_w(v)); - return E_NOTIMPL; + nsAString action_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, wine_dbgstr_w(v)); + + nsAString_InitDepend(&action_str, v); + nsres = nsIDOMHTMLFormElement_SetAction(This->nsform, &action_str); + nsAString_Finish(&action_str); + if(NS_FAILED(nsres)) { + ERR("SetAction failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLFormElement_get_action(IHTMLFormElement *iface, BSTR *p) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString action_str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&action_str, NULL); + nsres = nsIDOMHTMLFormElement_GetAction(This->nsform, &action_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *action; + nsAString_GetData(&action_str, &action); + hres = nsuri_to_url(action, FALSE, p); + }else { + ERR("GetAction failed: %08x\n", nsres); + hres = E_FAIL; + } + + return hres; } static HRESULT WINAPI HTMLFormElement_put_dir(IHTMLFormElement *iface, BSTR v) @@ -238,8 +301,19 @@ static HRESULT WINAPI HTMLFormElement_put_length(IHTMLFormElement *iface, LONG v static HRESULT WINAPI HTMLFormElement_get_length(IHTMLFormElement *iface, LONG *p) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRInt32 length; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLFormElement_GetLength(This->nsform, &length); + if(NS_FAILED(nsres)) { + ERR("GetLength failed: %08x\n", nsres); + return E_FAIL; + } + + *p = length; + return S_OK; } static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown **p) @@ -253,7 +327,20 @@ static HRESULT WINAPI HTMLFormElement_item(IHTMLFormElement *iface, VARIANT name VARIANT index, IDispatch **pdisp) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(v v %p)\n", This, pdisp); + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); + + if(!pdisp) + return E_INVALIDARG; + *pdisp = NULL; + + if(V_VT(&name) == VT_I4) { + if(V_I4(&name) < 0) + return E_INVALIDARG; + return htmlform_item(This, V_I4(&name), pdisp); + } + + FIXME("Unsupported args\n"); return E_NOTIMPL; } @@ -428,34 +515,21 @@ static HRESULT HTMLFormElement_invoke(HTMLDOMNode *iface, EXCEPINFO *ei, IServiceProvider *caller) { HTMLFormElement *This = HTMLFORM_NODE_THIS(iface); - nsIDOMHTMLCollection *elements; - nsIDOMNode *item; - HTMLDOMNode *node; - nsresult nsres; + IDispatch *ret; + HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); - nsres = nsIDOMHTMLFormElement_GetElements(This->nsform, &elements); - if(NS_FAILED(nsres)) { - FIXME("GetElements failed: 0x%08x\n", nsres); - return E_FAIL; + hres = htmlform_item(This, id - MSHTML_DISPID_CUSTOM_MIN, &ret); + if(FAILED(hres)) + return hres; + + if(ret) { + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = ret; + }else { + V_VT(res) = VT_NULL; } - - nsres = nsIDOMHTMLCollection_Item(elements, id - MSHTML_DISPID_CUSTOM_MIN, &item); - nsIDOMHTMLCollection_Release(elements); - if(NS_FAILED(nsres)) { - FIXME("Item failed: 0x%08x\n", nsres); - return E_FAIL; - } - - node = get_node(This->element.node.doc, item, TRUE); - - V_VT(res) = VT_DISPATCH; - V_DISPATCH(res) = (IDispatch*)node; - - IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); - nsIDOMNode_Release(item); - return S_OK; } diff --git a/reactos/dll/win32/mshtml/htmlinput.c b/reactos/dll/win32/mshtml/htmlinput.c index 1b8d1c5413f..76a5063bc2e 100644 --- a/reactos/dll/win32/mshtml/htmlinput.c +++ b/reactos/dll/win32/mshtml/htmlinput.c @@ -106,8 +106,24 @@ static HRESULT WINAPI HTMLInputElement_Invoke(IHTMLInputElement *iface, DISPID d static HRESULT WINAPI HTMLInputElement_put_type(IHTMLInputElement *iface, BSTR v) { HTMLInputElement *This = HTMLINPUT_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString type_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + /* + * FIXME: + * On IE setting type works only on dynamically created elements before adding them to DOM tree. + */ + nsAString_InitDepend(&type_str, v); + nsres = nsIDOMHTMLInputElement_SetType(This->nsinput, &type_str); + nsAString_Finish(&type_str); + if(NS_FAILED(nsres)) { + ERR("SetType failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLInputElement_get_type(IHTMLInputElement *iface, BSTR *p) @@ -180,8 +196,20 @@ static HRESULT WINAPI HTMLInputElement_get_value(IHTMLInputElement *iface, BSTR static HRESULT WINAPI HTMLInputElement_put_name(IHTMLInputElement *iface, BSTR v) { HTMLInputElement *This = HTMLINPUT_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString name_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&name_str, v); + nsres = nsIDOMHTMLInputElement_SetName(This->nsinput, &name_str); + nsAString_Finish(&name_str); + if(NS_FAILED(nsres)) { + ERR("SetName failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR *p) @@ -190,6 +218,7 @@ static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR * nsAString name_str; const PRUnichar *name; nsresult nsres; + HRESULT hres = S_OK; TRACE("(%p)->(%p)\n", This, p); @@ -198,16 +227,14 @@ static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR * nsres = nsIDOMHTMLInputElement_GetName(This->nsinput, &name_str); if(NS_SUCCEEDED(nsres)) { nsAString_GetData(&name_str, &name); - *p = SysAllocString(name); + *p = *name ? SysAllocString(name) : NULL; }else { ERR("GetName failed: %08x\n", nsres); - return E_FAIL; + hres = E_FAIL; } nsAString_Finish(&name_str); - - TRACE("name=%s\n", debugstr_w(*p)); - return S_OK; + return hres; } static HRESULT WINAPI HTMLInputElement_put_status(IHTMLInputElement *iface, VARIANT_BOOL v) diff --git a/reactos/dll/win32/mshtml/htmloption.c b/reactos/dll/win32/mshtml/htmloption.c index 3e037627bf1..b8166341bd4 100644 --- a/reactos/dll/win32/mshtml/htmloption.c +++ b/reactos/dll/win32/mshtml/htmloption.c @@ -98,15 +98,35 @@ static HRESULT WINAPI HTMLOptionElement_Invoke(IHTMLOptionElement *iface, DISPID static HRESULT WINAPI HTMLOptionElement_put_selected(IHTMLOptionElement *iface, VARIANT_BOOL v) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%x)\n", This, v); + + nsres = nsIDOMHTMLOptionElement_SetSelected(This->nsoption, v != VARIANT_FALSE); + if(NS_FAILED(nsres)) { + ERR("SetSelected failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLOptionElement_get_selected(IHTMLOptionElement *iface, VARIANT_BOOL *p) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRBool selected; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLOptionElement_GetSelected(This->nsoption, &selected); + if(NS_FAILED(nsres)) { + ERR("GetSelected failed: %08x\n", nsres); + return E_FAIL; + } + + *p = selected ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLOptionElement_put_value(IHTMLOptionElement *iface, BSTR v) diff --git a/reactos/dll/win32/mshtml/htmlselect.c b/reactos/dll/win32/mshtml/htmlselect.c index 6698606a4c4..f3aa36f650f 100644 --- a/reactos/dll/win32/mshtml/htmlselect.c +++ b/reactos/dll/win32/mshtml/htmlselect.c @@ -42,6 +42,43 @@ typedef struct { #define HTMLSELECT(x) ((IHTMLSelectElement*) &(x)->lpHTMLSelectElementVtbl) +static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) +{ + nsIDOMHTMLOptionsCollection *nscol; + nsIDOMNode *nsnode; + nsresult nsres; + + nsres = nsIDOMHTMLSelectElement_GetOptions(This->nsselect, &nscol); + if(NS_FAILED(nsres)) { + ERR("GetOptions failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMHTMLOptionsCollection_Item(nscol, i, &nsnode); + nsIDOMHTMLOptionsCollection_Release(nscol); + if(NS_FAILED(nsres)) { + ERR("Item failed: %08x\n", nsres); + return E_FAIL; + } + + if(nsnode) { + HTMLDOMNode *node; + + node = get_node(This->element.node.doc, nsnode, TRUE); + nsIDOMNode_Release(nsnode); + if(!node) { + ERR("Could not find node\n"); + return E_FAIL; + } + + IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); + *ret = (IDispatch*)HTMLDOMNODE(node); + }else { + *ret = NULL; + } + return S_OK; +} + #define HTMLSELECT_THIS(iface) DEFINE_THIS(HTMLSelectElement, HTMLSelectElement, iface) static HRESULT WINAPI HTMLSelectElement_QueryInterface(IHTMLSelectElement *iface, @@ -170,8 +207,12 @@ static HRESULT WINAPI HTMLSelectElement_get_name(IHTMLSelectElement *iface, BSTR static HRESULT WINAPI HTMLSelectElement_get_options(IHTMLSelectElement *iface, IDispatch **p) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + *p = (IDispatch*)HTMLSELECT(This); + IDispatch_AddRef(*p); + return S_OK; } static HRESULT WINAPI HTMLSelectElement_put_onchange(IHTMLSelectElement *iface, VARIANT v) @@ -364,8 +405,15 @@ static HRESULT WINAPI HTMLSelectElement_remove(IHTMLSelectElement *iface, LONG i static HRESULT WINAPI HTMLSelectElement_put_length(IHTMLSelectElement *iface, LONG v) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%d)\n", This, v); + + nsres = nsIDOMHTMLSelectElement_SetLength(This->nsselect, v); + if(NS_FAILED(nsres)) + ERR("SetLength failed: %08x\n", nsres); + + return S_OK; } static HRESULT WINAPI HTMLSelectElement_get_length(IHTMLSelectElement *iface, LONG *p) @@ -397,7 +445,20 @@ static HRESULT WINAPI HTMLSelectElement_item(IHTMLSelectElement *iface, VARIANT VARIANT index, IDispatch **pdisp) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(v v %p)\n", This, pdisp); + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); + + if(!pdisp) + return E_POINTER; + *pdisp = NULL; + + if(V_VT(&name) == VT_I4) { + if(V_I4(&name) < 0) + return E_INVALIDARG; + return htmlselect_item(This, V_I4(&name), pdisp); + } + + FIXME("Unsupported args\n"); return E_NOTIMPL; } @@ -493,6 +554,60 @@ static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BO return IHTMLSelectElement_get_disabled(HTMLSELECT(This), p); } +#define DISPID_OPTIONCOL_0 MSHTML_DISPID_CUSTOM_MIN + +static HRESULT HTMLSelectElement_get_dispid(HTMLDOMNode *iface, BSTR name, DWORD flags, DISPID *dispid) +{ + const WCHAR *ptr; + DWORD idx = 0; + + for(ptr = name; *ptr && isdigitW(*ptr); ptr++) { + idx = idx*10 + (*ptr-'0'); + if(idx > MSHTML_CUSTOM_DISPID_CNT) { + WARN("too big idx\n"); + return DISP_E_UNKNOWNNAME; + } + } + if(*ptr) + return DISP_E_UNKNOWNNAME; + + *dispid = DISPID_OPTIONCOL_0 + idx; + return S_OK; +} + +static HRESULT HTMLSelectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLSelectElement *This = HTMLSELECT_NODE_THIS(iface); + + TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + IDispatch *ret; + HRESULT hres; + + hres = htmlselect_item(This, id-DISPID_OPTIONCOL_0, &ret); + if(FAILED(hres)) + return hres; + + if(ret) { + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = ret; + }else { + V_VT(res) = VT_NULL; + } + break; + } + + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; +} + #undef HTMLSELECT_NODE_THIS static const NodeImplVtbl HTMLSelectElementImplVtbl = { @@ -501,7 +616,11 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { NULL, NULL, HTMLSelectElementImpl_put_disabled, - HTMLSelectElementImpl_get_disabled + HTMLSelectElementImpl_get_disabled, + NULL, + NULL, + HTMLSelectElement_get_dispid, + HTMLSelectElement_invoke }; static const tid_t HTMLSelectElement_tids[] = { diff --git a/reactos/dll/win32/mshtml/htmltextarea.c b/reactos/dll/win32/mshtml/htmltextarea.c index 9ded8ac6e12..dd33c72df21 100644 --- a/reactos/dll/win32/mshtml/htmltextarea.c +++ b/reactos/dll/win32/mshtml/htmltextarea.c @@ -105,8 +105,20 @@ static HRESULT WINAPI HTMLTextAreaElement_get_type(IHTMLTextAreaElement *iface, static HRESULT WINAPI HTMLTextAreaElement_put_value(IHTMLTextAreaElement *iface, BSTR v) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString value_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&value_str, v); + nsres = nsIDOMHTMLTextAreaElement_SetValue(This->nstextarea, &value_str); + nsAString_Finish(&value_str); + if(NS_FAILED(nsres)) { + ERR("SetValue failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, BSTR *p) @@ -115,6 +127,7 @@ static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, nsAString value_str; const PRUnichar *value; nsresult nsres; + HRESULT hres = S_OK; TRACE("(%p)->(%p)\n", This, p); @@ -123,15 +136,14 @@ static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, nsres = nsIDOMHTMLTextAreaElement_GetValue(This->nstextarea, &value_str); if(NS_SUCCEEDED(nsres)) { nsAString_GetData(&value_str, &value); - *p = SysAllocString(value); + *p = *value ? SysAllocString(value) : NULL; }else { ERR("GetValue failed: %08x\n", nsres); + hres = E_FAIL; } nsAString_Finish(&value_str); - - TRACE("%s\n", debugstr_w(*p)); - return S_OK; + return hres; } static HRESULT WINAPI HTMLTextAreaElement_put_name(IHTMLTextAreaElement *iface, BSTR v) @@ -253,15 +265,35 @@ static HRESULT WINAPI HTMLTextAreaElement_get_onselect(IHTMLTextAreaElement *ifa static HRESULT WINAPI HTMLTextAreaElement_put_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL v) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%x)\n", This, v); + + nsres = nsIDOMHTMLTextAreaElement_SetReadOnly(This->nstextarea, v != VARIANT_FALSE); + if(NS_FAILED(nsres)) { + ERR("SetReadOnly failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_get_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL *p) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRBool b; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLTextAreaElement_GetReadOnly(This->nstextarea, &b); + if(NS_FAILED(nsres)) { + ERR("GetReadOnly failed: %08x\n", nsres); + return E_FAIL; + } + + *p = b ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_put_rows(IHTMLTextAreaElement *iface, LONG v) diff --git a/reactos/dll/win32/mshtml/htmlwindow.c b/reactos/dll/win32/mshtml/htmlwindow.c index 5dbea55905c..1701b533288 100644 --- a/reactos/dll/win32/mshtml/htmlwindow.c +++ b/reactos/dll/win32/mshtml/htmlwindow.c @@ -511,20 +511,34 @@ static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID return clear_task_timer(&This->doc->basedoc, FALSE, timerID); } +#define MAX_MESSAGE_LEN 2000 + static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - WCHAR wszTitle[100]; + WCHAR title[100], *msg = message; + DWORD len; TRACE("(%p)->(%s)\n", This, debugstr_w(message)); - if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle, - sizeof(wszTitle)/sizeof(WCHAR))) { + if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, title, + sizeof(title)/sizeof(WCHAR))) { WARN("Could not load message box title: %d\n", GetLastError()); return S_OK; } - MessageBoxW(This->doc_obj->hwnd, message, wszTitle, MB_ICONWARNING); + len = SysStringLen(message); + if(len > MAX_MESSAGE_LEN) { + msg = heap_alloc((MAX_MESSAGE_LEN+1)*sizeof(WCHAR)); + if(!msg) + return E_OUTOFMEMORY; + memcpy(msg, message, MAX_MESSAGE_LEN*sizeof(WCHAR)); + msg[MAX_MESSAGE_LEN] = 0; + } + + MessageBoxW(This->doc_obj->hwnd, msg, title, MB_ICONWARNING); + if(msg != message) + heap_free(msg); return S_OK; } diff --git a/reactos/dll/win32/mshtml/mshtml_private.h b/reactos/dll/win32/mshtml/mshtml_private.h index 3db8d791e48..4deb4d6357d 100644 --- a/reactos/dll/win32/mshtml/mshtml_private.h +++ b/reactos/dll/win32/mshtml/mshtml_private.h @@ -144,6 +144,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_DISPID_CUSTOM_MIN 0x60000000 #define MSHTML_DISPID_CUSTOM_MAX 0x6fffffff +#define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN) typedef struct { HRESULT (*value)(IUnknown*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); @@ -727,8 +728,10 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*); void *nsalloc(size_t) __WINE_ALLOC_SIZE(1); void nsfree(void*); +void nsACString_InitDepend(nsACString*,const char*); void nsACString_SetData(nsACString*,const char*); PRUint32 nsACString_GetData(const nsACString*,const char**); +void nsACString_Finish(nsACString*); BOOL nsAString_Init(nsAString*,const PRUnichar*); void nsAString_InitDepend(nsAString*,const PRUnichar*); diff --git a/reactos/dll/win32/mshtml/nsembed.c b/reactos/dll/win32/mshtml/nsembed.c index 8a590079278..56c5d945618 100644 --- a/reactos/dll/win32/mshtml/nsembed.c +++ b/reactos/dll/win32/mshtml/nsembed.c @@ -32,6 +32,7 @@ #include "wine/unicode.h" #include "mshtml_private.h" +#include "htmlevent.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); WINE_DECLARE_DEBUG_CHANNEL(gecko); @@ -48,20 +49,14 @@ WINE_DECLARE_DEBUG_CHANNEL(gecko); #define PR_UINT32_MAX 0xffffffff -struct nsCStringContainer { - void *v; - void *d1; - PRUint32 d2; - PRUint32 d3; -}; - #define NS_STRING_CONTAINER_INIT_DEPEND 0x0002 +#define NS_CSTRING_CONTAINER_INIT_DEPEND 0x0002 static nsresult (*NS_InitXPCOM2)(nsIServiceManager**,void*,void*); static nsresult (*NS_ShutdownXPCOM)(nsIServiceManager*); static nsresult (*NS_GetComponentRegistrar)(nsIComponentRegistrar**); static nsresult (*NS_StringContainerInit2)(nsStringContainer*,const PRUnichar*,PRUint32,PRUint32); -static nsresult (*NS_CStringContainerInit)(nsCStringContainer*); +static nsresult (*NS_CStringContainerInit2)(nsCStringContainer*,const char*,PRUint32,PRUint32); static nsresult (*NS_StringContainerFinish)(nsStringContainer*); static nsresult (*NS_CStringContainerFinish)(nsCStringContainer*); static nsresult (*NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32); @@ -188,7 +183,7 @@ static BOOL load_xpcom(const PRUnichar *gre_path) NS_DLSYM(NS_ShutdownXPCOM); NS_DLSYM(NS_GetComponentRegistrar); NS_DLSYM(NS_StringContainerInit2); - NS_DLSYM(NS_CStringContainerInit); + NS_DLSYM(NS_CStringContainerInit2); NS_DLSYM(NS_StringContainerFinish); NS_DLSYM(NS_CStringContainerFinish); NS_DLSYM(NS_StringSetData); @@ -526,11 +521,18 @@ void nsfree(void *mem) nsIMemory_Free(nsmem, mem); } -static void nsACString_Init(nsACString *str, const char *data) +static BOOL nsACString_Init(nsACString *str, const char *data) { - NS_CStringContainerInit(str); - if(data) - nsACString_SetData(str, data); + return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0)); +} + +/* + * Initializes nsACString with data owned by caller. + * Caller must ensure that data is valid during lifetime of string object. + */ +void nsACString_InitDepend(nsACString *str, const char *data) +{ + NS_CStringContainerInit2(str, data, PR_UINT32_MAX, NS_CSTRING_CONTAINER_INIT_DEPEND); } void nsACString_SetData(nsACString *str, const char *data) @@ -543,7 +545,7 @@ PRUint32 nsACString_GetData(const nsACString *str, const char **data) return NS_CStringGetData(str, data, NULL); } -static void nsACString_Finish(nsACString *str) +void nsACString_Finish(nsACString *str) { NS_CStringContainerFinish(str); } @@ -1006,6 +1008,8 @@ static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuList TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode); + fire_event(This->doc->basedoc.doc_node /* FIXME */, EVENTID_CONTEXTMENU, TRUE, aNode, aEvent); + nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres); diff --git a/reactos/dll/win32/mshtml/nsiface.idl b/reactos/dll/win32/mshtml/nsiface.idl index 66ab8e6a49b..4ccc64a7c02 100644 --- a/reactos/dll/win32/mshtml/nsiface.idl +++ b/reactos/dll/win32/mshtml/nsiface.idl @@ -119,7 +119,6 @@ typedef nsISupports nsIDOMDOMImplementation; typedef nsISupports nsIDOMCDATASection; typedef nsISupports nsIDOMProcessingInstruction; typedef nsISupports nsIDOMEntityReference; -typedef nsISupports nsIDOMHTMLOptionsCollection; typedef nsISupports nsIWebProgressListener; typedef nsISupports nsIDOMCSSValue; typedef nsISupports nsIPrintSession; @@ -1319,6 +1318,20 @@ interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement nsresult SetValue(const nsAString *aValue); } +[ + object, + uuid(bce0213c-f70f-488f-b93f-688acca55d63), + local + /* FROZEN */ +] +interface nsIDOMHTMLOptionsCollection : nsISupports +{ + nsresult GetLength(PRUint32 *aLength); + nsresult SetLength(PRUint32 aLength); + nsresult Item(PRUint32 index, nsIDOMNode **_retval); + nsresult NamedItem(const nsAString *name, nsIDOMNode **_retval); +} + [ object, uuid(a6cf9090-15b3-11d2-932e-00805f8add32), diff --git a/reactos/dll/win32/mshtml/nsio.c b/reactos/dll/win32/mshtml/nsio.c index 0c8e45704d7..63c9a6a3d6a 100644 --- a/reactos/dll/win32/mshtml/nsio.c +++ b/reactos/dll/win32/mshtml/nsio.c @@ -196,16 +196,15 @@ static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri) url = heap_strdupW(uri->wine_url); hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url); - heap_free(url); - if(hres != S_OK || !new_url) - return FALSE; - - if(strcmpW(url, new_url)) { - FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url)); - ret = TRUE; + if(hres == S_OK && new_url) { + if(strcmpW(url, new_url)) { + FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url)); + ret = TRUE; + } + CoTaskMemFree(new_url); } - CoTaskMemFree(new_url); + heap_free(url); return ret; } @@ -229,7 +228,7 @@ nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, PRBool *_retva } wine_uri->is_doc_uri = TRUE; - *_retval = translate_url(nscontainer->doc->basedoc.doc_obj, wine_uri); + *_retval = translate_url(nscontainer->doc, wine_uri); } nsIURI_Release(NSURI(wine_uri)); @@ -2453,6 +2452,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * HTMLWindow *window = NULL; nsIURI *uri = NULL; LPCWSTR base_wine_url = NULL; + nsACString spec_str; nsresult nsres; nsACString_GetData(aSpec, &spec); @@ -2485,7 +2485,9 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * } } + nsACString_InitDepend(&spec_str, spec); nsres = nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, &uri); + nsACString_Finish(&spec_str); if(NS_FAILED(nsres)) TRACE("NewURI failed: %08x\n", nsres); diff --git a/reactos/dll/win32/mshtml/ros_diff.patch b/reactos/dll/win32/mshtml/ros_diff.patch new file mode 100644 index 00000000000..51add30a06c --- /dev/null +++ b/reactos/dll/win32/mshtml/ros_diff.patch @@ -0,0 +1,43 @@ +--- C:/Users/CHRIST~1/AppData/Local/Temp/install.-rev47414.svn001.tmp.c Sa Mai 29 16:46:40 2010 ++++ C:/Users/Christoph/Desktop/Projekte/ReactOS/dll/win32/mshtml/install.c Sa Mai 29 16:43:49 2010 +@@ -60,6 +60,11 @@ + '\\','W','i','n','e', + '\\','M','S','H','T','M','L',0}; + ++static const CHAR mshtml_keyA[] = ++ {'S','o','f','t','w','a','r','e', ++ '\\','W','i','n','e', ++ '\\','M','S','H','T','M','L',0}; ++ + static HWND install_dialog = NULL; + static LPWSTR tmp_file_name = NULL; + static HANDLE tmp_file = INVALID_HANDLE_VALUE; +@@ -225,23 +230,18 @@ + static BOOL install_from_registered_dir(void) + { + char *file_name; +- HKEY hkey; + DWORD res, type, size = MAX_PATH; + BOOL ret; + ++ file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); + /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ +- res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey); +- if(res != ERROR_SUCCESS) +- return FALSE; +- +- file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); +- res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); ++ res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + if(res == ERROR_MORE_DATA) { + file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME)); +- res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); ++ res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + } +- RegCloseKey(hkey); +- if(res != ERROR_SUCCESS || type != REG_SZ) { ++ ++ if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { + heap_free(file_name); + return FALSE; + } diff --git a/reactos/dll/win32/mshtml/secmgr.c b/reactos/dll/win32/mshtml/secmgr.c index e35a83b5c29..c74e19fd93b 100644 --- a/reactos/dll/win32/mshtml/secmgr.c +++ b/reactos/dll/win32/mshtml/secmgr.c @@ -90,6 +90,8 @@ static HRESULT confirm_safety(HTMLDocumentNode *This, const WCHAR *url, struct C IObjectSafety *obj_safety; HRESULT hres; + TRACE("%s %p %s\n", debugstr_w(url), cs->pUnk, debugstr_guid(&cs->clsid)); + /* FIXME: Check URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY */ hres = IInternetSecurityManager_ProcessUrlAction(This->secmgr, url, URLACTION_SCRIPT_SAFE_ACTIVEX, @@ -119,11 +121,17 @@ static HRESULT confirm_safety(HTMLDocumentNode *This, const WCHAR *url, struct C } hres = IObjectSafety_GetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, &supported_opts, &enabled_opts); - if(SUCCEEDED(hres)) { - enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER; - if(supported_opts & INTERFACE_USES_SECURITY_MANAGER) - enabled_opts |= INTERFACE_USES_SECURITY_MANAGER; - hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts); + if(FAILED(hres)) + supported_opts = 0; + + enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + if(supported_opts & INTERFACE_USES_SECURITY_MANAGER) + enabled_opts |= INTERFACE_USES_SECURITY_MANAGER; + + hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts); + if(FAILED(hres)) { + enabled_opts &= ~INTERFACE_USES_SECURITY_MANAGER; + hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatch, enabled_opts, enabled_opts); } IObjectSafety_Release(obj_safety); @@ -175,6 +183,7 @@ static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHos *(DWORD*)*ppPolicy = policy; *pcbPolicy = sizeof(policy); + TRACE("policy %x\n", policy); return S_OK; } diff --git a/reactos/dll/win32/mshtml/task.c b/reactos/dll/win32/mshtml/task.c index eae51cacd15..c896179715b 100644 --- a/reactos/dll/win32/mshtml/task.c +++ b/reactos/dll/win32/mshtml/task.c @@ -222,7 +222,6 @@ static void call_timer_disp(IDispatch *disp) static LRESULT process_timer(void) { thread_data_t *thread_data = get_thread_data(TRUE); - HTMLDocument *doc; IDispatch *disp; DWORD tc; task_timer_t *timer; @@ -238,7 +237,6 @@ static LRESULT process_timer(void) return 0; } - doc = timer->doc; disp = timer->disp; IDispatch_AddRef(disp); From 04c946ceccaa934bed6088bf6bceddf2b5082659 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 29 May 2010 16:00:43 +0000 Subject: [PATCH 092/292] [NTOSKRNL] - Fix stack skipping logic in IofCompleteRequest - Fixes displaying MULTIPLE_IRP_COMPLETE_REQUESTS bug check - Patch by lassy with a typo fix by me svn path=/trunk/; revision=47417 --- reactos/ntoskrnl/io/iomgr/irp.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/irp.c b/reactos/ntoskrnl/io/iomgr/irp.c index 0863f58907b..d7e4ed2741f 100644 --- a/reactos/ntoskrnl/io/iomgr/irp.c +++ b/reactos/ntoskrnl/io/iomgr/irp.c @@ -1217,15 +1217,22 @@ IofCompleteRequest(IN PIRP Irp, ErrorCode = PtrToUlong(LastStackPtr->Parameters.Others.Argument4); } - /* Get the Current Stack */ - StackPtr = IoGetCurrentIrpStackLocation(Irp); - - /* Loop the Stacks and complete the IRPs */ - do + /* + * Start the loop with the current stack and point the IRP to the next stack + * and then keep incrementing the stack as we loop through. The IRP should + * always point to the next stack location w.r.t the one currently being + * analyzed, so completion routine code will see the appropriate value. + * Because of this, we must loop until the current stack location is +1 of + * the stack count, because when StackPtr is at the end, CurrentLocation is +1. + */ + for (StackPtr = IoGetCurrentIrpStackLocation(Irp), + Irp->CurrentLocation++, + Irp->Tail.Overlay.CurrentStackLocation++; + Irp->CurrentLocation <= (Irp->StackCount + 1); + StackPtr++, + Irp->CurrentLocation++, + Irp->Tail.Overlay.CurrentStackLocation++) { - /* Skip current stack location */ - IoSkipCurrentIrpStackLocation(Irp); - /* Set Pending Returned */ Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED; @@ -1287,10 +1294,7 @@ IofCompleteRequest(IN PIRP Irp, /* Clear the stack location */ IopClearStackLocation(StackPtr); } - - /* Move pointer to next stack location */ - StackPtr++; - } while (Irp->CurrentLocation <= Irp->StackCount); + } /* Check if the IRP is an associated IRP */ if (Irp->Flags & IRP_ASSOCIATED_IRP) From 08ca572fc4b96f1684fa17b19e408ee17e1347bb Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 29 May 2010 16:49:23 +0000 Subject: [PATCH 093/292] [CMD] copy command: - Don't pass device path to FindFirstFile, use short path instead - Join duplicate code to simplify processing See issue #3575 for more details. svn path=/trunk/; revision=47418 --- reactos/base/shell/cmd/copy.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/reactos/base/shell/cmd/copy.c b/reactos/base/shell/cmd/copy.c index d451fea09e8..a5bf33eefcb 100644 --- a/reactos/base/shell/cmd/copy.c +++ b/reactos/base/shell/cmd/copy.c @@ -604,28 +604,30 @@ INT cmd_copy (LPTSTR param) bTouch = TRUE; bDone = TRUE; } - - if(_tcslen(tmpName) == 2) - { - if(tmpName[1] == _T(':')) - { - GetRootPath(tmpName,szSrcPath,MAX_PATH); - } - } - else - /* Get the full path to first file in the string of file names */ - GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); } else { bDone = TRUE; - if(_tcslen(arg[nSrc]) == 2 && arg[nSrc][1] == _T(':')) + _tcscpy(tmpName, arg[nSrc]); + } + + /* Get full path or root names */ + if(_tcslen(tmpName) == 2 && tmpName[1] == _T(':')) + { + GetRootPath(tmpName,szSrcPath,MAX_PATH); + } + else + { + /* Get the full path to first file in the string of file names */ + GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); + + /* We got a device path of form \\.\x */ + /* FindFirstFile cannot handle this, therefore use the short path */ + if (szSrcPath[0] == _T('\\') && szSrcPath[1] == _T('\\') && + szSrcPath[2] == _T('.') && szSrcPath[3] == _T('\\')) { - GetRootPath(arg[nSrc],szSrcPath,MAX_PATH); + _tcscpy(szSrcPath, tmpName); } - else - /* Get the full path of the source file */ - GetFullPathName (arg[nSrc], MAX_PATH, szSrcPath, NULL); } /* From this point on, we can assume that the shortest path is 3 letters long From 2489a60f61d9883e808318297ec8c81076f0ed35 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 17:33:37 +0000 Subject: [PATCH 094/292] [WS2_32] implement WSAAddressToStringA/W (taken from wine) svn path=/trunk/; revision=47419 --- reactos/dll/win32/ws2_32/misc/ns.c | 64 +++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/ws2_32/misc/ns.c b/reactos/dll/win32/ws2_32/misc/ns.c index fee4f032868..04e5b4bc5e2 100644 --- a/reactos/dll/win32/ws2_32/misc/ns.c +++ b/reactos/dll/win32/ws2_32/misc/ns.c @@ -32,10 +32,44 @@ WSAAddressToStringA(IN LPSOCKADDR lpsaAddress, OUT LPSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength) { - UNIMPLEMENTED + DWORD size; + CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ + CHAR *p; - WSASetLastError(WSASYSCALLFAILURE); - return SOCKET_ERROR; + if (!lpsaAddress) return SOCKET_ERROR; + if (!lpszAddressString || !lpdwAddressStringLength) return SOCKET_ERROR; + + switch(lpsaAddress->sa_family) + { + case AF_INET: + if (dwAddressLength < sizeof(SOCKADDR_IN)) return SOCKET_ERROR; + sprintf( buffer, "%u.%u.%u.%u:%u", + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 24 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 16 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 8 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) & 0xff), + ntohs( ((SOCKADDR_IN *)lpsaAddress)->sin_port ) ); + + p = strchr( buffer, ':' ); + if (!((SOCKADDR_IN *)lpsaAddress)->sin_port) *p = 0; + break; + default: + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + + size = strlen( buffer ) + 1; + + if (*lpdwAddressStringLength < size) + { + *lpdwAddressStringLength = size; + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *lpdwAddressStringLength = size; + strcpy( lpszAddressString, buffer ); + return 0; } @@ -50,10 +84,28 @@ WSAAddressToStringW(IN LPSOCKADDR lpsaAddress, OUT LPWSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength) { - UNIMPLEMENTED + INT ret; + DWORD size; + WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ + CHAR bufAddr[54]; - WSASetLastError(WSASYSCALLFAILURE); - return SOCKET_ERROR; + size = *lpdwAddressStringLength; + ret = WSAAddressToStringA(lpsaAddress, dwAddressLength, NULL, bufAddr, &size); + + if (ret) return ret; + + MultiByteToWideChar( CP_ACP, 0, bufAddr, size, buffer, sizeof( buffer )/sizeof(WCHAR)); + + if (*lpdwAddressStringLength < size) + { + *lpdwAddressStringLength = size; + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *lpdwAddressStringLength = size; + lstrcpyW( lpszAddressString, buffer ); + return 0; } From 4141772cae66f27668e08c696097b860d5b91a94 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 17:47:03 +0000 Subject: [PATCH 095/292] [SHLWAPI] sync to wine 1.2 RC2 svn path=/trunk/; revision=47420 --- reactos/dll/win32/shlwapi/ordinal.c | 3 +- reactos/dll/win32/shlwapi/reg.c | 42 ++++++++++-- reactos/dll/win32/shlwapi/shlwapi.spec | 1 + reactos/dll/win32/shlwapi/string.c | 4 +- reactos/dll/win32/shlwapi/thread.c | 95 ++++++++++++++++++++++++-- reactos/dll/win32/shlwapi/url.c | 54 +++++++-------- 6 files changed, 158 insertions(+), 41 deletions(-) diff --git a/reactos/dll/win32/shlwapi/ordinal.c b/reactos/dll/win32/shlwapi/ordinal.c index 332bdb67f79..22851d92010 100644 --- a/reactos/dll/win32/shlwapi/ordinal.c +++ b/reactos/dll/win32/shlwapi/ordinal.c @@ -484,7 +484,6 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) DWORD mystrlen, mytype; DWORD len; HKEY mykey; - HRESULT retval; LCID mylcid; WCHAR *mystr; LONG lres; @@ -512,7 +511,7 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) /* Did not find a value in the registry or the user buffer is too small */ mylcid = GetUserDefaultLCID(); - retval = LcidToRfc1766W(mylcid, mystr, mystrlen); + LcidToRfc1766W(mylcid, mystr, mystrlen); len = lstrlenW(mystr); memcpy( langbuf, mystr, min(*buflen, len+1)*sizeof(WCHAR) ); diff --git a/reactos/dll/win32/shlwapi/reg.c b/reactos/dll/win32/shlwapi/reg.c index d641955ba05..09fce55cb3f 100644 --- a/reactos/dll/win32/shlwapi/reg.c +++ b/reactos/dll/win32/shlwapi/reg.c @@ -331,8 +331,25 @@ LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) { - FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex, - debugstr_a(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + HKEY dokey; + + TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, + pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + + if (((enumRegFlags == SHREGENUM_HKCU) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { + return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + + if (((enumRegFlags == SHREGENUM_HKLM) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { + return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + FIXME("no support for SHREGENUM_BOTH\n"); return ERROR_INVALID_FUNCTION; } @@ -345,8 +362,25 @@ LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) { - FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex, - debugstr_w(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + HKEY dokey; + + TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, + pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + + if (((enumRegFlags == SHREGENUM_HKCU) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { + return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + + if (((enumRegFlags == SHREGENUM_HKLM) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { + return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + FIXME("no support for SHREGENUM_BOTH\n"); return ERROR_INVALID_FUNCTION; } diff --git a/reactos/dll/win32/shlwapi/shlwapi.spec b/reactos/dll/win32/shlwapi/shlwapi.spec index 367046b5ebc..268a2e20145 100644 --- a/reactos/dll/win32/shlwapi/shlwapi.spec +++ b/reactos/dll/win32/shlwapi/shlwapi.spec @@ -683,6 +683,7 @@ @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) @ stdcall SHCreateStreamOnFileW(wstr long ptr) @ stdcall SHCreateStreamWrapper(ptr ptr long ptr) +@ stdcall SHCreateThreadRef(ptr ptr) @ stdcall SHDeleteEmptyKeyA(long ptr) @ stdcall SHDeleteEmptyKeyW(long ptr) @ stdcall SHDeleteKeyA(long str) diff --git a/reactos/dll/win32/shlwapi/string.c b/reactos/dll/win32/shlwapi/string.c index e00a92582e0..a0269b6cb37 100644 --- a/reactos/dll/win32/shlwapi/string.c +++ b/reactos/dll/win32/shlwapi/string.c @@ -1415,7 +1415,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, break; case STRRET_CSTR: - if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len) + if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len )) dest[len-1] = 0; break; @@ -1423,7 +1423,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, if (pidl) { if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, - dest, len ) && len) + dest, len )) dest[len-1] = 0; } break; diff --git a/reactos/dll/win32/shlwapi/thread.c b/reactos/dll/win32/shlwapi/thread.c index cfe6615cd69..00d26f78eb7 100644 --- a/reactos/dll/win32/shlwapi/thread.c +++ b/reactos/dll/win32/shlwapi/thread.c @@ -120,6 +120,93 @@ typedef struct tagSHLWAPI_THREAD_INFO IUnknown *refIE; /* Reference to the IE process */ } SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO; +typedef struct +{ + const IUnknownVtbl* lpVtbl; + LONG *ref; +} threadref; + +static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObj); + + if (ppvObj == NULL) + return E_POINTER; + + if (IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj); + *ppvObj = This; + IUnknown_AddRef((IUnknown*)*ppvObj); + return S_OK; + } + + *ppvObj = NULL; + FIXME("(%p, %s, %p) interface not supported\n", This, debugstr_guid(riid), ppvObj); + return E_NOINTERFACE; +} + +static ULONG WINAPI threadref_AddRef(IUnknown *iface) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + return InterlockedIncrement(This->ref); +} + +static ULONG WINAPI threadref_Release(IUnknown *iface) +{ + LONG refcount; + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + + refcount = InterlockedDecrement(This->ref); + if (!refcount) + HeapFree(GetProcessHeap(), 0, This); + + return refcount; +} + +/* VTable */ +static const IUnknownVtbl threadref_vt = +{ + threadref_QueryInterface, + threadref_AddRef, + threadref_Release, +}; + +/************************************************************************* + * SHCreateThreadRef [SHLWAPI.@] + * + * Create a per-thread IUnknown object + * + * PARAMS + * lprefcount [I] Pointer to a LONG to be used as refcount + * lppUnknown [O] Destination to receive the created object reference + * + * RETURNS + * Success: S_OK. lppUnknown is set to the object reference. + * Failure: E_INVALIDARG, if a parameter is NULL + */ +HRESULT WINAPI SHCreateThreadRef(LONG *lprefcount, IUnknown **lppUnknown) +{ + threadref * This; + TRACE("(%p, %p)\n", lprefcount, lppUnknown); + + if (!lprefcount || !lppUnknown) + return E_INVALIDARG; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(threadref)); + This->lpVtbl = &threadref_vt; + This->ref = lprefcount; + + *lprefcount = 1; + *lppUnknown = (IUnknown *) This; + TRACE("=> returning S_OK with %p\n", This); + return S_OK; +} /************************************************************************* * SHGetThreadRef [SHLWAPI.@] @@ -131,13 +218,13 @@ typedef struct tagSHLWAPI_THREAD_INFO * * RETURNS * Success: S_OK. lppUnknown is set to the object reference. - * Failure: E_NOINTERFACE, if an error occurs or lppUnknown is NULL. + * Failure: E_NOINTERFACE, if an error occurs or no object is set */ HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown) { TRACE("(%p)\n", lppUnknown); - if (!lppUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) + if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) return E_NOINTERFACE; *lppUnknown = TlsGetValue(SHLWAPI_ThreadRef_index); @@ -159,13 +246,13 @@ HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown) * * RETURNS * Success: S_OK. lpUnknown is stored and can be retrieved by SHGetThreadRef() - * Failure: E_NOINTERFACE, if an error occurs or lpUnknown is NULL. + * Failure: E_NOINTERFACE, if an error occurs */ HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown) { TRACE("(%p)\n", lpUnknown); - if (!lpUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) + if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) return E_NOINTERFACE; TlsSetValue(SHLWAPI_ThreadRef_index, lpUnknown); diff --git a/reactos/dll/win32/shlwapi/url.c b/reactos/dll/win32/shlwapi/url.c index cd83b457178..ad7d989a4bb 100644 --- a/reactos/dll/win32/shlwapi/url.c +++ b/reactos/dll/win32/shlwapi/url.c @@ -232,40 +232,34 @@ HRESULT WINAPI ParseURLW(LPCWSTR x, PARSEDURLW *y) HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized, LPDWORD pcchCanonicalized, DWORD dwFlags) { - LPWSTR base, canonical; + LPWSTR url, canonical; HRESULT ret; - DWORD len, len2; + DWORD len; TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_a(pszUrl), pszCanonicalized, pcchCanonicalized, dwFlags, pcchCanonicalized ? *pcchCanonicalized : -1); - if(!pszUrl || !pszCanonicalized || !pcchCanonicalized) + if(!pszUrl || !pszCanonicalized || !pcchCanonicalized || !*pcchCanonicalized) return E_INVALIDARG; - base = HeapAlloc(GetProcessHeap(), 0, - (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR)); - canonical = base + INTERNET_MAX_URL_LENGTH; - - MultiByteToWideChar(0, 0, pszUrl, -1, base, INTERNET_MAX_URL_LENGTH); - len = INTERNET_MAX_URL_LENGTH; - - ret = UrlCanonicalizeW(base, canonical, &len, dwFlags); - if (ret != S_OK) { - *pcchCanonicalized = len * 2; - HeapFree(GetProcessHeap(), 0, base); - return ret; + len = strlen(pszUrl)+1; + url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + canonical = HeapAlloc(GetProcessHeap(), 0, *pcchCanonicalized*sizeof(WCHAR)); + if(!url || !canonical) { + HeapFree(GetProcessHeap(), 0, url); + HeapFree(GetProcessHeap(), 0, canonical); + return E_OUTOFMEMORY; } - len2 = WideCharToMultiByte(0, 0, canonical, -1, 0, 0, 0, 0); - if (len2 > *pcchCanonicalized) { - *pcchCanonicalized = len2; - HeapFree(GetProcessHeap(), 0, base); - return E_POINTER; - } - WideCharToMultiByte(0, 0, canonical, -1, pszCanonicalized, *pcchCanonicalized, 0, 0); - *pcchCanonicalized = len; - HeapFree(GetProcessHeap(), 0, base); - return S_OK; + MultiByteToWideChar(0, 0, pszUrl, -1, url, len); + + ret = UrlCanonicalizeW(url, canonical, pcchCanonicalized, dwFlags); + if(ret == S_OK) + WideCharToMultiByte(0, 0, canonical, -1, pszCanonicalized, + *pcchCanonicalized+1, 0, 0); + + HeapFree(GetProcessHeap(), 0, canonical); + return ret; } /************************************************************************* @@ -287,11 +281,12 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, static const WCHAR wszFile[] = {'f','i','l','e',':'}; static const WCHAR wszRes[] = {'r','e','s',':'}; static const WCHAR wszLocalhost[] = {'l','o','c','a','l','h','o','s','t'}; + static const WCHAR wszFilePrefix[] = {'f','i','l','e',':','/','/','/'}; TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_w(pszUrl), pszCanonicalized, pcchCanonicalized, dwFlags, pcchCanonicalized ? *pcchCanonicalized : -1); - if(!pszUrl || !pszCanonicalized || !pcchCanonicalized) + if(!pszUrl || !pszCanonicalized || !pcchCanonicalized || !*pcchCanonicalized) return E_INVALIDARG; if(!*pszUrl) { @@ -300,8 +295,9 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, } nByteLen = (strlenW(pszUrl) + 1) * sizeof(WCHAR); /* length in bytes */ + /* Allocate memory for simplified URL (before escaping) */ lpszUrlCpy = HeapAlloc(GetProcessHeap(), 0, - INTERNET_MAX_URL_LENGTH * sizeof(WCHAR)); + nByteLen+sizeof(wszFilePrefix)+sizeof(WCHAR)); if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszFile) && !memcmp(wszFile, pszUrl, sizeof(wszFile))) @@ -328,8 +324,6 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, state = 0; if(pszUrl[1] == ':') { /* Assume path */ - static const WCHAR wszFilePrefix[] = {'f','i','l','e',':','/','/','/'}; - memcpy(wk2, wszFilePrefix, sizeof(wszFilePrefix)); wk2 += sizeof(wszFilePrefix)/sizeof(WCHAR); if (dwFlags & URL_FILE_USE_PATHURL) @@ -833,6 +827,8 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative, if (ret == S_OK) { /* Reuse mrelative as temp storage as its already allocated and not needed anymore */ + if(*pcchCombined == 0) + *pcchCombined = 1; ret = UrlCanonicalizeW(preliminary, mrelative, pcchCombined, (dwFlags & ~URL_FILE_USE_PATHURL)); if(SUCCEEDED(ret) && pszCombined) { lstrcpyW(pszCombined, mrelative); From fcb1ce77af507375b5ee415e4f1a095c82575fdd Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 29 May 2010 18:01:20 +0000 Subject: [PATCH 096/292] [CMD] File completion - Don't pass device paths to FindFirstFile (similar to r47418) - Allows to complete files, whose names start like DOS devices (COMx, LPTx. AUX, NUL, CON, etc) See issue #4848 for more details. svn path=/trunk/; revision=47421 --- reactos/base/shell/cmd/filecomp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/reactos/base/shell/cmd/filecomp.c b/reactos/base/shell/cmd/filecomp.c index 7cb99a72f12..d2127fde250 100644 --- a/reactos/base/shell/cmd/filecomp.c +++ b/reactos/base/shell/cmd/filecomp.c @@ -590,10 +590,20 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor) /* Start the search for all the files */ GetFullPathName(szBaseWord, MAX_PATH, szSearchPath, NULL); + + /* Got a device path? Fallback to the the current dir plus the short path */ + if (szSearchPath[0] == _T('\\') && szSearchPath[1] == _T('\\') && + szSearchPath[2] == _T('.') && szSearchPath[3] == _T('\\')) + { + GetCurrentDirectory(MAX_PATH, szSearchPath); + _tcscat(szSearchPath, _T("\\")); + _tcscat(szSearchPath, szBaseWord); + } + if(StartLength > 0) - { + { _tcscat(szSearchPath,_T("*")); - } + } _tcscpy(LastSearch,szSearchPath); _tcscpy(LastPrefix,szPrefix); } From 5e8f4e5fd6764b5766c266adbc84dd46b30260bd Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 29 May 2010 18:04:05 +0000 Subject: [PATCH 097/292] [MSHTML_WINETEST] sync to wine 1.2 RC2 svn path=/trunk/; revision=47422 --- rostests/winetests/mshtml/dom.c | 373 ++++++++++++++++++++++++-- rostests/winetests/mshtml/htmldoc.c | 10 + rostests/winetests/mshtml/jstest.html | 16 ++ rostests/winetests/mshtml/script.c | 110 ++++++-- 4 files changed, 478 insertions(+), 31 deletions(-) diff --git a/rostests/winetests/mshtml/dom.c b/rostests/winetests/mshtml/dom.c index c6f54793ce5..4f954a8ba30 100644 --- a/rostests/winetests/mshtml/dom.c +++ b/rostests/winetests/mshtml/dom.c @@ -508,7 +508,7 @@ static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids) } } -#define test_get_dispid(u,id) _test_disp(__LINE__,u,id) +#define test_get_dispid(u,id) _test_get_dispid(__LINE__,u,id) static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid) { IDispatchEx *dispex; @@ -673,6 +673,39 @@ static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk) return anchor; } +#define get_textarea_iface(u) _get_textarea_iface(__LINE__,u) +static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk) +{ + IHTMLTextAreaElement *textarea; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextAreaElement, (void**)&textarea); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextAreaElement: %08x\n", hres); + return textarea; +} + +#define get_select_iface(u) _get_select_iface(__LINE__,u) +static IHTMLSelectElement *_get_select_iface(unsigned line, IUnknown *unk) +{ + IHTMLSelectElement *select; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLSelectElement, (void**)&select); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLSelectElement: %08x\n", hres); + return select; +} + +#define get_form_iface(u) _get_form_iface(__LINE__,u) +static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk) +{ + IHTMLFormElement *form; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLFormElement, (void**)&form); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLFormElement: %08x\n", hres); + return form; +} + #define get_text_iface(u) _get_text_iface(__LINE__,u) static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk) { @@ -1113,6 +1146,85 @@ static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, co _test_option_value(line, option, value); } +#define test_option_selected(o,s) _test_option_selected(__LINE__,o,s) +static void _test_option_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex) +{ + VARIANT_BOOL b = 0x100; + HRESULT hres; + + hres = IHTMLOptionElement_get_selected(option, &b); + ok_(__FILE__,line)(hres == S_OK, "get_selected failed: %08x\n", hres); + ok_(__FILE__,line)(b == ex, "selected = %x, expected %x\n", b, ex); +} + +#define test_option_put_selected(o,s) _test_option_put_selected(__LINE__,o,s) +static void _test_option_put_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b) +{ + HRESULT hres; + + hres = IHTMLOptionElement_put_selected(option, b); + ok_(__FILE__,line)(hres == S_OK, "put_selected failed: %08x\n", hres); + _test_option_selected(line, option, b); +} + +#define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v) +static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + BSTR value = (void*)0xdeadbeef; + HRESULT hres; + + hres = IHTMLTextAreaElement_get_value(textarea, &value); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres); + if(exval) + ok_(__FILE__,line)(!strcmp_wa(value, exval), "value = %s, expected %s\n", wine_dbgstr_w(value), exval); + else + ok_(__FILE__,line)(!value, "value = %p\n", value); + SysFreeString(value); +} + +#define test_textarea_put_value(t,v) _test_textarea_put_value(__LINE__,t,v) +static void _test_textarea_put_value(unsigned line, IUnknown *unk, const char *value) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + BSTR tmp = a2bstr(value); + HRESULT hres; + + hres = IHTMLTextAreaElement_put_value(textarea, tmp); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "put_value failed: %08x\n", hres); + SysFreeString(tmp); + + _test_textarea_value(line, unk, value); +} + +#define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v) +static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + VARIANT_BOOL b = 0x100; + HRESULT hres; + + hres = IHTMLTextAreaElement_get_readOnly(textarea, &b); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "get_readOnly failed: %08x\n", hres); + ok_(__FILE__,line)(b == ex, "readOnly = %x, expected %x\n", b, ex); +} + +#define test_textarea_put_readonly(t,v) _test_textarea_put_readonly(__LINE__,t,v) +static void _test_textarea_put_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL b) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + HRESULT hres; + + hres = IHTMLTextAreaElement_put_readOnly(textarea, b); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "put_readOnly failed: %08x\n", hres); + + _test_textarea_readonly(line, unk, b); +} + #define test_comment_text(c,t) _test_comment_text(__LINE__,c,t) static void _test_comment_text(unsigned line, IUnknown *unk, const char *extext) { @@ -1161,12 +1273,13 @@ static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *do _test_option_text(line, option, txt); _test_option_value(line, option, val); + _test_option_selected(line, option, VARIANT_FALSE); return option; } #define test_img_width(o,w) _test_img_width(__LINE__,o,w) -static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp) +static void _test_img_width(unsigned line, IHTMLImgElement *img, const LONG exp) { LONG found = -1; HRESULT hres; @@ -1177,7 +1290,7 @@ static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp) } #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w) -static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long width) +static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const LONG width) { HRESULT hres; @@ -1188,7 +1301,7 @@ static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long } #define test_img_height(o,h) _test_img_height(__LINE__,o,h) -static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp) +static void _test_img_height(unsigned line, IHTMLImgElement *img, const LONG exp) { LONG found = -1; HRESULT hres; @@ -1199,7 +1312,7 @@ static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp } #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w) -static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const long height) +static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const LONG height) { HRESULT hres; @@ -1275,6 +1388,18 @@ static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length); } +#define test_select_put_length(s,l) _test_select_put_length(__LINE__,s,l) +static void _test_select_put_length(unsigned line, IUnknown *unk, LONG length) +{ + IHTMLSelectElement *select = _get_select_iface(line, unk); + HRESULT hres; + + hres = IHTMLSelectElement_put_length(select, length); + ok_(__FILE__,line) (hres == S_OK, "put_length failed: %08x\n", hres); + _test_select_length(line, select, length); + IHTMLSelectElement_Release(select); +} + #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i) static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index) { @@ -1995,9 +2120,49 @@ static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue) hres = IHTMLImgElement_get_name(img, &sName); ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres); ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName)); + IHTMLImgElement_Release(img); SysFreeString(sName); } +#define test_input_type(i,t) _test_input_type(__LINE__,i,t) +static void _test_input_type(unsigned line, IHTMLInputElement *input, const char *extype) +{ + BSTR type; + HRESULT hres; + + hres = IHTMLInputElement_get_type(input, &type); + ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres); + ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype); + SysFreeString(type); +} + +#define test_input_name(u, c) _test_input_name(__LINE__,u, c) +static void _test_input_name(unsigned line, IHTMLInputElement *input, const char *exname) +{ + BSTR name = (BSTR)0xdeadbeef; + HRESULT hres; + + hres = IHTMLInputElement_get_name(input, &name); + ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres); + if(exname) + ok_(__FILE__,line) (!strcmp_wa (name, exname), "name=%s, expected %s\n", wine_dbgstr_w(name), exname); + else + ok_(__FILE__,line) (!name, "name=%p, expected NULL\n", name); + SysFreeString(name); +} + +#define test_input_set_name(u, c) _test_input_set_name(__LINE__,u, c) +static void _test_input_set_name(unsigned line, IHTMLInputElement *input, const char *name) +{ + BSTR tmp = a2bstr(name); + HRESULT hres; + + hres = IHTMLInputElement_put_name(input, tmp); + ok_(__FILE__,line) (hres == S_OK, "put_name failed: %08x\n", hres); + SysFreeString(tmp); + + _test_input_name(line, input, name); +} #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b) static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb) @@ -2366,6 +2531,52 @@ static void _test_elem_client_rect(unsigned line, IUnknown *unk) IHTMLElement2_Release(elem); } +#define test_form_length(e,l) _test_form_length(__LINE__,e,l) +static void _test_form_length(unsigned line, IUnknown *unk, LONG exlen) +{ + IHTMLFormElement *form = _get_form_iface(line, unk); + LONG len = 0xdeadbeef; + HRESULT hres; + + hres = IHTMLFormElement_get_length(form, &len); + ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres); + ok_(__FILE__,line)(len == exlen, "length=%d, expected %d\n", len, exlen); + + IHTMLFormElement_Release(form); +} + +#define test_form_action(f,a) _test_form_action(__LINE__,f,a) +static void _test_form_action(unsigned line, IUnknown *unk, const char *ex) +{ + IHTMLFormElement *form = _get_form_iface(line, unk); + BSTR action = (void*)0xdeadbeef; + HRESULT hres; + + hres = IHTMLFormElement_get_action(form, &action); + ok_(__FILE__,line)(hres == S_OK, "get_action failed: %08x\n", hres); + if(ex) + ok_(__FILE__,line)(!strcmp_wa(action, ex), "action=%s, expected %s\n", wine_dbgstr_w(action), ex); + else + ok_(__FILE__,line)(!action, "action=%p\n", action); + + IHTMLFormElement_Release(form); +} + +#define test_form_put_action(f,a) _test_form_put_action(__LINE__,f,a) +static void _test_form_put_action(unsigned line, IUnknown *unk, const char *action) +{ + IHTMLFormElement *form = _get_form_iface(line, unk); + BSTR tmp = a2bstr(action); + HRESULT hres; + + hres = IHTMLFormElement_put_action(form, tmp); + ok_(__FILE__,line)(hres == S_OK, "put_action failed: %08x\n", hres); + SysFreeString(tmp); + IHTMLFormElement_Release(form); + + _test_form_action(line, unk, action); +} + #define get_elem_doc(e) _get_elem_doc(__LINE__,e) static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk) { @@ -2753,6 +2964,10 @@ static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id) static void test_select_elem(IHTMLSelectElement *select) { + IDispatch *disp, *disp2; + VARIANT name, index; + HRESULT hres; + test_select_type(select, "select-one"); test_select_length(select, 2); test_select_selidx(select, 0); @@ -2764,6 +2979,89 @@ static void test_select_elem(IHTMLSelectElement *select) test_select_get_disabled(select, VARIANT_FALSE); test_select_set_disabled(select, VARIANT_TRUE); test_select_set_disabled(select, VARIANT_FALSE); + + disp = NULL; + hres = IHTMLSelectElement_get_options(select, &disp); + ok(hres == S_OK, "get_options failed: %08x\n", hres); + ok(disp != NULL, "options == NULL\n"); + ok(iface_cmp((IUnknown*)disp, (IUnknown*)select), "disp != select\n"); + IDispatch_Release(disp); + + V_VT(&index) = VT_EMPTY; + V_VT(&name) = VT_I4; + V_I4(&name) = -1; + disp = (void*)0xdeadbeef; + hres = IHTMLSelectElement_item(select, name, index, &disp); + ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres); + ok(!disp, "disp = %p\n", disp); + + V_I4(&name) = 2; + disp = (void*)0xdeadbeef; + hres = IHTMLSelectElement_item(select, name, index, &disp); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(!disp, "disp = %p\n", disp); + + V_I4(&name) = 1; + hres = IHTMLSelectElement_item(select, name, index, NULL); + ok(hres == E_POINTER || broken(hres == E_INVALIDARG), "item failed: %08x, expected E_POINTER\n", hres); + + disp = NULL; + hres = IHTMLSelectElement_item(select, name, index, &disp); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(disp != NULL, "disp = NULL\n"); + test_disp((IUnknown*)disp, &DIID_DispHTMLOptionElement, NULL); + + V_VT(&index) = VT_I4; + V_I4(&index) = 1; + disp2 = NULL; + hres = IHTMLSelectElement_item(select, name, index, &disp2); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(disp2 != NULL, "disp = NULL\n"); + ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n"); + IDispatch_Release(disp2); + IDispatch_Release(disp); +} + +static void test_form_item(IHTMLElement *elem) +{ + IHTMLFormElement *form = get_form_iface((IUnknown*)elem); + IDispatch *disp, *disp2; + VARIANT name, index; + HRESULT hres; + + V_VT(&index) = VT_EMPTY; + V_VT(&name) = VT_I4; + V_I4(&name) = -1; + disp = (void*)0xdeadbeef; + hres = IHTMLFormElement_item(form, name, index, &disp); + ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres); + ok(!disp, "disp = %p\n", disp); + + V_I4(&name) = 2; + disp = (void*)0xdeadbeef; + hres = IHTMLFormElement_item(form, name, index, &disp); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(!disp, "disp = %p\n", disp); + + V_I4(&name) = 1; + hres = IHTMLFormElement_item(form, name, index, NULL); + ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres); + + disp = NULL; + hres = IHTMLFormElement_item(form, name, index, &disp); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(disp != NULL, "disp = NULL\n"); + test_disp((IUnknown*)disp, &DIID_DispHTMLInputElement, NULL); + + V_VT(&index) = VT_I4; + V_I4(&index) = 1; + disp2 = NULL; + hres = IHTMLFormElement_item(form, name, index, &disp2); + ok(hres == S_OK, "item failed: %08x\n", hres); + ok(disp2 != NULL, "disp = NULL\n"); + ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n"); + IDispatch_Release(disp2); + IDispatch_Release(disp); } static void test_create_option_elem(IHTMLDocument2 *doc) @@ -2774,6 +3072,8 @@ static void test_create_option_elem(IHTMLDocument2 *doc) test_option_put_text(option, "new text"); test_option_put_value(option, "new value"); + test_option_put_selected(option, VARIANT_TRUE); + test_option_put_selected(option, VARIANT_FALSE); IHTMLOptionElement_Release(option); } @@ -3142,7 +3442,7 @@ static void test_navigator(IHTMLDocument2 *doc) hres = IOmNavigator_get_platform(navigator, &bstr); ok(hres == S_OK, "get_platform failed: %08x\n", hres); #ifdef _WIN64 - ok(!strcmp_wa(bstr, "Win64"), "unexpected platform %s\n", wine_dbgstr_w(bstr)); + ok(!strcmp_wa(bstr, "Win64") || broken(!strcmp_wa(bstr, "Win32") /* IE6 */), "unexpected platform %s\n", wine_dbgstr_w(bstr)); #else ok(!strcmp_wa(bstr, "Win32"), "unexpected platform %s\n", wine_dbgstr_w(bstr)); #endif @@ -5553,12 +5853,9 @@ static void test_elems(IHTMLDocument2 *doc) elem = get_elem_by_id(doc, "s", TRUE); if(elem) { - IHTMLSelectElement *select; + IHTMLSelectElement *select = get_select_iface((IUnknown*)elem); IHTMLDocument2 *doc_node, *elem_doc; - hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select); - ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres); - test_select_elem(select); test_elem_title((IUnknown*)select, NULL); @@ -5646,6 +5943,7 @@ static void test_elems(IHTMLDocument2 *doc) test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE); test_input_get_disabled(input, VARIANT_FALSE); test_elem_client_size((IUnknown*)elem); + test_input_type(input, "text"); test_node_get_value_str((IUnknown*)elem, NULL); test_node_put_value_str((IUnknown*)elem, "test"); @@ -5666,6 +5964,9 @@ static void test_elems(IHTMLDocument2 *doc) test_input_set_checked(input, VARIANT_TRUE); test_input_set_checked(input, VARIANT_FALSE); + test_input_name(input, NULL); + test_input_set_name(input, "test"); + test_input_src(input, NULL); test_input_set_src(input, "about:blank"); @@ -5788,6 +6089,13 @@ static void test_elems(IHTMLDocument2 *doc) IHTMLElement_Release(elem); + elem = get_doc_elem_by_id(doc, "frm"); + ok(elem != NULL, "elem == NULL\n"); + if(elem) { + test_form_length((IUnknown*)elem, 0); + IHTMLElement_Release(elem); + } + test_stylesheets(doc); test_create_option_elem(doc); test_create_img_elem(doc); @@ -5854,6 +6162,17 @@ static void test_elems(IHTMLDocument2 *doc) IHTMLDocument3_Release(doc3); + elem = get_elem_by_id(doc, "s", TRUE); + if(elem) { + static const elem_type_t select_types[] = { ET_OPTION, ET_OPTION, ET_OPTION }; + + test_select_put_length((IUnknown*)elem, 3); + test_elem_all((IUnknown*)elem, select_types, sizeof(select_types)/sizeof(*select_types)); + test_select_put_length((IUnknown*)elem, 1); + test_elem_all((IUnknown*)elem, select_types, 1); + IHTMLElement_Release(elem); + } + window = get_doc_window(doc); test_window_name(window, NULL); set_window_name(window, "test name"); @@ -5863,29 +6182,51 @@ static void test_elems(IHTMLDocument2 *doc) static void test_elems2(IHTMLDocument2 *doc) { - IHTMLElement *elem, *elem2; + IHTMLElement *elem, *elem2, *div; static const elem_type_t outer_types[] = { ET_BR, ET_A }; - elem = get_doc_elem_by_id(doc, "divid"); + div = get_doc_elem_by_id(doc, "divid"); - test_elem_set_innerhtml((IUnknown*)elem, "

    "); + test_elem_set_innerhtml((IUnknown*)div, "
    "); elem2 = get_doc_elem_by_id(doc, "innerid"); ok(elem2 != NULL, "elem2 == NULL\n"); test_elem_set_outerhtml((IUnknown*)elem2, "
    a"); - test_elem_all((IUnknown*)elem, outer_types, sizeof(outer_types)/sizeof(*outer_types)); + test_elem_all((IUnknown*)div, outer_types, sizeof(outer_types)/sizeof(*outer_types)); IHTMLElement_Release(elem2); elem2 = get_doc_elem_by_id(doc, "aid"); ok(elem2 != NULL, "elem2 == NULL\n"); test_elem_set_outerhtml((IUnknown*)elem2, ""); - test_elem_all((IUnknown*)elem, outer_types, 1); + test_elem_all((IUnknown*)div, outer_types, 1); IHTMLElement_Release(elem2); - IHTMLElement_Release(elem); + test_elem_set_innerhtml((IUnknown*)div, ""); + elem = get_elem_by_id(doc, "ta", TRUE); + if(elem) { + test_textarea_value((IUnknown*)elem, NULL); + test_textarea_put_value((IUnknown*)elem, "test"); + test_textarea_readonly((IUnknown*)elem, VARIANT_FALSE); + test_textarea_put_readonly((IUnknown*)elem, VARIANT_TRUE); + test_textarea_put_readonly((IUnknown*)elem, VARIANT_FALSE); + IHTMLElement_Release(elem); + } + + test_elem_set_innerhtml((IUnknown*)div, + "
    "); + elem = get_elem_by_id(doc, "form", TRUE); + if(elem) { + test_form_length((IUnknown*)elem, 2); + test_form_item(elem); + test_form_action((IUnknown*)elem, NULL); + test_form_put_action((IUnknown*)elem, "about:blank"); + IHTMLElement_Release(elem); + } + + IHTMLElement_Release(div); } static void test_create_elems(IHTMLDocument2 *doc) diff --git a/rostests/winetests/mshtml/htmldoc.c b/rostests/winetests/mshtml/htmldoc.c index c4c41a8b423..7e0d4374365 100644 --- a/rostests/winetests/mshtml/htmldoc.c +++ b/rostests/winetests/mshtml/htmldoc.c @@ -3405,6 +3405,14 @@ static void test_put_href(IHTMLDocument2 *doc) test_download(DWL_VERBDONE); } +static void test_clear(IHTMLDocument2 *doc) +{ + HRESULT hres; + + hres = IHTMLDocument2_clear(doc); + ok(hres == S_OK, "clear failed: %08x\n", hres); +} + static const OLECMDF expect_cmds[OLECMDID_GETPRINTTEMPLATE+1] = { 0, OLECMDF_SUPPORTED, /* OLECMDID_OPEN */ @@ -4566,6 +4574,8 @@ static void test_HTMLDocument_hlink(void) test_Close(doc, FALSE); test_IsDirty(doc, S_FALSE); test_GetCurMoniker((IUnknown*)doc, &Moniker, NULL); + test_clear(doc); + test_GetCurMoniker((IUnknown*)doc, &Moniker, NULL); if(view) IOleDocumentView_Release(view); diff --git a/rostests/winetests/mshtml/jstest.html b/rostests/winetests/mshtml/jstest.html index 6192f815af3..3363c5ae8ca 100644 --- a/rostests/winetests/mshtml/jstest.html +++ b/rostests/winetests/mshtml/jstest.html @@ -20,6 +20,17 @@ function test_removeAttribute(e) { } +function test_select_index() { + var s = document.getElementById("sel"); + + ok("0" in s, "'0' is not in s"); + ok(s[0].text === "opt1", "s[0].text = " + s[0].text); + ok("1" in s, "'1 is not in s"); + ok(s[1].text === "opt2", "s[1].text = " + s[1].text); + ok("2" in s, "'2' is in s"); + ok(s[2] === null, "s[2] = " + s[2]); +} + function runTest() { obj = new Object(); ok(obj === window.obj, "obj !== window.obj"); @@ -28,11 +39,16 @@ function runTest() { test_removeAttribute(document.getElementById("divid")); test_removeAttribute(document.body); + test_select_index(); external.reportSuccess(); }
    + diff --git a/rostests/winetests/mshtml/script.c b/rostests/winetests/mshtml/script.c index 56d83efa696..23f1ab861c7 100644 --- a/rostests/winetests/mshtml/script.c +++ b/rostests/winetests/mshtml/script.c @@ -123,7 +123,8 @@ DEFINE_EXPECT(script_testprop2_d); DEFINE_EXPECT(AXQueryInterface_IActiveScript); DEFINE_EXPECT(AXQueryInterface_IObjectSafety); DEFINE_EXPECT(AXGetInterfaceSafetyOptions); -DEFINE_EXPECT(AXSetInterfaceSafetyOptions); +DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatch); +DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); DEFINE_EXPECT(external_success); #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}" @@ -148,6 +149,8 @@ static BOOL doc_complete; static IDispatch *script_disp; static BOOL ax_objsafe; static HWND container_hwnd; +static HRESULT ax_getopt_hres = S_OK, ax_setopt_dispex_hres = S_OK, ax_setopt_disp_hres = S_OK; +static DWORD ax_setopt; static const char *debugstr_guid(REFIID riid) { @@ -1265,25 +1268,35 @@ static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *if ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n"); ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n"); - *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER; - *pdwEnabledOptions = INTERFACE_USES_DISPEX; + if(SUCCEEDED(ax_getopt_hres)) { + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER; + *pdwEnabledOptions = INTERFACE_USES_DISPEX; + } - return S_OK; + return ax_getopt_hres; } static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) { - CHECK_EXPECT(AXSetInterfaceSafetyOptions); + if(IsEqualGUID(&IID_IDispatchEx, riid)) { + CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); + ok(dwOptionSetMask == ax_setopt, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, ax_setopt); + ok(dwEnabledOptions == ax_setopt, "dwEnabledOptions=%x, expected %x\n", dwOptionSetMask, ax_setopt); + return ax_setopt_dispex_hres; + } - ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid)); + if(IsEqualGUID(&IID_IDispatch, riid)) { + DWORD exopt = ax_setopt & ~INTERFACE_USES_SECURITY_MANAGER; - ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), - "dwOptionSetMask=%x\n", dwOptionSetMask); - ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), - "dwEnabledOptions=%x\n", dwOptionSetMask); + CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatch); + ok(dwOptionSetMask == exopt, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, exopt); + ok(dwEnabledOptions == exopt, "dwEnabledOptions=%x, expected %x\n", dwOptionSetMask, exopt); + return ax_setopt_disp_hres; + } - return S_OK; + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; } static const IObjectSafetyVtbl AXObjectSafetyVtbl = { @@ -1311,6 +1324,8 @@ static void test_security(void) BYTE *ppolicy; HRESULT hres; + ax_setopt = INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER; + hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp); ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres); @@ -1332,13 +1347,13 @@ static void test_security(void) SET_EXPECT(AXQueryInterface_IActiveScript); SET_EXPECT(AXQueryInterface_IObjectSafety); SET_EXPECT(AXGetInterfaceSafetyOptions); - SET_EXPECT(AXSetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); CHECK_CALLED(AXQueryInterface_IActiveScript); CHECK_CALLED(AXQueryInterface_IObjectSafety); CHECK_CALLED(AXGetInterfaceSafetyOptions); - CHECK_CALLED(AXSetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx); ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); @@ -1376,13 +1391,13 @@ static void test_security(void) SET_EXPECT(AXQueryInterface_IActiveScript); SET_EXPECT(AXQueryInterface_IObjectSafety); SET_EXPECT(AXGetInterfaceSafetyOptions); - SET_EXPECT(AXSetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); CHECK_CALLED(AXQueryInterface_IActiveScript); CHECK_CALLED(AXQueryInterface_IObjectSafety); CHECK_CALLED(AXGetInterfaceSafetyOptions); - CHECK_CALLED(AXSetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx); ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); @@ -1394,6 +1409,69 @@ static void test_security(void) skip("Could not set safety registry\n"); } + ax_objsafe = TRUE; + + ax_setopt_dispex_hres = E_NOINTERFACE; + SET_EXPECT(AXQueryInterface_IActiveScript); + SET_EXPECT(AXQueryInterface_IObjectSafety); + SET_EXPECT(AXGetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch); + hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + CHECK_CALLED(AXQueryInterface_IActiveScript); + CHECK_CALLED(AXQueryInterface_IObjectSafety); + CHECK_CALLED(AXGetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch); + + ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); + ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); + ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy); + CoTaskMemFree(ppolicy); + + ax_setopt_dispex_hres = E_FAIL; + ax_setopt_disp_hres = E_NOINTERFACE; + SET_EXPECT(AXQueryInterface_IActiveScript); + SET_EXPECT(AXQueryInterface_IObjectSafety); + SET_EXPECT(AXGetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch); + hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + CHECK_CALLED(AXQueryInterface_IActiveScript); + CHECK_CALLED(AXQueryInterface_IObjectSafety); + CHECK_CALLED(AXGetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch); + + ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); + ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); + ok(*(DWORD*)ppolicy == URLPOLICY_DISALLOW, "policy = %x\n", *(DWORD*)ppolicy); + CoTaskMemFree(ppolicy); + + ax_setopt_dispex_hres = E_FAIL; + ax_setopt_disp_hres = S_OK; + ax_getopt_hres = E_NOINTERFACE; + ax_setopt = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + SET_EXPECT(AXQueryInterface_IActiveScript); + SET_EXPECT(AXQueryInterface_IObjectSafety); + SET_EXPECT(AXGetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx); + SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch); + hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + CHECK_CALLED(AXQueryInterface_IActiveScript); + CHECK_CALLED(AXQueryInterface_IObjectSafety); + CHECK_CALLED(AXGetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx); + CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch); + + ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); + ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); + ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy); + CoTaskMemFree(ppolicy); + IInternetHostSecurityManager_Release(sec_mgr); } @@ -1995,6 +2073,8 @@ static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTST } hres = IActiveScriptSite_OnStateChange(site, (state = ss)); + ok(hres == S_OK, "OnStateChange failed: %08x\n", hres); + return S_OK; } From 00fbba2fb4e16e0708b4c4f18400591acf11b5aa Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 29 May 2010 18:22:47 +0000 Subject: [PATCH 098/292] [NTOSKRNL / RTL] - Implement BreakOnTermination case for NtQueryInformationProcess and NtSetInformationProcess. - Implement RtlSetProcessIsCritical. svn path=/trunk/; revision=47423 --- reactos/include/ndk/rtlfuncs.h | 4 +- reactos/lib/rtl/process.c | 46 ++++++++++++---- reactos/ntoskrnl/include/internal/ps_i.h | 6 +-- reactos/ntoskrnl/ps/query.c | 67 ++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 14 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 18aa4749ad4..d0f3f06d701 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2042,12 +2042,12 @@ RtlRemoteCall( ); NTSYSAPI -VOID +NTSTATUS NTAPI RtlSetProcessIsCritical( IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon + IN BOOLEAN NeedBreaks ); NTSYSAPI diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c index b8585b0fe6f..5d6c6896a04 100644 --- a/reactos/lib/rtl/process.c +++ b/reactos/lib/rtl/process.c @@ -5,6 +5,7 @@ * PURPOSE: Process functions * PROGRAMMER: Alex Ionescu (alex@relsoft.net) * Ariadne (ariadne@xs4all.nl) + * Eric Kohl */ /* INCLUDES ****************************************************************/ @@ -351,18 +352,45 @@ RtlEncodeSystemPointer(IN PVOID Pointer) } /* - * @unimplemented + * @implemented + * + * NOTES: + * Implementation based on the documentation from: + * http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm */ -NTSYSAPI -VOID +NTSTATUS NTAPI -RtlSetProcessIsCritical( - IN BOOLEAN NewValue, - OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon) +RtlSetProcessIsCritical(IN BOOLEAN NewValue, + OUT PBOOLEAN OldValue OPTIONAL, + IN BOOLEAN NeedBreaks) { - //TODO - UNIMPLEMENTED; + ULONG BreakOnTermination = FALSE; + + if (OldValue) + *OldValue = FALSE; + + /* Fail, if the critical breaks flag is required but is not set */ + if (NeedBreaks == TRUE && + !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS)) + return STATUS_UNSUCCESSFUL; + + if (OldValue) + { + /* Query and return the old break on termination flag for the process */ + ZwQueryInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG), + NULL); + *OldValue = (BOOLEAN)BreakOnTermination; + } + + /* Set the break on termination flag for the process */ + BreakOnTermination = NewValue; + return ZwSetInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG)); } ULONG diff --git a/reactos/ntoskrnl/include/internal/ps_i.h b/reactos/ntoskrnl/include/internal/ps_i.h index 75a4994f24a..13251f8e901 100644 --- a/reactos/ntoskrnl/include/internal/ps_i.h +++ b/reactos/ntoskrnl/include/internal/ps_i.h @@ -249,9 +249,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = /* ProcessBreakOnTermination */ IQS_SAME ( - UCHAR, - UCHAR, - 0 + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET ), /* ProcessDebugObjectHandle */ diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index b4c2abaefea..c919c419931 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -5,6 +5,7 @@ * PURPOSE: Process Manager: Thread/Process Query/Set Information * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Thomas Weidenmueller (w3seek@reactos.org) + * Eric Kohl */ /* INCLUDES ******************************************************************/ @@ -735,6 +736,43 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, ObDereferenceObject(Process); break; + case ProcessBreakOnTermination: + + /* Set the return length*/ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) + break; + + /* Enter SEH for writing back data */ + _SEH2_TRY + { + /* Return the BreakOnTermination state */ + *(PULONG)ProcessInformation = Process->BreakOnTermination; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* Dereference the process */ + ObDereferenceObject(Process); + break; + /* Per-process security cookie */ case ProcessCookie: @@ -1146,6 +1184,35 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, Status = STATUS_NOT_IMPLEMENTED; break; + case ProcessBreakOnTermination: + + /* Check buffer length */ + if (ProcessInformationLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Setting 'break on termination' requires the SeDebugPrivilege */ + if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) + { + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + /* Enter SEH for direct buffer read */ + _SEH2_TRY + { + Process->BreakOnTermination = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + break; + /* We currently don't implement any of these */ case ProcessLdtInformation: case ProcessLdtSize: From c916ce9d20b578acd4589e499c50c51271105cfe Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 29 May 2010 18:33:50 +0000 Subject: [PATCH 099/292] Testers: Please pay attention to this build and test it fully: [NTOS]: Implement MiDecrementShareCount (to start replacing MmReleasePageMemoryConsumer calls for pages that were grabbed through ARM3, not Mm). [NTOS]: Implement MiInitializePfn (to initialize pages grabbed through ARM3/MiRemoveAnyPage instead of Mm/MmAllocPage). [NTOS]: For stack pages, use new ARM3 PFN alloc/free routines, as a first test/beginning of the new ARM3 ABI. [NTOS]: Implement and start using the Pending-Deletion PFN flag. [NTOS]: As a result, for stack pages, the Transition page state will now be seen, and the new routine for re-inserting pages into the free list will now be used. Tracking of page table references is also done now for these pages (but we don't free the PT since this doesn't seem safe yet). svn path=/trunk/; revision=47424 --- reactos/ntoskrnl/mm/ARM3/contmem.c | 10 ++- reactos/ntoskrnl/mm/ARM3/miarm.h | 21 +++++ reactos/ntoskrnl/mm/ARM3/pagfault.c | 2 +- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 122 ++++++++++++++++++++++++++++ reactos/ntoskrnl/mm/ARM3/procsup.c | 56 +++++++++---- 5 files changed, 188 insertions(+), 23 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/contmem.c b/reactos/ntoskrnl/mm/ARM3/contmem.c index 0d7628bf88f..2f3eda954e2 100644 --- a/reactos/ntoskrnl/mm/ARM3/contmem.c +++ b/reactos/ntoskrnl/mm/ARM3/contmem.c @@ -502,6 +502,9 @@ MiFreeContiguousMemory(IN PVOID BaseAddress) ASSERT(Pfn1->u4.VerifierAllocation == 0); ASSERT(Pfn1->u3.e1.PrototypePte == 0); + /* Set the special pending delete marker */ + MI_SET_PFN_DELETED(Pfn1); + /* Keep going for assertions */ PointerPte++; } while (Pfn1++->u3.e1.EndOfAllocation == 0); @@ -531,12 +534,11 @@ MiFreeContiguousMemory(IN PVOID BaseAddress) // Loop all the pages // LastPage = PageFrameIndex + PageCount; + Pfn1 = MiGetPfnEntry(PageFrameIndex); do { - // - // Free each one, and move on - // - MmReleasePageMemoryConsumer(MC_NPPOOL, PageFrameIndex++); + /* Decrement the share count and move on */ + MiDecrementShareCount(Pfn1++, PageFrameIndex++); } while (PageFrameIndex < LastPage); // diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 193eb04e698..4c5e3bc441b 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -119,6 +119,12 @@ // #define MI_MAKE_SOFTWARE_PTE(p, x) ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS)) +// +// Marks a PTE as deleted +// +#define MI_SET_PFN_DELETED(x) ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1)) +#define MI_IS_PFN_DELETED(x) ((ULONG_PTR)((x)->PteAddress) & 1) + // // Special values for LoadedImports // @@ -585,6 +591,21 @@ MiAllocatePfn( IN ULONG Protection ); +VOID +NTAPI +MiInitializePfn( + IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN BOOLEAN Modified +); + +VOID +NTAPI +MiDecrementShareCount( + IN PMMPFN Pfn1, + IN PFN_NUMBER PageFrameIndex +); + PFN_NUMBER NTAPI MiRemoveAnyPage( diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 7455a100af1..ceff13bcc8d 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -91,7 +91,7 @@ MiResolveDemandZeroFault(IN PVOID Address, { PFN_NUMBER PageFrameNumber; MMPTE TempPte; - DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", + DPRINT1("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", Address, Process); diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index ff17eb0b3c8..b70e191c030 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -561,4 +561,126 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) } } +VOID +NTAPI +MiInitializePfn(IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN BOOLEAN Modified) +{ + PMMPFN Pfn1; + NTSTATUS Status; + PMMPTE PointerPtePte; + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + /* Setup the PTE */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->PteAddress = PointerPte; + + /* Check if this PFN is part of a valid address space */ + if (PointerPte->u.Hard.Valid == 1) + { + /* FIXME: TODO */ + ASSERT(FALSE); + } + + /* Otherwise this is a fresh page -- set it up */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u2.ShareCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; + ASSERT(Pfn1->u3.e1.Rom == 0); + Pfn1->u3.e1.Modified = Modified; + + /* Get the page table for the PTE */ + PointerPtePte = MiAddressToPte(PointerPte); + if (PointerPtePte->u.Hard.Valid == 0) + { + /* Make sure the PDE gets paged in properly */ + Status = MiCheckPdeForPagedPool(PointerPte); + if (!NT_SUCCESS(Status)) + { + /* Crash */ + KeBugCheckEx(MEMORY_MANAGEMENT, + 0x61940, + (ULONG_PTR)PointerPte, + (ULONG_PTR)PointerPtePte->u.Long, + (ULONG_PTR)MiPteToAddress(PointerPte)); + } + } + + /* Get the PFN for the page table */ + PageFrameIndex = PFN_FROM_PTE(PointerPtePte); + ASSERT(PageFrameIndex != 0); + Pfn1->u4.PteFrame = PageFrameIndex; + + /* Increase its share count so we don't get rid of it */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->u2.ShareCount++; +} + +VOID +NTAPI +MiDecrementShareCount(IN PMMPFN Pfn1, + IN PFN_NUMBER PageFrameIndex) +{ + ASSERT(PageFrameIndex > 0); + ASSERT(MiGetPfnEntry(PageFrameIndex) != NULL); + ASSERT(Pfn1 == MiGetPfnEntry(PageFrameIndex)); + + /* Page must be in-use */ + if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) && + (Pfn1->u3.e1.PageLocation != StandbyPageList)) + { + /* Otherwise we have PFN corruption */ + KeBugCheckEx(PFN_LIST_CORRUPT, + 0x99, + PageFrameIndex, + Pfn1->u3.e1.PageLocation, + 0); + } + + /* Check if the share count is now 0 */ + ASSERT(Pfn1->u2.ShareCount < 0xF000000); + if (!--Pfn1->u2.ShareCount) + { + /* ReactOS does not handle these */ + ASSERT(Pfn1->u3.e1.PrototypePte == 0); + + /* Put the page in transition */ + Pfn1->u3.e1.PageLocation = TransitionPage; + + /* PFN lock must be held */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + /* Page should at least have one reference */ + ASSERT(Pfn1->u3.e2.ReferenceCount != 0); + if (Pfn1->u3.e2.ReferenceCount == 1) + { + /* In ReactOS, this path should always be hit with a deleted PFN */ + ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE); + + /* Clear the last reference */ + Pfn1->u3.e2.ReferenceCount = 0; + + /* + * OriginalPte is used by AweReferenceCount in ReactOS, but either + * ways we shouldn't be seeing RMAP entries at this point + */ + ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0); + ASSERT(Pfn1->OriginalPte.u.Long == 0); + + /* Mark the page temporarily as valid, we're going to make it free soon */ + Pfn1->u3.e1.PageLocation = ActiveAndValid; + + /* Bring it back into the free list */ + MiInsertPageInFreeList(PageFrameIndex); + } + else + { + /* Otherwise, just drop the reference count */ + InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount); + } + } +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index 8f1e6b732c1..e82a567d329 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -31,8 +31,10 @@ MmDeleteKernelStack(IN PVOID StackBase, IN BOOLEAN GuiStack) { PMMPTE PointerPte; - PFN_NUMBER StackPages; + PFN_NUMBER StackPages, PageFrameNumber;//, PageTableFrameNumber; + PMMPFN Pfn1;//, Pfn2; ULONG i; + KIRQL OldIrql; // // This should be the guard page, so decrement by one @@ -46,6 +48,9 @@ MmDeleteKernelStack(IN PVOID StackBase, StackPages = BYTES_TO_PAGES(GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE); + /* Acquire the PFN lock */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + // // Loop them // @@ -56,10 +61,22 @@ MmDeleteKernelStack(IN PVOID StackBase, // if (PointerPte->u.Hard.Valid == 1) { - // - // Nuke it - // - MmReleasePageMemoryConsumer(MC_NPPOOL, PFN_FROM_PTE(PointerPte)); + /* Get the PTE's page */ + PageFrameNumber = PFN_FROM_PTE(PointerPte); + Pfn1 = MiGetPfnEntry(PageFrameNumber); +#if 0 // ARM3 might not own the page table, so don't take this risk. Leak it instead! + /* Now get the page of the page table mapping it */ + PageTableFrameNumber = Pfn1->u4.PteFrame; + Pfn2 = MiGetPfnEntry(PageTableFrameNumber); + + /* Remove a shared reference, since the page is going away */ + MiDecrementShareCount(Pfn2, PageTableFrameNumber); +#endif + /* Set the special pending delete marker */ + Pfn1->PteAddress = (PMMPTE)((ULONG_PTR)Pfn1->PteAddress | 1); + + /* And now delete the actual stack page */ + MiDecrementShareCount(Pfn1, PageFrameNumber); } // @@ -73,6 +90,9 @@ MmDeleteKernelStack(IN PVOID StackBase, // ASSERT(PointerPte->u.Hard.Valid == 0); + /* Release the PFN lock */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + // // Release the PTEs // @@ -154,15 +174,14 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, // PointerPte++; - // - // Get a page - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + /* Get a page */ + PageFrameIndex = MiRemoveAnyPage(0); - // - // Write it - // + /* Initialize the PFN entry for this page */ + MiInitializePfn(PageFrameIndex, PointerPte, 1); + + /* Write the valid PTE */ + TempPte.u.Hard.PageFrameNumber = PageFrameIndex; ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 1); *PointerPte = TempPte; @@ -250,13 +269,14 @@ MmGrowKernelStackEx(IN PVOID StackPointer, // while (LimitPte >= NewLimitPte) { - // - // Get a page - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + /* Get a page */ + PageFrameIndex = MiRemoveAnyPage(0); + + /* Initialize the PFN entry for this page */ + MiInitializePfn(PageFrameIndex, LimitPte, 1); /* Write the valid PTE */ + TempPte.u.Hard.PageFrameNumber = PageFrameIndex; ASSERT(LimitPte->u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 1); *LimitPte-- = TempPte; From c5cc4a4bd77cb3c8b2cf1d7a9e54c68a839de18d Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 29 May 2010 19:13:19 +0000 Subject: [PATCH 100/292] [NTOSKRNL] Do not use _SEH2_YIELD in NtSetInformationProcess, NtQueryInformationThread and NtSetInformationThread while a thread or process is still being referenced. svn path=/trunk/; revision=47425 --- reactos/ntoskrnl/ps/query.c | 70 ++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index c919c419931..d27ff3e4dfe 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -925,11 +925,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Get the LPC Port */ Status = ObReferenceObjectByHandle(PortHandle, 0, @@ -969,11 +971,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Assign the actual token */ Status = PspSetPrimaryToken(Process, TokenHandle, NULL); break; @@ -1021,11 +1025,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Setting the session id requires the SeTcbPrivilege */ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) { @@ -1089,10 +1095,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Check for invalid PriorityClass value */ if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL) { @@ -1288,7 +1296,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle, Access = THREAD_SET_THREAD_TOKEN; } - /* Reference the process */ + /* Reference the thread */ Status = ObReferenceObjectByHandle(ThreadHandle, Access, PsThreadType, @@ -1318,11 +1326,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Validate it */ if ((Priority > HIGH_PRIORITY) || (Priority <= LOW_PRIORITY)) @@ -1353,11 +1363,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Validate it */ if ((Priority > THREAD_BASE_PRIORITY_MAX) || (Priority < THREAD_BASE_PRIORITY_MIN)) @@ -1398,8 +1410,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; @@ -1465,11 +1477,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Assign the actual token */ Status = PsAssignImpersonationToken(Thread, TokenHandle); break; @@ -1491,11 +1505,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Set the address */ Thread->Win32StartAddress = Address; break; @@ -1517,11 +1533,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Validate it */ if (IdealProcessor > MAXIMUM_PROCESSORS) { @@ -1564,11 +1582,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* Call the kernel */ KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost); break; @@ -1590,11 +1610,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; + if (!NT_SUCCESS(Status)) break; + /* This is only valid for the current thread */ if (Thread != PsGetCurrentThread()) { From 27957c22127afa7d72127b768cf63384f18a0e78 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 29 May 2010 19:21:08 +0000 Subject: [PATCH 101/292] [NTOS]: Fix Implementation of BreakOnTermination -- Process Flags should be accessed with interlocked bit semantics, not through C bitfield extension. [NTOS]: Revert 47425 and apply a better fix. svn path=/trunk/; revision=47426 --- reactos/ntoskrnl/ps/query.c | 72 +++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index d27ff3e4dfe..342c818945e 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -753,8 +753,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, PreviousMode, (PVOID*)&Process, NULL); - if (!NT_SUCCESS(Status)) - break; + if (!NT_SUCCESS(Status)) break; /* Enter SEH for writing back data */ _SEH2_TRY @@ -869,6 +868,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, PROCESS_SESSION_INFORMATION SessionInfo = {0}; PROCESS_PRIORITY_CLASS PriorityClass = {0}; PVOID ExceptionPort; + ULONG Break; PAGED_CODE(); /* Verify Information Class validity */ @@ -927,11 +927,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Get the LPC Port */ Status = ObReferenceObjectByHandle(PortHandle, 0, @@ -973,11 +972,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Assign the actual token */ Status = PspSetPrimaryToken(Process, TokenHandle, NULL); break; @@ -1027,11 +1025,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Setting the session id requires the SeTcbPrivilege */ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) { @@ -1096,11 +1093,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, { /* Return the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Check for invalid PriorityClass value */ if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL) { @@ -1201,24 +1197,37 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, break; } + /* Enter SEH for direct buffer read */ + _SEH2_TRY + { + Break = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Break = 0; + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); + } + _SEH2_END; + /* Setting 'break on termination' requires the SeDebugPrivilege */ if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) { Status = STATUS_PRIVILEGE_NOT_HELD; break; } + + /* Set or clear the flag */ + if (Break) + { + PspSetProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT); + } + else + { + PspClearProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT); + } - /* Enter SEH for direct buffer read */ - _SEH2_TRY - { - Process->BreakOnTermination = *(PULONG)ProcessInformation; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Get exception code */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; break; /* We currently don't implement any of these */ @@ -1328,11 +1337,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Validate it */ if ((Priority > HIGH_PRIORITY) || (Priority <= LOW_PRIORITY)) @@ -1365,11 +1373,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Validate it */ if ((Priority > THREAD_BASE_PRIORITY_MAX) || (Priority < THREAD_BASE_PRIORITY_MIN)) @@ -1479,11 +1486,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Assign the actual token */ Status = PsAssignImpersonationToken(Thread, TokenHandle); break; @@ -1507,11 +1513,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Set the address */ Thread->Win32StartAddress = Address; break; @@ -1535,11 +1540,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Validate it */ if (IdealProcessor > MAXIMUM_PROCESSORS) { @@ -1584,11 +1588,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* Call the kernel */ KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost); break; @@ -1612,11 +1615,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle, { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; - if (!NT_SUCCESS(Status)) break; - /* This is only valid for the current thread */ if (Thread != PsGetCurrentThread()) { From fa9cd08b02fed8d1bd4c10a2f3119f22fa4157dd Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 29 May 2010 19:27:32 +0000 Subject: [PATCH 102/292] Timo/Physicus: Please validate for AMD64. [NTOS]: Write down the PTE attribute flags for X86/AMD64. Timo/Physicus: Please double-check. [NTOS]: Write down the array that converts from the MM_ protection flags arleady defined, into the appropriate PTE attribute flags that are architecture-specific. [NTOS]: This will allow constant-time conversion of NT attributes into PTE attributes. Win32 attributes to NT attributes conversion won't be needed until VAD support. svn path=/trunk/; revision=47427 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 4c5e3bc441b..a670bcdb3fd 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -89,6 +89,90 @@ #define MM_DECOMMIT 0x10 #define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE) +// +// Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits +// The Memory Manager's definition define the attributes that must be preserved +// and these PTE definitions describe the attributes in the hardware sense. This +// helps deal with hardware differences between the actual boolean expression of +// the argument. +// +// For example, in the logical attributes, we want to express read-only as a flag +// but on x86, it is writability that must be set. On the other hand, on x86, just +// like in the kernel, it is disabling the caches that requires a special flag, +// while on certain architectures such as ARM, it is enabling the cache which +// requires a flag. +// +#if defined(_M_IX86) || defined(_M_AMD64) +// +// Access Flags +// +#define PTE_READONLY 0 +#define PTE_EXECUTE 0 // Not worrying about NX yet +#define PTE_EXECUTE_READ 0 // Not worrying about NX yet +#define PTE_READWRITE 0x2 +#define PTE_WRITECOPY 0x200 +#define PTE_EXECUTE_READWRITE 0x0 +#define PTE_EXECUTE_WRITECOPY 0x200 +// +// Cache flags +// +#define PTE_ENABLE_CACHE 0 +#define PTE_DISABLE_CACHE 0x10 +#define PTE_WRITECOMBINED_CACHE 0x10 +#elif defined(_M_ARM) +#else +#error Define these please! +#endif +static const +ULONG +MmProtectToPteMask[32] = +{ + // + // These are the base MM_ protection flags + // + 0, + PTE_READONLY | PTE_ENABLE_CACHE, + PTE_EXECUTE | PTE_ENABLE_CACHE, + PTE_EXECUTE_READ | PTE_ENABLE_CACHE, + PTE_READWRITE | PTE_ENABLE_CACHE, + PTE_WRITECOPY | PTE_ENABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE, + // + // These OR in the MM_NOCACHE flag + // + 0, + PTE_READONLY | PTE_DISABLE_CACHE, + PTE_EXECUTE | PTE_DISABLE_CACHE, + PTE_EXECUTE_READ | PTE_DISABLE_CACHE, + PTE_READWRITE | PTE_DISABLE_CACHE, + PTE_WRITECOPY | PTE_DISABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE, + // + // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM + // + 0, + PTE_READONLY | PTE_ENABLE_CACHE, + PTE_EXECUTE | PTE_ENABLE_CACHE, + PTE_EXECUTE_READ | PTE_ENABLE_CACHE, + PTE_READWRITE | PTE_ENABLE_CACHE, + PTE_WRITECOPY | PTE_ENABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE, + // + // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining? + // + 0, + PTE_READONLY | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE, + PTE_READWRITE | PTE_WRITECOMBINED_CACHE, + PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE, +}; + // // Assertions for session images, addresses, and PTEs // From 6af485d3aaf3a567504048d983f7caa429e8145c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 29 May 2010 20:40:28 +0000 Subject: [PATCH 103/292] [FORMATTING] No code changes. svn path=/trunk/; revision=47428 --- reactos/lib/rtl/process.c | 43 ++++++++------- reactos/ntoskrnl/se/sd.c | 104 +++++++++++++++++++++--------------- reactos/ntoskrnl/se/token.c | 34 ++++++------ 3 files changed, 101 insertions(+), 80 deletions(-) diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c index 5d6c6896a04..50e36eb38d5 100644 --- a/reactos/lib/rtl/process.c +++ b/reactos/lib/rtl/process.c @@ -43,7 +43,7 @@ RtlpMapFile(PUNICODE_STRING ImageFileName, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to read image file from disk\n"); - return(Status); + return Status; } /* Now create a section for this image */ @@ -94,7 +94,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to reserve 1MB of space \n"); - return(Status); + return Status; } } @@ -118,7 +118,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to allocate Environment Block\n"); - return(Status); + return Status; } /* Write the Environment Block */ @@ -144,7 +144,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to allocate Parameter Block\n"); - return(Status); + return Status; } /* Write the Parameter Block */ @@ -245,7 +245,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, { DPRINT1("Could not create Kernel Process Object\n"); ZwClose(hSection); - return(Status); + return Status; } /* Get some information on the image */ @@ -259,7 +259,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, DPRINT1("Could not query Section Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); - return(Status); + return Status; } /* Get some information about the process */ @@ -273,7 +273,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, DPRINT1("Could not query Process Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); - return(Status); + return Status; } /* Create Process Environment */ @@ -312,22 +312,21 @@ PVOID NTAPI RtlEncodePointer(IN PVOID Pointer) { - ULONG Cookie; - NTSTATUS Status; + ULONG Cookie; + NTSTATUS Status; - Status = ZwQueryInformationProcess(NtCurrentProcess(), - ProcessCookie, - &Cookie, - sizeof(Cookie), - NULL); + Status = ZwQueryInformationProcess(NtCurrentProcess(), + ProcessCookie, + &Cookie, + sizeof(Cookie), + NULL); + if(!NT_SUCCESS(Status)) + { + DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status); + return Pointer; + } - if(!NT_SUCCESS(Status)) - { - DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status); - return Pointer; - } - - return (PVOID)((ULONG_PTR)Pointer ^ Cookie); + return (PVOID)((ULONG_PTR)Pointer ^ Cookie); } /* @@ -337,7 +336,7 @@ PVOID NTAPI RtlDecodePointer(IN PVOID Pointer) { - return RtlEncodePointer(Pointer); + return RtlEncodePointer(Pointer); } /* diff --git a/reactos/ntoskrnl/se/sd.c b/reactos/ntoskrnl/se/sd.c index a0cb2cc5595..0e0eadcea36 100644 --- a/reactos/ntoskrnl/se/sd.c +++ b/reactos/ntoskrnl/se/sd.c @@ -249,9 +249,11 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == sizeof(SECURITY_QUALITY_OF_SERVICE)) { - /* don't allocate memory here because ExAllocate should bugcheck - the system if it's buggy, SEH would catch that! So make a local - copy of the qos structure.*/ + /* + * Don't allocate memory here because ExAllocate should bugcheck + * the system if it's buggy, SEH would catch that! So make a local + * copy of the qos structure. + */ RtlCopyMemory(&SafeQos, ObjectAttributes->SecurityQualityOfService, sizeof(SECURITY_QUALITY_OF_SERVICE)); @@ -407,8 +409,10 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _SEH2_TRY { - /* first only probe and copy until the control field of the descriptor - to determine whether it's a self-relative descriptor */ + /* + * First only probe and copy until the control field of the descriptor + * to determine whether it's a self-relative descriptor + */ DescriptorSize = FIELD_OFFSET(SECURITY_DESCRIPTOR, Owner); ProbeForRead(OriginalSecurityDescriptor, @@ -420,22 +424,24 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _SEH2_YIELD(return STATUS_UNKNOWN_REVISION); } - /* make a copy on the stack */ + /* Make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - /* probe and copy the entire security descriptor structure. The SIDs - and ACLs will be probed and copied later though */ + /* + * Probe and copy the entire security descriptor structure. The SIDs + * and ACLs will be probed and copied later though + */ ProbeForRead(OriginalSecurityDescriptor, DescriptorSize, sizeof(ULONG)); if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - + DescriptorCopy.Owner = (PSID)RelSD->Owner; DescriptorCopy.Group = (PSID)RelSD->Group; DescriptorCopy.Sacl = (PACL)RelSD->Sacl; @@ -468,12 +474,12 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, } else { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { return STATUS_UNKNOWN_REVISION; } - /* make a copy on the stack */ + /* Make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; @@ -482,7 +488,7 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - + DescriptorCopy.Owner = (PSID)RelSD->Owner; DescriptorCopy.Group = (PSID)RelSD->Group; DescriptorCopy.Sacl = (PACL)RelSD->Sacl; @@ -499,9 +505,11 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, if (DescriptorCopy.Control & SE_SELF_RELATIVE) { - /* in case we're dealing with a self-relative descriptor, do a basic convert - to an absolute descriptor. We do this so we can simply access the data - using the pointers without calculating them again. */ + /* + * In case we're dealing with a self-relative descriptor, do a basic convert + * to an absolute descriptor. We do this so we can simply access the data + * using the pointers without calculating them again. + */ DescriptorCopy.Control &= ~SE_SELF_RELATIVE; if (DescriptorCopy.Owner != NULL) { @@ -521,7 +529,7 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, } } - /* determine the size of the SIDs */ + /* Determine the size of the SIDs */ #define DetermineSIDSize(SidType) \ do { \ if(DescriptorCopy.SidType != NULL) \ @@ -530,7 +538,7 @@ SID *SidType = (SID*)DescriptorCopy.SidType; \ \ if(CurrentMode != KernelMode) \ { \ -/* securely access the buffers! */ \ +/* Securely access the buffers! */ \ _SEH2_TRY \ { \ SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \ @@ -561,7 +569,7 @@ DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ #undef DetermineSIDSize - /* determine the size of the ACLs */ + /* Determine the size of the ACLs */ #define DetermineACLSize(AclType, AclFlag) \ do { \ if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \ @@ -571,7 +579,7 @@ PACL AclType = (PACL)DescriptorCopy.AclType; \ \ if(CurrentMode != KernelMode) \ { \ -/* securely access the buffers! */ \ +/* Securely access the buffers! */ \ _SEH2_TRY \ { \ AclType##Size = ProbeForReadUshort(&AclType->AclSize); \ @@ -604,27 +612,31 @@ DescriptorCopy.AclType = NULL; \ #undef DetermineACLSize - /* allocate enough memory to store a complete copy of a self-relative - security descriptor */ + /* + * Allocate enough memory to store a complete copy of a self-relative + * security descriptor + */ NewDescriptor = ExAllocatePoolWithTag(PoolType, DescriptorSize, TAG_SD); - if(NewDescriptor != NULL) + if (NewDescriptor != NULL) { ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR); - + RtlZeroMemory(NewDescriptor, DescriptorSize); NewDescriptor->Revision = DescriptorCopy.Revision; NewDescriptor->Sbz1 = DescriptorCopy.Sbz1; NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE; - + _SEH2_TRY { - /* setup the offsets and copy the SIDs and ACLs to the new - self-relative security descriptor. Probing the pointers is not - neccessary anymore as we did that when collecting the sizes! - Make sure to validate the SIDs and ACLs *again* as they could have - been modified in the meanwhile! */ + /* + * Setup the offsets and copy the SIDs and ACLs to the new + * self-relative security descriptor. Probing the pointers is not + * neccessary anymore as we did that when collecting the sizes! + * Make sure to validate the SIDs and ACLs *again* as they could have + * been modified in the meanwhile! + */ #define CopySID(Type) \ do { \ if(DescriptorCopy.Type != NULL) \ @@ -673,14 +685,16 @@ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* we failed to copy the data to the new descriptor */ + /* We failed to copy the data to the new descriptor */ ExFreePool(NewDescriptor); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - /* we're finally done! copy the pointer to the captured descriptor to - to the caller */ + /* + * We're finally done! + * Copy the pointer to the captured descriptor to to the caller. + */ *CapturedSecurityDescriptor = NewDescriptor; return STATUS_SUCCESS; } @@ -691,7 +705,7 @@ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } else { - /* nothing to do... */ + /* Nothing to do... */ *CapturedSecurityDescriptor = NULL; } @@ -765,6 +779,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } @@ -776,6 +791,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); SaclLength = ROUND_UP(Sacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } @@ -846,14 +862,16 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, { PAGED_CODE(); - /* WARNING! You need to call this function with the same value for CurrentMode - and CaptureIfKernelMode that you previously passed to - SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ - if(CapturedSecurityDescriptor != NULL && - (CurrentMode != KernelMode || - (CurrentMode == KernelMode && CaptureIfKernelMode))) + /* + * WARNING! You need to call this function with the same value for CurrentMode + * and CaptureIfKernelMode that you previously passed to + * SeCaptureSecurityDescriptor() in order to avoid memory leaks! + */ + if (CapturedSecurityDescriptor != NULL && + (CurrentMode != KernelMode || + (CurrentMode == KernelMode && CaptureIfKernelMode))) { - /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ + /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD); } @@ -888,8 +906,9 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ObjectSd = *ObjectsSecurityDescriptor; + /* The object does not have a security descriptor. */ if (!ObjectSd) - return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. + return STATUS_NO_SECURITY_ON_OBJECT; SecurityInformation = *_SecurityInformation; @@ -1074,8 +1093,9 @@ SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL, { PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor; + /* The object does not have a security descriptor. */ if (!ObjectSd) - return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. + return STATUS_NO_SECURITY_ON_OBJECT; UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 7bb2d95bb54..30f7fc84bef 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -790,10 +790,10 @@ SepCreateSystemProcessToken(VOID) Privileges[i].Attributes = 0; Privileges[i++].Luid = SeTakeOwnershipPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePagefilePrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeLockMemoryPrivilege; Privileges[i].Attributes = 0; @@ -802,16 +802,16 @@ SepCreateSystemProcessToken(VOID) Privileges[i].Attributes = 0; Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePermanentPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeDebugPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeAuditPrivilege; Privileges[i].Attributes = 0; @@ -820,7 +820,7 @@ SepCreateSystemProcessToken(VOID) Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeChangeNotifyPrivilege; Privileges[i].Attributes = 0; @@ -835,7 +835,7 @@ SepCreateSystemProcessToken(VOID) Privileges[i].Attributes = 0; Privileges[i++].Luid = SeLoadDriverPrivilege; - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeProfileSingleProcessPrivilege; Privileges[i].Attributes = 0; @@ -1709,7 +1709,7 @@ NtSetInformationToken(IN HANDLE TokenHandle, { PACL CapturedAcl; - /* capture and copy the dacl */ + /* Capture and copy the dacl */ Status = SepCaptureAcl(InputAcl, PreviousMode, PagedPool, @@ -1717,19 +1717,19 @@ NtSetInformationToken(IN HANDLE TokenHandle, &CapturedAcl); if (NT_SUCCESS(Status)) { - /* free the previous dacl if present */ + /* Free the previous dacl if present */ if(Token->DefaultDacl != NULL) { ExFreePool(Token->DefaultDacl); } - /* set the new dacl */ + /* Set the new dacl */ Token->DefaultDacl = CapturedAcl; } } else { - /* clear and free the default dacl if present */ + /* Clear and free the default dacl if present */ if (Token->DefaultDacl != NULL) { ExFreePool(Token->DefaultDacl); @@ -1750,7 +1750,7 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_TRY { - /* buffer size was already verified, no need to check here again */ + /* Buffer size was already verified, no need to check here again */ SessionId = *(PULONG)TokenInformation; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -1880,7 +1880,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, } } - /* free the captured structure */ + /* Free the captured structure */ SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, PreviousMode, FALSE); @@ -1997,7 +1997,8 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle, } else { - /* FIXME: Should revert all the changes, calculate how + /* + * FIXME: Should revert all the changes, calculate how * much space would be needed, set ResultLength * accordingly and fail. */ @@ -2044,7 +2045,8 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle, } else { - /* FIXME: Should revert all the changes, calculate how + /* + * FIXME: Should revert all the changes, calculate how * much space would be needed, set ResultLength * accordingly and fail. */ From d259616ce432047c60e491537dcd72df9bf2ec89 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 29 May 2010 21:15:48 +0000 Subject: [PATCH 104/292] [RTL] Implement RtlEncodeSystemPointer using the user shared data cookie. svn path=/trunk/; revision=47429 --- reactos/lib/rtl/process.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c index 50e36eb38d5..ae91e2423f7 100644 --- a/reactos/lib/rtl/process.c +++ b/reactos/lib/rtl/process.c @@ -340,14 +340,13 @@ RtlDecodePointer(IN PVOID Pointer) } /* - * @unimplemented + * @implemented */ PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer) { - UNIMPLEMENTED; - return NULL; + return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie); } /* From 554237576f9032d4577b62e73b4606754be36d9c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 29 May 2010 21:48:32 +0000 Subject: [PATCH 105/292] [_mingw.h] Help compilation with clang. Patch by Amine Khaldi. svn path=/trunk/; revision=47430 --- reactos/include/crt/_mingw.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/crt/_mingw.h b/reactos/include/crt/_mingw.h index d4e53ff435a..cff811248d8 100644 --- a/reactos/include/crt/_mingw.h +++ b/reactos/include/crt/_mingw.h @@ -157,10 +157,12 @@ allow GCC to optimize away some EH unwind code, at least in DW2 case. */ //#endif #ifdef __GNUC__ +#ifndef __clang__ #define __int8 char #define __int16 short #define __int32 int #define __int64 long long +#endif #ifdef _WIN64 typedef int __int128 __attribute__ ((mode (TI))); # endif From a77d6480a61cc8563579dfc9a1d7b0c2487c7967 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 29 May 2010 23:54:47 +0000 Subject: [PATCH 106/292] [BOOTVID] Dramatically simplify 4bpp blitting routine See issue #5103 for more details. svn path=/trunk/; revision=47431 --- reactos/drivers/base/bootvid/i386/vga.c | 212 +++--------------------- 1 file changed, 23 insertions(+), 189 deletions(-) diff --git a/reactos/drivers/base/bootvid/i386/vga.c b/reactos/drivers/base/bootvid/i386/vga.c index eeb06fe8df5..1c80994c0e7 100644 --- a/reactos/drivers/base/bootvid/i386/vga.c +++ b/reactos/drivers/base/bootvid/i386/vga.c @@ -402,33 +402,20 @@ BitBlt(IN ULONG Left, IN ULONG BitsPerPixel, IN ULONG Delta) { - ULONG LeftAnd, LeftShifted, LeftPlusOne, LeftPos; - ULONG lMask, rMask; - UCHAR NotlMask; - ULONG Distance; - ULONG DistanceMinusLeftBpp; - ULONG SomeYesNoFlag, SomeYesNoFlag2; - PUCHAR PixelPosition, m; - PUCHAR i, k; - ULONG j; - ULONG x; - ULONG Plane; - UCHAR LeftArray[84]; - PUCHAR CurrentLeft; - PUCHAR l; - ULONG LoopCount; - UCHAR pMask, PlaneShift; - BOOLEAN Odd; - UCHAR Value; + ULONG sx, dx, dy; + UCHAR color; + ULONG offset = 0; + const ULONG Bottom = Top + Height; + const ULONG Right = Left + Width; /* Check if the buffer isn't 4bpp */ if (BitsPerPixel != 4) { /* FIXME: TODO */ DbgPrint("Unhandled BitBlt\n" - "%lxx%lx @ (%lx,%lx)\n" - "Bits Per Pixel %lx\n" - "Buffer: %p. Delta: %lx\n", + "%lux%lu @ (%lu|%lu)\n" + "Bits Per Pixel %lu\n" + "Buffer: %p. Delta: %lu\n", Width, Height, Left, @@ -439,181 +426,28 @@ BitBlt(IN ULONG Left, return; } - /* Get the masks and other values */ - LeftAnd = Left & 0x7; - lMask = lMaskTable[LeftAnd]; - Distance = Width + Left; - rMask = rMaskTable[(Distance - 1) & 0x7]; - Left >>= 3; - - /* Set some values */ - SomeYesNoFlag = FALSE; - SomeYesNoFlag2 = FALSE; - Distance = (Distance - 1) >> 3; - DistanceMinusLeftBpp = Distance - Left; - - /* Check if the distance is equal to the left position and add the masks */ - if (Left == Distance) lMask += rMask; - - /* Check if there's no distance offset */ - if (DistanceMinusLeftBpp) - { - /* Set the first flag on */ - SomeYesNoFlag = TRUE; - - /* Decrease offset and check if we still have one */ - if (--DistanceMinusLeftBpp) - { - /* Still have a distance offset */ - SomeYesNoFlag2 = TRUE; - } - } - - /* Calculate initial pixel position */ - PixelPosition = (PUCHAR)VgaBase + (Top * 80) + Left; - - /* Set loop buffer variable */ - i = Buffer; - - /* Switch to mode 0 */ - ReadWriteMode(0); - - /* Leave now if the height is 0 */ - if (Height <= 0) return; - - /* Set more weird values */ - CurrentLeft = &LeftArray[Left]; - NotlMask = ~(UCHAR)lMask; - LeftPlusOne = Left + 1; - LeftShifted = (lMask << 8) | 8; - j = Height; - - /* Start the height loop */ + /* 4bpp blitting */ + dy = Top; do { - /* Start the plane loop */ - Plane = 0; + sx = 0; do { - /* Clear the current value */ - *CurrentLeft = 0; - LoopCount = 0; + /* Extract color */ + color = Buffer[offset + sx]; - /* Set the buffer loop variable for this loop */ - k = i; + /* Calc destination x */ + dx = Left + (sx << 1); - /* Calculate plane shift and pixel mask */ - PlaneShift = 1 << Plane; - pMask = PixelMask[LeftAnd]; + /* Set two pixels */ + SetPixel(dx, dy, color >> 4); + SetPixel(dx + 1, dy, color & 0x0F); - /* Check if we have a width */ - if (Width > 0) - { - /* Loop it */ - l = CurrentLeft; - x = Width; - do - { - /* Check if we're odd and increase the loop count */ - Odd = LoopCount & 1 ? TRUE : FALSE; - LoopCount++; - if (Odd) - { - /* Check for the plane shift */ - if (*k & PlaneShift) - { - /* Write the pixel mask */ - *l |= pMask; - } - - /* Increase buffer position */ - k++; - } - else - { - /* Check for plane shift */ - if ((*k >> 4) & PlaneShift) - { - /* Write the pixel mask */ - *l |= pMask; - } - } - - /* Shift the pixel mask */ - pMask >>= 1; - if (!pMask) - { - /* Move to the next current left position and clear it */ - l++; - *l = 0; - - /* Set the pixel mask to 0x80 */ - pMask = 0x80; - } - } while (--x); - } - - /* Set the plane value */ - __outpw(0x3C4, (1 << (Plane + 8) | 2)); - - /* Select the bitmask register and write the mask */ - __outpw(0x3CE, (USHORT)LeftShifted); - - /* Read the current Pixel value */ - Value = READ_REGISTER_UCHAR(PixelPosition); - - /* Add our mask */ - Value = (Value & NotlMask) | *CurrentLeft; - - /* Set current left for the loop, and write new pixel value */ - LeftPos = LeftPlusOne; - WRITE_REGISTER_UCHAR(PixelPosition, Value); - - /* Set loop pixel position and check if we should loop */ - m = PixelPosition + 1; - if (SomeYesNoFlag2) - { - /* Set the bitmask to 0xFF for all 4 planes */ - __outpw(0x3CE, 0xFF08); - - /* Check if we have any distance left */ - if (DistanceMinusLeftBpp > 0) - { - /* Start looping it */ - x = DistanceMinusLeftBpp; - do - { - /* Write the value */ - WRITE_REGISTER_UCHAR(m, LeftArray[LeftPos]); - - /* Go to the next position */ - m++; - LeftPos++; - } while (--x); - } - } - - /* Check if the first flag is on */ - if (SomeYesNoFlag) - { - /* Set the mask value */ - __outpw(0x3CE, (rMask << 8) | 8); - - /* Read the current Pixel value */ - Value = READ_REGISTER_UCHAR(m); - - /* Add our mask */ - Value = (Value & ~(UCHAR)rMask) | LeftArray[LeftPos]; - - /* Set current left for the loop, and write new pixel value */ - WRITE_REGISTER_UCHAR(m, Value); - } - } while (++Plane < 4); - - /* Update pixel position, buffer and height */ - PixelPosition += 80; - i += Delta; - } while (--j); + sx++; + } while (dx < Right); + offset += Delta; + dy++; + } while (dy < Bottom); } VOID From c816943def7d4286da10dc4e2d709ff9611eb551 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 30 May 2010 03:02:39 +0000 Subject: [PATCH 107/292] [NTOS]: Implement MiAllocatePfn, it is a simpler wrapper that grabs a page, sets its protection, and initializes its PFN entry. [NTOS]: Use MiAllocatePfn in MiLoadImageSection instead of MmAllocPage. Other than doing a better job at initializing the page, it creates our first caller of this function, great for testing, since this is a rather high-demand function, especially at boot. Please test. svn path=/trunk/; revision=47432 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 38 ++++++++++++++++++++++++++++++ reactos/ntoskrnl/mm/sysldr.c | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index b70e191c030..0a7ea0730b3 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -618,6 +618,44 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex, Pfn1->u2.ShareCount++; } +PFN_NUMBER +NTAPI +MiAllocatePfn(IN PMMPTE PointerPte, + IN ULONG Protection) +{ + KIRQL OldIrql; + PFN_NUMBER PageFrameIndex; + MMPTE TempPte; + + /* Make an empty software PTE */ + MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Check if we're running low on pages */ + if (MmAvailablePages < 128) + { + DPRINT1("Warning, running low on memory: %d pages left\n", MmAvailablePages); + //MiEnsureAvailablePageOrWait(NULL, OldIrql); + } + + /* Grab a page */ + PageFrameIndex = MiRemoveAnyPage(0); + + /* Write the software PTE */ + ASSERT(PointerPte->u.Hard.Valid == 0); + *PointerPte = TempPte; + PointerPte->u.Soft.Protection |= Protection; + + /* Initialize its PFN entry */ + MiInitializePfn(PageFrameIndex, PointerPte, TRUE); + + /* Release the PFN lock and return the page */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + return PageFrameIndex; +} + VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index fcecf3c8da5..a242b4b2f6c 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -172,7 +172,7 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, while (PointerPte < LastPte) { /* Allocate a page */ - TempPte.u.Hard.PageFrameNumber = MmAllocPage(MC_NPPOOL); + TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE); /* Write it */ ASSERT(PointerPte->u.Hard.Valid == 0); From 7774953380169e80fb78a45ccbdb252f8950d297 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 30 May 2010 06:23:41 +0000 Subject: [PATCH 108/292] [user32] - Pass a pointer to a structure, that holds the CallBack procedure and data, as the 5th parameter to NtUserMessageCall. - Fix a bug In User32CallSendAsyncProcForKernel, the ArgumentLength is the size of SENDASYNCPROC_CALLBACK_ARGUMENTS. [win32k] - For types FNID_SENDMESSAGECALLBACK call co_IntSendMessageWithCallBack to put the message in the send queue. - Rewrite code for when messages have a completioncallback svn path=/trunk/; revision=47434 --- reactos/dll/win32/user32/windows/message.c | 16 +++++++++++-- reactos/dll/win32/user32/windows/window.c | 3 ++- reactos/include/reactos/win32k/callback.h | 7 ++++++ .../subsystems/win32/win32k/ntuser/message.c | 15 ++++++++++-- .../subsystems/win32/win32k/ntuser/msgqueue.c | 23 +++++-------------- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 5631469c03c..6c849042b7a 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -60,6 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); * content). When a ACK message is generated, the list of pair is searched for a * matching pair, so that the client memory handle can be returned. */ + typedef struct tagDDEPAIR { HGLOBAL ClientMem; @@ -2214,11 +2215,16 @@ SendMessageCallbackA( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, TRUE); } @@ -2236,11 +2242,17 @@ SendMessageCallbackW( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, FALSE); } diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 2427cd76ee0..e0c657cdfa9 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -29,9 +29,10 @@ User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength) PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs; TRACE("User32CallSendAsyncProcKernel()\n"); + CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments; - if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)) + if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS)) { return(STATUS_INFO_LENGTH_MISMATCH); } diff --git a/reactos/include/reactos/win32k/callback.h b/reactos/include/reactos/win32k/callback.h index 7dd97948adc..fc7c0bb95e2 100644 --- a/reactos/include/reactos/win32k/callback.h +++ b/reactos/include/reactos/win32k/callback.h @@ -33,6 +33,13 @@ typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS LRESULT Result; } SENDASYNCPROC_CALLBACK_ARGUMENTS, *PSENDASYNCPROC_CALLBACK_ARGUMENTS; +typedef struct _CALL_BACK_INFO +{ + SENDASYNCPROC CallBack; + ULONG_PTR Context; +} CALL_BACK_INFO, * PCALL_BACK_INFO; + + typedef struct _HOOKPROC_CALLBACK_ARGUMENTS { INT HookId; diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index b626b881db4..b6d8ab70443 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1625,12 +1625,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if (Window->pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { DPRINT1("Failed to unpack message parameters\n"); - RETURN(TRUE); } RETURN(TRUE); } @@ -2621,6 +2620,18 @@ NtUserMessageCall( } break; case FNID_SENDMESSAGECALLBACK: + { + PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo; + + if (!CallBackInfo) + break; + + if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam, + CallBackInfo->CallBack, CallBackInfo->Context, NULL)) + { + DPRINT1("Callback failure!\n"); + } + } break; // CallNextHook bypass. case FNID_CALLWNDPROC: diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index fe1d9a80af7..5e408a817cc 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -894,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; BOOL SenderReturned; - PUSER_SENT_MESSAGE_NOTIFY NotifyMessage; if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { @@ -965,26 +964,16 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* Notify the sender if they specified a callback. */ + /* Call the callback if the message was sent with SendMessageCallback */ if (!SenderReturned && Message->CompletionCallback != NULL) { - if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool, - sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG))) - { - DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n"); - goto Notified; - } - NotifyMessage->CompletionCallback = - Message->CompletionCallback; - NotifyMessage->CompletionCallbackContext = - Message->CompletionCallbackContext; - NotifyMessage->Result = Result; - NotifyMessage->hWnd = Message->Msg.hwnd; - NotifyMessage->Msg = Message->Msg.message; - MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage); + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Result); } -Notified: /* Only if it is not a no wait message */ if (!(Message->HookMessage & MSQ_SENTNOWAIT)) From 41cf6b121f1c42c81575a262460ef90eab30ae97 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 10:20:31 +0000 Subject: [PATCH 109/292] [URLMON] sync to wine 1.2 RC2 svn path=/trunk/; revision=47438 --- reactos/dll/win32/urlmon/binding.c | 83 ++++++++++++++++++------- reactos/dll/win32/urlmon/file.c | 5 +- reactos/dll/win32/urlmon/umon.c | 9 +++ reactos/dll/win32/urlmon/uri.c | 99 ++++++++++++++++++++++++++++++ reactos/include/psdk/urlmon.idl | 10 +++ 5 files changed, 184 insertions(+), 22 deletions(-) diff --git a/reactos/dll/win32/urlmon/binding.c b/reactos/dll/win32/urlmon/binding.c index dcf0207278c..e0f3624ff6b 100644 --- a/reactos/dll/win32/urlmon/binding.c +++ b/reactos/dll/win32/urlmon/binding.c @@ -47,6 +47,7 @@ typedef struct { BYTE buf[1024*8]; DWORD size; BOOL init; + HANDLE file; HRESULT hres; LPWSTR cache_file; @@ -57,7 +58,7 @@ typedef struct _stgmed_obj_t stgmed_obj_t; typedef struct { void (*release)(stgmed_obj_t*); HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*); - void *(*get_result)(stgmed_obj_t*); + HRESULT (*get_result)(stgmed_obj_t*,DWORD,void**); } stgmed_obj_vtbl; struct _stgmed_obj_t { @@ -101,6 +102,7 @@ struct Binding { LPWSTR redirect_url; IID iid; BOOL report_mime; + BOOL use_cache_file; DWORD state; HRESULT hres; download_state_t download_state; @@ -134,6 +136,20 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf) buf->init = TRUE; } +static void read_protocol_data(stgmed_buf_t *stgmed_buf) +{ + BYTE buf[8192]; + DWORD read; + HRESULT hres; + + fill_stgmed_buffer(stgmed_buf); + if(stgmed_buf->size < sizeof(stgmed_buf->buf)) + return; + + do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read); + while(hres == S_OK); +} + static void dump_BINDINFO(BINDINFO *bi) { static const char * const BINDINFOF_str[] = { @@ -339,6 +355,19 @@ static void create_object(Binding *binding) IInternetProtocol_Terminate(binding->protocol, 0); } +static void cache_file_available(Binding *This, const WCHAR *file_name) +{ + heap_free(This->stgmed_buf->cache_file); + This->stgmed_buf->cache_file = heap_strdupW(file_name); + + if(This->use_cache_file) { + This->stgmed_buf->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(This->stgmed_buf->file == INVALID_HANDLE_VALUE) + WARN("CreateFile failed: %u\n", GetLastError()); + } +} + #define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface) static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) @@ -377,6 +406,8 @@ static ULONG WINAPI StgMedUnk_Release(IUnknown *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->file != INVALID_HANDLE_VALUE) + CloseHandle(This->file); IInternetProtocol_Release(This->protocol); heap_free(This->cache_file); heap_free(This); @@ -403,6 +434,7 @@ static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol) ret->ref = 1; ret->size = 0; ret->init = FALSE; + ret->file = INVALID_HANDLE_VALUE; ret->hres = S_OK; ret->cache_file = NULL; @@ -488,6 +520,15 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv, TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead); + if(This->buf->file != INVALID_HANDLE_VALUE) { + if (!ReadFile(This->buf->file, pv, cb, &read, NULL)) + return INET_E_DOWNLOAD_FAILURE; + + if(pcbRead) + *pcbRead = read; + return read ? S_OK : S_FALSE; + } + if(This->buf->size) { read = cb; @@ -637,12 +678,13 @@ static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return S_OK; } -static void *stgmed_stream_get_result(stgmed_obj_t *obj) +static HRESULT stgmed_stream_get_result(stgmed_obj_t *obj, DWORD bindf, void **result) { ProtocolStream *stream = (ProtocolStream*)obj; IStream_AddRef(STREAM(stream)); - return STREAM(stream); + *result = STREAM(stream); + return S_OK; } static const stgmed_obj_vtbl stgmed_stream_vtbl = { @@ -689,16 +731,7 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return INET_E_DATA_NOT_AVAILABLE; } - fill_stgmed_buffer(file_obj->buf); - if(file_obj->buf->size == sizeof(file_obj->buf->buf)) { - BYTE buf[1024]; - DWORD read; - HRESULT hres; - - do { - hres = IInternetProtocol_Read(file_obj->buf->protocol, buf, sizeof(buf), &read); - }while(hres == S_OK); - } + read_protocol_data(file_obj->buf); stgmed->tymed = TYMED_FILE; stgmed->u.lpszFileName = file_obj->buf->cache_file; @@ -707,9 +740,9 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return S_OK; } -static void *stgmed_file_get_result(stgmed_obj_t *obj) +static HRESULT stgmed_file_get_result(stgmed_obj_t *obj, DWORD bindf, void **result) { - return NULL; + return bindf & BINDF_ASYNCHRONOUS ? MK_S_ASYNCHRONOUS : S_OK; } static const stgmed_obj_vtbl stgmed_file_vtbl = { @@ -987,8 +1020,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink mime_available(This, szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: - heap_free(This->stgmed_buf->cache_file); - This->stgmed_buf->cache_file = heap_strdupW(szStatusText); + cache_file_available(This, szStatusText); break; case BINDSTATUS_DECODING: IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText); @@ -1019,9 +1051,12 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED)) return; - if(This->download_state == BEFORE_DOWNLOAD) { + if(This->stgmed_buf->file != INVALID_HANDLE_VALUE) + read_protocol_data(This->stgmed_buf); + else if(This->download_state == BEFORE_DOWNLOAD) fill_stgmed_buffer(This->stgmed_buf); + if(This->download_state == BEFORE_DOWNLOAD) { This->download_state = DOWNLOADING; sent_begindownloaddata = TRUE; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, @@ -1430,8 +1465,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, if(to_obj) ret->bindinfo.dwOptions |= 0x100000; - if(!is_urlmon_protocol(url)) + if(!(ret->bindf & BINDF_ASYNCHRONOUS)) { ret->bindf |= BINDF_NEEDFILE; + ret->use_cache_file = TRUE; + }else if(!is_urlmon_protocol(url)) { + ret->bindf |= BINDF_NEEDFILE; + } ret->url = heap_strdupW(url); @@ -1530,12 +1569,14 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED)) IInternetProtocol_UnlockRequest(binding->protocol); - *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj); + hres = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj, binding->bindf, ppv); + }else { + hres = MK_S_ASYNCHRONOUS; } IBinding_Release(BINDING(binding)); - return *ppv ? S_OK : MK_S_ASYNCHRONOUS; + return hres; } HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) diff --git a/reactos/dll/win32/urlmon/file.c b/reactos/dll/win32/urlmon/file.c index ed4802b8a3b..a517d949222 100644 --- a/reactos/dll/win32/urlmon/file.c +++ b/reactos/dll/win32/urlmon/file.c @@ -141,7 +141,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char); file_name = url+sizeof(wszFile)/sizeof(WCHAR); - if(file_name[0] == '/' && file_name[1] == '/') + + /* Strip both forward and back slashes */ + if( (file_name[0] == '/' && file_name[1] == '/') || + (file_name[0] == '\\' && file_name[1] == '\\')) file_name += 2; if(*file_name == '/') file_name++; diff --git a/reactos/dll/win32/urlmon/umon.c b/reactos/dll/win32/urlmon/umon.c index 5e6a8f6c21f..7ce22cc6de8 100644 --- a/reactos/dll/win32/urlmon/umon.c +++ b/reactos/dll/win32/urlmon/umon.c @@ -513,6 +513,12 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags); + if (ppmk) + *ppmk = NULL; + + if (!szURL || !ppmk) + return E_INVALIDARG; + if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n"); if(!(obj = alloc_moniker())) @@ -619,6 +625,9 @@ HRESULT WINAPI MkParseDisplayNameEx(IBindCtx *pbc, LPCWSTR szDisplayName, ULONG { TRACE("(%p %s %p %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk); + if (!pbc || !szDisplayName || !*szDisplayName || !pchEaten || !ppmk) + return E_INVALIDARG; + if(is_registered_protocol(szDisplayName)) { HRESULT hres; diff --git a/reactos/dll/win32/urlmon/uri.c b/reactos/dll/win32/urlmon/uri.c index 668aa9b7109..27b0863c2cb 100644 --- a/reactos/dll/win32/urlmon/uri.c +++ b/reactos/dll/win32/urlmon/uri.c @@ -1,5 +1,6 @@ /* * Copyright 2010 Jacek Caban for CodeWeavers + * Copyright 2010 Thomas Mullaly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -97,6 +98,20 @@ static HRESULT WINAPI Uri_GetPropertyDWORD(IUri *iface, Uri_PROPERTY uriProp, DW { Uri *This = URI_THIS(iface); FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags); + + if(!pcchProperty) + return E_INVALIDARG; + + /* Microsoft's implementation for the ZONE property of a URI seems to be lacking... + * From what I can tell, instead of checking which URLZONE the URI belongs to it + * simply assigns URLZONE_INVALID and returns E_NOTIMPL. This also applies to the GetZone + * function. + */ + if(uriProp == Uri_PROPERTY_ZONE) { + *pcchProperty = URLZONE_INVALID; + return E_NOTIMPL; + } + return E_NOTIMPL; } @@ -111,6 +126,10 @@ static HRESULT WINAPI Uri_GetAbsoluteUri(IUri *iface, BSTR *pstrAbsoluteUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrAbsoluteUri); + + if(!pstrAbsoluteUri) + return E_POINTER; + return E_NOTIMPL; } @@ -118,6 +137,10 @@ static HRESULT WINAPI Uri_GetAuthority(IUri *iface, BSTR *pstrAuthority) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrAuthority); + + if(!pstrAuthority) + return E_POINTER; + return E_NOTIMPL; } @@ -125,6 +148,10 @@ static HRESULT WINAPI Uri_GetDisplayUri(IUri *iface, BSTR *pstrDisplayUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrDisplayUri); + + if(!pstrDisplayUri) + return E_POINTER; + return E_NOTIMPL; } @@ -132,6 +159,10 @@ static HRESULT WINAPI Uri_GetDomain(IUri *iface, BSTR *pstrDomain) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrDomain); + + if(!pstrDomain) + return E_POINTER; + return E_NOTIMPL; } @@ -139,6 +170,10 @@ static HRESULT WINAPI Uri_GetExtension(IUri *iface, BSTR *pstrExtension) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrExtension); + + if(!pstrExtension) + return E_POINTER; + return E_NOTIMPL; } @@ -146,6 +181,10 @@ static HRESULT WINAPI Uri_GetFragment(IUri *iface, BSTR *pstrFragment) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrFragment); + + if(!pstrFragment) + return E_POINTER; + return E_NOTIMPL; } @@ -160,6 +199,10 @@ static HRESULT WINAPI Uri_GetPassword(IUri *iface, BSTR *pstrPassword) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPassword); + + if(!pstrPassword) + return E_POINTER; + return E_NOTIMPL; } @@ -167,6 +210,10 @@ static HRESULT WINAPI Uri_GetPath(IUri *iface, BSTR *pstrPath) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPath); + + if(!pstrPath) + return E_POINTER; + return E_NOTIMPL; } @@ -174,6 +221,10 @@ static HRESULT WINAPI Uri_GetPathAndQuery(IUri *iface, BSTR *pstrPathAndQuery) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPathAndQuery); + + if(!pstrPathAndQuery) + return E_POINTER; + return E_NOTIMPL; } @@ -181,6 +232,10 @@ static HRESULT WINAPI Uri_GetQuery(IUri *iface, BSTR *pstrQuery) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrQuery); + + if(!pstrQuery) + return E_POINTER; + return E_NOTIMPL; } @@ -188,6 +243,10 @@ static HRESULT WINAPI Uri_GetRawUri(IUri *iface, BSTR *pstrRawUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrRawUri); + + if(!pstrRawUri) + return E_POINTER; + return E_NOTIMPL; } @@ -195,6 +254,10 @@ static HRESULT WINAPI Uri_GetSchemeName(IUri *iface, BSTR *pstrSchemeName) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrSchemeName); + + if(!pstrSchemeName) + return E_POINTER; + return E_NOTIMPL; } @@ -202,6 +265,10 @@ static HRESULT WINAPI Uri_GetUserInfo(IUri *iface, BSTR *pstrUserInfo) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrUserInfo); + + if(!pstrUserInfo) + return E_POINTER; + return E_NOTIMPL; } @@ -209,6 +276,10 @@ static HRESULT WINAPI Uri_GetUserName(IUri *iface, BSTR *pstrUserName) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrUserName); + + if(!pstrUserName) + return E_POINTER; + return E_NOTIMPL; } @@ -216,6 +287,10 @@ static HRESULT WINAPI Uri_GetHostType(IUri *iface, DWORD *pdwHostType) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwHostType); + + if(!pdwHostType) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -223,6 +298,10 @@ static HRESULT WINAPI Uri_GetPort(IUri *iface, DWORD *pdwPort) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwPort); + + if(!pdwPort) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -230,6 +309,10 @@ static HRESULT WINAPI Uri_GetScheme(IUri *iface, DWORD *pdwScheme) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwScheme); + + if(!pdwScheme) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -237,6 +320,14 @@ static HRESULT WINAPI Uri_GetZone(IUri *iface, DWORD *pdwZone) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwZone); + + if(!pdwZone) + return E_INVALIDARG; + + /* Microsoft doesn't seem to have this implemented yet... See + * the comment in Uri_GetPropertyDWORD for more about this. + */ + *pdwZone = URLZONE_INVALID; return E_NOTIMPL; } @@ -296,6 +387,14 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU TRACE("(%s %x %x %p)\n", debugstr_w(pwzURI), dwFlags, (DWORD)dwReserved, ppURI); + if(!ppURI) + return E_INVALIDARG; + + if(!pwzURI) { + *ppURI = NULL; + return E_INVALIDARG; + } + ret = heap_alloc(sizeof(Uri)); if(!ret) return E_OUTOFMEMORY; diff --git a/reactos/include/psdk/urlmon.idl b/reactos/include/psdk/urlmon.idl index 2ab3b2b021d..c1d3bec3b57 100644 --- a/reactos/include/psdk/urlmon.idl +++ b/reactos/include/psdk/urlmon.idl @@ -1231,6 +1231,7 @@ interface IInternetZoneManager : IUnknown typedef enum tagURLZONE { + URLZONE_INVALID = -1, URLZONE_PREDEFINED_MIN = 0, URLZONE_LOCAL_MACHINE = 0, URLZONE_INTRANET = 1, @@ -1563,6 +1564,15 @@ interface IUri : IUnknown Uri_PROPERTY_DWORD_LAST = Uri_PROPERTY_ZONE } Uri_PROPERTY; + typedef enum + { + Uri_HOST_UNKNOWN = 0, + Uri_HOST_DNS = 1, + Uri_HOST_IPV4 = 2, + Uri_HOST_IPV6 = 3, + Uri_HOST_IDN = 4 + } Uri_HOST_TYPE; + HRESULT GetPropertyBSTR( [in] Uri_PROPERTY uriProp, [out] BSTR *pbstrProperty, From aa5ababad06e9ae32b3b795a612cfa9678c3d913 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 10:25:19 +0000 Subject: [PATCH 110/292] [SHDOCVW] sync to wine 1.2 RC2 svn path=/trunk/; revision=47439 --- reactos/dll/win32/shdocvw/iexplore.c | 12 ++- reactos/dll/win32/shdocvw/intshcut.c | 3 + reactos/dll/win32/shdocvw/navigate.c | 127 ++++++++++++++++++++++- reactos/dll/win32/shdocvw/shdocvw.h | 6 ++ reactos/dll/win32/shdocvw/shdocvw.inf | 6 +- reactos/dll/win32/shdocvw/shdocvw.spec | 2 +- reactos/dll/win32/shdocvw/shdocvw_main.c | 21 ++++ reactos/dll/win32/shdocvw/view.c | 114 ++++++++++++++++++++ reactos/dll/win32/shdocvw/webbrowser.c | 7 ++ 9 files changed, 289 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/shdocvw/iexplore.c b/reactos/dll/win32/shdocvw/iexplore.c index d65810f58f9..9c14cfc1631 100644 --- a/reactos/dll/win32/shdocvw/iexplore.c +++ b/reactos/dll/win32/shdocvw/iexplore.c @@ -37,6 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); +#define IDI_APPICON 101 + static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 }; static LRESULT iewnd_OnCreate(HWND hwnd, LPCREATESTRUCTW lpcs) @@ -85,7 +87,7 @@ ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) void register_iewindow_class(void) { - WNDCLASSW wc; + WNDCLASSEXW wc; memset(&wc, 0, sizeof wc); wc.style = 0; @@ -93,13 +95,15 @@ void register_iewindow_class(void) wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(InternetExplorer*); wc.hInstance = shdocvw_hinstance; - wc.hIcon = 0; - wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDI_APPLICATION)); + wc.hIcon = LoadIconW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON)); + wc.hIconSm = LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); + wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW)); wc.hbrBackground = 0; wc.lpszClassName = szIEWinFrame; wc.lpszMenuName = NULL; - RegisterClassW(&wc); + RegisterClassExW(&wc); } void unregister_iewindow_class(void) diff --git a/reactos/dll/win32/shdocvw/intshcut.c b/reactos/dll/win32/shdocvw/intshcut.c index b389ec3727a..32dab6dd519 100644 --- a/reactos/dll/win32/shdocvw/intshcut.c +++ b/reactos/dll/win32/shdocvw/intshcut.c @@ -74,6 +74,7 @@ static BOOL run_winemenubuilder( const WCHAR *args ) PROCESS_INFORMATION pi; BOOL ret; WCHAR app[MAX_PATH]; + void *redir; GetSystemDirectoryW( app, MAX_PATH - sizeof(menubuilder)/sizeof(WCHAR) ); strcatW( app, menubuilder ); @@ -91,7 +92,9 @@ static BOOL run_winemenubuilder( const WCHAR *args ) memset(&si, 0, sizeof(si)); si.cb = sizeof(si); + Wow64DisableWow64FsRedirection( &redir ); ret = CreateProcessW( app, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); + Wow64RevertWow64FsRedirection( redir ); heap_free( buffer ); diff --git a/reactos/dll/win32/shdocvw/navigate.c b/reactos/dll/win32/shdocvw/navigate.c index 8ba5f692740..99980c7c31b 100644 --- a/reactos/dll/win32/shdocvw/navigate.c +++ b/reactos/dll/win32/shdocvw/navigate.c @@ -642,7 +642,7 @@ static HRESULT async_doc_navigate(DocHost *This, LPCWSTR url, LPCWSTR headers, P return free_doc_navigate_task(task, TRUE); } - if(task->post_data) { + if(post_data) { task->post_data = SafeArrayCreateVector(VT_UI1, 0, post_data_size); if(!task->post_data) return free_doc_navigate_task(task, TRUE); @@ -950,7 +950,132 @@ static const IHlinkFrameVtbl HlinkFrameVtbl = { HlinkFrame_UpdateHlink }; +#define TARGETFRAME2_THIS(iface) DEFINE_THIS(WebBrowser, ITargetFrame2, iface) + +static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv); +} + +static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER2(This)); +} + +static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER2(This)); +} + +static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppszFrameName); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppunkParent); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc)); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppContainer); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%x)\n", This, dwFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, pdwFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias); + return E_NOTIMPL; +} + +#undef TARGETFRAME2_THIS + +static const ITargetFrame2Vtbl TargetFrame2Vtbl = { + TargetFrame2_QueryInterface, + TargetFrame2_AddRef, + TargetFrame2_Release, + TargetFrame2_SetFrameName, + TargetFrame2_GetFrameName, + TargetFrame2_GetParentFrame, + TargetFrame2_SetFrameSrc, + TargetFrame2_GetFrameSrc, + TargetFrame2_GetFramesContainer, + TargetFrame2_SetFrameOptions, + TargetFrame2_GetFrameOptions, + TargetFrame2_SetFrameMargins, + TargetFrame2_GetFrameMargins, + TargetFrame2_FindFrame, + TargetFrame2_GetTargetAlias +}; + void WebBrowser_HlinkFrame_Init(WebBrowser *This) { This->lpHlinkFrameVtbl = &HlinkFrameVtbl; + This->lpITargetFrame2Vtbl = &TargetFrame2Vtbl; } diff --git a/reactos/dll/win32/shdocvw/shdocvw.h b/reactos/dll/win32/shdocvw/shdocvw.h index 1184298dca9..1af0365d25d 100644 --- a/reactos/dll/win32/shdocvw/shdocvw.h +++ b/reactos/dll/win32/shdocvw/shdocvw.h @@ -37,6 +37,7 @@ #include "exdisp.h" #include "mshtmhst.h" #include "hlink.h" +#include "htiframe.h" #include "wine/unicode.h" @@ -126,7 +127,9 @@ struct WebBrowser { const IOleInPlaceActiveObjectVtbl *lpOleInPlaceActiveObjectVtbl; const IOleCommandTargetVtbl *lpOleCommandTargetVtbl; const IHlinkFrameVtbl *lpHlinkFrameVtbl; + const ITargetFrame2Vtbl *lpITargetFrame2Vtbl; const IServiceProviderVtbl *lpServiceProviderVtbl; + const IDataObjectVtbl *lpDataObjectVtbl; LONG ref; @@ -184,6 +187,8 @@ struct InternetExplorer { #define ACTIVEOBJ(x) ((IOleInPlaceActiveObject*) &(x)->lpOleInPlaceActiveObjectVtbl) #define OLECMD(x) ((IOleCommandTarget*) &(x)->lpOleCommandTargetVtbl) #define HLINKFRAME(x) ((IHlinkFrame*) &(x)->lpHlinkFrameVtbl) +#define DATAOBJECT(x) ((IDataObject*) &(x)->lpDataObjectVtbl) +#define TARGETFRAME2(x) ((ITargetFrame2*) &(x)->lpITargetFrame2Vtbl) #define CLIENTSITE(x) ((IOleClientSite*) &(x)->lpOleClientSiteVtbl) #define INPLACESITE(x) ((IOleInPlaceSite*) &(x)->lpOleInPlaceSiteVtbl) @@ -198,6 +203,7 @@ struct InternetExplorer { void WebBrowser_OleObject_Init(WebBrowser*); void WebBrowser_ViewObject_Init(WebBrowser*); +void WebBrowser_DataObject_Init(WebBrowser*); void WebBrowser_Persist_Init(WebBrowser*); void WebBrowser_ClassInfo_Init(WebBrowser*); void WebBrowser_HlinkFrame_Init(WebBrowser*); diff --git a/reactos/dll/win32/shdocvw/shdocvw.inf b/reactos/dll/win32/shdocvw/shdocvw.inf index 932c9beaf25..f08759c5a93 100644 --- a/reactos/dll/win32/shdocvw/shdocvw.inf +++ b/reactos/dll/win32/shdocvw/shdocvw.inf @@ -149,9 +149,9 @@ HKLM,"Software\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe","Path",, [IE.Reg] -HKLM,"Software\Microsoft\Internet Explorer","Build",,"62900.2180" -HKLM,"Software\Microsoft\Internet Explorer","IVer",,"103" -HKLM,"Software\Microsoft\Internet Explorer","Version",,"6.0.2900.2180" +HKLM,"Software\Microsoft\Internet Explorer","Build",,"86001" +HKLM,"Software\Microsoft\Internet Explorer","Version",,"8.0.6001.18702" +HKLM,"Software\Microsoft\Internet Explorer","W2kVersion",,"8.0.6001.18702" [Strings] diff --git a/reactos/dll/win32/shdocvw/shdocvw.spec b/reactos/dll/win32/shdocvw/shdocvw.spec index aa5ef512b3c..4a0dd2c678a 100644 --- a/reactos/dll/win32/shdocvw/shdocvw.spec +++ b/reactos/dll/win32/shdocvw/shdocvw.spec @@ -40,7 +40,7 @@ 151 stdcall -noname URLSubRegQueryA(str str long ptr long long) 152 stub -noname CShellUIHelper_CreateInstance2 153 stub -noname IsURLChild -158 stub -noname SHRestricted2A +158 stdcall -noname SHRestricted2A(long str long) 159 stdcall -noname SHRestricted2W(long wstr long) 160 stub -noname SHIsRestricted2W 161 stub @ # CSearchAssistantOC::OnDraw diff --git a/reactos/dll/win32/shdocvw/shdocvw_main.c b/reactos/dll/win32/shdocvw/shdocvw_main.c index 746753f0ab2..5dfd2b99ddf 100644 --- a/reactos/dll/win32/shdocvw/shdocvw_main.c +++ b/reactos/dll/win32/shdocvw/shdocvw_main.c @@ -440,3 +440,24 @@ DWORD WINAPI SHRestricted2W(DWORD res, LPCWSTR url, DWORD reserved) FIXME("(%d %s %d) stub\n", res, debugstr_w(url), reserved); return 0; } + +/****************************************************************** + * SHRestricted2A (SHDOCVW.158) + * + * See SHRestricted2W + */ +DWORD WINAPI SHRestricted2A(DWORD restriction, LPCSTR url, DWORD reserved) +{ + LPWSTR urlW = NULL; + DWORD res; + + TRACE("(%d, %s, %d)\n", restriction, debugstr_a(url), reserved); + if (url) { + DWORD len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0); + urlW = heap_alloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len); + } + res = SHRestricted2W(restriction, urlW, reserved); + heap_free(urlW); + return res; +} diff --git a/reactos/dll/win32/shdocvw/view.c b/reactos/dll/win32/shdocvw/view.c index d2e58579cb6..9ee7c067333 100644 --- a/reactos/dll/win32/shdocvw/view.c +++ b/reactos/dll/win32/shdocvw/view.c @@ -1,5 +1,6 @@ /* * Copyright 2005 Jacek Caban + * Copyright 2010 Ilya Shpigor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,6 +22,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); +/********************************************************************** + * Implement the IViewObject interface + */ + #define VIEWOBJ_THIS(iface) DEFINE_THIS(WebBrowser, ViewObject, iface) static HRESULT WINAPI ViewObject_QueryInterface(IViewObject2 *iface, REFIID riid, void **ppv) @@ -122,3 +127,112 @@ void WebBrowser_ViewObject_Init(WebBrowser *This) { This->lpViewObjectVtbl = &ViewObjectVtbl; } + +/********************************************************************** + * Implement the IDataObject interface + */ + +#define DATAOBJ_THIS(iface) DEFINE_THIS(WebBrowser, DataObject, iface) + +static HRESULT WINAPI DataObject_QueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID * ppvObj) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_QueryInterface(WEBBROWSER(This), riid, ppvObj); +} + +static ULONG WINAPI DataObject_AddRef(LPDATAOBJECT iface) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER(This)); +} + +static ULONG WINAPI DataObject_Release(LPDATAOBJECT iface) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER(This)); +} + +static HRESULT WINAPI DataObject_GetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_GetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_QueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_SetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_EnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_DAdvise(LPDATAOBJECT iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_DUnadvise(LPDATAOBJECT iface, DWORD dwConnection) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_EnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static const IDataObjectVtbl DataObjectVtbl = { + DataObject_QueryInterface, + DataObject_AddRef, + DataObject_Release, + DataObject_GetData, + DataObject_GetDataHere, + DataObject_QueryGetData, + DataObject_GetCanonicalFormatEtc, + DataObject_SetData, + DataObject_EnumFormatEtc, + DataObject_DAdvise, + DataObject_DUnadvise, + DataObject_EnumDAdvise +}; + +#undef DATAOBJ_THIS + +void WebBrowser_DataObject_Init(WebBrowser *This) +{ + This->lpDataObjectVtbl = &DataObjectVtbl; +} diff --git a/reactos/dll/win32/shdocvw/webbrowser.c b/reactos/dll/win32/shdocvw/webbrowser.c index 2ac9b9985d5..0c26a83b55e 100644 --- a/reactos/dll/win32/shdocvw/webbrowser.c +++ b/reactos/dll/win32/shdocvw/webbrowser.c @@ -102,9 +102,15 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid }else if(IsEqualGUID(&IID_IHlinkFrame, riid)) { TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv); *ppv = HLINKFRAME(This); + }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) { + TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv); + *ppv = TARGETFRAME2(This); }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { *ppv = SERVPROV(This); TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); + }else if(IsEqualGUID(&IID_IDataObject, riid)) { + *ppv = DATAOBJECT(This); + TRACE("(%p)->(IID_IDataObject %p)\n", This, ppv); }else if(IsEqualGUID(&IID_IQuickActivate, riid)) { TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv); return E_NOINTERFACE; @@ -1132,6 +1138,7 @@ static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, voi WebBrowser_OleObject_Init(ret); WebBrowser_ViewObject_Init(ret); + WebBrowser_DataObject_Init(ret); WebBrowser_Persist_Init(ret); WebBrowser_ClassInfo_Init(ret); WebBrowser_HlinkFrame_Init(ret); From 07f8aeb0e8856708731f6d0b153921b3ff0f72cf Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 11:25:21 +0000 Subject: [PATCH 111/292] [WS2_32] set LastError to 0 when WSASendTo was successful svn path=/trunk/; revision=47440 --- reactos/dll/win32/ws2_32/misc/sndrcv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/dll/win32/ws2_32/misc/sndrcv.c b/reactos/dll/win32/ws2_32/misc/sndrcv.c index f1b68feb158..8fb4186933e 100644 --- a/reactos/dll/win32/ws2_32/misc/sndrcv.c +++ b/reactos/dll/win32/ws2_32/misc/sndrcv.c @@ -410,6 +410,8 @@ WSASendTo(IN SOCKET s, if (Code == SOCKET_ERROR) WSASetLastError(Errno); + else + WSASetLastError(0); return Code; } From 64fc3cd5d79f46043af8651f9ad802d99a7e98dc Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 12:21:21 +0000 Subject: [PATCH 112/292] [NTDDK] Protect IoMapTransfer from incompatible redefinition. Patch by AmineKhaldi. svn path=/trunk/; revision=47441 --- reactos/include/ddk/ntddk.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 55569692a96..f9281f95bac 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -2134,6 +2134,7 @@ IoAllocateAdapterChannel( IN PVOID Context); #endif +#if !defined(DMA_MACROS_DEFINED) //DECLSPEC_DEPRECATED_DDK NTHALAPI PHYSICAL_ADDRESS @@ -2145,6 +2146,7 @@ IoMapTransfer( IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice); +#endif NTKERNELAPI VOID From 4af7c48119b8cb4815d03ff5b78014a749d88984 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 13:02:29 +0000 Subject: [PATCH 113/292] [intrin_x86.h] - cast return value of __sync_val_compare_and_swap to make clang happy - add __cdecl to a number of intrinsics to make them (hopefully) compatible with crt header declarations. svn path=/trunk/; revision=47442 --- reactos/include/crt/mingw32/intrin_x86.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/include/crt/mingw32/intrin_x86.h b/reactos/include/crt/mingw32/intrin_x86.h index 9e83ed81838..bf9470e1237 100644 --- a/reactos/include/crt/mingw32/intrin_x86.h +++ b/reactos/include/crt/mingw32/intrin_x86.h @@ -114,7 +114,7 @@ __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destinati __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) { - return __sync_val_compare_and_swap(Destination, Comperand, Exchange); + return (void *)__sync_val_compare_and_swap(Destination, Comperand, Exchange); } __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value) @@ -137,7 +137,7 @@ __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Targe { /* NOTE: ditto */ __sync_synchronize(); - return __sync_lock_test_and_set(Target, Value); + return (void *)__sync_lock_test_and_set(Target, Value); } __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value) @@ -879,14 +879,14 @@ __INTRIN_INLINE unsigned short _rotl16(unsigned short value, unsigned char shift return retval; } -__INTRIN_INLINE unsigned int _rotl(unsigned int value, int shift) +__INTRIN_INLINE unsigned int __cdecl _rotl(unsigned int value, int shift) { unsigned long retval; __asm__("roll %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); return retval; } -__INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift) +__INTRIN_INLINE unsigned int __cdecl _rotr(unsigned int value, int shift) { unsigned long retval; __asm__("rorl %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); @@ -956,14 +956,14 @@ __INTRIN_INLINE unsigned long long __ull_rshift(const unsigned long long Mask, i return retval; } -__INTRIN_INLINE unsigned short _byteswap_ushort(unsigned short value) +__INTRIN_INLINE unsigned short __cdecl _byteswap_ushort(unsigned short value) { unsigned short retval; __asm__("rorw $8, %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value)); return retval; } -__INTRIN_INLINE unsigned long _byteswap_ulong(unsigned long value) +__INTRIN_INLINE unsigned long __cdecl _byteswap_ulong(unsigned long value) { unsigned long retval; __asm__("bswapl %[retval]" : [retval] "=r" (retval) : "[retval]" (value)); @@ -971,7 +971,7 @@ __INTRIN_INLINE unsigned long _byteswap_ulong(unsigned long value) } #ifdef _M_AMD64 -__INTRIN_INLINE unsigned __int64 _byteswap_uint64(unsigned __int64 value) +__INTRIN_INLINE unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 value) { unsigned __int64 retval; __asm__("bswapq %[retval]" : [retval] "=r" (retval) : "[retval]" (value)); From 76dc59573264445be43d21f6fbef2c38456ce537 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 14:02:47 +0000 Subject: [PATCH 114/292] [DDK] Cast the string parameter of ASSERTMSG to PCHAR to allow passing string constants which are PCCHAR without a warning. svn path=/trunk/; revision=47443 --- reactos/include/ddk/wdm.h | 2 +- reactos/include/xdk/rtlfuncs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/ddk/wdm.h b/reactos/include/ddk/wdm.h index 3a523235742..af239bbb4c3 100644 --- a/reactos/include/ddk/wdm.h +++ b/reactos/include/ddk/wdm.h @@ -9459,7 +9459,7 @@ RtlCheckBit( #define ASSERTMSG(msg, exp) \ (VOID)((!(exp)) ? \ - RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, msg ), FALSE : TRUE) + RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, (PCHAR)msg ), FALSE : TRUE) #define RTL_SOFT_ASSERT(exp) \ (VOID)((!(exp)) ? \ diff --git a/reactos/include/xdk/rtlfuncs.h b/reactos/include/xdk/rtlfuncs.h index a5302dcea9f..ee7742c2f94 100644 --- a/reactos/include/xdk/rtlfuncs.h +++ b/reactos/include/xdk/rtlfuncs.h @@ -1858,7 +1858,7 @@ RtlCheckBit( #define ASSERTMSG(msg, exp) \ (VOID)((!(exp)) ? \ - RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, msg ), FALSE : TRUE) + RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, (PCHAR)msg ), FALSE : TRUE) #define RTL_SOFT_ASSERT(exp) \ (VOID)((!(exp)) ? \ From 065ed554bed989abd161948bcd3885ad935084e8 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 15:00:04 +0000 Subject: [PATCH 115/292] [PSDK] add missing definitions svn path=/trunk/; revision=47444 --- reactos/include/psdk/commctrl.h | 3 +++ reactos/include/psdk/shellapi.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/reactos/include/psdk/commctrl.h b/reactos/include/psdk/commctrl.h index 9f3366e3474..2b51c2e072f 100644 --- a/reactos/include/psdk/commctrl.h +++ b/reactos/include/psdk/commctrl.h @@ -2392,6 +2392,7 @@ extern "C" { #define LVFI_PARAM 0x1 #define LVFI_STRING 0x2 +#define LVFI_SUBSTRING 0x4 #define LVFI_PARTIAL 0x8 #define LVFI_WRAP 0x20 #define LVFI_NEARESTXY 0x40 @@ -4380,6 +4381,8 @@ typedef struct tagTVDISPINFOEXW { SYSTEMTIME st; } MCHITTESTINFO,*PMCHITTESTINFO; +#define MCHITTESTINFO_V1_SIZE CCSIZEOF_STRUCT(MCHITTESTINFO, st) + #define MCHT_TITLE 0x10000 #define MCHT_CALENDAR 0x20000 #define MCHT_TODAYLINK 0x30000 diff --git a/reactos/include/psdk/shellapi.h b/reactos/include/psdk/shellapi.h index 26fe6450873..ff7b94ea3f9 100644 --- a/reactos/include/psdk/shellapi.h +++ b/reactos/include/psdk/shellapi.h @@ -128,6 +128,19 @@ extern "C" { #define SHGFI_PIDL 8 #define SHGFI_USEFILEATTRIBUTES 16 +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define SHIL_LARGE 0x0 +#define SHIL_SMALL 0x1 +#define SHIL_EXTRALARGE 0x2 +#define SHIL_SYSSMALL 0x3 +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define SHIL_JUMBO 0x4 +#define SHIL_LAST SHIL_JUMBO +#else +#define SHIL_LAST SHIL_SYSSMALL +#endif +#endif + typedef struct _SHCREATEPROCESSINFOW { DWORD cbSize; From 306e2ff6f2d0d214ff708835e6a9c1bbc649146e Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 15:09:25 +0000 Subject: [PATCH 116/292] [MMSYS] Adjust German dialog item positions and sizes svn path=/trunk/; revision=47445 --- reactos/dll/cpl/mmsys/lang/de-DE.rc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/mmsys/lang/de-DE.rc b/reactos/dll/cpl/mmsys/lang/de-DE.rc index 81e3d437828..6ddf8ae5a35 100644 --- a/reactos/dll/cpl/mmsys/lang/de-DE.rc +++ b/reactos/dll/cpl/mmsys/lang/de-DE.rc @@ -36,9 +36,9 @@ BEGIN LTEXT "&Programmereignisse:",-1,8,118,150,17 CONTROL "", IDC_SCHEME_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 8, 130, 230, 60, WS_EX_CLIENTEDGE LTEXT "&Klänge:", IDC_TEXT_SOUND,8,194,80,17, WS_DISABLED - COMBOBOX IDC_SOUND_LIST, 8, 205, 155, 146, CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED - PUSHBUTTON "", IDC_PLAY_SOUND, 168,205,15,15, WS_DISABLED | BS_ICON - PUSHBUTTON "&Durchsuchen...", IDC_BROWSE_SOUND, 188,205,81,15, WS_DISABLED + COMBOBOX IDC_SOUND_LIST, 8, 205, 135, 146, CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED + PUSHBUTTON "", IDC_PLAY_SOUND, 148,205,15,15, WS_DISABLED | BS_ICON + PUSHBUTTON "&Durchsuchen...", IDC_BROWSE_SOUND, 168,205,70,15, WS_DISABLED END IDD_AUDIO DIALOGEX 0, 0, 246, 228 From 5df0484c21a85a331e915d64d687fd492d3b950c Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 15:13:04 +0000 Subject: [PATCH 117/292] [MMSYS] Load the no sound item in the shared buffer before preparing the reactos/media path for loading individual files See issue #5436 for more details. svn path=/trunk/; revision=47446 --- reactos/dll/cpl/mmsys/sounds.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/reactos/dll/cpl/mmsys/sounds.c b/reactos/dll/cpl/mmsys/sounds.c index be314e181e0..c7ff17187a5 100644 --- a/reactos/dll/cpl/mmsys/sounds.c +++ b/reactos/dll/cpl/mmsys/sounds.c @@ -718,6 +718,14 @@ LoadSoundFiles(HWND hwndDlg) LRESULT lResult; UINT length; + /* Add no sound listview item */ + if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH)) + { + szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0'; + SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath); + } + + /* Load sound files */ length = GetWindowsDirectoryW(szPath, MAX_PATH); if (length == 0 || length >= MAX_PATH - 9) { @@ -736,11 +744,6 @@ LoadSoundFiles(HWND hwndDlg) { return FALSE; } - if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH)) - { - szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0'; - SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath); - } do { @@ -1054,6 +1057,7 @@ SoundsDlgProc(HWND hwndDlg, ZeroMemory(&item, sizeof(LVITEM)); item.mask = LVIF_PARAM; item.iItem = nm->iItem; + if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item)) { LRESULT lCount, lIndex, lResult; From 769948f75a0724593af7befc549179c25ff5d076 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 15:18:08 +0000 Subject: [PATCH 118/292] [PSDK] add missing definitions svn path=/trunk/; revision=47447 --- reactos/include/psdk/prsht.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/include/psdk/prsht.h b/reactos/include/psdk/prsht.h index 91f3e76de14..dc1b1afedac 100644 --- a/reactos/include/psdk/prsht.h +++ b/reactos/include/psdk/prsht.h @@ -82,7 +82,11 @@ extern "C" { #if (_WIN32_IE >= 0x0500) #define PSM_GETRESULT 1159 #define PropSheet_GetResult(hDlg) SNDMSG(hDlg, PSM_GETRESULT, 0, 0) + #define PSM_HWNDTOINDEX 1153 +#define PropSheet_HwndToIndex(hDlg, hwnd) \ + (int)SNDMSG(hDlg, PSM_HWNDTOINDEX, (WPARAM)(hwnd), 0) + #define PSM_IDTOINDEX 1157 #define PSM_INDEXTOHWND 1154 #define PSM_INDEXTOID 1158 From d6fb44f0d74c8d95ec70adfb99c4e537b3cf54c1 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 15:19:09 +0000 Subject: [PATCH 119/292] [COMCTL32_WINETEST] sync to wine 1.2 RC2 svn path=/trunk/; revision=47448 --- rostests/winetests/comctl32/comboex.c | 175 +- rostests/winetests/comctl32/comctl32.rbuild | 3 +- rostests/winetests/comctl32/comctl32_ros.diff | 37 - rostests/winetests/comctl32/datetime.c | 507 +-- rostests/winetests/comctl32/dpa.c | 540 +++- rostests/winetests/comctl32/header.c | 433 ++- rostests/winetests/comctl32/imagelist.c | 679 +++- rostests/winetests/comctl32/ipaddress.c | 7 +- rostests/winetests/comctl32/listview.c | 2861 +++++++++++++++-- rostests/winetests/comctl32/misc.c | 4 +- rostests/winetests/comctl32/monthcal.c | 982 ++++-- rostests/winetests/comctl32/mru.c | 120 +- rostests/winetests/comctl32/msg.c | 251 -- rostests/winetests/comctl32/msg.h | 239 +- rostests/winetests/comctl32/progress.c | 7 +- rostests/winetests/comctl32/propsheet.c | 249 +- rostests/winetests/comctl32/rebar.c | 235 +- rostests/winetests/comctl32/resources.h | 10 + rostests/winetests/comctl32/rsrc.rc | 34 + rostests/winetests/comctl32/status.c | 108 + rostests/winetests/comctl32/subclass.c | 48 +- rostests/winetests/comctl32/tab.c | 558 ++-- rostests/winetests/comctl32/testlist.c | 2 - rostests/winetests/comctl32/toolbar.c | 212 +- rostests/winetests/comctl32/tooltips.c | 340 +- rostests/winetests/comctl32/trackbar.c | 138 +- rostests/winetests/comctl32/treeview.c | 748 +++-- rostests/winetests/comctl32/updown.c | 400 ++- rostests/winetests/comctl32/v6util.h | 142 + 29 files changed, 8176 insertions(+), 1893 deletions(-) delete mode 100644 rostests/winetests/comctl32/comctl32_ros.diff delete mode 100644 rostests/winetests/comctl32/msg.c create mode 100644 rostests/winetests/comctl32/v6util.h diff --git a/rostests/winetests/comctl32/comboex.c b/rostests/winetests/comctl32/comboex.c index 1e741924ce8..f9a42dfe604 100644 --- a/rostests/winetests/comctl32/comboex.c +++ b/rostests/winetests/comctl32/comboex.c @@ -22,11 +22,23 @@ #include #include "wine/test.h" +#include "msg.h" + +#define EDITBOX_SEQ_INDEX 0 +#define NUM_MSG_SEQUENCES 1 + +#define EDITBOX_ID 0 + +#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) + +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; static HWND hComboExParentWnd; static HINSTANCE hMainHinst; static const char ComboExTestClass[] = "ComboExTestClass"; +static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR); + #define MAX_CHARS 100 static char *textBuffer = NULL; @@ -42,7 +54,7 @@ static LONG addItem(HWND cbex, int idx, LPTSTR text) { cbexItem.iItem = idx; cbexItem.pszText = text; cbexItem.cchTextMax = 0; - return (LONG)SendMessage(cbex, CBEM_INSERTITEM, 0,(LPARAM)&cbexItem); + return SendMessage(cbex, CBEM_INSERTITEM, 0, (LPARAM)&cbexItem); } static LONG setItem(HWND cbex, int idx, LPTSTR text) { @@ -52,11 +64,11 @@ static LONG setItem(HWND cbex, int idx, LPTSTR text) { cbexItem.iItem = idx; cbexItem.pszText = text; cbexItem.cchTextMax = 0; - return (LONG)SendMessage(cbex, CBEM_SETITEM, 0,(LPARAM)&cbexItem); + return SendMessage(cbex, CBEM_SETITEM, 0, (LPARAM)&cbexItem); } static LONG delItem(HWND cbex, int idx) { - return (LONG)SendMessage(cbex, CBEM_DELETEITEM, (LPARAM)idx, 0); + return SendMessage(cbex, CBEM_DELETEITEM, idx, 0); } static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEM *cbItem) { @@ -65,7 +77,51 @@ static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEM *cbItem) { cbItem->pszText = textBuffer; cbItem->iItem = idx; cbItem->cchTextMax = 100; - return (LONG)SendMessage(cbex, CBEM_GETITEM, 0, (LPARAM)cbItem); + return SendMessage(cbex, CBEM_GETITEM, 0, (LPARAM)cbItem); +} + +static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + static LONG defwndproc_counter = 0; + LRESULT ret; + struct message msg; + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + msg.id = EDITBOX_ID; + + if (message != WM_PAINT && + message != WM_ERASEBKGND && + message != WM_NCPAINT && + message != WM_NCHITTEST && + message != WM_GETTEXT && + message != WM_GETICON && + message != WM_DEVICECHANGE) + { + add_message(sequences, EDITBOX_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); + defwndproc_counter--; + return ret; +} + +static HWND subclass_editbox(HWND hwndComboEx) +{ + WNDPROC oldproc; + HWND hwnd; + + hwnd = (HWND)SendMessage(hwndComboEx, CBEM_GETEDITCONTROL, 0, 0); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)editbox_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); + + return hwnd; } static void test_comboboxex(void) { @@ -288,6 +344,41 @@ static void test_WM_LBUTTONDOWN(void) DestroyWindow(hComboEx); } +static void test_CB_GETLBTEXT(void) +{ + HWND hCombo; + CHAR buff[1]; + COMBOBOXEXITEMA item; + LRESULT ret; + + hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN); + + /* set text to null */ + addItem(hCombo, 0, NULL); + + buff[0] = 'a'; + item.mask = CBEIF_TEXT; + item.iItem = 0; + item.pszText = buff; + item.cchTextMax = 1; + ret = SendMessage(hCombo, CBEM_GETITEMA, 0, (LPARAM)&item); + ok(ret != 0, "CBEM_GETITEM failed\n"); + ok(buff[0] == 0, "\n"); + + ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0); + ok(ret == 0, "Expected zero length\n"); + + ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0); + ok(ret == 0, "Expected zero length\n"); + + buff[0] = 'a'; + ret = SendMessage(hCombo, CB_GETLBTEXT, 0, (LPARAM)buff); + ok(ret == 0, "Expected zero length\n"); + ok(buff[0] == 0, "Expected null terminator as a string, got %s\n", buff); + + DestroyWindow(hCombo); +} + static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { @@ -321,6 +412,8 @@ static int init(void) iccex.dwICC = ICC_USEREX_CLASSES; pInitCommonControlsEx(&iccex); + pSetWindowSubclass = (void*)GetProcAddress(hComctl32, (LPSTR)410); + wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; @@ -355,13 +448,87 @@ static void cleanup(void) UnregisterClassA(ComboExTestClass, GetModuleHandleA(NULL)); } +static void test_comboboxex_subclass(void) +{ + HWND hComboEx, hCombo, hEdit; + + hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN); + + hCombo = (HWND)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0); + ok(hCombo != NULL, "Failed to get internal combo\n"); + hEdit = (HWND)SendMessage(hComboEx, CBEM_GETEDITCONTROL, 0, 0); + ok(hEdit != NULL, "Failed to get internal edit\n"); + + if (pSetWindowSubclass) + { + ok(GetPropA(hCombo, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n"); + ok(GetPropA(hEdit, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n"); + } + + DestroyWindow(hComboEx); +} + +static const struct message test_setitem_edit_seq[] = { + { WM_SETTEXT, sent|id, 0, 0, EDITBOX_ID }, + { EM_SETSEL, sent|id|wparam|lparam, 0, 0, EDITBOX_ID }, + { EM_SETSEL, sent|id|wparam|lparam, 0, -1, EDITBOX_ID }, + { 0 } +}; + +static void test_get_set_item(void) +{ + char textA[] = "test"; + HWND hComboEx; + COMBOBOXEXITEMA item; + BOOL ret; + + hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN); + + subclass_editbox(hComboEx); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.mask = CBEIF_TEXT; + item.pszText = textA; + item.iItem = -1; + ret = SendMessage(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + + ok_sequence(sequences, EDITBOX_SEQ_INDEX, test_setitem_edit_seq, "set item data for edit", FALSE); + + /* get/set lParam */ + item.mask = CBEIF_LPARAM; + item.iItem = -1; + item.lParam = 0xdeadbeef; + ret = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.lParam == 0, "Expected zero, got %ld\n", item.lParam); + + item.lParam = 0xdeadbeef; + ret = SendMessage(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + + item.lParam = 0; + ret = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.lParam == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", item.lParam); + + DestroyWindow(hComboEx); +} + START_TEST(comboex) { if (!init()) return; + init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + test_comboboxex(); test_WM_LBUTTONDOWN(); + test_CB_GETLBTEXT(); + test_comboboxex_subclass(); + test_get_set_item(); cleanup(); } diff --git a/rostests/winetests/comctl32/comctl32.rbuild b/rostests/winetests/comctl32/comctl32.rbuild index 94804620870..d1e44b5de16 100644 --- a/rostests/winetests/comctl32/comctl32.rbuild +++ b/rostests/winetests/comctl32/comctl32.rbuild @@ -4,6 +4,8 @@ . + 0x0600 + 0x0500 comboex.c datetime.c dpa.c @@ -14,7 +16,6 @@ misc.c monthcal.c mru.c - msg.c progress.c propsheet.c rebar.c diff --git a/rostests/winetests/comctl32/comctl32_ros.diff b/rostests/winetests/comctl32/comctl32_ros.diff deleted file mode 100644 index d8b962d3ae0..00000000000 --- a/rostests/winetests/comctl32/comctl32_ros.diff +++ /dev/null @@ -1,37 +0,0 @@ -Index: dpa.c -=================================================================== ---- dpa.c (revision 25766) -+++ dpa.c (working copy) -@@ -25,6 +25,7 @@ - - #include "windef.h" - #include "winbase.h" -+#include "wingdi.h" - #include "winuser.h" - #include "commctrl.h" - #include "objidl.h" -Index: monthcal.c -=================================================================== ---- monthcal.c (revision 25766) -+++ monthcal.c (working copy) -@@ -23,6 +23,7 @@ - - #include "windef.h" - #include "winbase.h" -+#include "wingdi.h" - #include "winuser.h" - - #include "commctrl.h" -Index: mru.c -=================================================================== ---- mru.c (revision 25766) -+++ mru.c (working copy) -@@ -75,7 +75,7 @@ - - - /* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ --static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey) -+static LONG mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey) - { - LONG ret; - DWORD dwMaxSubkeyLen, dwMaxValueLen; diff --git a/rostests/winetests/comctl32/datetime.c b/rostests/winetests/comctl32/datetime.c index 8fdbbe53608..a97ab342dae 100644 --- a/rostests/winetests/comctl32/datetime.c +++ b/rostests/winetests/comctl32/datetime.c @@ -33,113 +33,97 @@ static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; static const struct message test_dtm_set_format_seq[] = { - { DTM_SETFORMATA, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { DTM_SETFORMATA, sent|wparam, 0x00000000 }, + { DTM_SETFORMATA, sent|wparam|lparam, 0, 0 }, + { DTM_SETFORMATA, sent|wparam, 0 }, { 0 } }; static const struct message test_dtm_set_and_get_mccolor_seq[] = { - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00ffffff }, - { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00dcb464 }, - { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(255, 255, 255) }, + { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(100, 180, 220) }, + { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 }, { 0 } }; static const struct message test_dtm_set_and_get_mcfont_seq[] = { - { DTM_SETMCFONT, sent|lparam, 0, 0x00000001 }, - { DTM_GETMCFONT, sent|wparam|lparam, 0x00000000, 0x00000000 }, + { DTM_SETMCFONT, sent|lparam, 0, 1 }, + { DTM_GETMCFONT, sent|wparam|lparam, 0, 0 }, { 0 } }; static const struct message test_dtm_get_monthcal_seq[] = { - { DTM_GETMONTHCAL, sent|wparam|lparam, 0x00000000, 0x00000000 }, + { DTM_GETMONTHCAL, sent|wparam|lparam, 0, 0 }, { 0 } }; static const struct message test_dtm_set_and_get_range_seq[] = { - { DTM_SETRANGE, sent|wparam, 0x00000001 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000002 }, - { DTM_SETRANGE, sent|wparam, 0x00000002 }, - { DTM_GETRANGE, sent|wparam, 0x00000000}, - { DTM_SETRANGE, sent|wparam, 0x00000001 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MAX }, + { DTM_SETRANGE, sent|wparam, GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, { 0 } }; static const struct message test_dtm_set_range_swap_min_max_seq[] = { - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, - { DTM_SETRANGE, sent|wparam, 0x00000003 }, - { DTM_GETRANGE, sent|wparam, 0x00000000 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, + { DTM_GETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, + { DTM_GETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, + { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX }, + { DTM_GETRANGE, sent|wparam, 0 }, { 0 } }; static const struct message test_dtm_set_and_get_system_time_seq[] = { - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 }, - { 0x0090, sent|optional }, /* Vista */ - { WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 }, - { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 }, - { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 }, + { DTM_SETSYSTEMTIME, sent|wparam, GDT_NONE }, + { DTM_GETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, + { DTM_GETSYSTEMTIME, sent|wparam, 0 }, + { DTM_SETSYSTEMTIME, sent|wparam, 0 }, { 0 } }; -static const struct message destroy_window_seq[] = { - { 0x0090, sent|optional }, /* Vista */ - { WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { 0 } -}; - -struct subclass_info -{ - WNDPROC oldproc; -}; - static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -154,21 +138,17 @@ static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wPa add_message(sequences, DATETIME_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } -static HWND create_datetime_control(DWORD style, DWORD exstyle) +static HWND create_datetime_control(DWORD style) { - struct subclass_info *info; + WNDPROC oldproc; HWND hWndDateTime = NULL; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - hWndDateTime = CreateWindowEx(0, DATETIMEPICK_CLASS, NULL, @@ -179,44 +159,47 @@ static HWND create_datetime_control(DWORD style, DWORD exstyle) NULL, NULL); - if (!hWndDateTime) { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!hWndDateTime) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC, - (LONG_PTR)datetime_subclass_proc); - SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC, + (LONG_PTR)datetime_subclass_proc); + SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)oldproc); return hWndDateTime; } -static void test_dtm_set_format(HWND hWndDateTime) +static void test_dtm_set_format(void) { + HWND hWnd; CHAR txt[256]; SYSTEMTIME systime; LRESULT r; - r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, 0); + hWnd = create_datetime_control(DTS_SHOWNONE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + r = SendMessage(hWnd, DTM_SETFORMAT, 0, 0); expect(1, r); - r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, + r = SendMessage(hWnd, DTM_SETFORMAT, 0, (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy"); expect(1, r); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE); - r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, + r = SendMessage(hWnd, DTM_SETFORMAT, 0, (LPARAM)"'hh' hh"); expect(1, r); ZeroMemory(&systime, sizeof(systime)); systime.wYear = 2000; systime.wMonth = systime.wDay = 1; - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime); expect(1, r); - GetWindowText(hWndDateTime, txt, 256); - todo_wine ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + GetWindowText(hWnd, txt, 256); + ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt); + + DestroyWindow(hWnd); } static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name) @@ -239,43 +222,60 @@ static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r); } -static void test_dtm_set_and_get_mccolor(HWND hWndDateTime) +static void test_dtm_set_and_get_mccolor(void) { - test_mccolor_types(hWndDateTime, MCSC_BACKGROUND, "MCSC_BACKGROUND"); - test_mccolor_types(hWndDateTime, MCSC_MONTHBK, "MCSC_MONTHBK"); - test_mccolor_types(hWndDateTime, MCSC_TEXT, "MCSC_TEXT"); - test_mccolor_types(hWndDateTime, MCSC_TITLEBK, "MCSC_TITLEBK"); - test_mccolor_types(hWndDateTime, MCSC_TITLETEXT, "MCSC_TITLETEXT"); - test_mccolor_types(hWndDateTime, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT"); + HWND hWnd; + + hWnd = create_datetime_control(DTS_SHOWNONE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + test_mccolor_types(hWnd, MCSC_BACKGROUND, "MCSC_BACKGROUND"); + test_mccolor_types(hWnd, MCSC_MONTHBK, "MCSC_MONTHBK"); + test_mccolor_types(hWnd, MCSC_TEXT, "MCSC_TEXT"); + test_mccolor_types(hWnd, MCSC_TITLEBK, "MCSC_TITLEBK"); + test_mccolor_types(hWnd, MCSC_TITLETEXT, "MCSC_TITLETEXT"); + test_mccolor_types(hWnd, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT"); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + + DestroyWindow(hWnd); } -static void test_dtm_set_and_get_mcfont(HWND hWndDateTime) +static void test_dtm_set_and_get_mcfont(void) { HFONT hFontOrig, hFontNew; + HWND hWnd; + + hWnd = create_datetime_control(DTS_SHOWNONE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); hFontOrig = GetStockObject(DEFAULT_GUI_FONT); - SendMessage(hWndDateTime, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE); - hFontNew = (HFONT)SendMessage(hWndDateTime, DTM_GETMCFONT, 0, 0); + SendMessage(hWnd, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE); + hFontNew = (HFONT)SendMessage(hWnd, DTM_GETMCFONT, 0, 0); ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(hWnd); } -static void test_dtm_get_monthcal(HWND hWndDateTime) +static void test_dtm_get_monthcal(void) { LRESULT r; + HWND hWnd; + + hWnd = create_datetime_control(DTS_SHOWNONE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); todo_wine { - r = SendMessage(hWndDateTime, DTM_GETMONTHCAL, 0, 0); + r = SendMessage(hWnd, DTM_GETMONTHCAL, 0, 0); ok(r == 0, "Expected NULL(no child month calendar control), got %ld\n", r); } ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(hWnd); } static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds) @@ -318,24 +318,29 @@ static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2) #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n") #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n") -static void test_dtm_set_and_get_range(HWND hWndDateTime) +static void test_dtm_set_and_get_range(void) { LRESULT r; SYSTEMTIME st[2]; SYSTEMTIME getSt[2]; + HWND hWnd; + + hWnd = create_datetime_control(DTS_SHOWNONE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); /* initialize st[0] to lowest possible value */ fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0); /* initialize st[1] to all invalid numbers */ fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == GDTR_MIN, "Expected %x, not %x(GDTR_MAX) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MIN, GDTR_MAX, GDTR_MIN | GDTR_MAX, r); expect_systime(&st[0], &getSt[0]); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st); expect_unsuccess(0, r); /* set st[0] to all invalid numbers */ @@ -343,25 +348,25 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime) /* set st[1] to highest possible value */ fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); todo_wine { ok(r == GDTR_MAX, "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MAX, GDTR_MIN, GDTR_MIN | GDTR_MAX, r); } expect_systime(&st[1], &getSt[1]); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st); expect_unsuccess(0, r); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect_unsuccess(0, r); /* set st[0] to highest possible value */ fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); expect_systime(&st[0], &getSt[0]); expect_systime(&st[1], &getSt[1]); @@ -371,9 +376,9 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime) /* set st[1] to highest possible value */ fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); expect_systime(&st[0], &getSt[0]); expect_systime(&st[1], &getSt[1]); @@ -383,32 +388,37 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime) /* set st[1] to value lower than maximum */ fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); expect_systime(&st[0], &getSt[0]); expect_systime(&st[1], &getSt[1]); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + + DestroyWindow(hWnd); } /* when maxmax, min and max values should be swapped by DTM_SETRANGE automatically */ - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); todo_wine { - expect_systime(&st[0], &getSt[0]); - } - todo_wine { - expect_systime(&st[1], &getSt[1]); + ok(compare_systime(&st[0], &getSt[0]) == 1 || + broken(compare_systime(&st[0], &getSt[1]) == 1), /* comctl32 version <= 5.80 */ + "ST1 != ST2\n"); + + ok(compare_systime(&st[1], &getSt[1]) == 1 || + broken(compare_systime(&st[1], &getSt[0]) == 1), /* comctl32 version <= 5.80 */ + "ST1 != ST2\n"); } fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]); ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r); /* the time part seems to not change after swapping the min and max values and doing DTM_SETSYSTEMTIME */ expect_systime_date(&st[0], &getSt[0]); todo_wine { - expect_systime_time(&origSt, &getSt[0]); + ok(compare_systime_time(&origSt, &getSt[0]) == 1 || + broken(compare_systime_time(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */ + "ST1.time != ST2.time\n"); } /* set st[0] to value higher than minimum */ @@ -447,18 +462,21 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime) /* set st[1] to value lower than maximum */ fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); /* for some reason after we swapped the min and max values before, whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values swapped*/ - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); todo_wine { - expect_systime(&st[0], &getSt[1]); - } - todo_wine { - expect_systime(&st[1], &getSt[0]); + ok(compare_systime(&st[0], &getSt[1]) == 1 || + broken(compare_systime(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */ + "ST1 != ST2\n"); + + ok(compare_systime(&st[1], &getSt[0]) == 1 || + broken(compare_systime(&st[1], &getSt[1]) == 1), /* comctl32 version <= 5.80 */ + "ST1 != ST2\n"); } /* set st[0] to value higher than st[1] */ @@ -467,9 +485,9 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime) /* set min>max again, so that the return values of DTM_GETRANGE are no longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/ - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); expect_systime(&st[0], &getSt[1]); expect_systime(&st[1], &getSt[0]); @@ -479,25 +497,25 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime) /* set st[1] to highest possible value */ fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); + r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt); + r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt); ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r); expect_systime(&st[0], &getSt[0]); expect_systime(&st[1], &getSt[1]); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + + DestroyWindow(hWnd); } -static void test_dtm_set_and_get_system_time(HWND hWndDateTime) +static void test_dtm_set_and_get_system_time(void) { LRESULT r; - SYSTEMTIME st; - SYSTEMTIME getSt; - HWND hWndDateTime_test_gdt_none; + SYSTEMTIME st, getSt, ref; + HWND hWnd, hWndDateTime_test_gdt_none; - hWndDateTime_test_gdt_none = create_datetime_control(0, 0); + hWndDateTime_test_gdt_none = create_datetime_control(0); ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none); if(hWndDateTime_test_gdt_none) { @@ -513,64 +531,175 @@ static void test_dtm_set_and_get_system_time(HWND hWndDateTime) DestroyWindow(hWndDateTime_test_gdt_none); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st); + hWnd = create_datetime_control(DTS_SHOWNONE); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r); /* set st to lowest possible value */ fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); expect(1, r); /* set st to highest possible value */ fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); expect(1, r); /* set st to value between min and max */ fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); expect(1, r); - r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r); expect_systime(&st, &getSt); /* set st to invalid value */ fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000); - r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); expect_unsuccess(0, r); ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* set to some valid value */ + GetSystemTime(&ref); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&ref); + expect(1, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + + /* year invalid */ + st = ref; + st.wYear = 0; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + todo_wine expect(1, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* month invalid */ + st = ref; + st.wMonth = 13; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* day invalid */ + st = ref; + st.wDay = 32; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* day of week isn't validated */ + st = ref; + st.wDayOfWeek = 10; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(1, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* hour invalid */ + st = ref; + st.wHour = 25; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* minute invalid */ + st = ref; + st.wMinute = 60; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* sec invalid */ + st = ref; + st.wSecond = 60; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + /* msec invalid */ + st = ref; + st.wMilliseconds = 1000; + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(0, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + expect_systime(&ref, &getSt); + + /* day of week should be calculated automatically, + actual day of week for this date is 4 */ + fill_systime_struct(&st, 2009, 10, 1, 1, 0, 0, 10, 200); + r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st); + expect(1, r); + r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); + expect(GDT_VALID, r); + /* 01.10.2009 is Thursday */ + expect(4, (LRESULT)getSt.wDayOfWeek); + st.wDayOfWeek = 4; + expect_systime(&st, &getSt); + + DestroyWindow(hWnd); } -static void test_datetime_control(void) +static void test_wm_set_get_text(void) { - HWND hWndDateTime; + static const CHAR a_str[] = "a"; + char buff[16], time[16]; + HWND hWnd; + LRESULT ret; - hWndDateTime = create_datetime_control(DTS_SHOWNONE, 0); + hWnd = create_datetime_control(0); - ok(hWndDateTime != NULL, "Expected non NULL, got %p\n", hWndDateTime); - if(hWndDateTime!=NULL) { - test_dtm_set_format(hWndDateTime); - test_dtm_set_and_get_mccolor(hWndDateTime); - test_dtm_set_and_get_mcfont(hWndDateTime); - test_dtm_get_monthcal(hWndDateTime); - test_dtm_set_and_get_range(hWndDateTime); - test_dtm_set_range_swap_min_max(hWndDateTime); - test_dtm_set_and_get_system_time(hWndDateTime); - } - else { - skip("hWndDateTime is NULL\n"); - } + ret = SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)a_str); + ok(CB_ERR == ret || + broken(0 == ret) || /* comctl32 <= 4.72 */ + broken(1 == ret), /* comctl32 <= 4.70 */ + "Expected CB_ERR, got %ld\n", ret); - DestroyWindow(hWndDateTime); - ok_sequence(sequences, DATETIME_SEQ_INDEX, destroy_window_seq, "test_dtm_set_and_get_system_time", TRUE); + buff[0] = 0; + ret = SendMessage(hWnd, WM_GETTEXT, sizeof(buff), (LPARAM)buff); + ok(strcmp(buff, a_str) != 0, "Expected text not to change, got %s\n", buff); + + GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time)); + ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff); + + DestroyWindow(hWnd); +} + +static void test_dts_shownone(void) +{ + HWND hwnd; + DWORD style; + + /* it isn't allowed to change DTS_SHOWNONE after creation */ + hwnd = create_datetime_control(0); + style = GetWindowLong(hwnd, GWL_STYLE); + SetWindowLong(hwnd, GWL_STYLE, style | DTS_SHOWNONE); + style = GetWindowLong(hwnd, GWL_STYLE); + ok(!(style & DTS_SHOWNONE), "Expected DTS_SHOWNONE not to be set\n"); + DestroyWindow(hwnd); + + hwnd = create_datetime_control(DTS_SHOWNONE); + style = GetWindowLong(hwnd, GWL_STYLE); + SetWindowLong(hwnd, GWL_STYLE, style & ~DTS_SHOWNONE); + style = GetWindowLong(hwnd, GWL_STYLE); + ok(style & DTS_SHOWNONE, "Expected DTS_SHOWNONE to be set\n"); + DestroyWindow(hwnd); } START_TEST(datetime) @@ -592,5 +721,13 @@ START_TEST(datetime) init_msg_sequences(sequences, NUM_MSG_SEQUENCES); - test_datetime_control(); + test_dtm_set_format(); + test_dtm_set_and_get_mccolor(); + test_dtm_set_and_get_mcfont(); + test_dtm_get_monthcal(); + test_dtm_set_and_get_range(); + test_dtm_set_range_swap_min_max(); + test_dtm_set_and_get_system_time(); + test_wm_set_get_text(); + test_dts_shownone(); } diff --git a/rostests/winetests/comctl32/dpa.c b/rostests/winetests/comctl32/dpa.c index 221bcba1678..419c1b14d0e 100644 --- a/rostests/winetests/comctl32/dpa.c +++ b/rostests/winetests/comctl32/dpa.c @@ -31,17 +31,14 @@ #include "wine/test.h" -#define DPAM_NOSORT 0x1 -#define DPAM_INSERT 0x4 -#define DPAM_DELETE 0x8 +#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) -typedef struct _ITEMDATA +typedef struct _STREAMDATA { - INT iPos; - PVOID pvData; -} ITEMDATA, *LPITEMDATA; - -typedef HRESULT (CALLBACK *PFNDPASTM)(LPITEMDATA,IStream*,LPARAM); + DWORD dwSize; + DWORD dwData2; + DWORD dwItems; +} STREAMDATA, *PSTREAMDATA; static HDPA (WINAPI *pDPA_Clone)(const HDPA,const HDPA); static HDPA (WINAPI *pDPA_Create)(INT); @@ -55,9 +52,9 @@ static INT (WINAPI *pDPA_GetPtr)(const HDPA,INT); static INT (WINAPI *pDPA_GetPtrIndex)(const HDPA,PVOID); static BOOL (WINAPI *pDPA_Grow)(HDPA,INT); static INT (WINAPI *pDPA_InsertPtr)(const HDPA,INT,PVOID); -static HRESULT (WINAPI *pDPA_LoadStream)(HDPA*,PFNDPASTM,IStream*,LPARAM); +static HRESULT (WINAPI *pDPA_LoadStream)(HDPA*,PFNDPASTREAM,IStream*,LPVOID); static BOOL (WINAPI *pDPA_Merge)(const HDPA,const HDPA,DWORD,PFNDPACOMPARE,PFNDPAMERGE,LPARAM); -static HRESULT (WINAPI *pDPA_SaveStream)(HDPA,PFNDPASTM,IStream*,LPARAM); +static HRESULT (WINAPI *pDPA_SaveStream)(HDPA,PFNDPASTREAM,IStream*,LPVOID); static INT (WINAPI *pDPA_Search)(HDPA,PVOID,INT,PFNDPACOMPARE,LPARAM,UINT); static BOOL (WINAPI *pDPA_SetPtr)(const HDPA,INT,PVOID); static BOOL (WINAPI *pDPA_Sort)(const HDPA,PFNDPACOMPARE,LPARAM); @@ -109,14 +106,22 @@ static INT CALLBACK CB_CmpGT(PVOID p1, PVOID p2, LPARAM lp) return p1 > p2 ? -1 : p1 < p2 ? 1 : 0; } +/* merge callback messages counter + DPAMM_MERGE 1 + DPAMM_DELETE 2 + DPAMM_INSERT 3 */ +static INT nMessages[4]; + static PVOID CALLBACK CB_MergeInsertSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp) { + nMessages[op]++; ok(lp == 0xdeadbeef, "lp=%ld\n", lp); return p1; } static PVOID CALLBACK CB_MergeDeleteOddSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp) { + nMessages[op]++; ok(lp == 0xdeadbeef, "lp=%ld\n", lp); return ((PCHAR)p2)+1; } @@ -134,30 +139,30 @@ static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp) return pItem != (PVOID)3; } -static HRESULT CALLBACK CB_Save(LPITEMDATA pInfo, IStream *pStm, LPARAM lp) +static HRESULT CALLBACK CB_Save(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp) { HRESULT hRes; - - ok(lp == 0xdeadbeef, "lp=%ld\n", lp); + + ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp); hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - hRes = IStream_Write(pStm, &pInfo->pvData, sizeof(PVOID), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); + hRes = IStream_Write(pStm, &pInfo->pvItem, sizeof(PVOID), NULL); + expect(S_OK, hRes); return S_OK; } -static HRESULT CALLBACK CB_Load(LPITEMDATA pInfo, IStream *pStm, LPARAM lp) +static HRESULT CALLBACK CB_Load(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp) { HRESULT hRes; INT iOldPos; iOldPos = pInfo->iPos; - ok(lp == 0xdeadbeef, "lp=%ld\n", lp); + ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp); hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); ok(pInfo->iPos == iOldPos, "iPos=%d iOldPos=%d\n", pInfo->iPos, iOldPos); - hRes = IStream_Read(pStm, &pInfo->pvData, sizeof(PVOID), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + hRes = IStream_Read(pStm, &pInfo->pvItem, sizeof(PVOID), NULL); + expect(S_OK, hRes); return S_OK; } @@ -200,7 +205,6 @@ static void test_dpa(void) INT ret, i; PVOID p; DWORD dw, dw2, dw3; - HRESULT hRes; BOOL rc; GetSystemInfo(&si); @@ -209,9 +213,9 @@ static void test_dpa(void) dpa3 = pDPA_CreateEx(0, hHeap); ok(dpa3 != NULL, "\n"); ret = pDPA_Grow(dpa3, si.dwPageSize + 1); - todo_wine ok(!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY, + ok(!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "ret=%d error=%d\n", ret, GetLastError()); - + dpa = pDPA_Create(0); ok(dpa != NULL, "\n"); @@ -288,9 +292,9 @@ static void test_dpa(void) ok(j == DPA_ERR, "j=%d\n", j); /* ... but for a binary search it's ignored */ j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, i+1, CB_CmpLT, 0xdeadbeef, DPAS_SORTED); - todo_wine ok(j+1 == i, "j=%d i=%d\n", j, i); + ok(j+1 == i, "j=%d i=%d\n", j, i); } - + /* Try to get the index of a nonexistent item */ i = pDPA_GetPtrIndex(dpa, (PVOID)7); ok(i == DPA_ERR, "i=%d\n", i); @@ -335,49 +339,6 @@ static void test_dpa(void) ok(j != i, "i=%d\n", i); } - if(pDPA_Merge) - { - /* Delete all even entries from dpa */ - p = pDPA_DeletePtr(dpa, 1); - p = pDPA_DeletePtr(dpa, 2); - p = pDPA_DeletePtr(dpa, 3); - rc=CheckDPA(dpa, 0x135, &dw); - ok(rc, "dw=0x%x\n", dw); - - /* Delete all odd entries from dpa2 */ - pDPA_Merge(dpa2, dpa, DPAM_DELETE, - CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef); - todo_wine - { - rc=CheckDPA(dpa2, 0x246, &dw2); - ok(rc, "dw=0x%x\n", dw2); - } - - /* Merge dpa3 into dpa2 and dpa */ - pDPA_Merge(dpa, dpa3, DPAM_INSERT|DPAM_NOSORT, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); - pDPA_Merge(dpa2, dpa3, DPAM_INSERT|DPAM_NOSORT, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); - - rc=CheckDPA(dpa, 0x123456, &dw); - ok(rc, "dw=0x%x\n", dw); - rc=CheckDPA(dpa2, 0x123456, &dw2); - ok(rc || - broken(!rc), /* win98 */ - "dw2=0x%x\n", dw2); - rc=CheckDPA(dpa3, 0x123456, &dw3); - ok(rc, "dw3=0x%x\n", dw3); - } - - if(pDPA_EnumCallback) - { - nEnum = 0; - pDPA_EnumCallback(dpa2, CB_EnumFirstThree, dpa2); - rc=CheckDPA(dpa2, 0x777456, &dw2); - ok(rc, "dw=0x%x\n", dw2); - ok(nEnum == 3, "nEnum=%d\n", nEnum); - } - /* Setting item with huge index should work */ ok(pDPA_SetPtr(dpa2, 0x12345, (PVOID)0xdeadbeef), "\n"); ret = pDPA_GetPtrIndex(dpa2, (PVOID)0xdeadbeef); @@ -386,62 +347,397 @@ static void test_dpa(void) pDPA_DeleteAllPtrs(dpa2); rc=CheckDPA(dpa2, 0, &dw2); ok(rc, "dw2=0x%x\n", dw2); + + pDPA_Destroy(dpa); pDPA_Destroy(dpa2); + pDPA_Destroy(dpa3); +} - if(pDPA_DestroyCallback) +static void test_DPA_Merge(void) +{ + HDPA dpa, dpa2, dpa3; + INT ret, i; + DWORD dw; + BOOL rc; + + if(!pDPA_Merge) { - nEnum = 0; - pDPA_DestroyCallback(dpa3, CB_EnumFirstThree, dpa3); - ok(nEnum == 3, "nEnum=%d\n", nEnum); + win_skip("DPA_Merge() not available\n"); + return; } - else pDPA_Destroy(dpa3); - if(!pDPA_SaveStream) - goto skip_stream_tests; + dpa = pDPA_Create(0); + dpa2 = pDPA_Create(0); + dpa3 = pDPA_Create(0); + + ret = pDPA_InsertPtr(dpa, 0, (PVOID)1); + ok(ret == 0, "ret=%d\n", ret); + ret = pDPA_InsertPtr(dpa, 1, (PVOID)3); + ok(ret == 1, "ret=%d\n", ret); + ret = pDPA_InsertPtr(dpa, 2, (PVOID)5); + ok(ret == 2, "ret=%d\n", ret); + + rc = CheckDPA(dpa, 0x135, &dw); + ok(rc, "dw=0x%x\n", dw); + + for (i = 0; i < 6; i++) + { + ret = pDPA_InsertPtr(dpa2, i, (PVOID)(INT_PTR)(6-i)); + ok(ret == i, "ret=%d\n", ret); + ret = pDPA_InsertPtr(dpa3, i, (PVOID)(INT_PTR)(i+1)); + ok(ret == i, "ret=%d\n", ret); + } + + rc = CheckDPA(dpa2, 0x654321, &dw); + ok(rc, "dw=0x%x\n", dw); + rc = CheckDPA(dpa3, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); + + /* Delete all odd entries from dpa2 */ + memset(nMessages, 0, sizeof(nMessages)); + pDPA_Merge(dpa2, dpa, DPAM_INTERSECT, + CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef); + rc = CheckDPA(dpa2, 0x246, &dw); + ok(rc, "dw=0x%x\n", dw); + + expect(3, nMessages[DPAMM_MERGE]); + expect(3, nMessages[DPAMM_DELETE]); + expect(0, nMessages[DPAMM_INSERT]); + + for (i = 0; i < 6; i++) + { + ret = pDPA_InsertPtr(dpa2, i, (PVOID)(INT_PTR)(6-i)); + ok(ret == i, "ret=%d\n", ret); + } + + /* DPAM_INTERSECT - returning source while merging */ + memset(nMessages, 0, sizeof(nMessages)); + pDPA_Merge(dpa2, dpa, DPAM_INTERSECT, + CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + rc = CheckDPA(dpa2, 0x135, &dw); + ok(rc, "dw=0x%x\n", dw); + + expect(3, nMessages[DPAMM_MERGE]); + expect(6, nMessages[DPAMM_DELETE]); + expect(0, nMessages[DPAMM_INSERT]); + + /* DPAM_UNION */ + pDPA_DeleteAllPtrs(dpa); + pDPA_InsertPtr(dpa, 0, (PVOID)1); + pDPA_InsertPtr(dpa, 1, (PVOID)3); + pDPA_InsertPtr(dpa, 2, (PVOID)5); + pDPA_DeleteAllPtrs(dpa2); + pDPA_InsertPtr(dpa2, 0, (PVOID)2); + pDPA_InsertPtr(dpa2, 1, (PVOID)4); + pDPA_InsertPtr(dpa2, 2, (PVOID)6); + + memset(nMessages, 0, sizeof(nMessages)); + pDPA_Merge(dpa2, dpa, DPAM_UNION, + CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + rc = CheckDPA(dpa2, 0x123456, &dw); + ok(rc || + broken(!rc && dw == 0x23456), /* 4.7x */ + "dw=0x%x\n", dw); + + expect(0, nMessages[DPAMM_MERGE]); + expect(0, nMessages[DPAMM_DELETE]); + ok(nMessages[DPAMM_INSERT] == 3 || + broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */ + "Expected 3, got %d\n", nMessages[DPAMM_INSERT]); + + /* Merge dpa3 into dpa2 and dpa */ + memset(nMessages, 0, sizeof(nMessages)); + pDPA_Merge(dpa, dpa3, DPAM_UNION|DPAM_SORTED, + CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + expect(3, nMessages[DPAMM_MERGE]); + expect(0, nMessages[DPAMM_DELETE]); + expect(3, nMessages[DPAMM_INSERT]); + + + pDPA_DeleteAllPtrs(dpa2); + pDPA_InsertPtr(dpa2, 0, (PVOID)2); + pDPA_InsertPtr(dpa2, 1, (PVOID)4); + pDPA_InsertPtr(dpa2, 2, (PVOID)6); + + memset(nMessages, 0, sizeof(nMessages)); + pDPA_Merge(dpa2, dpa3, DPAM_UNION|DPAM_SORTED, + CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + expect(3, nMessages[DPAMM_MERGE]); + expect(0, nMessages[DPAMM_DELETE]); + ok(nMessages[DPAMM_INSERT] == 3 || + broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */ + "Expected 3, got %d\n", nMessages[DPAMM_INSERT]); + + rc = CheckDPA(dpa, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); + rc = CheckDPA(dpa2, 0x123456, &dw); + ok(rc || + broken(!rc), /* win98 */ + "dw=0x%x\n", dw); + rc = CheckDPA(dpa3, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); + + pDPA_Destroy(dpa); + pDPA_Destroy(dpa2); + pDPA_Destroy(dpa3); +} + +static void test_DPA_EnumCallback(void) +{ + HDPA dpa; + BOOL rc; + DWORD dw; + INT i, ret; + + if(!pDPA_EnumCallback) + { + win_skip("DPA_EnumCallback() not available\n"); + return; + } + + dpa = pDPA_Create(0); + + for (i = 0; i < 6; i++) + { + ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1)); + ok(ret == i, "ret=%d\n", ret); + } + + rc = CheckDPA(dpa, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); + + nEnum = 0; + /* test callback sets first 3 items to 7 */ + pDPA_EnumCallback(dpa, CB_EnumFirstThree, dpa); + rc = CheckDPA(dpa, 0x777456, &dw); + ok(rc, "dw=0x%x\n", dw); + ok(nEnum == 3, "nEnum=%d\n", nEnum); + + pDPA_Destroy(dpa); +} + +static void test_DPA_DestroyCallback(void) +{ + HDPA dpa; + INT i, ret; + + if(!pDPA_DestroyCallback) + { + win_skip("DPA_DestroyCallback() not available\n"); + return; + } + + dpa = pDPA_Create(0); + + for (i = 0; i < 3; i++) + { + ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1)); + ok(ret == i, "ret=%d\n", ret); + } + + nEnum = 0; + pDPA_DestroyCallback(dpa, CB_EnumFirstThree, dpa); + ok(nEnum == 3, "nEnum=%d\n", nEnum); +} + +static void test_DPA_LoadStream(void) +{ + static const WCHAR szStg[] = { 'S','t','g',0 }; + IStorage* pStg = NULL; + IStream* pStm = NULL; + LARGE_INTEGER li; + ULARGE_INTEGER uli; + DWORD dwMode; + HRESULT hRes; + STREAMDATA header; + ULONG written, ret; + HDPA dpa; + + if(!pDPA_LoadStream) + { + win_skip("DPA_LoadStream() not available. Skipping stream tests.\n"); + return; + } hRes = CoInitialize(NULL); - if(hRes == S_OK) + if (hRes != S_OK) { - static const WCHAR szStg[] = { 'S','t','g',0 }; - IStorage* pStg = NULL; - IStream* pStm = NULL; - LARGE_INTEGER liZero; - DWORD dwMode; - liZero.QuadPart = 0; - - dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE; - hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - - hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - - hRes = pDPA_SaveStream(dpa, CB_Save, pStm, 0xdeadbeef); - todo_wine ok(hRes == S_OK, "hRes=0x%x\n", hRes); - pDPA_Destroy(dpa); - - hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, 0xdeadbeef); - todo_wine - { - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - rc=CheckDPA(dpa, 0x123456, &dw); - ok(rc, "dw=0x%x\n", dw); - } - - ret = IStream_Release(pStm); - ok(!ret, "ret=%d\n", ret); - - ret = IStorage_Release(pStg); - ok(!ret, "ret=%d\n", ret); - - CoUninitialize(); + ok(0, "hResult: %d\n", hRes); + return; } - else ok(0, "hResult: %d\n", hRes); -skip_stream_tests: + dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE; + hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg); + expect(S_OK, hRes); + + hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm); + expect(S_OK, hRes); + + /* write less than header size */ + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + memset(&header, 0, sizeof(header)); + written = 0; + uli.QuadPart = sizeof(header)-1; + hRes = IStream_SetSize(pStm, uli); + expect(S_OK, hRes); + hRes = IStream_Write(pStm, &header, sizeof(header)-1, &written); + expect(S_OK, hRes); + written -= sizeof(header)-1; + expect(0, written); + + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL); + expect(E_FAIL, hRes); + + /* check stream position after header read failed */ + li.QuadPart = 0; + uli.QuadPart = 1; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_CUR, &uli); + expect(S_OK, hRes); + ok(uli.QuadPart == 0, "Expected to position reset\n"); + + /* write valid header for empty DPA */ + header.dwSize = sizeof(header); + header.dwData2 = 1; + header.dwItems = 0; + written = 0; + + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + uli.QuadPart = sizeof(header); + hRes = IStream_SetSize(pStm, uli); + expect(S_OK, hRes); + + hRes = IStream_Write(pStm, &header, sizeof(header), &written); + expect(S_OK, hRes); + written -= sizeof(header); + expect(0, written); + + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + dpa = NULL; + hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL); + expect(S_OK, hRes); + DPA_Destroy(dpa); + + /* try with altered dwData2 field */ + header.dwSize = sizeof(header); + header.dwData2 = 2; + header.dwItems = 0; + + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + hRes = IStream_Write(pStm, &header, sizeof(header), &written); + expect(S_OK, hRes); + written -= sizeof(header); + expect(0, written); + + li.QuadPart = 0; + hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef); + expect(E_FAIL, hRes); + + ret = IStream_Release(pStm); + ok(!ret, "ret=%d\n", ret); + + ret = IStorage_Release(pStg); + ok(!ret, "ret=%d\n", ret); + + CoUninitialize(); +} + +static void test_DPA_SaveStream(void) +{ + HDPA dpa; + static const WCHAR szStg[] = { 'S','t','g',0 }; + IStorage* pStg = NULL; + IStream* pStm = NULL; + DWORD dwMode, dw; + HRESULT hRes; + ULONG ret; + INT i; + BOOL rc; + LARGE_INTEGER liZero; + + if(!pDPA_SaveStream) + { + win_skip("DPA_SaveStream() not available. Skipping stream tests.\n"); + return; + } + + hRes = CoInitialize(NULL); + if (hRes != S_OK) + { + ok(0, "hResult: %d\n", hRes); + return; + } + + dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE; + hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg); + expect(S_OK, hRes); + + hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm); + expect(S_OK, hRes); + + dpa = pDPA_Create(0); + + /* simple parameter check */ + hRes = pDPA_SaveStream(dpa, NULL, pStm, NULL); + ok(hRes == E_INVALIDARG || + broken(hRes == S_OK) /* XP and below */, "Wrong result, %d\n", hRes); +if (0) { + /* crashes on XP */ + hRes = pDPA_SaveStream(NULL, CB_Save, pStm, NULL); + expect(E_INVALIDARG, hRes); + + hRes = pDPA_SaveStream(dpa, CB_Save, NULL, NULL); + expect(E_INVALIDARG, hRes); +} + + /* saving/loading */ + for (i = 0; i < 6; i++) + { + ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1)); + ok(ret == i, "ret=%d\n", ret); + } + + liZero.QuadPart = 0; + hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + + hRes = pDPA_SaveStream(dpa, CB_Save, pStm, (void*)0xdeadbeef); + expect(S_OK, hRes); pDPA_Destroy(dpa); + + liZero.QuadPart = 0; + hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL); + expect(S_OK, hRes); + hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef); + expect(S_OK, hRes); + rc = CheckDPA(dpa, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); + pDPA_Destroy(dpa); + + ret = IStream_Release(pStm); + ok(!ret, "ret=%d\n", ret); + + ret = IStorage_Release(pStg); + ok(!ret, "ret=%d\n", ret); + + CoUninitialize(); } START_TEST(dpa) @@ -450,8 +746,16 @@ START_TEST(dpa) hcomctl32 = GetModuleHandleA("comctl32.dll"); - if(InitFunctionPtrs(hcomctl32)) - test_dpa(); - else + if(!InitFunctionPtrs(hcomctl32)) + { win_skip("Needed functions are not available\n"); + return; + } + + test_dpa(); + test_DPA_Merge(); + test_DPA_EnumCallback(); + test_DPA_DestroyCallback(); + test_DPA_LoadStream(); + test_DPA_SaveStream(); } diff --git a/rostests/winetests/comctl32/header.c b/rostests/winetests/comctl32/header.c index 76612530c98..d9b4a7329ff 100644 --- a/rostests/winetests/comctl32/header.c +++ b/rostests/winetests/comctl32/header.c @@ -24,6 +24,7 @@ #include #include "wine/test.h" +#include "v6util.h" #include "msg.h" typedef struct tagEXPECTEDNOTIFY @@ -121,7 +122,6 @@ static const struct message deleteItem_getItemCount_seq[] = { }; static const struct message orderArray_seq[] = { - { HDM_GETITEMCOUNT, sent }, { HDM_SETORDERARRAY, sent|wparam, 2 }, { HDM_GETORDERARRAY, sent|wparam, 2 }, { 0 } @@ -244,7 +244,7 @@ static LONG addItem(HWND hdex, int idx, LPSTR text) hdItem.cxy = 100; hdItem.pszText = text; hdItem.cchTextMax = 0; - return (LONG)SendMessage(hdex, HDM_INSERTITEMA, (WPARAM)idx, (LPARAM)&hdItem); + return SendMessage(hdex, HDM_INSERTITEMA, idx, (LPARAM)&hdItem); } static LONG setItem(HWND hdex, int idx, LPSTR text, BOOL fCheckNotifies) @@ -259,7 +259,7 @@ static LONG setItem(HWND hdex, int idx, LPSTR text, BOOL fCheckNotifies) expect_notify(HDN_ITEMCHANGINGA, FALSE, &hdexItem); expect_notify(HDN_ITEMCHANGEDA, FALSE, &hdexItem); } - ret = (LONG)SendMessage(hdex, HDM_SETITEMA, (WPARAM)idx, (LPARAM)&hdexItem); + ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem); if (fCheckNotifies) ok(notifies_received(), "setItem(): not all expected notifies were received\n"); return ret; @@ -279,19 +279,19 @@ static LONG setItemUnicodeNotify(HWND hdex, int idx, LPSTR text, LPWSTR wText) expect_notify(HDN_ITEMCHANGINGW, TRUE, (HDITEMA*)&hdexNotify); expect_notify(HDN_ITEMCHANGEDW, TRUE, (HDITEMA*)&hdexNotify); - ret = (LONG)SendMessage(hdex, HDM_SETITEMA, (WPARAM)idx, (LPARAM)&hdexItem); + ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem); ok(notifies_received(), "setItemUnicodeNotify(): not all expected notifies were received\n"); return ret; } static LONG delItem(HWND hdex, int idx) { - return (LONG)SendMessage(hdex, HDM_DELETEITEM, (WPARAM)idx, 0); + return SendMessage(hdex, HDM_DELETEITEM, idx, 0); } static LONG getItemCount(HWND hdex) { - return (LONG)SendMessage(hdex, HDM_GETITEMCOUNT, 0, 0); + return SendMessage(hdex, HDM_GETITEMCOUNT, 0, 0); } static LONG getItem(HWND hdex, int idx, LPSTR textBuffer) @@ -300,7 +300,7 @@ static LONG getItem(HWND hdex, int idx, LPSTR textBuffer) hdItem.mask = HDI_TEXT; hdItem.pszText = textBuffer; hdItem.cchTextMax = MAX_CHARS; - return (LONG)SendMessage(hdex, HDM_GETITEMA, (WPARAM)idx, (LPARAM)&hdItem); + return SendMessage(hdex, HDM_GETITEMA, idx, (LPARAM)&hdItem); } static void addReadDelItem(HWND hdex, HDITEMA *phdiCreate, int maskRead, HDITEMA *phdiRead) @@ -396,14 +396,9 @@ static WCHAR pszUniTestW[] = {'T','S','T',0}; ok(res == i, "Got Item Count as %d\n", res);\ } -struct subclass_info -{ - WNDPROC oldproc; -}; - static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -417,7 +412,7 @@ static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wPara add_message(sequences, HEADER_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; @@ -487,7 +482,7 @@ static HWND create_custom_parent_window(void) static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems) { - struct subclass_info *info; + WNDPROC oldproc; HWND childHandle; HDLAYOUT hlayout; RECT rectwin; @@ -505,9 +500,6 @@ static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems) flush_sequences(sequences, NUM_MSG_SEQUENCES); - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; childHandle = CreateWindowEx(0, WC_HEADER, NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ, @@ -534,9 +526,9 @@ static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems) SetWindowPos(childHandle, winpos.hwndInsertAfter, winpos.x, winpos.y, winpos.cx, winpos.cy, 0); - info->oldproc = (WNDPROC)SetWindowLongPtrA(childHandle, GWLP_WNDPROC, - (LONG_PTR)header_subclass_proc); - SetWindowLongPtrA(childHandle, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(childHandle, GWLP_WNDPROC, + (LONG_PTR)header_subclass_proc); + SetWindowLongPtrA(childHandle, GWLP_USERDATA, (LONG_PTR)oldproc); return childHandle; } @@ -756,10 +748,10 @@ static void test_header_control (void) TEST_GET_ITEM(i, 4); TEST_GET_ITEMCOUNT(6); } - - SendMessageA(hWndHeader, HDM_SETUNICODEFORMAT, (WPARAM)TRUE, 0); + + SendMessageA(hWndHeader, HDM_SETUNICODEFORMAT, TRUE, 0); setItemUnicodeNotify(hWndHeader, 3, pszUniTestA, pszUniTestW); - SendMessageA(hWndHeader, WM_NOTIFYFORMAT, (WPARAM)hHeaderParentWnd, (LPARAM)NF_REQUERY); + SendMessageA(hWndHeader, WM_NOTIFYFORMAT, (WPARAM)hHeaderParentWnd, NF_REQUERY); setItem(hWndHeader, 3, str_items[4], TRUE); dont_expect_notify(HDN_GETDISPINFOA); @@ -820,10 +812,8 @@ static void test_hdm_getitemrect(HWND hParent) expect(80, rect.left); expect(0, rect.top); expect(160, rect.right); - todo_wine - { - expect(g_customheight, rect.bottom); - } + expect(g_customheight, rect.bottom); + retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect); ok(retVal == TRUE, "Getting item rect should TRUE, got %d\n", retVal); @@ -832,10 +822,8 @@ static void test_hdm_getitemrect(HWND hParent) expect(0, rect.top); expect(80, rect.right); - todo_wine - { - expect(g_customheight, rect.bottom); - } + expect(g_customheight, rect.bottom); + retVal = SendMessage(hChild, HDM_GETITEMRECT, 10, (LPARAM) &rect); ok(retVal == 0, "Getting rect of nonexistent item should return 0, got %d\n", retVal); @@ -907,30 +895,25 @@ static void test_hdm_hittest(HWND hParent) flush_sequences(sequences, NUM_MSG_SEQUENCES); retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo); - todo_wine - { - expect(0, retVal); - expect(0, hdHitTestInfo.iItem); - } + expect(0, retVal); + expect(0, hdHitTestInfo.iItem); + expect(HHT_ONDIVIDER, hdHitTestInfo.flags); pt.x = secondItemRightBoundary - 1; pt.y = bottomBoundary - 1; hdHitTestInfo.pt = pt; retVal = SendMessage(hChild, HDM_HITTEST, 1, (LPARAM) &hdHitTestInfo); - todo_wine - { - expect(1, retVal); - } + expect(1, retVal); expect(1, hdHitTestInfo.iItem); + expect(HHT_ONDIVIDER, hdHitTestInfo.flags); pt.x = secondItemRightBoundary; pt.y = bottomBoundary + 1; hdHitTestInfo.pt = pt; - todo_wine - { - retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo); - expect(-1, retVal); - } + retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo); + expect(-1, retVal); + expect(-1, hdHitTestInfo.iItem); + expect(HHT_BELOW, hdHitTestInfo.flags); ok_sequence(sequences, HEADER_SEQ_INDEX, hittest_seq, "hittest sequence testing", FALSE); @@ -951,11 +934,9 @@ static void test_hdm_sethotdivider(HWND hParent) "adder header control to parent", FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); - todo_wine - { - retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, TRUE, 0X00050005); - expect(0, retVal); - } + retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, TRUE, MAKELPARAM(5, 5)); + expect(0, retVal); + retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 100); expect(100, retVal); retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 1); @@ -973,7 +954,7 @@ static void test_hdm_sethotdivider(HWND hParent) static void test_hdm_imageMessages(HWND hParent) { HIMAGELIST hImageList = ImageList_Create (4, 4, 0, 1, 0); - HIMAGELIST hImageListRetVal; + HIMAGELIST hIml; HWND hChild; flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -983,14 +964,15 @@ static void test_hdm_imageMessages(HWND hParent) flush_sequences(sequences, NUM_MSG_SEQUENCES); - hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_SETIMAGELIST, 0, (LPARAM) hImageList); - ok(hImageListRetVal == NULL, "Expected NULL, got %p\n", hImageListRetVal); + hIml = (HIMAGELIST) SendMessage(hChild, HDM_SETIMAGELIST, 0, (LPARAM) hImageList); + ok(hIml == NULL, "Expected NULL, got %p\n", hIml); - hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_GETIMAGELIST, 0, 0); - ok(hImageListRetVal != NULL, "Expected non-NULL handle, got %p\n", hImageListRetVal); + hIml = (HIMAGELIST) SendMessage(hChild, HDM_GETIMAGELIST, 0, 0); + ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml); - hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_CREATEDRAGIMAGE, 0, 0); - ok(hImageListRetVal != NULL, "Expected non-NULL handle, got %p\n", hImageListRetVal); + hIml = (HIMAGELIST) SendMessage(hChild, HDM_CREATEDRAGIMAGE, 0, 0); + ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml); + ImageList_Destroy(hIml); ok_sequence(sequences, HEADER_SEQ_INDEX, imageMessages_seq, "imageMessages sequence testing", FALSE); @@ -1025,9 +1007,16 @@ static void test_hdm_filterMessages(HWND hParent) todo_wine { retVal = SendMessage(hChild, HDM_CLEARFILTER, 0, 1); - expect(1, retVal); + if (retVal == 0) + win_skip("HDM_CLEARFILTER needs 5.80\n"); + else + expect(1, retVal); + retVal = SendMessage(hChild, HDM_EDITFILTER, 1, 0); - expect(1, retVal); + if (retVal == 0) + win_skip("HDM_EDITFILTER needs 5.80\n"); + else + expect(1, retVal); } if (winetest_interactive) ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_interactive, @@ -1076,7 +1065,10 @@ static void test_hdm_bitmapmarginMessages(HWND hParent) flush_sequences(sequences, NUM_MSG_SEQUENCES); retVal = SendMessage(hChild, HDM_GETBITMAPMARGIN, 0, 0); - expect(6, retVal); + if (retVal == 0) + win_skip("HDM_GETBITMAPMARGIN needs 5.80\n"); + else + expect(6, retVal); ok_sequence(sequences, HEADER_SEQ_INDEX, bitmapmarginMessages_seq, "bitmapmarginMessages sequence testing", FALSE); @@ -1085,7 +1077,6 @@ static void test_hdm_bitmapmarginMessages(HWND hParent) static void test_hdm_index_messages(HWND hParent) { - HWND hChild; int retVal; int loopcnt; @@ -1098,6 +1089,7 @@ static void test_hdm_index_messages(HWND hParent) static char thirdHeaderItem[] = "Type"; static char fourthHeaderItem[] = "Date Modified"; static char *items[] = {firstHeaderItem, secondHeaderItem, thirdHeaderItem, fourthHeaderItem}; + RECT rect; HDITEM hdItem; hdItem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT; hdItem.fmt = HDF_LEFT; @@ -1125,17 +1117,17 @@ static void test_hdm_index_messages(HWND hParent) retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem); ok(retVal == TRUE, "Deleting item 3 should return TRUE, got %d\n", retVal); - retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem); + retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0); ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal); retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem); ok(retVal == FALSE, "Deleting already-deleted item should return FALSE, got %d\n", retVal); - retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem); + retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0); ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal); retVal = SendMessage(hChild, HDM_DELETEITEM, 2, (LPARAM) &hdItem); ok(retVal == TRUE, "Deleting item 2 should return TRUE, got %d\n", retVal); - retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem); + retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0); ok(retVal == 2, "Getting item count should return 2, got %d\n", retVal); ok_sequence(sequences, HEADER_SEQ_INDEX, deleteItem_getItemCount_seq, @@ -1156,9 +1148,19 @@ static void test_hdm_index_messages(HWND hParent) expect(0, strcmpResult); expect(80, hdItem.cxy); + iSize = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0); + + /* item should be updated just after accepting new array */ + ShowWindow(hChild, SW_HIDE); + retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray); + expect(TRUE, retVal); + rect.left = 0; + retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect); + expect(TRUE, retVal); + ok(rect.left != 0, "Expected updated rectangle\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCES); - iSize = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem); retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray); ok(retVal == TRUE, "Setting header items order should return TRUE, got %d\n", retVal); @@ -1187,12 +1189,156 @@ static void test_hdm_index_messages(HWND hParent) DestroyWindow(hChild); } +static void test_hdf_fixedwidth(HWND hParent) +{ + HWND hChild; + HDITEM hdItem; + DWORD ret; + RECT rect; + HDHITTESTINFO ht; + + hChild = create_custom_header_control(hParent, FALSE); + + hdItem.mask = HDI_WIDTH | HDI_FORMAT; + hdItem.fmt = HDF_FIXEDWIDTH; + hdItem.cxy = 80; + + ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem); + expect(0, ret); + + /* try to change width */ + rect.right = rect.bottom = 0; + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + ok(rect.right != 0, "Expected not zero width\n"); + ok(rect.bottom != 0, "Expected not zero height\n"); + + SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2)); + SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2)); + SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2)); + + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + + if (hdItem.cxy != rect.right) + { + win_skip("HDF_FIXEDWIDTH format not supported\n"); + DestroyWindow(hChild); + return; + } + + /* try to adjust with message */ + hdItem.mask = HDI_WIDTH; + hdItem.cxy = 90; + + ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem); + expect(TRUE, ret); + + rect.right = 0; + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + expect(90, rect.right); + + /* hittesting doesn't report ondivider flag for HDF_FIXEDWIDTH */ + ht.pt.x = rect.right - 1; + ht.pt.y = rect.bottom / 2; + SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht); + expect(HHT_ONHEADER, ht.flags); + + /* try to adjust with message */ + hdItem.mask = HDI_FORMAT; + hdItem.fmt = 0; + + ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem); + expect(TRUE, ret); + + ht.pt.x = 90; + ht.pt.y = rect.bottom / 2; + SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht); + expect(HHT_ONDIVIDER, ht.flags); + + DestroyWindow(hChild); +} + +static void test_hds_nosizing(HWND hParent) +{ + HWND hChild; + HDITEM hdItem; + DWORD ret; + RECT rect; + HDHITTESTINFO ht; + + hChild = create_custom_header_control(hParent, FALSE); + + memset(&hdItem, 0, sizeof(hdItem)); + hdItem.mask = HDI_WIDTH; + hdItem.cxy = 80; + + ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem); + expect(0, ret); + + /* HDS_NOSIZING only blocks hittesting */ + ret = GetWindowLong(hChild, GWL_STYLE); + SetWindowLong(hChild, GWL_STYLE, ret | HDS_NOSIZING); + + /* try to change width with mouse gestures */ + rect.right = rect.bottom = 0; + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + ok(rect.right != 0, "Expected not zero width\n"); + ok(rect.bottom != 0, "Expected not zero height\n"); + + SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2)); + SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2)); + SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2)); + + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + + if (hdItem.cxy != rect.right) + { + win_skip("HDS_NOSIZING style not supported\n"); + DestroyWindow(hChild); + return; + } + + /* this style doesn't set HDF_FIXEDWIDTH for items */ + hdItem.mask = HDI_FORMAT; + ret = SendMessage(hChild, HDM_GETITEM, 0, (LPARAM)&hdItem); + expect(TRUE, ret); + ok(!(hdItem.fmt & HDF_FIXEDWIDTH), "Unexpected HDF_FIXEDWIDTH\n"); + + /* try to adjust with message */ + hdItem.mask = HDI_WIDTH; + hdItem.cxy = 90; + + ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem); + expect(TRUE, ret); + + rect.right = 0; + SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect); + expect(90, rect.right); + + /* hittesting doesn't report ondivider flags for HDS_NOSIZING */ + ht.pt.x = rect.right - 1; + ht.pt.y = rect.bottom / 2; + SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht); + expect(HHT_ONHEADER, ht.flags); + + /* try to adjust with message */ + ret = GetWindowLong(hChild, GWL_STYLE); + SetWindowLong(hChild, GWL_STYLE, ret & ~HDS_NOSIZING); + + ht.pt.x = 90; + ht.pt.y = rect.bottom / 2; + SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht); + expect(HHT_ONDIVIDER, ht.flags); + + DestroyWindow(hChild); +} + #define TEST_NMCUSTOMDRAW(draw_stage, item_spec, lparam, _left, _top, _right, _bottom) \ ok(nm->dwDrawStage == draw_stage, "Invalid dwDrawStage %d vs %d\n", draw_stage, nm->dwDrawStage); \ if (item_spec != -1) \ ok(nm->dwItemSpec == item_spec, "Invalid dwItemSpec %d vs %ld\n", item_spec, nm->dwItemSpec); \ ok(nm->lItemlParam == lparam, "Invalid lItemlParam %d vs %ld\n", lparam, nm->lItemlParam); \ - ok(nm->rc.top == _top && nm->rc.bottom == _bottom && nm->rc.left == _left && nm->rc.right == _right, \ + ok((nm->rc.top == _top && nm->rc.bottom == _bottom && nm->rc.left == _left && nm->rc.right == _right) || \ + broken(draw_stage != CDDS_ITEMPREPAINT), /* comctl32 < 5.80 */ \ "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", _left, _top, _right, _bottom, \ nm->rc.left, nm->rc.top, nm->rc.right, nm->rc.bottom); @@ -1545,15 +1691,139 @@ static int init(void) return 1; } +/* maximum 8 items allowed */ +static void check_orderarray(HWND hwnd, DWORD start, DWORD set, DWORD expected, + int todo, int line) +{ + int count, i; + INT order[8]; + DWORD ret, array = 0; + + count = SendMessage(hwnd, HDM_GETITEMCOUNT, 0, 0); + + /* initial order */ + for(i = 1; i<=count; i++) + order[i-1] = start>>(4*(count-i)) & 0xf; + + ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order); + ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret); + + /* new order */ + for(i = 1; i<=count; i++) + order[i-1] = set>>(4*(count-i)) & 0xf; + ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order); + ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret); + + /* check actual order */ + ret = SendMessage(hwnd, HDM_GETORDERARRAY, count, (LPARAM)order); + ok_(__FILE__, line)(ret, "Expected HDM_GETORDERARAY to succeed, got %d\n", ret); + for(i = 1; i<=count; i++) + array |= order[i-1]<<(4*(count-i)); + + if (todo) { + todo_wine + ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array); + } + else + ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array); +} + +static void test_hdm_orderarray(void) +{ + HWND hwnd; + INT order[5]; + DWORD ret; + + hwnd = create_header_control(); + + /* three items */ + addItem(hwnd, 0, NULL); + addItem(hwnd, 1, NULL); + addItem(hwnd, 2, NULL); + + ret = SendMessage(hwnd, HDM_GETORDERARRAY, 3, (LPARAM)order); + if (!ret) + { + win_skip("HDM_GETORDERARRAY not implemented.\n"); + DestroyWindow(hwnd); + return; + } + + expect(0, order[0]); + expect(1, order[1]); + expect(2, order[2]); + +if (0) +{ + /* null pointer, crashes native */ + ret = SendMessage(hwnd, HDM_SETORDERARRAY, 3, 0); + expect(FALSE, ret); +} + /* count out of limits */ + ret = SendMessage(hwnd, HDM_SETORDERARRAY, 5, (LPARAM)order); + expect(FALSE, ret); + /* count out of limits */ + ret = SendMessage(hwnd, HDM_SETORDERARRAY, 2, (LPARAM)order); + expect(FALSE, ret); + + /* try with out of range item index */ + /* (0,1,2)->(1,0,3) => (1,0,2) */ + check_orderarray(hwnd, 0x120, 0x103, 0x102, FALSE, __LINE__); + /* (1,0,2)->(3,0,1) => (0,2,1) */ + check_orderarray(hwnd, 0x102, 0x301, 0x021, TRUE, __LINE__); + /* (0,2,1)->(2,3,1) => (2,0,1) */ + check_orderarray(hwnd, 0x021, 0x231, 0x201, FALSE, __LINE__); + + /* (0,1,2)->(0,2,2) => (0,1,2) */ + check_orderarray(hwnd, 0x012, 0x022, 0x012, FALSE, __LINE__); + + addItem(hwnd, 3, NULL); + + /* (0,1,2,3)->(0,1,2,2) => (0,1,3,2) */ + check_orderarray(hwnd, 0x0123, 0x0122, 0x0132, FALSE, __LINE__); + /* (0,1,2,3)->(0,1,3,3) => (0,1,2,3) */ + check_orderarray(hwnd, 0x0123, 0x0133, 0x0123, FALSE, __LINE__); + /* (0,1,2,3)->(0,4,2,3) => (0,1,2,3) */ + check_orderarray(hwnd, 0x0123, 0x0423, 0x0123, FALSE, __LINE__); + /* (0,1,2,3)->(4,0,1,2) => (0,1,3,2) */ + check_orderarray(hwnd, 0x0123, 0x4012, 0x0132, TRUE, __LINE__); + /* (0,1,3,2)->(4,0,1,4) => (0,3,1,2) */ + check_orderarray(hwnd, 0x0132, 0x4014, 0x0312, TRUE, __LINE__); + /* (0,1,2,3)->(4,1,0,2) => (1,0,3,2) */ + check_orderarray(hwnd, 0x0123, 0x4102, 0x1032, TRUE, __LINE__); + /* (0,1,2,3)->(0,1,4,2) => (0,1,2,3) */ + check_orderarray(hwnd, 0x0123, 0x0142, 0x0132, FALSE, __LINE__); + /* (0,1,2,3)->(4,4,4,4) => (0,1,2,3) */ + check_orderarray(hwnd, 0x0123, 0x4444, 0x0123, FALSE, __LINE__); + /* (0,1,2,3)->(4,4,1,2) => (0,1,3,2) */ + check_orderarray(hwnd, 0x0123, 0x4412, 0x0132, TRUE, __LINE__); + /* (0,1,2,3)->(4,4,4,1) => (0,2,3,1) */ + check_orderarray(hwnd, 0x0123, 0x4441, 0x0231, TRUE, __LINE__); + /* (0,1,2,3)->(1,4,4,4) => (1,0,2,3) */ + check_orderarray(hwnd, 0x0123, 0x1444, 0x1023, FALSE, __LINE__); + /* (0,1,2,3)->(4,2,4,1) => (0,2,3,1) */ + check_orderarray(hwnd, 0x0123, 0x4241, 0x0231, FALSE, __LINE__); + /* (0,1,2,3)->(4,2,0,1) => (2,0,3,1) */ + check_orderarray(hwnd, 0x0123, 0x4201, 0x2031, TRUE, __LINE__); + /* (3,2,1,0)->(4,2,0,1) => (3,2,0,1) */ + check_orderarray(hwnd, 0x3210, 0x4201, 0x3201, FALSE, __LINE__); + + DestroyWindow(hwnd); +} + START_TEST(header) { HWND parent_hwnd; + ULONG_PTR ctx_cookie; + HANDLE hCtx; + HWND hwnd; if (!init()) return; test_header_control(); test_header_order(); + test_hdm_orderarray(); test_customdraw(); DestroyWindow(hHeaderParentWnd); @@ -1573,6 +1843,33 @@ START_TEST(header) test_hdm_unicodeformatMessages(parent_hwnd); test_hdm_bitmapmarginMessages(parent_hwnd); - DestroyWindow(parent_hwnd); + if (!load_v6_module(&ctx_cookie, &hCtx)) + { + DestroyWindow(parent_hwnd); + return; + } + /* this is a XP SP3 failure workaround */ + hwnd = CreateWindowExA(0, WC_HEADER, NULL, + WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ, + 0, 0, 100, 100, + parent_hwnd, NULL, GetModuleHandleA(NULL), NULL); + + if (!IsWindow(hwnd)) + { + win_skip("FIXME: failed to create Header window.\n"); + unload_v6_module(ctx_cookie, hCtx); + DestroyWindow(parent_hwnd); + return; + } + else + DestroyWindow(hwnd); + + /* comctl32 version 6 tests start here */ + test_hdf_fixedwidth(parent_hwnd); + test_hds_nosizing(parent_hwnd); + + unload_v6_module(ctx_cookie, hCtx); + + DestroyWindow(parent_hwnd); } diff --git a/rostests/winetests/comctl32/imagelist.c b/rostests/winetests/comctl32/imagelist.c index 3fe249f3ad5..cf749c82732 100644 --- a/rostests/winetests/comctl32/imagelist.c +++ b/rostests/winetests/comctl32/imagelist.c @@ -4,6 +4,7 @@ * Copyright 2004 Michael Stefaniuc * Copyright 2002 Mike McCormack for CodeWeavers * Copyright 2007 Dmitry Timoshkov + * Copyright 2009 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,8 +34,12 @@ #include "winuser.h" #include "objbase.h" #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */ +#include "initguid.h" +#include "commoncontrols.h" +#include "shellapi.h" #include "wine/test.h" +#include "v6util.h" #undef VISIBLE @@ -65,10 +70,14 @@ typedef struct _ILHEAD } ILHEAD; #include "poppack.h" +static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int); +static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP); static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*); static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT); +static HRESULT (WINAPI *pImageList_CoCreateInstance)(REFCLSID,const IUnknown *, + REFIID,void **); +static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **); -static HDC desktopDC; static HINSTANCE hinst; /* These macros build cursor/bitmap data in 4x4 pixel blocks */ @@ -327,7 +336,7 @@ static BOOL DoTest1(void) HICON hicon3 ; /* create an imagelist to play with */ - himl = ImageList_Create(84,84,0x10,0,3); + himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3); ok(himl!=0,"failed to create imagelist\n"); /* load the icons to add to the image list */ @@ -393,7 +402,7 @@ static BOOL DoTest2(void) HICON hicon3 ; /* create an imagelist to play with */ - himl = ImageList_Create(84,84,0x10,0,3); + himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3); ok(himl!=0,"failed to create imagelist\n"); /* load the icons to add to the image list */ @@ -442,7 +451,7 @@ static BOOL DoTest3(void) ok(hdc!=NULL, "couldn't get DC\n"); /* create an imagelist to play with */ - himl = ImageList_Create(48,48,0x10,0,3); + himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3); ok(himl!=0,"failed to create imagelist\n"); /* load the icons to add to the image list */ @@ -824,7 +833,7 @@ static void check_bitmap_data(const char *bm_data, ULONG bm_data_size, static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max) { - ILHEAD *ilh = (ILHEAD *)ilh_data; + const ILHEAD *ilh = (const ILHEAD *)ilh_data; ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC); ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion); @@ -981,13 +990,639 @@ static void test_imagelist_storage(void) iml_clear_stream_data(); } +static void test_shell_imagelist(void) +{ + BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**); + IImageList *iml = NULL; + HMODULE hShell32; + HRESULT hr; + int out = 0; + RECT rect; + int cx, cy; + + /* Try to load function from shell32 */ + hShell32 = LoadLibrary("shell32.dll"); + pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727); + + if (!pSHGetImageList) + { + win_skip("SHGetImageList not available, skipping test\n"); + return; + } + + /* Get system image list */ + hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml); + + ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr); + + if (hr != S_OK) + return; + + IImageList_GetImageCount(iml, &out); + ok(out > 0, "IImageList_GetImageCount returned out <= 0\n"); + + /* Fetch the small icon size */ + cx = GetSystemMetrics(SM_CXSMICON); + cy = GetSystemMetrics(SM_CYSMICON); + + /* Check icon size matches */ + IImageList_GetImageRect(iml, 0, &rect); + ok(((rect.right == cx) && (rect.bottom == cy)), + "IImageList_GetImageRect returned r:%d,b:%d\n", + rect.right, rect.bottom); + + IImageList_Release(iml); + FreeLibrary(hShell32); +} + +static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2) +{ + HBITMAP hBitmap; + UINT32 *buffer = NULL; + BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB, + 0, 0, 0, 0, 0}}; + + hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0); + ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n"); + + if(!hBitmap || !buffer) + { + DeleteObject(hBitmap); + return NULL; + } + + buffer[0] = pixel1; + buffer[1] = pixel2; + + return hBitmap; +} + +static BOOL colour_match(UINT32 x, UINT32 y) +{ + const INT32 tolerance = 8; + + const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF)); + const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8)); + const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16)); + + return (dr <= tolerance && dg <= tolerance && db <= tolerance); +} + +static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits, + UINT32 expected, int line) +{ + bits[0] = 0x00FFFFFF; + pImageList_DrawIndirect(ildp); + ok(colour_match(bits[0], expected), + "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n", + bits[0] & 0x00FFFFFF, expected, line); +} + + +static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, + UINT fStyle, UINT32 expected, int line) +{ + IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc, + 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000}; + check_ImageList_DrawIndirect(&ildp, bits, expected, line); +} + +static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, + DWORD dwRop, UINT32 expected, int line) +{ + IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc, + 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000}; + check_ImageList_DrawIndirect(&ildp, bits, expected, line); +} + +static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle, + UINT fState, DWORD Frame, UINT32 expected, int line) +{ + IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc, + 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000}; + check_ImageList_DrawIndirect(&ildp, bits, expected, line); +} + +static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, + UINT fStyle, UINT fState, DWORD Frame, UINT32 expected, + UINT32 broken_expected, int line) +{ + IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc, + 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000}; + bits[0] = 0x00FFFFFF; + pImageList_DrawIndirect(&ildp); + ok(colour_match(bits[0], expected) || + broken(colour_match(bits[0], broken_expected)), + "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n", + bits[0] & 0x00FFFFFF, expected, line); +} + +static void test_ImageList_DrawIndirect(void) +{ + HIMAGELIST himl = NULL; + int ret; + HDC hdcDst = NULL; + HBITMAP hbmOld = NULL, hbmDst = NULL; + HBITMAP hbmMask = NULL, hbmInverseMask = NULL; + HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL; + int iImage = -1, iAlphaImage = -1, iTransparentImage = -1; + UINT32 *bits = 0; + UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF; + + BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB, + 0, 0, 0, 0, 0}}; + + hdcDst = CreateCompatibleDC(0); + ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n"); + if (!hdcDst) + return; + + hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits); + ok(hbmMask != 0, "CreateBitmap failed\n"); + if(!hbmMask) goto cleanup; + + hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits); + ok(hbmInverseMask != 0, "CreateBitmap failed\n"); + if(!hbmInverseMask) goto cleanup; + + himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1); + ok(himl != 0, "ImageList_Create failed\n"); + if(!himl) goto cleanup; + + /* Add a no-alpha image */ + hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF); + if(!hbmImage) goto cleanup; + + iImage = pImageList_Add(himl, hbmImage, hbmMask); + ok(iImage != -1, "ImageList_Add failed\n"); + if(iImage == -1) goto cleanup; + + /* Add an alpha image */ + hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF); + if(!hbmAlphaImage) goto cleanup; + + iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask); + ok(iAlphaImage != -1, "ImageList_Add failed\n"); + if(iAlphaImage == -1) goto cleanup; + + /* Add a transparent alpha image */ + hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF); + if(!hbmTransparentImage) goto cleanup; + + iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask); + ok(iTransparentImage != -1, "ImageList_Add failed\n"); + if(iTransparentImage == -1) goto cleanup; + + /* 32-bit Tests */ + bitmapInfo.bmiHeader.biBitCount = 32; + hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n"); + if (!hbmDst || !bits) + goto cleanup; + hbmOld = SelectObject(hdcDst, hbmDst); + + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__); + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__); + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__); + + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__); + todo_wine + { + check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__); + check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__); + + } + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__); + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__); + todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__); + + check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__); + + check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__); + check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__); + + /* ILD_ROP is ignored when the image has an alpha channel */ + check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__); + check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__); + + todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__); + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__); + + check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__); + check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__); + + check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__); + check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__); + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__); + +cleanup: + + if(hbmOld) + SelectObject(hdcDst, hbmOld); + if(hbmDst) + DeleteObject(hbmDst); + + if(hdcDst) + DeleteDC(hdcDst); + + if(hbmMask) + DeleteObject(hbmMask); + if(hbmInverseMask) + DeleteObject(hbmInverseMask); + + if(hbmImage) + DeleteObject(hbmImage); + if(hbmAlphaImage) + DeleteObject(hbmAlphaImage); + if(hbmTransparentImage) + DeleteObject(hbmTransparentImage); + + if(himl) + { + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + } +} + +static void test_iimagelist(void) +{ + IImageList *imgl; + HIMAGELIST himl; + HRESULT hr; + ULONG ret; + + if (!pHIMAGELIST_QueryInterface) + { + win_skip("XP imagelist functions not available\n"); + return; + } + + /* test reference counting on destruction */ + imgl = (IImageList*)createImageList(32, 32); + ret = IUnknown_AddRef(imgl); + ok(ret == 2, "Expected 2, got %d\n", ret); + ret = ImageList_Destroy((HIMAGELIST)imgl); + ok(ret == TRUE, "Expected TRUE, got %d\n", ret); + ret = ImageList_Destroy((HIMAGELIST)imgl); + ok(ret == TRUE, "Expected TRUE, got %d\n", ret); + ret = ImageList_Destroy((HIMAGELIST)imgl); + ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + + imgl = (IImageList*)createImageList(32, 32); + ret = IUnknown_AddRef(imgl); + ok(ret == 2, "Expected 2, got %d\n", ret); + ret = ImageList_Destroy((HIMAGELIST)imgl); + ok(ret == TRUE, "Expected TRUE, got %d\n", ret); + ret = IImageList_Release(imgl); + ok(ret == 0, "Expected 0, got %d\n", ret); + ret = ImageList_Destroy((HIMAGELIST)imgl); + ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + + if (!pImageList_CoCreateInstance) + { + win_skip("Vista imagelist functions not available\n"); + return; + } + + hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl); + ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr); + + if (hr == S_OK) + IImageList_Release(imgl); + + himl = createImageList(32, 32); + + if (!himl) + return; + + hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl); + ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr); + + if (hr == S_OK) + IImageList_Release(imgl); + + ImageList_Destroy(himl); +} + +static void testHotspot_v6(void) +{ + struct hotspot { + int dx; + int dy; + }; + +#define SIZEX1 47 +#define SIZEY1 31 +#define SIZEX2 11 +#define SIZEY2 17 +#define HOTSPOTS_MAX 4 /* Number of entries in hotspots */ + static const struct hotspot hotspots[HOTSPOTS_MAX] = { + { 10, 7 }, + { SIZEX1, SIZEY1 }, + { -9, -8 }, + { -7, 35 } + }; + int i, j; + HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1); + HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2); + IImageList *imgl1, *imgl2; + HRESULT hr; + + /* cast to IImageList */ + imgl1 = (IImageList *) himl1; + imgl2 = (IImageList *) himl2; + + for (i = 0; i < HOTSPOTS_MAX; i++) { + for (j = 0; j < HOTSPOTS_MAX; j++) { + int dx1 = hotspots[i].dx; + int dy1 = hotspots[i].dy; + int dx2 = hotspots[j].dx; + int dy2 = hotspots[j].dy; + int correctx, correcty, newx, newy; + char loc[256]; + IImageList *imglNew; + POINT ppt; + + hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1); + ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1); + sprintf(loc, "BeginDrag (%d,%d)\n", i, j); + + /* check merging the dragged image with a second image */ + hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2); + ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n", + dx1, dy1, dx2, dy2); + sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j); + + /* check new hotspot, it should be the same like the old one */ + hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew); + ok(SUCCEEDED(hr), "GetDragImage failed\n"); + ok(ppt.x == dx1 && ppt.y == dy1, + "Expected drag hotspot [%d,%d] got [%d,%d]\n", + dx1, dy1, ppt.x, ppt.y); + /* check size of new dragged image */ + IImageList_GetIconSize(imglNew, &newx, &newy); + correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2)); + correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2)); + ok(newx == correctx && newy == correcty, + "Expected drag image size [%d,%d] got [%d,%d]\n", + correctx, correcty, newx, newy); + sprintf(loc, "GetDragImage (%d,%d)\n", i, j); + IImageList_EndDrag(imgl2); + } + } +#undef SIZEX1 +#undef SIZEY1 +#undef SIZEX2 +#undef SIZEY2 +#undef HOTSPOTS_MAX + IImageList_Release(imgl2); + IImageList_Release(imgl1); +} + +static void DoTest1_v6(void) +{ + IImageList *imgl; + HIMAGELIST himl; + HRESULT hr; + + HICON hicon1; + HICON hicon2; + HICON hicon3; + + int ret = 0; + + /* create an imagelist to play with */ + himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3); + ok(himl != 0,"failed to create imagelist\n"); + + imgl = (IImageList *) himl; + + /* load the icons to add to the image list */ + hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok(hicon1 != 0, "no hicon1\n"); + hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok(hicon2 != 0, "no hicon2\n"); + hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok(hicon3 != 0, "no hicon3\n"); + + /* remove when nothing exists */ + hr = IImageList_Remove(imgl, 0); + ok(!(SUCCEEDED(hr)), "removed nonexistent icon\n"); + + /* removing everything from an empty imagelist should succeed */ + hr = IImageList_Remove(imgl, -1); + ok(SUCCEEDED(hr), "removed nonexistent icon\n"); + + /* add three */ + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon1, &ret)) && (ret == 0),"failed to add icon1\n"); + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon2, &ret)) && (ret == 1),"failed to add icon2\n"); + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon3, &ret)) && (ret == 2),"failed to add icon3\n"); + + /* remove an index out of range */ + ok(FAILED(IImageList_Remove(imgl, 4711)),"removed nonexistent icon\n"); + + /* remove three */ + ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n"); + ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n"); + ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n"); + + /* remove one extra */ + ok(FAILED(IImageList_Remove(imgl, 0)),"removed nonexistent icon\n"); + + /* check SetImageCount/GetImageCount */ + ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "couldn't increase image count\n"); + ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 3), "invalid image count after increase\n"); + ok(SUCCEEDED(IImageList_SetImageCount(imgl, 1)), "couldn't decrease image count\n"); + ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 1), "invalid image count after decrease to 1\n"); + ok(SUCCEEDED(IImageList_SetImageCount(imgl, 0)), "couldn't decrease image count\n"); + ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 0), "invalid image count after decrease to 0\n"); + + /* destroy it */ + ok(SUCCEEDED(IImageList_Release(imgl)),"release imagelist failed\n"); + + ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n"); + ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n"); + ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n"); +} + +static void DoTest3_v6(void) +{ + IImageList *imgl; + HIMAGELIST himl; + + HBITMAP hbm1; + HBITMAP hbm2; + HBITMAP hbm3; + + IMAGELISTDRAWPARAMS imldp; + HWND hwndfortest; + HDC hdc; + int ret; + + hwndfortest = create_a_window(); + hdc = GetDC(hwndfortest); + ok(hdc!=NULL, "couldn't get DC\n"); + + /* create an imagelist to play with */ + himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3); + ok(himl!=0,"failed to create imagelist\n"); + + imgl = (IImageList *) himl; + + /* load the icons to add to the image list */ + hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits); + ok(hbm1 != 0, "no bitmap 1\n"); + hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits); + ok(hbm2 != 0, "no bitmap 2\n"); + hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits); + ok(hbm3 != 0, "no bitmap 3\n"); + + /* add three */ + ok(SUCCEEDED(IImageList_Add(imgl, hbm1, 0, &ret)) && (ret == 0), "failed to add bitmap 1\n"); + ok(SUCCEEDED(IImageList_Add(imgl, hbm2, 0, &ret)) && (ret == 1), "failed to add bitmap 2\n"); + + ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "Setimage count failed\n"); + ok(SUCCEEDED(IImageList_Replace(imgl, 2, hbm3, 0)), "failed to replace bitmap 3\n"); + + memset(&imldp, 0, sizeof (imldp)); + ok(FAILED(IImageList_Draw(imgl, &imldp)), "zero data succeeded!\n"); + + imldp.cbSize = sizeof (imldp); + imldp.hdcDst = hdc; + imldp.himl = himl; + + if (FAILED(IImageList_Draw(imgl, &imldp))) + { + /* Earlier versions of native comctl32 use a smaller structure */ + imldp.cbSize -= 3 * sizeof(DWORD); + ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + } + + REDRAW(hwndfortest); + WAIT; + + imldp.fStyle = SRCCOPY; + imldp.rgbBk = CLR_DEFAULT; + imldp.rgbFg = CLR_DEFAULT; + imldp.y = 100; + imldp.x = 100; + ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + imldp.i ++; + ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + imldp.i ++; + ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + imldp.i ++; + ok(FAILED(IImageList_Draw(imgl, &imldp)), "should fail\n"); + + /* remove three */ + ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 1st bitmap\n"); + ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 2nd bitmap\n"); + ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 3rd bitmap\n"); + + /* destroy it */ + ok(SUCCEEDED(IImageList_Release(imgl)), "release imagelist failed\n"); + + /* bitmaps should not be deleted by the imagelist */ + ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n"); + ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n"); + ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n"); + + ReleaseDC(hwndfortest, hdc); + DestroyWindow(hwndfortest); +} + +static void testMerge_v6(void) +{ + HIMAGELIST himl1, himl2; + IImageList *imgl1, *imgl2, *merge; + HICON hicon1; + HWND hwnd = create_a_window(); + HRESULT hr; + int ret; + + himl1 = ImageList_Create(32,32,0,0,3); + ok(himl1 != NULL,"failed to create himl1\n"); + + himl2 = ImageList_Create(32,32,0,0,3); + ok(himl2 != NULL,"failed to create himl2\n"); + + hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok(hicon1 != NULL, "failed to create hicon1\n"); + + if (!himl1 || !himl2 || !hicon1) + return; + + /* cast to IImageList */ + imgl1 = (IImageList *) himl1; + imgl2 = (IImageList *) himl2; + + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl2 failed\n"); + + /* If himl1 has no images, merge still succeeds */ + hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl1,-1 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl1,0 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + /* Same happens if himl2 is empty */ + IImageList_Release(imgl2); + himl2 = ImageList_Create(32,32,0,0,3); + ok(himl2 != NULL,"failed to recreate himl2\n"); + + imgl2 = (IImageList *) himl2; + + hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl2,-1 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl2,0 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + /* Now try merging an image with itself */ + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"re-add icon1 to himl2 failed\n"); + + hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl2 with itself failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + /* Try merging 2 different image lists */ + ok(SUCCEEDED(IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl1 failed\n"); + + hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl1 with himl2 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge); + ok(SUCCEEDED(hr), "merge himl1 with himl2 8,16 failed\n"); + if (SUCCEEDED(hr)) IImageList_Release(merge); + + IImageList_Release(imgl1); + IImageList_Release(imgl2); + + DestroyIcon(hicon1); + DestroyWindow(hwnd); +} + START_TEST(imagelist) { + ULONG_PTR ctx_cookie; + HANDLE hCtx; + HMODULE hComCtl32 = GetModuleHandle("comctl32.dll"); + pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/ + pImageList_Add = NULL; pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect"); pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount"); - desktopDC=GetDC(NULL); hinst = GetModuleHandleA(NULL); InitCommonControls(); @@ -998,4 +1633,36 @@ START_TEST(imagelist) DoTest3(); testMerge(); test_imagelist_storage(); + + FreeLibrary(hComCtl32); + + /* Now perform v6 tests */ + + if (!load_v6_module(&ctx_cookie, &hCtx)) + return; + + /* Reload comctl32 */ + hComCtl32 = LoadLibraryA("comctl32.dll"); + pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create"); + pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add"); + pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect"); + pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount"); + pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance"); + pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface"); + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + /* Do v6.0 tests */ + test_ImageList_DrawIndirect(); + test_shell_imagelist(); + test_iimagelist(); + + testHotspot_v6(); + DoTest1_v6(); + DoTest3_v6(); + testMerge_v6(); + + CoUninitialize(); + + unload_v6_module(ctx_cookie, hCtx); } diff --git a/rostests/winetests/comctl32/ipaddress.c b/rostests/winetests/comctl32/ipaddress.c index d04223cb4fc..85f92b1d582 100644 --- a/rostests/winetests/comctl32/ipaddress.c +++ b/rostests/winetests/comctl32/ipaddress.c @@ -33,8 +33,6 @@ static HWND create_ipaddress_control (void) handle = CreateWindowEx(0, WC_IPADDRESS, NULL, WS_BORDER|WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - assert(handle); - return handle; } @@ -45,6 +43,11 @@ static void test_get_set_text(void) INT r; hwnd = create_ipaddress_control(); + if (!hwnd) + { + win_skip("IPAddress control not implemented\n"); + return; + } /* check text just after creation */ r = GetWindowText(hwnd, ip, sizeof(ip)/sizeof(CHAR)); diff --git a/rostests/winetests/comctl32/listview.c b/rostests/winetests/comctl32/listview.c index e94bdaaabd0..6ef82bb359a 100644 --- a/rostests/winetests/comctl32/listview.c +++ b/rostests/winetests/comctl32/listview.c @@ -3,6 +3,7 @@ * * Copyright 2006 Mike McCormack for CodeWeavers * Copyright 2007 George Gov + * Copyright 2009 Nikolay Sivov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,12 +25,15 @@ #include #include "wine/test.h" +#include "v6util.h" #include "msg.h" #define PARENT_SEQ_INDEX 0 #define PARENT_FULL_SEQ_INDEX 1 #define LISTVIEW_SEQ_INDEX 2 -#define NUM_MSG_SEQUENCES 3 +#define EDITBOX_SEQ_INDEX 3 +#define COMBINED_SEQ_INDEX 4 +#define NUM_MSG_SEQUENCES 5 #define LISTVIEW_ID 0 #define HEADER_ID 1 @@ -38,32 +42,33 @@ #define expect2(expected1, expected2, got1, got2) ok(expected1 == got1 && expected2 == got2, \ "expected (%d,%d), got (%d,%d)\n", expected1, expected2, got1, got2) -HWND hwndparent; +static const WCHAR testparentclassW[] = + {'L','i','s','t','v','i','e','w',' ','t','e','s','t',' ','p','a','r','e','n','t','W', 0}; + +static HWND hwndparent, hwndparentW; +/* prevents edit box creation, LVN_BEGINLABELEDIT return value */ +static BOOL blockEdit; +/* return nonzero on NM_HOVER */ +static BOOL g_block_hover; +/* dumps LVN_ITEMCHANGED message data */ +static BOOL g_dump_itemchanged; +/* format reported to control: + -1 falls to defproc, anything else returned */ +static INT notifyFormat; +/* indicates we're running < 5.80 version */ +static BOOL g_is_below_5; +/* item data passed to LVN_GETDISPINFOA */ +static LVITEMA g_itema; + +static HWND subclass_editbox(HWND hwndListview); static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; -static const struct message create_parent_wnd_seq[] = { - { WM_GETMINMAXINFO, sent }, - { WM_NCCREATE, sent }, - { WM_NCCALCSIZE, sent|wparam, 0 }, - { WM_CREATE, sent }, - { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_QUERYNEWPALETTE, sent|optional }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGED, sent|optional }, - { WM_NCCALCSIZE, sent|wparam|optional, 1 }, - { WM_ACTIVATEAPP, sent|wparam, 1 }, - { WM_NCACTIVATE, sent|wparam, 1 }, - { WM_ACTIVATE, sent|wparam, 1 }, - { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, - { WM_IME_NOTIFY, sent|defwinproc|optional }, - { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, - /* Win9x adds SWP_NOZORDER below */ - { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, - { WM_NCCALCSIZE, sent|wparam|optional, 1 }, - { WM_SIZE, sent }, - { WM_MOVE, sent }, +static const struct message create_ownerdrawfixed_parent_seq[] = { + { WM_NOTIFYFORMAT, sent }, + { WM_QUERYUISTATE, sent|optional }, /* Win2K and higher */ + { WM_MEASUREITEM, sent }, + { WM_PARENTNOTIFY, sent }, { 0 } }; @@ -71,10 +76,10 @@ static const struct message redraw_listview_seq[] = { { WM_PAINT, sent|id, 0, 0, LISTVIEW_ID }, { WM_PAINT, sent|id, 0, 0, HEADER_ID }, { WM_NCPAINT, sent|id|defwinproc, 0, 0, HEADER_ID }, - { WM_ERASEBKGND, sent|id|defwinproc, 0, 0, HEADER_ID }, + { WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, HEADER_ID }, { WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID }, { WM_NCPAINT, sent|id|defwinproc, 0, 0, LISTVIEW_ID }, - { WM_ERASEBKGND, sent|id|defwinproc, 0, 0, LISTVIEW_ID }, + { WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, LISTVIEW_ID }, { 0 } }; @@ -123,6 +128,8 @@ static const struct message listview_item_count_seq[] = { { LVM_INSERTITEM, sent }, { LVM_GETITEMCOUNT, sent }, { LVM_DELETEITEM, sent|wparam, 2 }, + { WM_NCPAINT, sent|optional }, + { WM_ERASEBKGND, sent|optional }, { LVM_GETITEMCOUNT, sent }, { LVM_DELETEALLITEMS, sent }, { LVM_GETITEMCOUNT, sent }, @@ -139,6 +146,8 @@ static const struct message listview_itempos_seq[] = { { LVM_INSERTITEM, sent }, { LVM_INSERTITEM, sent }, { LVM_SETITEMPOSITION, sent|wparam|lparam, 1, MAKELPARAM(10,5) }, + { WM_NCPAINT, sent|optional }, + { WM_ERASEBKGND, sent|optional }, { LVM_GETITEMPOSITION, sent|wparam, 1 }, { LVM_SETITEMPOSITION, sent|wparam|lparam, 2, MAKELPARAM(0,0) }, { LVM_GETITEMPOSITION, sent|wparam, 2 }, @@ -168,9 +177,128 @@ static const struct message forward_erasebkgnd_parent_seq[] = { { 0 } }; -struct subclass_info -{ - WNDPROC oldproc; +static const struct message ownderdata_select_focus_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, + { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, /* version 4.7x */ + { 0 } +}; + +static const struct message ownerdata_setstate_all_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_defocus_all_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, + { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_deselect_all_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ODCACHEHINT }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message select_all_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message textcallback_set_again_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message single_getdispinfo_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, + { 0 } +}; + +static const struct message getitemposition_seq1[] = { + { LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID }, + { 0 } +}; + +static const struct message getitemposition_seq2[] = { + { LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID }, + { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID }, + { 0 } +}; + +static const struct message editbox_create_pos[] = { + /* sequence sent after LVN_BEGINLABELEDIT */ + /* next two are 4.7x specific */ + { WM_WINDOWPOSCHANGING, sent }, + { WM_WINDOWPOSCHANGED, sent|optional }, + + { WM_WINDOWPOSCHANGING, sent|optional }, + { WM_NCCALCSIZE, sent }, + { WM_WINDOWPOSCHANGED, sent }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + /* the rest is todo, skipped in 4.7x */ + { WM_WINDOWPOSCHANGING, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|optional }, + { 0 } +}; + +static const struct message scroll_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_BEGINSCROLL }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ENDSCROLL }, + { 0 } +}; + +static const struct message setredraw_seq[] = { + { WM_SETREDRAW, sent|id|wparam, FALSE, 0, LISTVIEW_ID }, + { 0 } +}; + +static const struct message lvs_ex_transparentbkgnd_seq[] = { + { WM_PRINTCLIENT, sent|lparam, 0, PRF_ERASEBKGND }, + { 0 } +}; + +static const struct message edit_end_nochange[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA }, + { WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW }, /* todo */ + { WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS }, + { 0 } +}; + +static const struct message hover_parent[] = { + { WM_GETDLGCODE, sent }, /* todo_wine */ + { WM_NOTIFY, sent|id, 0, 0, NM_HOVER }, + { 0 } +}; + +static const struct message listview_destroy[] = { + { 0x0090, sent|optional }, /* Vista */ + { WM_PARENTNOTIFY, sent }, + { WM_SHOWWINDOW, sent }, + { WM_WINDOWPOSCHANGING, sent }, + { WM_WINDOWPOSCHANGED, sent|optional }, + { WM_DESTROY, sent }, + { WM_NOTIFY, sent|id, 0, 0, LVN_DELETEALLITEMS }, + { WM_NCDESTROY, sent }, + { 0 } }; static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -184,6 +312,7 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; + if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code; /* log system messages, except for painting */ if (message < WM_USER && @@ -198,9 +327,67 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam); add_message(sequences, PARENT_SEQ_INDEX, &msg); + add_message(sequences, COMBINED_SEQ_INDEX, &msg); } add_message(sequences, PARENT_FULL_SEQ_INDEX, &msg); + switch (message) + { + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->code) + { + case LVN_BEGINLABELEDIT: + /* subclass edit box */ + if (!blockEdit) + subclass_editbox(((NMHDR*)lParam)->hwndFrom); + + return blockEdit; + + case LVN_ENDLABELEDIT: + { + /* always accept new item text */ + NMLVDISPINFO *di = (NMLVDISPINFO*)lParam; + trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText); + return TRUE; + } + case LVN_BEGINSCROLL: + case LVN_ENDSCROLL: + { + NMLVSCROLL *pScroll = (NMLVSCROLL*)lParam; + + trace("LVN_%sSCROLL: (%d,%d)\n", pScroll->hdr.code == LVN_BEGINSCROLL ? + "BEGIN" : "END", pScroll->dx, pScroll->dy); + } + break; + case LVN_ITEMCHANGED: + if (g_dump_itemchanged) + { + NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam; + trace("LVN_ITEMCHANGED: item=%d,new=%x,old=%x,changed=%x\n", + nmlv->iItem, nmlv->uNewState, nmlv->uOldState, nmlv->uChanged); + } + break; + case LVN_GETDISPINFOA: + { + NMLVDISPINFOA *dispinfo = (NMLVDISPINFOA*)lParam; + g_itema = dispinfo->item; + } + break; + case NM_HOVER: + if (g_block_hover) return 1; + break; + } + break; + } + case WM_NOTIFYFORMAT: + { + /* force to return format */ + if (lParam == NF_QUERY && notifyFormat != -1) return notifyFormat; + break; + } + } + defwndproc_counter++; ret = DefWindowProcA(hwnd, message, wParam, lParam); defwndproc_counter--; @@ -208,39 +395,72 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP return ret; } -static BOOL register_parent_wnd_class(void) +static BOOL register_parent_wnd_class(BOOL Unicode) { - WNDCLASSA cls; + WNDCLASSA clsA; + WNDCLASSW clsW; - cls.style = 0; - cls.lpfnWndProc = parent_wnd_proc; - cls.cbClsExtra = 0; - cls.cbWndExtra = 0; - cls.hInstance = GetModuleHandleA(NULL); - cls.hIcon = 0; - cls.hCursor = LoadCursorA(0, IDC_ARROW); - cls.hbrBackground = GetStockObject(WHITE_BRUSH); - cls.lpszMenuName = NULL; - cls.lpszClassName = "Listview test parent class"; - return RegisterClassA(&cls); + if (Unicode) + { + clsW.style = 0; + clsW.lpfnWndProc = parent_wnd_proc; + clsW.cbClsExtra = 0; + clsW.cbWndExtra = 0; + clsW.hInstance = GetModuleHandleW(NULL); + clsW.hIcon = 0; + clsW.hCursor = LoadCursorA(0, IDC_ARROW); + clsW.hbrBackground = GetStockObject(WHITE_BRUSH); + clsW.lpszMenuName = NULL; + clsW.lpszClassName = testparentclassW; + } + else + { + clsA.style = 0; + clsA.lpfnWndProc = parent_wnd_proc; + clsA.cbClsExtra = 0; + clsA.cbWndExtra = 0; + clsA.hInstance = GetModuleHandleA(NULL); + clsA.hIcon = 0; + clsA.hCursor = LoadCursorA(0, IDC_ARROW); + clsA.hbrBackground = GetStockObject(WHITE_BRUSH); + clsA.lpszMenuName = NULL; + clsA.lpszClassName = "Listview test parent class"; + } + + return Unicode ? RegisterClassW(&clsW) : RegisterClassA(&clsA); } -static HWND create_parent_window(void) +static HWND create_parent_window(BOOL Unicode) { - if (!register_parent_wnd_class()) + static const WCHAR nameW[] = {'t','e','s','t','p','a','r','e','n','t','n','a','m','e','W',0}; + HWND hwnd; + + if (!register_parent_wnd_class(Unicode)) return NULL; - return CreateWindowEx(0, "Listview test parent class", - "Listview test parent window", - WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | - WS_MAXIMIZEBOX | WS_VISIBLE, - 0, 0, 100, 100, - GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + blockEdit = FALSE; + notifyFormat = -1; + + if (Unicode) + hwnd = CreateWindowExW(0, testparentclassW, nameW, + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleW(NULL), NULL); + else + hwnd = CreateWindowExA(0, "Listview test parent class", + "Listview test parent window", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE ); + return hwnd; } static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -262,53 +482,20 @@ static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wPa msg.lParam = lParam; msg.id = LISTVIEW_ID; add_message(sequences, LISTVIEW_SEQ_INDEX, &msg); + add_message(sequences, COMBINED_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } static HWND create_listview_control(DWORD style) { - struct subclass_info *info; + WNDPROC oldproc; HWND hwnd; RECT rect; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - - GetClientRect(hwndparent, &rect); - hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo", - WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT | style, - 0, 0, rect.right, rect.bottom, - hwndparent, NULL, GetModuleHandleA(NULL), NULL); - ok(hwnd != NULL, "gle=%d\n", GetLastError()); - - if (!hwnd) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } - - info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, - (LONG_PTR)listview_subclass_proc); - SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info); - - return hwnd; -} - -static HWND create_custom_listview_control(DWORD style) -{ - struct subclass_info *info; - HWND hwnd; - RECT rect; - - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - GetClientRect(hwndparent, &rect); hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo", WS_CHILD | WS_BORDER | WS_VISIBLE | style, @@ -316,22 +503,42 @@ static HWND create_custom_listview_control(DWORD style) hwndparent, NULL, GetModuleHandleA(NULL), NULL); ok(hwnd != NULL, "gle=%d\n", GetLastError()); - if (!hwnd) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!hwnd) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, - (LONG_PTR)listview_subclass_proc); - SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)listview_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); + + return hwnd; +} + +/* unicode listview window with specified parent */ +static HWND create_listview_controlW(DWORD style, HWND parent) +{ + WNDPROC oldproc; + HWND hwnd; + RECT rect; + static const WCHAR nameW[] = {'f','o','o',0}; + + GetClientRect(parent, &rect); + hwnd = CreateWindowExW(0, WC_LISTVIEWW, nameW, + WS_CHILD | WS_BORDER | WS_VISIBLE | style, + 0, 0, rect.right, rect.bottom, + parent, NULL, GetModuleHandleW(NULL), NULL); + ok(hwnd != NULL, "gle=%d\n", GetLastError()); + + if (!hwnd) return NULL; + + oldproc = (WNDPROC)SetWindowLongPtrW(hwnd, GWLP_WNDPROC, + (LONG_PTR)listview_subclass_proc); + SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); return hwnd; } static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -347,28 +554,156 @@ static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wPara add_message(sequences, LISTVIEW_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } static HWND subclass_header(HWND hwndListview) { - struct subclass_info *info; + WNDPROC oldproc; HWND hwnd; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - hwnd = ListView_GetHeader(hwndListview); - info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, - (LONG_PTR)header_subclass_proc); - SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)header_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); return hwnd; } +static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + static LONG defwndproc_counter = 0; + LRESULT ret; + struct message msg; + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + + /* all we need is sizing */ + if (message == WM_WINDOWPOSCHANGING || + message == WM_NCCALCSIZE || + message == WM_WINDOWPOSCHANGED || + message == WM_MOVE || + message == WM_SIZE) + { + add_message(sequences, EDITBOX_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); + defwndproc_counter--; + return ret; +} + +static HWND subclass_editbox(HWND hwndListview) +{ + WNDPROC oldproc; + HWND hwnd; + + hwnd = (HWND)SendMessage(hwndListview, LVM_GETEDITCONTROL, 0, 0); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)editbox_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); + + return hwnd; +} + +/* Performs a single LVM_HITTEST test */ +static void test_lvm_hittest_(HWND hwnd, INT x, INT y, INT item, UINT flags, UINT broken_flags, + BOOL todo_item, BOOL todo_flags, int line) +{ + LVHITTESTINFO lpht; + DWORD ret; + + lpht.pt.x = x; + lpht.pt.y = y; + lpht.iSubItem = 10; + + trace("hittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); + ret = SendMessage(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht); + + if (todo_item) + { + todo_wine + { + ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n"); + } + } + else + { + ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n"); + } + + if (todo_flags) + { + todo_wine + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); + } + else if (broken_flags) + ok_(__FILE__, line)(lpht.flags == flags || broken(lpht.flags == broken_flags), + "Expected flags %x, got %x\n", flags, lpht.flags); + else + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); +} + +#define test_lvm_hittest(a,b,c,d,e,f,g,h) test_lvm_hittest_(a,b,c,d,e,f,g,h,__LINE__) + +/* Performs a single LVM_SUBITEMHITTEST test */ +static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subitem, UINT flags, + BOOL todo_item, BOOL todo_subitem, BOOL todo_flags, int line) +{ + LVHITTESTINFO lpht; + DWORD ret; + + lpht.pt.x = x; + lpht.pt.y = y; + + trace("subhittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); + ret = SendMessage(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht); + + if (todo_item) + { + todo_wine + { + ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + } + } + else + { + ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + } + + if (todo_subitem) + { + todo_wine + ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); + } + else + ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); + + if (todo_flags) + { + todo_wine + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); + } + else + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); +} + +#define test_lvm_subitemhittest(a,b,c,d,e,f,g,h,i) test_lvm_subitemhittest_(a,b,c,d,e,f,g,h,i,__LINE__) + static void test_images(void) { HWND hwnd; @@ -392,7 +727,9 @@ static void test_images(void) 10, 10, 100, 200, hwndparent, NULL, NULL, NULL); ok(hwnd != NULL, "failed to create listview window\n"); - r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, 0x940); + r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, + LVS_EX_UNDERLINEHOT | LVS_EX_FLATSB | LVS_EX_ONECLICKACTIVATE); + ok(r == 0, "should return zero\n"); r = SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl); @@ -491,7 +828,12 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(item.state == 0x1ccc, "state %x\n", item.state); + if (item.state != 0x1ccc) + { + win_skip("LVS_EX_CHECKBOXES style is unavailable. Skipping.\n"); + DestroyWindow(hwnd); + return; + } /* Now add an item without specifying a state and check that its state goes to 0x1000 */ item.iItem = 2; @@ -827,59 +1169,99 @@ static void test_items(void) r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); ok(r != 0, "ret %d\n", r); + /* set text to callback value already having it */ + r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0); + expect(TRUE, r); + memset (&item, 0, sizeof (item)); + item.mask = LVIF_TEXT; + item.pszText = LPSTR_TEXTCALLBACK; + item.iItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); + ok(r == 0, "ret %d\n", r); + memset (&item, 0, sizeof (item)); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + item.pszText = LPSTR_TEXTCALLBACK; + r = SendMessage(hwnd, LVM_SETITEMTEXT, 0 , (LPARAM) &item); + expect(TRUE, r); + + ok_sequence(sequences, PARENT_SEQ_INDEX, textcallback_set_again_parent_seq, + "check callback text comparison rule", FALSE); + DestroyWindow(hwnd); } static void test_columns(void) { - HWND hwnd, hwndheader; - LVCOLUMN column; - DWORD rc; + HWND hwnd; + LVCOLUMNA column; + LVITEMA item; INT order[2]; + CHAR buff[5]; + DWORD rc; - hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT, + hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_REPORT, 10, 10, 100, 200, hwndparent, NULL, NULL, NULL); ok(hwnd != NULL, "failed to create listview window\n"); /* Add a column with no mask */ memset(&column, 0xcc, sizeof(column)); column.mask = 0; - rc = ListView_InsertColumn(hwnd, 0, &column); - ok(rc==0, "Inserting column with no mask failed with %d\n", rc); + rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column); + ok(rc == 0, "Inserting column with no mask failed with %d\n", rc); /* Check its width */ - rc = ListView_GetColumnWidth(hwnd, 0); - ok(rc==10 || - broken(rc==0), /* win9x */ + rc = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); + ok(rc == 10 || broken(rc == 0) /* win9x */, "Inserting column with no mask failed to set width to 10 with %d\n", rc); DestroyWindow(hwnd); /* LVM_GETCOLUMNORDERARRAY */ - hwnd = create_listview_control(0); - hwndheader = subclass_header(hwnd); + hwnd = create_listview_control(LVS_REPORT); + subclass_header(hwnd); memset(&column, 0, sizeof(column)); column.mask = LVCF_WIDTH; column.cx = 100; - rc = ListView_InsertColumn(hwnd, 0, &column); + rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column); ok(rc == 0, "Inserting column failed with %d\n", rc); column.cx = 200; - rc = ListView_InsertColumn(hwnd, 1, &column); + rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&column); ok(rc == 1, "Inserting column failed with %d\n", rc); flush_sequences(sequences, NUM_MSG_SEQUENCES); - rc = SendMessage(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&order); - ok(rc != 0, "Expected LVM_GETCOLUMNORDERARRAY to succeed\n"); + rc = SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&order); + ok(rc == 1, "Expected LVM_GETCOLUMNORDERARRAY to succeed\n"); ok(order[0] == 0, "Expected order 0, got %d\n", order[0]); ok(order[1] == 1, "Expected order 1, got %d\n", order[1]); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_getorderarray_seq, "get order array", FALSE); + /* after column added subitem is considered as present */ + insert_item(hwnd, 0); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + item.pszText = buff; + item.cchTextMax = sizeof(buff); + item.iItem = 0; + item.iSubItem = 1; + item.mask = LVIF_TEXT; + memset(&g_itema, 0, sizeof(g_itema)); + rc = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + ok(rc == 1, "got %d\n", rc); + ok(g_itema.iSubItem == 1, "got %d\n", g_itema.iSubItem); + + ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, + "get subitem text after column added", FALSE); + DestroyWindow(hwnd); } + /* test setting imagelist between WM_NCCREATE and WM_CREATE */ static WNDPROC listviewWndProc; static HIMAGELIST test_create_imagelist; @@ -907,6 +1289,8 @@ static void test_create(void) LVCOLUMNA col; RECT rect; WNDCLASSEX cls; + DWORD style; + cls.cbSize = sizeof(WNDCLASSEX); ok(GetClassInfoEx(GetModuleHandle(NULL), "SysListView32", &cls), "GetClassInfoEx failed\n"); listviewWndProc = cls.lpfnWndProc; @@ -918,6 +1302,15 @@ static void test_create(void) hList = CreateWindow("MyListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0); ok((HIMAGELIST)SendMessage(hList, LVM_GETIMAGELIST, 0, 0) == test_create_imagelist, "Image list not obtained\n"); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); + + if (!IsWindow(hHeader)) + { + /* version 4.0 */ + win_skip("LVM_GETHEADER not implemented. Skipping.\n"); + DestroyWindow(hList); + return; + } + ok(IsWindow(hHeader) && IsWindowVisible(hHeader), "Listview not in report mode\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); DestroyWindow(hList); @@ -937,6 +1330,8 @@ static void test_create(void) hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); ok(IsWindow(hHeader), "Header should be created\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); + style = GetWindowLong(hHeader, GWL_STYLE); + ok(!(style & HDS_HIDDEN), "Not expected HDS_HIDDEN\n"); DestroyWindow(hList); hList = CreateWindow("SysListView32", "Test", WS_VISIBLE|LVS_LIST, 0, 0, 100, 100, NULL, NULL, @@ -1033,12 +1428,14 @@ static void test_create(void) ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_HEADERDRAGDROP); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - ok(IsWindow(hHeader), "Header should be created\n"); + ok(IsWindow(hHeader) || + broken(!IsWindow(hHeader)), /* 4.7x common controls */ + "Header should be created\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); DestroyWindow(hList); /* not report style accepts LVS_EX_HEADERDRAGDROP too */ - hList = create_custom_listview_control(0); + hList = create_listview_control(LVS_ICON); SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_HEADERDRAGDROP); r = SendMessage(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); ok(r & LVS_EX_HEADERDRAGDROP, "Expected LVS_EX_HEADERDRAGDROP to be set\n"); @@ -1061,17 +1458,24 @@ static void test_create(void) ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); DestroyWindow(hList); + + /* WM_MEASUREITEM should be sent when created with LVS_OWNERDRAWFIXED */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + hList = create_listview_control(LVS_OWNERDRAWFIXED | LVS_REPORT); + ok_sequence(sequences, PARENT_SEQ_INDEX, create_ownerdrawfixed_parent_seq, + "created with LVS_OWNERDRAWFIXED|LVS_REPORT - parent seq", FALSE); + DestroyWindow(hList); } static void test_redraw(void) { - HWND hwnd, hwndheader; + HWND hwnd; HDC hdc; BOOL res; DWORD r; - hwnd = create_listview_control(0); - hwndheader = subclass_header(hwnd); + hwnd = create_listview_control(LVS_REPORT); + subclass_header(hwnd); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1167,7 +1571,7 @@ static void test_customdraw(void) HWND hwnd; WNDPROC oldwndproc; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); insert_column(hwnd, 0); insert_column(hwnd, 1); @@ -1193,10 +1597,10 @@ static void test_icon_spacing(void) WORD w, h; DWORD r; - hwnd = create_custom_listview_control(LVS_ICON); + hwnd = create_listview_control(LVS_ICON); ok(hwnd != NULL, "failed to create a listview window\n"); - r = SendMessage(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwndparent, (LPARAM)NF_REQUERY); + r = SendMessage(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwndparent, NF_REQUERY); expect(NFR_ANSI, r); /* reset the icon spacing to defaults */ @@ -1217,6 +1621,13 @@ static void test_icon_spacing(void) "Expected %d, got %d\n", MAKELONG(w, h), r); r = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(25, 35)); + if (r == 0) + { + /* version 4.0 */ + win_skip("LVM_SETICONSPACING unimplemented. Skipping.\n"); + DestroyWindow(hwnd); + return; + } expect(MAKELONG(20,30), r); r = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1,-1)); @@ -1239,7 +1650,7 @@ static void test_color(void) COLORREF color; COLORREF colors[4] = {RGB(0,0,0), RGB(100,50,200), CLR_NONE, RGB(255,255,255)}; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1277,6 +1688,11 @@ static void test_item_count(void) HWND hwnd; DWORD r; + HDC hdc; + HFONT hOldFont; + TEXTMETRICA tm; + RECT rect; + INT height; LVITEM item0; LVITEM item1; @@ -1285,9 +1701,22 @@ static void test_item_count(void) static CHAR item1text[] = "item1"; static CHAR item2text[] = "item2"; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); + /* resize in dpiaware manner to fit all 3 items added */ + hdc = GetDC(0); + hOldFont = SelectObject(hdc, GetStockObject(SYSTEM_FONT)); + GetTextMetricsA(hdc, &tm); + /* 2 extra pixels for bounds and header border */ + height = tm.tmHeight + 2; + SelectObject(hdc, hOldFont); + ReleaseDC(0, hdc); + + GetWindowRect(hwnd, &rect); + /* 3 items + 1 header + 1 to be sure */ + MoveWindow(hwnd, 0, 0, rect.right - rect.left, 5 * height, FALSE); + flush_sequences(sequences, NUM_MSG_SEQUENCES); trace("test item count\n"); @@ -1375,7 +1804,7 @@ static void test_item_position(void) static CHAR item1text[] = "item1"; static CHAR item2text[] = "item2"; - hwnd = create_custom_listview_control(LVS_ICON); + hwnd = create_listview_control(LVS_ICON); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1440,7 +1869,7 @@ static void test_getorigin(void) position.x = position.y = 0; - hwnd = create_custom_listview_control(LVS_ICON); + hwnd = create_listview_control(LVS_ICON); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); trace("test get origin results\n"); @@ -1449,7 +1878,7 @@ static void test_getorigin(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(hwnd); - hwnd = create_custom_listview_control(LVS_SMALLICON); + hwnd = create_listview_control(LVS_SMALLICON); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); trace("test get origin results\n"); @@ -1458,7 +1887,7 @@ static void test_getorigin(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(hwnd); - hwnd = create_custom_listview_control(LVS_LIST); + hwnd = create_listview_control(LVS_LIST); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); trace("test get origin results\n"); @@ -1467,7 +1896,7 @@ static void test_getorigin(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(hwnd); - hwnd = create_custom_listview_control(LVS_REPORT); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); trace("test get origin results\n"); @@ -1496,6 +1925,7 @@ static void test_multiselect(void) BYTE kstate[256]; select_task task; LONG_PTR style; + LVITEMA item; static struct t_select_task task_list[] = { { "using VK_DOWN", 0, VK_DOWN, -1, -1 }, @@ -1505,7 +1935,7 @@ static void test_multiselect(void) }; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); for (i=0;i rect2.top, "expected not zero height\n"); +} + + arr[0] = 1; arr[1] = 0; arr[2] = 2; + r = SendMessage(hwnd, LVM_SETCOLUMNORDERARRAY, 3, (LPARAM)arr); + expect(TRUE, r); + + rect.left = LVIR_BOUNDS; + rect.top = 0; + rect.right = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); + ok(r == TRUE, "got %d\n", r); + expect(0, rect.left); + expect(600, rect.right); + + rect.left = LVIR_BOUNDS; + rect.top = 1; + rect.right = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); + ok(r == TRUE, "got %d\n", r); + expect(0, rect.left); + expect(200, rect.right); + + rect2.left = LVIR_BOUNDS; + rect2.top = 1; + rect2.right = rect2.bottom = -1; + r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 1, (LPARAM)&rect2); + ok(r == TRUE, "got %d\n", r); + expect(0, rect2.left); + expect(200, rect2.right); + /* items are of the same height */ + ok(rect2.top > 0, "expected positive item height\n"); + expect(rect.bottom, rect2.top); + expect(rect.bottom * 2 - rect.top, rect2.bottom); + + rect.left = LVIR_BOUNDS; + rect.top = 2; + rect.right = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); + ok(r == TRUE, "got %d\n", r); + expect(300, rect.left); + expect(600, rect.right); + DestroyWindow(hwnd); /* try it for non LVS_REPORT style */ @@ -1696,7 +2300,7 @@ static void test_sorting(void) static CHAR names[][5] = {"A", "B", "C", "D", "0"}; CHAR buff[10]; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); /* insert some items */ @@ -1746,7 +2350,7 @@ static void test_sorting(void) DestroyWindow(hwnd); /* switch to LVS_SORTASCENDING when some items added */ - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); item.mask = LVIF_TEXT; @@ -1873,24 +2477,31 @@ static void test_ownerdata(void) LVITEMA item; /* it isn't possible to set LVS_OWNERDATA after creation */ - hwnd = create_listview_control(0); - ok(hwnd != NULL, "failed to create a listview window\n"); - style = GetWindowLongPtrA(hwnd, GWL_STYLE); - ok(!(style & LVS_OWNERDATA) && style, "LVS_OWNERDATA isn't expected\n"); + if (g_is_below_5) + { + win_skip("set LVS_OWNERDATA after creation leads to crash on < 5.80\n"); + } + else + { + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(!(style & LVS_OWNERDATA) && style, "LVS_OWNERDATA isn't expected\n"); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + flush_sequences(sequences, NUM_MSG_SEQUENCES); - ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA); - ok(ret == style, "Expected set GWL_STYLE to succeed\n"); - ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq, + ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA); + ok(ret == style, "Expected set GWL_STYLE to succeed\n"); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq, "try to switch to LVS_OWNERDATA seq", FALSE); - style = GetWindowLongPtrA(hwnd, GWL_STYLE); - ok(!(style & LVS_OWNERDATA), "LVS_OWNERDATA isn't expected\n"); - DestroyWindow(hwnd); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(!(style & LVS_OWNERDATA), "LVS_OWNERDATA isn't expected\n"); + DestroyWindow(hwnd); + } /* try to set LVS_OWNERDATA after creation just having it */ - hwnd = create_listview_control(LVS_OWNERDATA); + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); style = GetWindowLongPtrA(hwnd, GWL_STYLE); ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n"); @@ -1904,23 +2515,30 @@ static void test_ownerdata(void) DestroyWindow(hwnd); /* try to remove LVS_OWNERDATA after creation just having it */ - hwnd = create_listview_control(LVS_OWNERDATA); - ok(hwnd != NULL, "failed to create a listview window\n"); - style = GetWindowLongPtrA(hwnd, GWL_STYLE); - ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n"); + if (g_is_below_5) + { + win_skip("remove LVS_OWNERDATA after creation leads to crash on < 5.80\n"); + } + else + { + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n"); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + flush_sequences(sequences, NUM_MSG_SEQUENCES); - ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_OWNERDATA); - ok(ret == style, "Expected set GWL_STYLE to succeed\n"); - ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq, + ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_OWNERDATA); + ok(ret == style, "Expected set GWL_STYLE to succeed\n"); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq, "try to switch to LVS_OWNERDATA seq", FALSE); - style = GetWindowLongPtrA(hwnd, GWL_STYLE); - ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n"); - DestroyWindow(hwnd); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n"); + DestroyWindow(hwnd); + } /* try select an item */ - hwnd = create_listview_control(LVS_OWNERDATA); + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); @@ -1938,7 +2556,7 @@ static void test_ownerdata(void) DestroyWindow(hwnd); /* LVM_SETITEM is unsupported on LVS_OWNERDATA */ - hwnd = create_listview_control(LVS_OWNERDATA); + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); @@ -1952,6 +2570,224 @@ static void test_ownerdata(void) res = SendMessageA(hwnd, LVM_SETITEM, 0, (LPARAM)&item); expect(FALSE, res); DestroyWindow(hwnd); + + /* check notifications after focused/selected changed */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 20, 0); + ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + "ownerdata select notification", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + "ownerdata focus notification", TRUE); + + /* select all, check notifications */ + item.stateMask = LVIS_SELECTED; + item.state = 0; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq, + "ownerdata select all notification", TRUE); + + /* select all again, note that all items are selected already */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq, + "ownerdata select all notification", TRUE); + /* deselect all */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_SELECTED; + item.state = 0; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq, + "ownerdata deselect all notification", TRUE); + + /* select one, then deselect all */ + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_SELECTED; + item.state = 0; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq, + "ownerdata select all notification", TRUE); + + /* remove focused, try to focus all */ + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + item.stateMask = LVIS_FOCUSED; + item.state = 0; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + item.stateMask = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_FOCUSED); + expect(0, res); + /* setting all to focused returns failure value */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(FALSE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata focus all notification", FALSE); + /* focus single item, remove all */ + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessage(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_FOCUSED; + item.state = 0; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_defocus_all_parent_seq, + "ownerdata remove focus all notification", TRUE); + /* set all cut */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_CUT; + item.state = LVIS_CUT; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq, + "ownerdata cut all notification", TRUE); + /* all marked cut, try again */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + item.stateMask = LVIS_CUT; + item.state = LVIS_CUT; + g_dump_itemchanged = TRUE; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, res); + g_dump_itemchanged = FALSE; + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq, + "ownerdata cut all notification #2", TRUE); + + DestroyWindow(hwnd); + + /* check notifications on LVM_GETITEM */ + /* zero callback mask */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); + ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata getitem selected state 1", FALSE); + + /* non zero callback mask but not we asking for */ + res = SendMessageA(hwnd, LVM_SETCALLBACKMASK, LVIS_OVERLAYMASK, 0); + expect(TRUE, res); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata getitem selected state 2", FALSE); + + /* LVIS_OVERLAYMASK callback mask, asking for index */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_OVERLAYMASK; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, + "ownerdata getitem selected state 2", FALSE); + + DestroyWindow(hwnd); + + /* LVS_SORTASCENDING/LVS_SORTDESCENDING aren't compatible with LVS_OWNERDATA */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_SORTASCENDING | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n"); + ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n"); + SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SORTASCENDING); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(!(style & LVS_SORTASCENDING), "Expected LVS_SORTASCENDING not set\n"); + DestroyWindow(hwnd); + /* apparently it's allowed to switch these style on after creation */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n"); + SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTASCENDING); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n"); + DestroyWindow(hwnd); + + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n"); + SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTDESCENDING); + style = GetWindowLongPtrA(hwnd, GWL_STYLE); + ok(style & LVS_SORTDESCENDING, "Expected LVS_SORTDESCENDING to be set\n"); + DestroyWindow(hwnd); } static void test_norecompute(void) @@ -1963,7 +2799,7 @@ static void test_norecompute(void) DWORD res; /* self containing control */ - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); memset(&item, 0, sizeof(item)); item.mask = LVIF_TEXT | LVIF_STATE; @@ -2003,7 +2839,7 @@ static void test_norecompute(void) DestroyWindow(hwnd); /* LVS_OWNERDATA */ - hwnd = create_listview_control(LVS_OWNERDATA); + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); item.mask = LVIF_STATE; @@ -2032,7 +2868,7 @@ static void test_nosortheader(void) HWND hwnd, header; LONG_PTR style; - hwnd = create_listview_control(0); + hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0); @@ -2050,7 +2886,7 @@ static void test_nosortheader(void) DestroyWindow(hwnd); /* create with LVS_NOSORTHEADER */ - hwnd = create_listview_control(LVS_NOSORTHEADER); + hwnd = create_listview_control(LVS_NOSORTHEADER | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0); @@ -2068,11 +2904,1626 @@ static void test_nosortheader(void) DestroyWindow(hwnd); } +static void test_setredraw(void) +{ + HWND hwnd; + DWORD_PTR style; + DWORD ret; + HDC hdc; + RECT rect; + + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* Passing WM_SETREDRAW to DefWinProc removes WS_VISIBLE. + ListView seems to handle it internally without DefWinProc */ + + /* default value first */ + ret = SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + expect(0, ret); + /* disable */ + style = GetWindowLongPtr(hwnd, GWL_STYLE); + ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n"); + ret = SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + expect(0, ret); + style = GetWindowLongPtr(hwnd, GWL_STYLE); + ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n"); + ret = SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + expect(0, ret); + + /* check update rect after redrawing */ + ret = SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + expect(0, ret); + InvalidateRect(hwnd, NULL, FALSE); + RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW); + rect.right = rect.bottom = 1; + GetUpdateRect(hwnd, &rect, FALSE); + expect(0, rect.right); + expect(0, rect.bottom); + + /* WM_ERASEBKGND */ + hdc = GetWindowDC(hwndparent); + ret = SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); + expect(TRUE, ret); + ret = SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + expect(0, ret); + ret = SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); + expect(TRUE, ret); + ret = SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + expect(0, ret); + ReleaseDC(hwndparent, hdc); + + /* check notification messages to show that repainting is disabled */ + ret = SendMessage(hwnd, LVM_SETITEMCOUNT, 1, 0); + expect(TRUE, ret); + ret = SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + expect(0, ret); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "redraw after WM_SETREDRAW (FALSE)", FALSE); + + ret = SendMessage(hwnd, LVM_SETBKCOLOR, 0, CLR_NONE); + expect(TRUE, ret); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "redraw after WM_SETREDRAW (FALSE) with CLR_NONE bkgnd", FALSE); + + /* message isn't forwarded to header */ + subclass_header(hwnd); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + expect(0, ret); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, setredraw_seq, + "WM_SETREDRAW: not forwarded to header", FALSE); + + DestroyWindow(hwnd); +} + +static void test_hittest(void) +{ + HWND hwnd; + DWORD r; + RECT bounds; + LVITEMA item; + static CHAR text[] = "1234567890ABCDEFGHIJKLMNOPQRST"; + POINT pos; + INT x, y; + HIMAGELIST himl, himl2; + HBITMAP hbmp; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* LVS_REPORT with a single subitem (2 columns) */ + insert_column(hwnd, 0); + insert_column(hwnd, 1); + insert_item(hwnd, 0); + + item.iSubItem = 0; + /* the only purpose of that line is to be as long as a half item rect */ + item.pszText = text; + r = SendMessage(hwnd, LVM_SETITEMTEXT, 0, (LPARAM)&item); + expect(TRUE, r); + + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0)); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(100, 0)); + expect(TRUE, r); + + memset(&bounds, 0, sizeof(bounds)); + bounds.left = LVIR_BOUNDS; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&bounds); + ok(bounds.bottom - bounds.top > 0, "Expected non zero item height\n"); + ok(bounds.right - bounds.left > 0, "Expected non zero item width\n"); + r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pos); + expect(TRUE, r); + + /* LVS_EX_FULLROWSELECT not set, no icons attached */ + + /* outside columns by x position - valid is [0, 199] */ + x = -1; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TOLEFT, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + + x = pos.x + 50; /* column half width */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMLABEL, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + /* outside possible client rectangle (to right) */ + x = pos.x + 500; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + /* subitem returned with -1 item too */ + x = pos.x + 150; + y = -10; + test_lvm_subitemhittest(hwnd, x, y, -1, 1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + /* parent client area is 100x100 by default */ + MoveWindow(hwnd, 0, 0, 300, 100, FALSE); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_NOWHERE, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_NOWHERE, 0, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + /* the same with LVS_EX_FULLROWSELECT */ + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEM, LVHT_ONITEMLABEL, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + MoveWindow(hwnd, 0, 0, 100, 100, FALSE); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE); + /* outside possible client rectangle (to right) */ + x = pos.x + 500; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + /* try with icons, state icons index is 1 based so at least 2 bitmaps needed */ + himl = ImageList_Create(16, 16, 0, 4, 4); + ok(himl != NULL, "failed to create imagelist\n"); + hbmp = CreateBitmap(16, 16, 1, 1, NULL); + ok(hbmp != NULL, "failed to create bitmap\n"); + r = ImageList_Add(himl, hbmp, 0); + ok(r == 0, "should be zero\n"); + hbmp = CreateBitmap(16, 16, 1, 1, NULL); + ok(hbmp != NULL, "failed to create bitmap\n"); + r = ImageList_Add(himl, hbmp, 0); + ok(r == 1, "should be one\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + + item.mask = LVIF_IMAGE; + item.iImage = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + /* on state icon */ + x = pos.x + 8; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMSTATEICON, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE); + + /* state icons indices are 1 based, check with valid index */ + item.mask = LVIF_STATE; + item.state = INDEXTOSTATEIMAGEMASK(1); + item.stateMask = LVIS_STATEIMAGEMASK; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + /* on state icon */ + x = pos.x + 8; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMSTATEICON, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE); + + himl2 = (HIMAGELIST)SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0); + ok(himl2 == himl, "should return handle\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + /* on item icon */ + x = pos.x + 8; + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMICON, 0, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMICON, FALSE, FALSE, FALSE); + y = (bounds.bottom - bounds.top) / 2; + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMICON, FALSE, FALSE, FALSE); + + DestroyWindow(hwnd); +} + +static void test_getviewrect(void) +{ + HWND hwnd; + DWORD r; + RECT rect; + LVITEMA item; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* empty */ + r = SendMessage(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + + insert_column(hwnd, 0); + insert_column(hwnd, 1); + + memset(&item, 0, sizeof(item)); + item.iItem = 0; + item.iSubItem = 0; + SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0)); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(120, 0)); + expect(TRUE, r); + + rect.left = rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* left is set to (2e31-1) - XP SP2 */ + expect(0, rect.right); + expect(0, rect.top); + expect(0, rect.bottom); + + /* switch to LVS_ICON */ + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~LVS_REPORT); + + rect.left = rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + expect(0, rect.left); + expect(0, rect.top); + /* precise value differs for 2k, XP and Vista */ + ok(rect.bottom > 0, "Expected positive bottom value, got %d\n", rect.bottom); + ok(rect.right > 0, "Expected positive right value, got %d\n", rect.right); + + DestroyWindow(hwnd); +} + +static void test_getitemposition(void) +{ + HWND hwnd, header; + DWORD r; + POINT pt; + RECT rect; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = subclass_header(hwnd); + + /* LVS_REPORT, single item, no columns added */ + insert_item(hwnd, 0); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + pt.x = pt.y = -1; + r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt); + expect(TRUE, r); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, getitemposition_seq1, "get item position 1", FALSE); + + /* LVS_REPORT, single item, single column */ + insert_column(hwnd, 0); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + pt.x = pt.y = -1; + r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt); + expect(TRUE, r); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, getitemposition_seq2, "get item position 2", TRUE); + + memset(&rect, 0, sizeof(rect)); + SendMessage(header, HDM_GETITEMRECT, 0, (LPARAM)&rect); + /* some padding? */ + expect(2, pt.x); + /* offset by header height */ + expect(rect.bottom - rect.top, pt.y); + + DestroyWindow(hwnd); +} + +static void test_columnscreation(void) +{ + HWND hwnd, header; + DWORD r; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + insert_item(hwnd, 0); + + /* headers columns aren't created automatically */ + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header handle\n"); + r = SendMessage(header, HDM_GETITEMCOUNT, 0, 0); + expect(0, r); + + DestroyWindow(hwnd); +} + +static void test_getitemrect(void) +{ + HWND hwnd; + HIMAGELIST himl; + HBITMAP hbm; + RECT rect; + DWORD r; + LVITEMA item; + LVCOLUMNA col; + INT order[2]; + POINT pt; + + /* rectangle isn't empty for empty text items */ + hwnd = create_listview_control(LVS_LIST); + memset(&item, 0, sizeof(item)); + item.mask = 0; + item.iItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + expect(0, r); + rect.left = LVIR_LABEL; + SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(0, rect.left); + expect(0, rect.top); + todo_wine expect(96, rect.right); + DestroyWindow(hwnd); + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* empty item */ + memset(&item, 0, sizeof(item)); + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + expect(0, r); + + rect.left = LVIR_BOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + + /* zero width rectangle with no padding */ + expect(0, rect.left); + expect(0, rect.right); + + insert_column(hwnd, 0); + insert_column(hwnd, 1); + + col.mask = LVCF_WIDTH; + col.cx = 50; + r = SendMessage(hwnd, LVM_SETCOLUMN, 0, (LPARAM)&col); + expect(TRUE, r); + + col.mask = LVCF_WIDTH; + col.cx = 100; + r = SendMessage(hwnd, LVM_SETCOLUMN, 1, (LPARAM)&col); + expect(TRUE, r); + + rect.left = LVIR_BOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + + /* still no left padding */ + expect(0, rect.left); + expect(150, rect.right); + + rect.left = LVIR_SELECTBOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding */ + expect(2, rect.left); + + rect.left = LVIR_LABEL; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding, column width */ + expect(2, rect.left); + expect(50, rect.right); + + /* no icons attached */ + rect.left = LVIR_ICON; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding */ + expect(2, rect.left); + expect(2, rect.right); + + /* change order */ + order[0] = 1; order[1] = 0; + r = SendMessage(hwnd, LVM_SETCOLUMNORDERARRAY, 2, (LPARAM)&order); + expect(TRUE, r); + pt.x = -1; + r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt); + expect(TRUE, r); + /* 1 indexed column width + padding */ + expect(102, pt.x); + /* rect is at zero too */ + rect.left = LVIR_BOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + expect(0, rect.left); + /* just width sum */ + expect(150, rect.right); + + rect.left = LVIR_SELECTBOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* column width + padding */ + expect(102, rect.left); + + /* back to initial order */ + order[0] = 0; order[1] = 1; + r = SendMessage(hwnd, LVM_SETCOLUMNORDERARRAY, 2, (LPARAM)&order); + expect(TRUE, r); + + /* state icons */ + himl = ImageList_Create(16, 16, 0, 2, 2); + ok(himl != NULL, "failed to create imagelist\n"); + hbm = CreateBitmap(16, 16, 1, 1, NULL); + ok(hbm != NULL, "failed to create bitmap\n"); + r = ImageList_Add(himl, hbm, 0); + ok(r == 0, "should be zero\n"); + hbm = CreateBitmap(16, 16, 1, 1, NULL); + ok(hbm != NULL, "failed to create bitmap\n"); + r = ImageList_Add(himl, hbm, 0); + ok(r == 1, "should be one\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + + item.mask = LVIF_STATE; + item.state = INDEXTOSTATEIMAGEMASK(1); + item.stateMask = LVIS_STATEIMAGEMASK; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + + /* icon bounds */ + rect.left = LVIR_ICON; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + stateicon width */ + expect(18, rect.left); + expect(18, rect.right); + /* label bounds */ + rect.left = LVIR_LABEL; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + stateicon width -> column width */ + expect(18, rect.left); + expect(50, rect.right); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0); + ok(r != 0, "should return current list handle\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + + item.mask = LVIF_STATE | LVIF_IMAGE; + item.iImage = 1; + item.state = 0; + item.stateMask = ~0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + + /* icon bounds */ + rect.left = LVIR_ICON; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding, icon width */ + expect(2, rect.left); + expect(18, rect.right); + /* label bounds */ + rect.left = LVIR_LABEL; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + icon width -> column width */ + expect(18, rect.left); + expect(50, rect.right); + + /* select bounds */ + rect.left = LVIR_SELECTBOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding, column width */ + expect(2, rect.left); + expect(50, rect.right); + + /* try with indentation */ + item.mask = LVIF_INDENT; + item.iIndent = 1; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + + /* bounds */ + rect.left = LVIR_BOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + 1 icon width, column width */ + expect(0, rect.left); + expect(150, rect.right); + + /* select bounds */ + rect.left = LVIR_SELECTBOUNDS; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + 1 icon width, column width */ + expect(2 + 16, rect.left); + expect(50, rect.right); + + /* label bounds */ + rect.left = LVIR_LABEL; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + 2 icon widths, column width */ + expect(2 + 16*2, rect.left); + expect(50, rect.right); + + /* icon bounds */ + rect.left = LVIR_ICON; + rect.right = rect.top = rect.bottom = -1; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); + /* padding + 1 icon width indentation, icon width */ + expect(2 + 16, rect.left); + expect(34, rect.right); + + DestroyWindow(hwnd); +} + +static void test_editbox(void) +{ + static CHAR testitemA[] = "testitem"; + static CHAR testitem1A[] = "testitem_quitelongname"; + static CHAR buffer[25]; + HWND hwnd, hwndedit, hwndedit2, header; + LVITEMA item; + DWORD r; + + hwnd = create_listview_control(LVS_EDITLABELS | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + insert_column(hwnd, 0); + + memset(&item, 0, sizeof(item)); + item.mask = LVIF_TEXT; + item.pszText = testitemA; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + expect(0, r); + + /* test notifications without edit created */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)0xdeadbeef); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "edit box WM_COMMAND (EN_SETFOCUS), no edit created", FALSE); + /* same thing but with valid window */ + hwndedit = CreateWindowA("Edit", "Test edit", WS_VISIBLE | WS_CHILD, 0, 0, 20, + 10, hwnd, (HMENU)1, (HINSTANCE)GetWindowLongPtrA(hwnd, GWLP_HINSTANCE), 0); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)hwndedit); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "edit box WM_COMMAND (EN_SETFOCUS), no edit created #2", FALSE); + DestroyWindow(hwndedit); + + /* setting focus is necessary */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + + /* test children Z-order after Edit box created */ + header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header to be created\n"); + ok(GetTopWindow(hwnd) == header, "Expected header to be on top\n"); + ok(GetNextWindow(header, GW_HWNDNEXT) == hwndedit, "got %p\n", GetNextWindow(header, GW_HWNDNEXT)); + + /* modify initial string */ + r = SendMessage(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem1A); + expect(TRUE, r); + + /* edit window is resized and repositioned, + check again for Z-order - it should be preserved */ + ok(GetTopWindow(hwnd) == header, "Expected header to be on top\n"); + ok(GetNextWindow(header, GW_HWNDNEXT) == hwndedit, "got %p\n", GetNextWindow(header, GW_HWNDNEXT)); + + /* return focus to listview */ + SetFocus(hwnd); + + memset(&item, 0, sizeof(item)); + item.mask = LVIF_TEXT; + item.pszText = buffer; + item.cchTextMax = sizeof(buffer); + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, r); + + ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n"); + + /* send LVM_EDITLABEL on already created edit */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + /* focus will be set to edit */ + ok(GetFocus() == hwndedit, "Expected Edit window to be focused\n"); + hwndedit2 = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit2), "Expected Edit window to be created\n"); + + /* creating label disabled when control isn't focused */ + SetFocus(0); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + todo_wine ok(hwndedit == NULL, "Expected Edit window not to be created\n"); + + /* check EN_KILLFOCUS handling */ + memset(&item, 0, sizeof(item)); + item.pszText = testitemA; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item); + expect(TRUE, r); + + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + /* modify edit and notify control that it lost focus */ + r = SendMessage(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem1A); + expect(TRUE, r); + r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit); + expect(0, r); + memset(&item, 0, sizeof(item)); + item.pszText = buffer; + item.cchTextMax = sizeof(buffer); + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item); + expect(lstrlen(item.pszText), r); + ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n"); + ok(!IsWindow(hwndedit), "Expected Edit window to be freed\n"); + /* end edit without saving */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwndedit, WM_KEYDOWN, VK_ESCAPE, 0); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange, + "edit box - end edit, no change, escape", TRUE); + /* end edit with saving */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwndedit, WM_KEYDOWN, VK_RETURN, 0); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange, + "edit box - end edit, no change, return", TRUE); + + memset(&item, 0, sizeof(item)); + item.pszText = buffer; + item.cchTextMax = sizeof(buffer); + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item); + expect(lstrlen(item.pszText), r); + ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n"); + + /* LVM_EDITLABEL with -1 destroys current edit */ + hwndedit = (HWND)SendMessage(hwnd, LVM_GETEDITCONTROL, 0, 0); + ok(hwndedit == NULL, "Expected Edit window not to be created\n"); + /* no edit present */ + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, -1, 0); + ok(hwndedit == NULL, "Expected Edit window not to be created\n"); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + /* edit present */ + ok(GetFocus() == hwndedit, "Expected Edit to be focused\n"); + hwndedit2 = (HWND)SendMessage(hwnd, LVM_EDITLABEL, -1, 0); + ok(hwndedit2 == NULL, "Expected Edit window not to be created\n"); + ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n"); + ok(GetFocus() == hwnd, "Expected List to be focused\n"); + /* check another negative value */ + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + ok(GetFocus() == hwndedit, "Expected Edit to be focused\n"); + hwndedit2 = (HWND)SendMessage(hwnd, LVM_EDITLABEL, -2, 0); + ok(hwndedit2 == NULL, "Expected Edit window not to be created\n"); + ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n"); + ok(GetFocus() == hwnd, "Expected List to be focused\n"); + /* and value greater than max item index */ + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + ok(GetFocus() == hwndedit, "Expected Edit to be focused\n"); + r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0); + hwndedit2 = (HWND)SendMessage(hwnd, LVM_EDITLABEL, r, 0); + ok(hwndedit2 == NULL, "Expected Edit window not to be created\n"); + ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n"); + ok(GetFocus() == hwnd, "Expected List to be focused\n"); + + /* messaging tests */ + SetFocus(hwnd); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + blockEdit = FALSE; + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + /* testing only sizing messages */ + ok_sequence(sequences, EDITBOX_SEQ_INDEX, editbox_create_pos, + "edit box create - sizing", FALSE); + + /* WM_COMMAND with EN_KILLFOCUS isn't forwared to parent */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange, + "edit box WM_COMMAND (EN_KILLFOCUS)", TRUE); + + DestroyWindow(hwnd); +} + +static void test_notifyformat(void) +{ + HWND hwnd, header; + DWORD r; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* CCM_GETUNICODEFORMAT == LVM_GETUNICODEFORMAT, + CCM_SETUNICODEFORMAT == LVM_SETUNICODEFORMAT */ + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY); + /* set */ + r = SendMessage(hwnd, LVM_SETUNICODEFORMAT, 1, 0); + expect(0, r); + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + if (r == 1) + { + r = SendMessage(hwnd, LVM_SETUNICODEFORMAT, 0, 0); + expect(1, r); + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + } + else + { + win_skip("LVM_GETUNICODEFORMAT is unsupported\n"); + DestroyWindow(hwnd); + return; + } + + DestroyWindow(hwnd); + + /* test failure in parent WM_NOTIFYFORMAT */ + notifyFormat = 0; + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY); + ok(r != 0, "Expected valid format\n"); + + notifyFormat = NFR_UNICODE; + r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY); + expect(NFR_UNICODE, r); + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + + notifyFormat = NFR_ANSI; + r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY); + expect(NFR_ANSI, r); + r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + + DestroyWindow(hwnd); + + /* try different unicode window combination and defaults */ + if (!GetModuleHandleW(NULL)) + { + win_skip("Additional notify format tests are incompatible with Win9x\n"); + return; + } + + hwndparentW = create_parent_window(TRUE); + ok(IsWindow(hwndparentW), "Unicode parent creation failed\n"); + if (!IsWindow(hwndparentW)) return; + + notifyFormat = -1; + hwnd = create_listview_controlW(LVS_REPORT, hwndparentW); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + DestroyWindow(hwnd); + /* receiving error code defaulting to ansi */ + notifyFormat = 0; + hwnd = create_listview_controlW(LVS_REPORT, hwndparentW); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + DestroyWindow(hwnd); + /* receiving ansi code from unicode window, use it */ + notifyFormat = NFR_ANSI; + hwnd = create_listview_controlW(LVS_REPORT, hwndparentW); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + DestroyWindow(hwnd); + /* unicode listview with ansi parent window */ + notifyFormat = -1; + hwnd = create_listview_controlW(LVS_REPORT, hwndparent); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + DestroyWindow(hwnd); + /* unicode listview with ansi parent window, return error code */ + notifyFormat = 0; + hwnd = create_listview_controlW(LVS_REPORT, hwndparent); + ok(hwnd != NULL, "failed to create a listview window\n"); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "expected header to be created\n"); + r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0); + expect(0, r); + r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); + expect(1, r); + DestroyWindow(hwnd); + + DestroyWindow(hwndparentW); +} + +static void test_indentation(void) +{ + HWND hwnd; + LVITEMA item; + DWORD r; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + memset(&item, 0, sizeof(item)); + item.mask = LVIF_INDENT; + item.iItem = 0; + item.iIndent = I_INDENTCALLBACK; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + expect(0, r); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + item.iItem = 0; + item.mask = LVIF_INDENT; + r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + + ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, + "get indent dispinfo", FALSE); + + DestroyWindow(hwnd); +} + +static INT CALLBACK DummyCompareEx(LPARAM first, LPARAM second, LPARAM param) +{ + return 0; +} + +static BOOL is_below_comctl_5(void) +{ + HWND hwnd; + BOOL ret; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + insert_item(hwnd, 0); + + ret = SendMessage(hwnd, LVM_SORTITEMSEX, 0, (LPARAM)&DummyCompareEx); + + DestroyWindow(hwnd); + + return !ret; +} + +static void test_get_set_view(void) +{ + HWND hwnd; + DWORD ret; + DWORD_PTR style; + + /* test style->view mapping */ + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + ret = SendMessage(hwnd, LVM_GETVIEW, 0, 0); + expect(LV_VIEW_DETAILS, ret); + + style = GetWindowLongPtr(hwnd, GWL_STYLE); + /* LVS_ICON == 0 */ + SetWindowLongPtr(hwnd, GWL_STYLE, style & ~LVS_REPORT); + ret = SendMessage(hwnd, LVM_GETVIEW, 0, 0); + expect(LV_VIEW_ICON, ret); + + style = GetWindowLongPtr(hwnd, GWL_STYLE); + SetWindowLongPtr(hwnd, GWL_STYLE, style | LVS_SMALLICON); + ret = SendMessage(hwnd, LVM_GETVIEW, 0, 0); + expect(LV_VIEW_SMALLICON, ret); + + style = GetWindowLongPtr(hwnd, GWL_STYLE); + SetWindowLongPtr(hwnd, GWL_STYLE, (style & ~LVS_SMALLICON) | LVS_LIST); + ret = SendMessage(hwnd, LVM_GETVIEW, 0, 0); + expect(LV_VIEW_LIST, ret); + + /* switching view doesn't touch window style */ + ret = SendMessage(hwnd, LVM_SETVIEW, LV_VIEW_DETAILS, 0); + expect(1, ret); + style = GetWindowLongPtr(hwnd, GWL_STYLE); + ok(style & LVS_LIST, "Expected style to be preserved\n"); + ret = SendMessage(hwnd, LVM_SETVIEW, LV_VIEW_ICON, 0); + expect(1, ret); + style = GetWindowLongPtr(hwnd, GWL_STYLE); + ok(style & LVS_LIST, "Expected style to be preserved\n"); + ret = SendMessage(hwnd, LVM_SETVIEW, LV_VIEW_SMALLICON, 0); + expect(1, ret); + style = GetWindowLongPtr(hwnd, GWL_STYLE); + ok(style & LVS_LIST, "Expected style to be preserved\n"); + + DestroyWindow(hwnd); +} + +static void test_canceleditlabel(void) +{ + HWND hwnd, hwndedit; + DWORD ret; + CHAR buff[10]; + LVITEMA itema; + static CHAR test[] = "test"; + static const CHAR test1[] = "test1"; + + hwnd = create_listview_control(LVS_EDITLABELS | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + insert_item(hwnd, 0); + + /* try without edit created */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessage(hwnd, LVM_CANCELEDITLABEL, 0, 0); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "cancel edit label without edit", FALSE); + + /* cancel without data change */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected edit control to be created\n"); + ret = SendMessage(hwnd, LVM_CANCELEDITLABEL, 0, 0); + expect(TRUE, ret); + ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n"); + + /* cancel after data change */ + memset(&itema, 0, sizeof(itema)); + itema.pszText = test; + ret = SendMessage(hwnd, LVM_SETITEMTEXT, 0, (LPARAM)&itema); + expect(TRUE, ret); + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected edit control to be created\n"); + ret = SetWindowText(hwndedit, test1); + ok(ret != 0, "Expected edit text to change\n"); + ret = SendMessage(hwnd, LVM_CANCELEDITLABEL, 0, 0); + expect(TRUE, ret); + ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n"); + memset(&itema, 0, sizeof(itema)); + itema.pszText = buff; + itema.cchTextMax = sizeof(buff)/sizeof(CHAR); + ret = SendMessage(hwnd, LVM_GETITEMTEXT, 0, (LPARAM)&itema); + expect(5, ret); + ok(strcmp(buff, test1) == 0, "Expected label text not to change\n"); + + DestroyWindow(hwnd); +} + +static void test_mapidindex(void) +{ + HWND hwnd; + DWORD ret; + + /* LVM_MAPINDEXTOID unsupported with LVS_OWNERDATA */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + insert_item(hwnd, 0); + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 0, 0); + expect(-1, ret); + DestroyWindow(hwnd); + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* LVM_MAPINDEXTOID with invalid index */ + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 0, 0); + expect(-1, ret); + + insert_item(hwnd, 0); + insert_item(hwnd, 1); + + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, -1, 0); + expect(-1, ret); + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 2, 0); + expect(-1, ret); + + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 0, 0); + expect(0, ret); + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 1, 0); + expect(1, ret); + /* remove 0 indexed item, id retained */ + SendMessage(hwnd, LVM_DELETEITEM, 0, 0); + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 0, 0); + expect(1, ret); + /* new id starts from previous value */ + insert_item(hwnd, 1); + ret = SendMessage(hwnd, LVM_MAPINDEXTOID, 1, 0); + expect(2, ret); + + /* get index by id */ + ret = SendMessage(hwnd, LVM_MAPIDTOINDEX, -1, 0); + expect(-1, ret); + ret = SendMessage(hwnd, LVM_MAPIDTOINDEX, 0, 0); + expect(-1, ret); + ret = SendMessage(hwnd, LVM_MAPIDTOINDEX, 1, 0); + expect(0, ret); + ret = SendMessage(hwnd, LVM_MAPIDTOINDEX, 2, 0); + expect(1, ret); + + DestroyWindow(hwnd); +} + +static void test_getitemspacing(void) +{ + HWND hwnd; + DWORD ret; + INT cx, cy; + HIMAGELIST himl; + HBITMAP hbmp; + LVITEMA itema; + + cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON); + cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON); + + /* LVS_ICON */ + hwnd = create_listview_control(LVS_ICON); + ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0); +todo_wine { + expect(cx, LOWORD(ret)); + expect(cy, HIWORD(ret)); +} + /* now try with icons */ + himl = ImageList_Create(40, 40, 0, 4, 4); + ok(himl != NULL, "failed to create imagelist\n"); + hbmp = CreateBitmap(40, 40, 1, 1, NULL); + ok(hbmp != NULL, "failed to create bitmap\n"); + ret = ImageList_Add(himl, hbmp, 0); + expect(0, ret); + ret = SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl); + expect(0, ret); + + itema.mask = LVIF_IMAGE; + itema.iImage = 0; + itema.iItem = 0; + itema.iSubItem = 0; + ret = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM)&itema); + expect(0, ret); + ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0); +todo_wine { + /* spacing + icon size returned */ + expect(cx + 40, LOWORD(ret)); + expect(cy + 40, HIWORD(ret)); +} + DestroyWindow(hwnd); + /* LVS_SMALLICON */ + hwnd = create_listview_control(LVS_SMALLICON); + ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0); +todo_wine { + expect(cx, LOWORD(ret)); + expect(cy, HIWORD(ret)); +} + DestroyWindow(hwnd); + /* LVS_REPORT */ + hwnd = create_listview_control(LVS_REPORT); + ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0); +todo_wine { + expect(cx, LOWORD(ret)); + expect(cy, HIWORD(ret)); +} + DestroyWindow(hwnd); + /* LVS_LIST */ + hwnd = create_listview_control(LVS_LIST); + ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0); +todo_wine { + expect(cx, LOWORD(ret)); + expect(cy, HIWORD(ret)); +} + DestroyWindow(hwnd); +} + +static void test_getcolumnwidth(void) +{ + HWND hwnd; + DWORD ret; + DWORD_PTR style; + LVCOLUMNA col; + LVITEMA itema; + + /* default column width */ + hwnd = create_listview_control(LVS_ICON); + ret = SendMessage(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); + expect(0, ret); + style = GetWindowLong(hwnd, GWL_STYLE); + SetWindowLong(hwnd, GWL_STYLE, style | LVS_LIST); + ret = SendMessage(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); + todo_wine expect(8, ret); + style = GetWindowLong(hwnd, GWL_STYLE) & ~LVS_LIST; + SetWindowLong(hwnd, GWL_STYLE, style | LVS_REPORT); + col.mask = 0; + ret = SendMessage(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col); + expect(0, ret); + ret = SendMessage(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); + expect(10, ret); + DestroyWindow(hwnd); + + /* default column width with item added */ + hwnd = create_listview_control(LVS_LIST); + memset(&itema, 0, sizeof(itema)); + SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema); + ret = SendMessage(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); + todo_wine expect(96, ret); + DestroyWindow(hwnd); +} + +static void test_scrollnotify(void) +{ + HWND hwnd; + DWORD ret; + + hwnd = create_listview_control(LVS_REPORT); + + insert_column(hwnd, 0); + insert_column(hwnd, 1); + insert_item(hwnd, 0); + + /* make it scrollable - resize */ + ret = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0)); + expect(TRUE, ret); + ret = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(100, 0)); + expect(TRUE, ret); + + /* try with dummy call */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessage(hwnd, LVM_SCROLL, 0, 0); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq, + "scroll notify 1", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessage(hwnd, LVM_SCROLL, 1, 0); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq, + "scroll notify 2", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessage(hwnd, LVM_SCROLL, 1, 1); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq, + "scroll notify 3", TRUE); + + DestroyWindow(hwnd); +} + +static void test_LVS_EX_TRANSPARENTBKGND(void) +{ + HWND hwnd; + DWORD ret; + HDC hdc; + + hwnd = create_listview_control(LVS_REPORT); + + ret = SendMessage(hwnd, LVM_SETBKCOLOR, 0, RGB(0, 0, 0)); + expect(TRUE, ret); + + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTBKGND, + LVS_EX_TRANSPARENTBKGND); + + ret = SendMessage(hwnd, LVM_GETBKCOLOR, 0, 0); + if (ret != CLR_NONE) + { + win_skip("LVS_EX_TRANSPARENTBKGND unsupported\n"); + DestroyWindow(hwnd); + return; + } + + /* try to set some back color and check this style bit */ + ret = SendMessage(hwnd, LVM_SETBKCOLOR, 0, RGB(0, 0, 0)); + expect(TRUE, ret); + ret = SendMessage(hwnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); + ok(!(ret & LVS_EX_TRANSPARENTBKGND), "Expected LVS_EX_TRANSPARENTBKGND to unset\n"); + + /* now test what this style actually does */ + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTBKGND, + LVS_EX_TRANSPARENTBKGND); + + hdc = GetWindowDC(hwndparent); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); + ok_sequence(sequences, PARENT_SEQ_INDEX, lvs_ex_transparentbkgnd_seq, + "LVS_EX_TRANSPARENTBKGND parent", FALSE); + + ReleaseDC(hwndparent, hdc); + + DestroyWindow(hwnd); +} + +static void test_approximate_viewrect(void) +{ + HWND hwnd; + DWORD ret; + HIMAGELIST himl; + HBITMAP hbmp; + LVITEMA itema; + static CHAR test[] = "abracadabra, a very long item label"; + + hwnd = create_listview_control(LVS_ICON); + himl = ImageList_Create(40, 40, 0, 4, 4); + ok(himl != NULL, "failed to create imagelist\n"); + hbmp = CreateBitmap(40, 40, 1, 1, NULL); + ok(hbmp != NULL, "failed to create bitmap\n"); + ret = ImageList_Add(himl, hbmp, 0); + expect(0, ret); + ret = SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl); + expect(0, ret); + + itema.mask = LVIF_IMAGE; + itema.iImage = 0; + itema.iItem = 0; + itema.iSubItem = 0; + ret = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM)&itema); + expect(0, ret); + + ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(75, 75)); + if (ret == 0) + { + /* version 4.0 */ + win_skip("LVM_SETICONSPACING unimplemented. Skipping.\n"); + return; + } + + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100)); + ok(MAKELONG(77,827)==ret,"Incorrect Approximate rect\n"); + + ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(50, 50)); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100)); + ok(MAKELONG(102,302)==ret,"Incorrect Approximate rect\n"); + + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100)); + ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + + itema.pszText = test; + ret = SendMessage(hwnd, LVM_SETITEMTEXT, 0, (LPARAM)&itema); + expect(TRUE, ret); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100)); + ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 0, MAKELPARAM(100,100)); + ok(MAKELONG(52,2)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 1, MAKELPARAM(100,100)); + ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 2, MAKELPARAM(100,100)); + ok(MAKELONG(102,52)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 3, MAKELPARAM(100,100)); + ok(MAKELONG(102,102)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 4, MAKELPARAM(100,100)); + ok(MAKELONG(102,102)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 5, MAKELPARAM(100,100)); + ok(MAKELONG(102,152)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 6, MAKELPARAM(100,100)); + ok(MAKELONG(102,152)==ret,"Incorrect Approximate rect\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 7, MAKELPARAM(160,100)); + ok(MAKELONG(152,152)==ret,"Incorrect Approximate rect\n"); + + DestroyWindow(hwnd); +} + +static void test_finditem(void) +{ + LVFINDINFOA fi; + static char f[5]; + HWND hwnd; + DWORD r; + + hwnd = create_listview_control(LVS_REPORT); + insert_item(hwnd, 0); + + memset(&fi, 0, sizeof(fi)); + + /* full string search, inserted text was "foo" */ + strcpy(f, "foo"); + fi.flags = LVFI_STRING; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + /* partial string search, inserted text was "foo" */ + strcpy(f, "fo"); + fi.flags = LVFI_STRING | LVFI_PARTIAL; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + /* partial string search, part after start char */ + strcpy(f, "oo"); + fi.flags = LVFI_STRING | LVFI_PARTIAL; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(-1, r); + + /* try with LVFI_SUBSTRING */ + strcpy(f, "fo"); + fi.flags = LVFI_SUBSTRING; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + if (r == -1) + { + win_skip("LVFI_SUBSTRING not supported\n"); + DestroyWindow(hwnd); + return; + } + expect(0, r); + strcpy(f, "f"); + fi.flags = LVFI_SUBSTRING; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + strcpy(f, "o"); + fi.flags = LVFI_SUBSTRING; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(-1, r); + + strcpy(f, "f"); + fi.flags = LVFI_SUBSTRING | LVFI_STRING; + fi.psz = f; + r = SendMessage(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + + DestroyWindow(hwnd); +} + +static void test_LVS_EX_HEADERINALLVIEWS(void) +{ + HWND hwnd, header; + DWORD style; + + hwnd = create_listview_control(LVS_ICON); + + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, + LVS_EX_HEADERINALLVIEWS); + + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + if (!IsWindow(header)) + { + win_skip("LVS_EX_HEADERINALLVIEWS unsupported\n"); + DestroyWindow(hwnd); + return; + } + + /* LVS_NOCOLUMNHEADER works as before */ + style = GetWindowLongA(hwnd, GWL_STYLE); + SetWindowLongW(hwnd, GWL_STYLE, style | LVS_NOCOLUMNHEADER); + style = GetWindowLongA(header, GWL_STYLE); + ok(style & HDS_HIDDEN, "Expected HDS_HIDDEN\n"); + style = GetWindowLongA(hwnd, GWL_STYLE); + SetWindowLongW(hwnd, GWL_STYLE, style & ~LVS_NOCOLUMNHEADER); + style = GetWindowLongA(header, GWL_STYLE); + ok(!(style & HDS_HIDDEN), "Expected HDS_HIDDEN to be unset\n"); + + /* try to remove style */ + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, 0); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header to be created\n"); + style = GetWindowLongA(header, GWL_STYLE); + ok(!(style & HDS_HIDDEN), "HDS_HIDDEN not expected\n"); + + DestroyWindow(hwnd); + + /* check other styles */ + hwnd = create_listview_control(LVS_LIST); + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, + LVS_EX_HEADERINALLVIEWS); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header to be created\n"); + DestroyWindow(hwnd); + + hwnd = create_listview_control(LVS_SMALLICON); + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, + LVS_EX_HEADERINALLVIEWS); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header to be created\n"); + DestroyWindow(hwnd); + + hwnd = create_listview_control(LVS_REPORT); + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, + LVS_EX_HEADERINALLVIEWS); + header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0); + ok(IsWindow(header), "Expected header to be created\n"); + DestroyWindow(hwnd); +} + +static void test_hover(void) +{ + HWND hwnd; + DWORD r; + + hwnd = create_listview_control(LVS_ICON); + + /* test WM_MOUSEHOVER forwarding */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwnd, WM_MOUSEHOVER, 0, 0); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, hover_parent, "NM_HOVER allow test", TRUE); + g_block_hover = TRUE; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + r = SendMessage(hwnd, WM_MOUSEHOVER, 0, 0); + expect(0, r); + ok_sequence(sequences, PARENT_SEQ_INDEX, hover_parent, "NM_HOVER block test", TRUE); + g_block_hover = FALSE; + + r = SendMessage(hwnd, LVM_SETHOVERTIME, 0, 500); + expect(HOVER_DEFAULT, r); + r = SendMessage(hwnd, LVM_GETHOVERTIME, 0, 0); + expect(500, r); + + DestroyWindow(hwnd); +} + +static void test_destroynotify(void) +{ + HWND hwnd; + + hwnd = create_listview_control(LVS_REPORT); + ok(hwnd != NULL, "failed to create listview window\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(hwnd); + ok_sequence(sequences, COMBINED_SEQ_INDEX, listview_destroy, "check destroy order", FALSE); +} + +static void test_header_notification(void) +{ + HWND list, header; + HDITEMA item; + NMHEADER nmh; + LVCOLUMNA col; + LRESULT ret; + + list = create_listview_control(LVS_REPORT); + ok(list != 0, "failed to create listview window\n"); + + memset(&col, 0, sizeof(col)); + col.mask = LVCF_WIDTH; + col.cx = 100; + ret = SendMessage(list, LVM_INSERTCOLUMNA, 0, (LPARAM)&col); + ok(!ret, "expected 0, got %ld\n", ret); + + header = subclass_header(list); + + ret = SendMessage(header, HDM_GETITEMCOUNT, 0, 0); + ok(ret == 1, "expected header item count 1, got %ld\n", ret); + + memset(&item, 0, sizeof(item)); + item.mask = HDI_WIDTH; + ret = SendMessage(header, HDM_GETITEMA, 0, (LPARAM)&item); + ok(ret, "HDM_GETITEM failed\n"); + ok(item.cxy == 100, "expected 100, got %d\n", item.cxy); + + nmh.hdr.hwndFrom = header; + nmh.hdr.idFrom = GetWindowLongPtr(header, GWLP_ID); + nmh.hdr.code = HDN_ITEMCHANGEDA; + nmh.iItem = 0; + nmh.iButton = 0; + item.mask = HDI_WIDTH; + item.cxy = 50; + nmh.pitem = &item; + ret = SendMessage(list, WM_NOTIFY, 0, (LPARAM)&nmh); + ok(!ret, "WM_NOTIFY/HDN_ITEMCHANGED failed\n"); + + DestroyWindow(list); +} + +static void test_createdragimage(void) +{ + HIMAGELIST himl; + POINT pt; + HWND list; + + list = create_listview_control(LVS_ICON); + ok(list != 0, "failed to create listview window\n"); + + insert_item(list, 0); + + /* NULL point */ + himl = (HIMAGELIST)SendMessageA(list, LVM_CREATEDRAGIMAGE, 0, 0); + ok(himl == NULL, "got %p\n", himl); + + himl = (HIMAGELIST)SendMessageA(list, LVM_CREATEDRAGIMAGE, 0, (LPARAM)&pt); + ok(himl != NULL, "got %p\n", himl); + ImageList_Destroy(himl); + + DestroyWindow(list); +} + START_TEST(listview) { HMODULE hComctl32; BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); + ULONG_PTR ctx_cookie; + HANDLE hCtx; + HWND hwnd; + hComctl32 = GetModuleHandleA("comctl32.dll"); pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); if (pInitCommonControlsEx) @@ -2087,11 +4538,12 @@ START_TEST(listview) init_msg_sequences(sequences, NUM_MSG_SEQUENCES); - flush_sequences(sequences, NUM_MSG_SEQUENCES); - hwndparent = create_parent_window(); - ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create parent window", TRUE); + hwndparent = create_parent_window(FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); + g_is_below_5 = is_below_comctl_5(); + + test_header_notification(); test_images(); test_checkboxes(); test_items(); @@ -2105,9 +4557,58 @@ START_TEST(listview) test_columns(); test_getorigin(); test_multiselect(); + test_getitemrect(); test_subitem_rect(); test_sorting(); test_ownerdata(); test_norecompute(); test_nosortheader(); + test_setredraw(); + test_hittest(); + test_getviewrect(); + test_getitemposition(); + test_columnscreation(); + test_editbox(); + test_notifyformat(); + test_indentation(); + test_getitemspacing(); + test_getcolumnwidth(); + test_approximate_viewrect(); + test_finditem(); + test_hover(); + test_destroynotify(); + test_createdragimage(); + + if (!load_v6_module(&ctx_cookie, &hCtx)) + { + DestroyWindow(hwndparent); + return; + } + + /* this is a XP SP3 failure workaround */ + hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo", + WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT, + 0, 0, 100, 100, + hwndparent, NULL, GetModuleHandleA(NULL), NULL); + if (!IsWindow(hwnd)) + { + win_skip("FIXME: failed to create ListView window.\n"); + unload_v6_module(ctx_cookie, hCtx); + DestroyWindow(hwndparent); + return; + } + else + DestroyWindow(hwnd); + + /* comctl32 version 6 tests start here */ + test_get_set_view(); + test_canceleditlabel(); + test_mapidindex(); + test_scrollnotify(); + test_LVS_EX_TRANSPARENTBKGND(); + test_LVS_EX_HEADERINALLVIEWS(); + + unload_v6_module(ctx_cookie, hCtx); + + DestroyWindow(hwndparent); } diff --git a/rostests/winetests/comctl32/misc.c b/rostests/winetests/comctl32/misc.c index e3cf04b79ab..8f83260db17 100644 --- a/rostests/winetests/comctl32/misc.c +++ b/rostests/winetests/comctl32/misc.c @@ -104,7 +104,9 @@ static void test_GetPtrAW(void) ok (count == sourcelen || broken(count == 0), /* win9x */ "Expected count to be %d, it was %d\n", sourcelen, count); - ok (!lstrcmp(dest, desttest), "Expected destination to not have changed\n"); + ok (!lstrcmp(dest, desttest) || + broken(!lstrcmp(dest, "")), /* Win7 */ + "Expected destination to not have changed\n"); count = 0; count = pStr_GetPtrA(source, NULL, destsize); diff --git a/rostests/winetests/comctl32/monthcal.c b/rostests/winetests/comctl32/monthcal.c index 1ca1997d720..30f682ff815 100644 --- a/rostests/winetests/comctl32/monthcal.c +++ b/rostests/winetests/comctl32/monthcal.c @@ -33,18 +33,16 @@ #include "msg.h" #define expect(expected, got) ok(expected == got, "Expected %d, got %d\n", expected, got); +#define expect_hex(expected, got) ok(expected == got, "Expected %x, got %x\n", expected, got); #define NUM_MSG_SEQUENCES 2 #define PARENT_SEQ_INDEX 0 #define MONTHCAL_SEQ_INDEX 1 -struct subclass_info -{ - WNDPROC oldproc; -}; - static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; +static HWND parent_wnd; + static const struct message create_parent_window_seq[] = { { WM_GETMINMAXINFO, sent }, { WM_NCCREATE, sent }, @@ -56,7 +54,7 @@ static const struct message create_parent_window_seq[] = { { WM_WINDOWPOSCHANGING, sent|wparam|optional, 0 }, { WM_WINDOWPOSCHANGED, sent|optional }, { WM_ACTIVATEAPP, sent|wparam, 1 }, - { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_NCACTIVATE, sent }, { WM_ACTIVATE, sent|wparam, 1 }, { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, { WM_IME_NOTIFY, sent|defwinproc|optional }, @@ -81,6 +79,7 @@ static const struct message create_monthcal_multi_sel_style_seq[] = { { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY }, { WM_QUERYUISTATE, sent|optional }, { WM_GETFONT, sent }, + { WM_PARENTNOTIFY, sent }, { 0 } }; @@ -126,7 +125,6 @@ static const struct message monthcal_color_seq[] = { static const struct message monthcal_curr_date_seq[] = { { MCM_SETCURSEL, sent|wparam, 0}, { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, - { WM_ERASEBKGND, sent|lparam|defwinproc, 0}, { MCM_SETCURSEL, sent|wparam, 0}, { MCM_SETCURSEL, sent|wparam, 0}, { MCM_GETCURSEL, sent|wparam, 0}, @@ -213,9 +211,6 @@ static const struct message monthcal_hit_test_seq[] = { { MCM_HITTEST, sent|wparam, 0}, { MCM_HITTEST, sent|wparam, 0}, { MCM_HITTEST, sent|wparam, 0}, - { MCM_HITTEST, sent|wparam, 0}, - { MCM_HITTEST, sent|wparam, 0}, - { MCM_HITTEST, sent|wparam, 0}, { 0 } }; @@ -224,7 +219,7 @@ static const struct message monthcal_todaylink_seq[] = { { MCM_SETTODAY, sent|wparam, 0}, { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, { MCM_GETTODAY, sent|wparam, 0}, - { WM_LBUTTONDOWN, sent|wparam|lparam, MK_LBUTTON, MAKELONG(70, 370)}, + { WM_LBUTTONDOWN, sent|wparam, MK_LBUTTON}, { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0}, { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, { MCM_GETCURSEL, sent|wparam, 0}, @@ -289,6 +284,9 @@ static const struct message destroy_monthcal_child_msgs_seq[] = { static const struct message destroy_monthcal_multi_sel_style_seq[] = { { 0x0090, sent|optional }, /* Vista */ + { WM_SHOWWINDOW, sent|wparam|lparam, 0, 0}, + { WM_WINDOWPOSCHANGING, sent|wparam, 0}, + { WM_WINDOWPOSCHANGED, sent|wparam, 0}, { WM_DESTROY, sent|wparam|lparam, 0, 0}, { WM_NCDESTROY, sent|wparam|lparam, 0, 0}, { 0 } @@ -299,12 +297,14 @@ static const struct message destroy_parent_seq[] = { { 0x0090, sent|optional }, /* Vista */ { WM_WINDOWPOSCHANGING, sent|wparam, 0}, { WM_WINDOWPOSCHANGED, sent|wparam, 0}, - { WM_NCACTIVATE, sent|wparam, 0}, - { WM_ACTIVATE, sent|wparam, 0}, + { WM_IME_SETCONTEXT, sent|wparam|optional, 0}, + { WM_IME_NOTIFY, sent|wparam|lparam|defwinproc|optional, 1, 0}, + { WM_NCACTIVATE, sent|wparam|optional, 0}, + { WM_ACTIVATE, sent|wparam|optional, 0}, { WM_NCACTIVATE, sent|wparam|lparam|optional, 0, 0}, { WM_ACTIVATE, sent|wparam|lparam|optional, 0, 0}, - { WM_ACTIVATEAPP, sent|wparam, 0}, - { WM_KILLFOCUS, sent|wparam|lparam, 0, 0}, + { WM_ACTIVATEAPP, sent|wparam|optional, 0}, + { WM_KILLFOCUS, sent|wparam|lparam|optional, 0, 0}, { WM_IME_SETCONTEXT, sent|wparam|optional, 0}, { WM_IME_NOTIFY, sent|wparam|lparam|defwinproc|optional, 1, 0}, { WM_DESTROY, sent|wparam|lparam, 0, 0}, @@ -315,30 +315,97 @@ static const struct message destroy_parent_seq[] = { static void test_monthcal(void) { HWND hwnd; - SYSTEMTIME st[2], st1[2]; + SYSTEMTIME st[2], st1[2], today; int res, month_range; + DWORD limits; hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT, 0, 300, 300, 0, 0, NULL, NULL); ok(hwnd != NULL, "Failed to create MonthCal\n"); + + /* test range just after creation */ + memset(&st, 0xcc, sizeof(st)); + limits = SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st); + ok(limits == 0 || + broken(limits == GDTR_MIN), /* comctl32 <= 4.70 */ + "No limits should be set (%d)\n", limits); + if (limits == GDTR_MIN) + { + win_skip("comctl32 <= 4.70 is broken\n"); + DestroyWindow(hwnd); + return; + } + + ok(0 == st[0].wYear || + broken(1752 == st[0].wYear), /* comctl32 <= 4.72 */ + "Expected 0, got %d\n", st[0].wYear); + ok(0 == st[0].wMonth || + broken(9 == st[0].wMonth), /* comctl32 <= 4.72 */ + "Expected 0, got %d\n", st[0].wMonth); + ok(0 == st[0].wDay || + broken(14 == st[0].wDay), /* comctl32 <= 4.72 */ + "Expected 0, got %d\n", st[0].wDay); + expect(0, st[0].wDayOfWeek); + expect(0, st[0].wHour); + expect(0, st[0].wMinute); + expect(0, st[0].wSecond); + expect(0, st[0].wMilliseconds); + + expect(0, st[1].wYear); + expect(0, st[1].wMonth); + expect(0, st[1].wDay); + expect(0, st[1].wDayOfWeek); + expect(0, st[1].wHour); + expect(0, st[1].wMinute); + expect(0, st[1].wSecond); + expect(0, st[1].wMilliseconds); + GetSystemTime(&st[0]); st[1] = st[0]; + SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&today); + /* Invalid date/time */ st[0].wYear = 2000; /* Time should not matter */ st[1].wHour = st[1].wMinute = st[1].wSecond = 70; + st[1].wMilliseconds = 1200; ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n"); + /* invalid timestamp is written back with today data and msecs untouched */ + expect(today.wHour, st[1].wHour); + expect(today.wMinute, st[1].wMinute); + expect(today.wSecond, st[1].wSecond); + expect(1200, st[1].wMilliseconds); + ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); - ok(st1[0].wYear != 2000, "Lover limit changed\n"); + ok(st1[0].wYear != 2000, "Lower limit changed\n"); + /* invalid timestamp should be replaced with today data, except msecs */ + expect(today.wHour, st1[1].wHour); + expect(today.wMinute, st1[1].wMinute); + expect(today.wSecond, st1[1].wSecond); + expect(1200, st1[1].wMilliseconds); + + /* Invalid date/time with invalid milliseconds only */ + GetSystemTime(&st[0]); + st[1] = st[0]; + /* Time should not matter */ + st[1].wMilliseconds = 1200; + ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n"); + /* invalid milliseconds field doesn't lead to invalid timestamp */ + expect(st[0].wHour, st[1].wHour); + expect(st[0].wMinute, st[1].wMinute); + expect(st[0].wSecond, st[1].wSecond); + expect(1200, st[1].wMilliseconds); + + GetSystemTime(&st[0]); st[1].wMonth = 0; ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Should have failed to set limits\n"); ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); - ok(st1[0].wYear != 2000, "Lover limit changed\n"); + ok(st1[0].wYear != 2000, "Lower limit changed\n"); ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Should have failed to set MAX limit\n"); ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); - ok(st1[0].wYear != 2000, "Lover limit changed\n"); + ok(st1[0].wYear != 2000, "Lower limit changed\n"); GetSystemTime(&st[0]); st[0].wDay = 20; @@ -373,6 +440,60 @@ static void test_monthcal(void) ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n"); ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n"); + /* set both limits, then set max < min */ + GetSystemTime(&st[0]); + st[1] = st[0]; + st[1].wYear++; + ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN|GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); + ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Min limit expected\n"); + st[1].wYear -= 2; + ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); + ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Max limit expected\n"); + + expect(0, st1[0].wYear); + expect(0, st1[0].wMonth); + expect(0, st1[0].wDay); + expect(0, st1[0].wDayOfWeek); + expect(0, st1[0].wHour); + expect(0, st1[0].wMinute); + expect(0, st1[0].wSecond); + expect(0, st1[0].wMilliseconds); + + expect(st[1].wYear, st1[1].wYear); + expect(st[1].wMonth, st1[1].wMonth); + expect(st[1].wDay, st1[1].wDay); + expect(st[1].wDayOfWeek, st1[1].wDayOfWeek); + expect(st[1].wHour, st1[1].wHour); + expect(st[1].wMinute, st1[1].wMinute); + expect(st[1].wSecond, st1[1].wSecond); + expect(st[1].wMilliseconds, st1[1].wMilliseconds); + + st[1] = st[0]; + st[1].wYear++; + ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN|GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); + ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Min limit expected\n"); + st[0].wYear++; /* start == end now */ + ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN, (LPARAM)st), "Failed to set limits\n"); + ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MIN, "Min limit expected\n"); + + expect(st[0].wYear, st1[0].wYear); + expect(st[0].wMonth, st1[0].wMonth); + expect(st[0].wDay, st1[0].wDay); + expect(st[0].wDayOfWeek, st1[0].wDayOfWeek); + expect(st[0].wHour, st1[0].wHour); + expect(st[0].wMinute, st1[0].wMinute); + expect(st[0].wSecond, st1[0].wSecond); + expect(st[0].wMilliseconds, st1[0].wMilliseconds); + + expect(0, st1[1].wYear); + expect(0, st1[1].wMonth); + expect(0, st1[1].wDay); + expect(0, st1[1].wDayOfWeek); + expect(0, st1[1].wHour); + expect(0, st1[1].wMinute); + expect(0, st1[1].wSecond); + expect(0, st1[1].wMilliseconds); + DestroyWindow(hwnd); } @@ -455,7 +576,7 @@ static HWND create_parent_window(void) static LRESULT WINAPI monthcal_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -467,38 +588,40 @@ static LRESULT WINAPI monthcal_subclass_proc(HWND hwnd, UINT message, WPARAM wPa msg.lParam = lParam; add_message(sequences, MONTHCAL_SEQ_INDEX, &msg); + /* some debug output for style changing */ + if ((message == WM_STYLECHANGING || + message == WM_STYLECHANGED) && lParam) + { + STYLESTRUCT *style = (STYLESTRUCT*)lParam; + trace("\told style: 0x%08x, new style: 0x%08x\n", style->styleOld, style->styleNew); + } + defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } -static HWND create_monthcal_control(DWORD style, HWND parent_window) +static HWND create_monthcal_control(DWORD style) { - struct subclass_info *info; + WNDPROC oldproc; HWND hwnd; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - hwnd = CreateWindowEx(0, MONTHCAL_CLASS, "", - style, + WS_CHILD | WS_BORDER | WS_VISIBLE | style, 0, 0, 300, 400, - parent_window, NULL, GetModuleHandleA(NULL), NULL); + parent_wnd, NULL, GetModuleHandleA(NULL), NULL); - if (!hwnd) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!hwnd) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, - (LONG_PTR)monthcal_subclass_proc); - SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)monthcal_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); + + SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0); return hwnd; } @@ -506,9 +629,12 @@ static HWND create_monthcal_control(DWORD style, HWND parent_window) /* Setter and Getters Tests */ -static void test_monthcal_color(HWND hwnd) +static void test_monthcal_color(void) { int res, temp; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -574,12 +700,17 @@ static void test_monthcal_color(HWND hwnd) expect(RGB(255,255,255), temp); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_color_seq, "monthcal color", FALSE); + + DestroyWindow(hwnd); } -static void test_monthcal_currDate(HWND hwnd) +static void test_monthcal_currdate(void) { SYSTEMTIME st_original, st_new, st_test; int res; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -629,28 +760,94 @@ static void test_monthcal_currDate(HWND hwnd) expect(st_original.wYear, st_new.wYear); expect(st_original.wMonth, st_new.wMonth); expect(st_original.wDay, st_new.wDay); - expect(st_original.wHour, st_new.wHour); - expect(st_original.wMinute, st_new.wMinute); - expect(st_original.wSecond, st_new.wSecond); + ok(st_original.wHour == st_new.wHour || + broken(0 == st_new.wHour), /* comctl32 <= 4.70 */ + "Expected %d, got %d\n", st_original.wHour, st_new.wHour); + ok(st_original.wMinute == st_new.wMinute || + broken(0 == st_new.wMinute), /* comctl32 <= 4.70 */ + "Expected %d, got %d\n", st_original.wMinute, st_new.wMinute); + ok(st_original.wSecond == st_new.wSecond || + broken(0 == st_new.wSecond), /* comctl32 <= 4.70 */ + "Expected %d, got %d\n", st_original.wSecond, st_new.wSecond); /* lparam cannot be NULL */ res = SendMessage(hwnd, MCM_GETCURSEL, 0, 0); expect(0, res); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_curr_date_seq, "monthcal currDate", TRUE); + + /* December, 31, 9999 is the maximum allowed date */ + memset(&st_new, 0, sizeof(st_new)); + st_new.wYear = 9999; + st_new.wMonth = 12; + st_new.wDay = 31; + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); + expect(1, res); + memset(&st_test, 0, sizeof(st_test)); + res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); + expect(1, res); + expect(st_new.wYear, st_test.wYear); + expect(st_new.wMonth, st_test.wMonth); + expect(st_new.wDay, st_test.wDay); + expect(st_new.wHour, st_test.wHour); + expect(st_new.wMinute, st_test.wMinute); + expect(st_new.wSecond, st_test.wSecond); + /* try one day later */ + st_original = st_new; + st_new.wYear = 10000; + st_new.wMonth = 1; + st_new.wDay = 1; + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); + ok(0 == res || + broken(1 == res), /* comctl32 <= 4.72 */ + "Expected 0, got %d\n", res); + if (0 == res) + { + memset(&st_test, 0, sizeof(st_test)); + res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); + expect(1, res); + expect(st_original.wYear, st_test.wYear); + expect(st_original.wMonth, st_test.wMonth); + expect(st_original.wDay, st_test.wDay); + expect(st_original.wHour, st_test.wHour); + expect(st_original.wMinute, st_test.wMinute); + expect(st_original.wSecond, st_test.wSecond); + } + + /* setting selection equal to current reports success even if out range */ + memset(&st_new, 0, sizeof(st_new)); + st_new.wYear = 2009; + st_new.wDay = 5; + st_new.wMonth = 10; + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); + expect(1, res); + memset(&st_test, 0, sizeof(st_test)); + st_test.wYear = 2009; + st_test.wDay = 6; + st_test.wMonth = 10; + res = SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN, (LPARAM)&st_test); + expect(1, res); + /* set to current again */ + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); + expect(1, res); + + DestroyWindow(hwnd); } -static void test_monthcal_firstDay(HWND hwnd) +static void test_monthcal_firstDay(void) { int res, fday, i, prev; - TCHAR b[128]; + CHAR b[128]; LCID lcid = LOCALE_USER_DEFAULT; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Setter and Getters for first day of week */ /* check for locale first day */ - if(GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, b, 128)){ + if(GetLocaleInfoA(lcid, LOCALE_IFIRSTDAYOFWEEK, b, 128)){ fday = atoi(b); trace("fday: %d\n", fday); res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0); @@ -660,7 +857,7 @@ static void test_monthcal_firstDay(HWND hwnd) /* checking for the values that actually will be stored as */ /* current first day when we set a new value */ for (i = -5; i < 12; i++){ - res = SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM) i); + res = SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, i); expect(prev, res); res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0); prev = res; @@ -681,11 +878,15 @@ static void test_monthcal_firstDay(HWND hwnd) skip("Cannot retrieve first day of the week\n"); } + DestroyWindow(hwnd); } -static void test_monthcal_unicode(HWND hwnd) +static void test_monthcal_unicode(void) { int res, temp; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -700,11 +901,15 @@ static void test_monthcal_unicode(HWND hwnd) /* current setting is 1, so, should return 1 */ res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0); - todo_wine {expect(1, res);} + ok(1 == res || + broken(0 == res), /* comctl32 <= 4.70 */ + "Expected 1, got %d\n", res); /* setting to 0, should return previous settings */ res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 0, 0); - todo_wine {expect(1, res);} + ok(1 == res || + broken(0 == res), /* comctl32 <= 4.70 */ + "Expected 1, got %d\n", res); /* current setting is 0, so, it should return 0 */ res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0); @@ -715,22 +920,67 @@ static void test_monthcal_unicode(HWND hwnd) expect(0, res); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_unicode_seq, "monthcal unicode", FALSE); + + DestroyWindow(hwnd); } -static void test_monthcal_HitTest(HWND hwnd) +static void test_monthcal_hittest(void) { + typedef struct hittest_test + { + UINT ht; + int todo; + } hittest_test_t; + + static const hittest_test_t title_hits[] = { + /* Start is the same everywhere */ + { MCHT_TITLE, 0 }, + { MCHT_TITLEBTNPREV, 0 }, + /* The middle piece is only tested for presence of items */ + /* End is the same everywhere */ + { MCHT_TITLEBTNNEXT, 0 }, + { MCHT_TITLE, 0 }, + { MCHT_NOWHERE, 1 } + }; + MCHITTESTINFO mchit; - UINT res; + UINT res, old_res; SYSTEMTIME st; LONG x; UINT title_index; - static const UINT title_hits[] = - { MCHT_NOWHERE, MCHT_TITLEBK, MCHT_TITLEBTNPREV, MCHT_TITLEBK, - MCHT_TITLEMONTH, MCHT_TITLEBK, MCHT_TITLEYEAR, MCHT_TITLEBK, - MCHT_TITLEBTNNEXT, MCHT_TITLEBK, MCHT_NOWHERE }; + HWND hwnd; + RECT r; + char yearmonth[80], *locale_month, *locale_year; + int month_count, year_count; + BOOL in_the_middle; memset(&mchit, 0, sizeof(MCHITTESTINFO)); + hwnd = create_monthcal_control(0); + + /* test with invalid structure size */ + mchit.cbSize = MCHITTESTINFO_V1_SIZE - 1; + mchit.pt.x = 0; + mchit.pt.y = 0; + res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + expect(0, mchit.pt.x); + expect(0, mchit.pt.y); + expect(-1, res); + expect(0, mchit.uHit); + /* test with invalid pointer */ + res = SendMessage(hwnd, MCM_HITTEST, 0, 0); + expect(-1, res); + + /* resize control to display single Calendar */ + res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + if (res == 0) + { + win_skip("Message MCM_GETMINREQRECT unsupported. Skipping.\n"); + DestroyWindow(hwnd); + return; + } + MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); + flush_sequences(sequences, NUM_MSG_SEQUENCES); st.wYear = 2007; @@ -745,60 +995,60 @@ static void test_monthcal_HitTest(HWND hwnd) res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); expect(1,res); - /* (0, 0) is the top left of the control and should not be active */ - mchit.cbSize = sizeof(MCHITTESTINFO); + /* (0, 0) is the top left of the control - title */ + mchit.cbSize = MCHITTESTINFO_V1_SIZE; mchit.pt.x = 0; mchit.pt.y = 0; - res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); + res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); expect(0, mchit.pt.x); expect(0, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_NOWHERE, res);} + expect_hex(MCHT_TITLE, res); - /* (300, 400) is the bottom right of the control and should not be active */ - mchit.pt.x = 300; - mchit.pt.y = 400; - res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(300, mchit.pt.x); - expect(400, mchit.pt.y); + /* bottom right of the control and should not be active */ + mchit.pt.x = r.right; + mchit.pt.y = r.bottom; + res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + expect(r.right, mchit.pt.x); + expect(r.bottom, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_NOWHERE, res);} + todo_wine expect_hex(MCHT_NOWHERE, res); - /* (500, 500) is completely out of the control and should not be active */ - mchit.pt.x = 500; - mchit.pt.y = 500; + /* completely out of the control, should not be active */ + mchit.pt.x = 2 * r.right; + mchit.pt.y = 2 * r.bottom; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(500, mchit.pt.x); - expect(500, mchit.pt.y); + expect(2 * r.right, mchit.pt.x); + expect(2 * r.bottom, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_NOWHERE, res);} + todo_wine expect_hex(MCHT_NOWHERE, res); - /* (120, 180) is in active area - calendar background */ - mchit.pt.x = 120; - mchit.pt.y = 180; + /* in active area - day of the week */ + mchit.pt.x = r.right / 2; + mchit.pt.y = r.bottom / 2; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(120, mchit.pt.x); - expect(180, mchit.pt.y); + expect(r.right / 2, mchit.pt.x); + expect(r.bottom / 2, mchit.pt.y); expect(mchit.uHit, res); - expect(MCHT_CALENDARBK, res); + expect_hex(MCHT_CALENDARDATE, res); - /* (70, 70) is in active area - day of the week */ - mchit.pt.x = 70; - mchit.pt.y = 70; + /* in active area - day of the week #2 */ + mchit.pt.x = r.right / 14; /* half of first day rect */ + mchit.pt.y = r.bottom / 2; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(70, mchit.pt.x); - expect(70, mchit.pt.y); + expect(r.right / 14, mchit.pt.x); + expect(r.bottom / 2, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_CALENDARDAY, res);} + expect_hex(MCHT_CALENDARDATE, res); - /* (70, 90) is in active area - date from prev month */ - mchit.pt.x = 70; - mchit.pt.y = 90; + /* in active area - date from prev month */ + mchit.pt.x = r.right / 14; /* half of first day rect */ + mchit.pt.y = 6 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(70, mchit.pt.x); - expect(90, mchit.pt.y); + expect(r.right / 14, mchit.pt.x); + expect(6 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_CALENDARDATEPREV, res);} + expect_hex(MCHT_CALENDARDATEPREV, res); #if 0 /* (125, 115) is in active area - date from this month */ @@ -811,142 +1061,164 @@ static void test_monthcal_HitTest(HWND hwnd) expect(MCHT_CALENDARDATE, res); #endif - /* (80, 220) is in active area - background section of the title */ - mchit.pt.x = 80; - mchit.pt.y = 220; + /* in active area - date from next month */ + mchit.pt.x = 11 * r.right / 14; + mchit.pt.y = 16 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(80, mchit.pt.x); - expect(220, mchit.pt.y); + expect(11 * r.right / 14, mchit.pt.x); + expect(16 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_TITLEBK, res);} + expect_hex(MCHT_CALENDARDATENEXT, res); - /* (140, 215) is in active area - month section of the title */ - mchit.pt.x = 140; - mchit.pt.y = 215; + /* in active area - today link */ + mchit.pt.x = r.right / 14; + mchit.pt.y = 18 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(140, mchit.pt.x); - expect(215, mchit.pt.y); + expect(r.right / 14, mchit.pt.x); + expect(18 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_TITLEMONTH, res);} + expect_hex(MCHT_TODAYLINK, res); - /* (170, 215) is in active area - year section of the title */ - mchit.pt.x = 170; - mchit.pt.y = 215; + /* in active area - today link */ + mchit.pt.x = r.right / 2; + mchit.pt.y = 18 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(170, mchit.pt.x); - expect(215, mchit.pt.y); + expect(r.right / 2, mchit.pt.x); + expect(18 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_TITLEYEAR, res);} + expect_hex(MCHT_TODAYLINK, res); - /* (150, 260) is in active area - date from this month */ - mchit.pt.x = 150; - mchit.pt.y = 260; + /* in active area - today link */ + mchit.pt.x = r.right / 10; + mchit.pt.y = 18 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(150, mchit.pt.x); - expect(260, mchit.pt.y); + expect(r.right / 10, mchit.pt.x); + expect(18 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_CALENDARDATE, res);} - - /* (150, 350) is in active area - date from next month */ - mchit.pt.x = 150; - mchit.pt.y = 350; - res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(150, mchit.pt.x); - expect(350, mchit.pt.y); - expect(mchit.uHit, res); - todo_wine {expect(MCHT_CALENDARDATENEXT, res);} - - /* (150, 370) is in active area - today link */ - mchit.pt.x = 150; - mchit.pt.y = 370; - res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(150, mchit.pt.x); - expect(370, mchit.pt.y); - expect(mchit.uHit, res); - todo_wine {expect(MCHT_TODAYLINK, res);} - - /* (70, 370) is in active area - today link */ - mchit.pt.x = 70; - mchit.pt.y = 370; - res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(70, mchit.pt.x); - expect(370, mchit.pt.y); - expect(mchit.uHit, res); - todo_wine {expect(MCHT_TODAYLINK, res);} + expect_hex(MCHT_TODAYLINK, res); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_hit_test_seq, "monthcal hit test", TRUE); /* The horizontal position of title bar elements depends on locale (y pos is constant), so we sample across a horizontal line and make sure we find all elements. */ - mchit.pt.y = 40; + + /* Get the format of the title */ + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, yearmonth, 80); + /* Find out if we have a month and/or year */ + locale_year = strstr(yearmonth, "y"); + locale_month = strstr(yearmonth, "M"); + + mchit.pt.x = 0; + mchit.pt.y = (5/2) * r.bottom / 19; title_index = 0; - for (x = 0; x < 300; x++){ + old_res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); + expect_hex(title_hits[title_index].ht, old_res); + + in_the_middle = FALSE; + month_count = year_count = 0; + for (x = 0; x < r.right; x++){ mchit.pt.x = x; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); expect(x, mchit.pt.x); - expect(40, mchit.pt.y); + expect((5/2) * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - if (res != title_hits[title_index]){ - title_index++; - if (sizeof(title_hits) / sizeof(title_hits[0]) <= title_index) - break; - todo_wine {expect(title_hits[title_index], res);} + if (res != old_res) { + + if (old_res == MCHT_TITLEBTNPREV) + in_the_middle = TRUE; + + if (res == MCHT_TITLEBTNNEXT) + in_the_middle = FALSE; + + if (in_the_middle) { + if (res == MCHT_TITLEMONTH) + month_count++; + else if (res == MCHT_TITLEYEAR) + year_count++; + } else { + title_index++; + + if (sizeof(title_hits) / sizeof(title_hits[0]) <= title_index) + break; + + if (title_hits[title_index].todo) { + todo_wine + ok(title_hits[title_index].ht == res, "Expected %x, got %x, pos %d\n", + title_hits[title_index].ht, res, x); + } else { + ok(title_hits[title_index].ht == res, "Expected %x, got %x, pos %d\n", + title_hits[title_index].ht, res, x); + } + } + old_res = res; } } - todo_wine {ok(300 <= x && title_index + 1 == sizeof(title_hits) / sizeof(title_hits[0]), - "Wrong title layout\n");} + + /* There are some limits, even if LOCALE_SYEARMONTH contains rubbish + * or no month/year indicators at all */ + if (locale_month) + todo_wine ok(month_count == 1, "Expected 1 month item, got %d\n", month_count); + else + ok(month_count <= 1, "Too many month items: %d\n", month_count); + + if (locale_year) + todo_wine ok(year_count == 1, "Expected 1 year item, got %d\n", year_count); + else + ok(year_count <= 1, "Too many year items: %d\n", year_count); + + todo_wine ok(month_count + year_count >= 1, "Not enough month and year items\n"); + + ok(r.right <= x && title_index + 1 == sizeof(title_hits) / sizeof(title_hits[0]), + "Wrong title layout\n"); + + DestroyWindow(hwnd); } -static void test_monthcal_todaylink(HWND hwnd) +static void test_monthcal_todaylink(void) { MCHITTESTINFO mchit; SYSTEMTIME st_test, st_new; - BOOL error = FALSE; UINT res; + HWND hwnd; + RECT r; memset(&mchit, 0, sizeof(MCHITTESTINFO)); + hwnd = create_monthcal_control(0); + + res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); + flush_sequences(sequences, NUM_MSG_SEQUENCES); - /* (70, 370) is in active area - today link */ - mchit.cbSize = sizeof(MCHITTESTINFO); - mchit.pt.x = 70; - mchit.pt.y = 370; + /* hit active area - today link */ + mchit.cbSize = MCHITTESTINFO_V1_SIZE; + mchit.pt.x = r.right / 14; + mchit.pt.y = 18 * r.bottom / 19; res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit); - expect(70, mchit.pt.x); - expect(370, mchit.pt.y); + expect(r.right / 14, mchit.pt.x); + expect(18 * r.bottom / 19, mchit.pt.y); expect(mchit.uHit, res); - todo_wine {expect(MCHT_TODAYLINK, res);} - if (70 != mchit.pt.x || 370 != mchit.pt.y || mchit.uHit != res - || MCHT_TODAYLINK != res) - error = TRUE; + expect(MCHT_TODAYLINK, res); st_test.wDay = 1; st_test.wMonth = 1; st_test.wYear = 2005; - memset(&st_new, 0, sizeof(SYSTEMTIME)); SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + memset(&st_new, 0, sizeof(st_new)); res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); expect(1, res); expect(1, st_new.wDay); expect(1, st_new.wMonth); expect(2005, st_new.wYear); - if (1 != res || 1 != st_new.wDay || 1 != st_new.wMonth - || 2005 != st_new.wYear) - error = TRUE; - if (error) { - skip("cannot perform today link test\n"); - return; - } - - res = SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(70, 370)); + res = SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(mchit.pt.x, mchit.pt.y)); expect(0, res); - memset(&st_new, 0, sizeof(SYSTEMTIME)); + memset(&st_new, 0, sizeof(st_new)); res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_new); expect(1, res); expect(1, st_new.wDay); @@ -954,18 +1226,24 @@ static void test_monthcal_todaylink(HWND hwnd) expect(2005, st_new.wYear); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_todaylink_seq, "monthcal hit test", TRUE); + + DestroyWindow(hwnd); } -static void test_monthcal_today(HWND hwnd) +static void test_monthcal_today(void) { SYSTEMTIME st_test, st_new; int res; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Setter and Getters for "today" information */ /* check for overflow, should be ok */ + memset(&st_test, 0, sizeof(st_test)); st_test.wDay = 38; st_test.wMonth = 38; @@ -1003,11 +1281,16 @@ static void test_monthcal_today(HWND hwnd) expect(0, st_new.wMonth); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_today_seq, "monthcal today", TRUE); + + DestroyWindow(hwnd); } -static void test_monthcal_scroll(HWND hwnd) +static void test_monthcal_scroll(void) { int res; + HWND hwnd; + + hwnd = create_monthcal_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1036,46 +1319,138 @@ static void test_monthcal_scroll(HWND hwnd) expect(-5, res); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_scroll_seq, "monthcal scroll", FALSE); + + DestroyWindow(hwnd); } -static void test_monthcal_monthrange(HWND hwnd) +static void test_monthcal_monthrange(void) { int res; - SYSTEMTIME st_visible[2], st_daystate[2]; + SYSTEMTIME st_visible[2], st_daystate[2], st; + HWND hwnd; + RECT r; + + hwnd = create_monthcal_control(0); - flush_sequences(sequences, NUM_MSG_SEQUENCES); st_visible[0].wYear = 0; st_visible[0].wMonth = 0; st_visible[0].wDay = 0; st_daystate[1] = st_daystate[0] = st_visible[1] = st_visible[0]; + st.wYear = 2000; + st.wMonth = 11; + st.wDay = 28; + st.wHour = 11; + st.wMinute = 59; + st.wSecond = 30; + st.wMilliseconds = 0; + st.wDayOfWeek = 0; + + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); + expect(1,res); + + /* to be locale independent */ + SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM)6); + + res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + expect(TRUE, res); + /* resize control to display two Calendars */ + MoveWindow(hwnd, 0, 0, r.right, (5/2)*r.bottom, FALSE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible); todo_wine { expect(2, res); - expect(2000, st_visible[0].wYear); - expect(11, st_visible[0].wMonth); - expect(1, st_visible[0].wDay); - expect(2000, st_visible[1].wYear); + } + expect(2000, st_visible[0].wYear); + expect(11, st_visible[0].wMonth); + expect(1, st_visible[0].wDay); + expect(2000, st_visible[1].wYear); + + todo_wine { expect(12, st_visible[1].wMonth); expect(31, st_visible[1].wDay); } res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, (LPARAM)st_daystate); todo_wine { expect(4, res); - expect(2000, st_daystate[0].wYear); - expect(10, st_daystate[0].wMonth); - expect(29, st_daystate[0].wDay); + } + expect(2000, st_daystate[0].wYear); + expect(10, st_daystate[0].wMonth); + expect(29, st_daystate[0].wDay); + + todo_wine { expect(2001, st_daystate[1].wYear); expect(1, st_daystate[1].wMonth); expect(6, st_daystate[1].wDay); } ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_monthrange_seq, "monthcal monthrange", FALSE); + + /* resize control to display single Calendar */ + MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); + + memset(&st, 0, sizeof(st)); + st.wMonth = 9; + st.wYear = 1752; + st.wDay = 14; + + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); + expect(1, res); + + /* September 1752 has 19 days */ + res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible); + expect(1, res); + + expect(1752, st_visible[0].wYear); + expect(9, st_visible[0].wMonth); + ok(14 == st_visible[0].wDay || + broken(1 == st_visible[0].wDay), /* comctl32 <= 4.72 */ + "Expected 14, got %d\n", st_visible[0].wDay); + + expect(1752, st_visible[1].wYear); + expect(9, st_visible[1].wMonth); + expect(19, st_visible[1].wDay); + + DestroyWindow(hwnd); } -static void test_monthcal_MaxSelDay(HWND hwnd) +static void test_monthcal_maxselday(void) { int res; + HWND hwnd; + DWORD style; + + hwnd = create_monthcal_control(0); + /* if no style specified default to 1 */ + res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); + expect(1, res); + res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 5, 0); + expect(0, res); + res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); + expect(1, res); + + /* try to set style */ + style = GetWindowLong(hwnd, GWL_STYLE); + SetWindowLong(hwnd, GWL_STYLE, style | MCS_MULTISELECT); + style = GetWindowLong(hwnd, GWL_STYLE); + ok(!(style & MCS_MULTISELECT), "Expected MCS_MULTISELECT not to be set\n"); + DestroyWindow(hwnd); + + hwnd = create_monthcal_control(MCS_MULTISELECT); + /* try to remove style */ + style = GetWindowLong(hwnd, GWL_STYLE); + SetWindowLong(hwnd, GWL_STYLE, style & ~MCS_MULTISELECT); + style = GetWindowLong(hwnd, GWL_STYLE); + ok(style & MCS_MULTISELECT, "Expected MCS_MULTISELECT to be set\n"); + DestroyWindow(hwnd); + + hwnd = create_monthcal_control(MCS_MULTISELECT); + + /* default width is a week */ + res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); + expect(7, res); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1090,20 +1465,32 @@ static void test_monthcal_MaxSelDay(HWND hwnd) res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); expect(15, res); + /* test invalid value */ res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, -1, 0); - todo_wine {expect(0, res);} + expect(0, res); res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); - todo_wine {expect(15, res);} + expect(15, res); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_max_sel_day_seq, "monthcal MaxSelDay", FALSE); + + /* zero value is invalid too */ + res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 0, 0); + expect(0, res); + res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0); + expect(15, res); + + DestroyWindow(hwnd); } -static void test_monthcal_size(HWND hwnd) +static void test_monthcal_size(void) { int res; RECT r1, r2; HFONT hFont1, hFont2; LOGFONTA logfont; + HWND hwnd; + + hwnd = create_monthcal_control(0); lstrcpyA(logfont.lfFaceName, "Arial"); memset(&logfont, 0, sizeof(logfont)); @@ -1116,15 +1503,181 @@ static void test_monthcal_size(HWND hwnd) /* initialize to a font we can compare against */ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont1, 0); res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r1); + ok(res, "SendMessage(MCM_GETMINREQRECT) failed\n"); /* check that setting a larger font results in an larger rect */ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont2, 0); res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r2); + ok(res, "SendMessage(MCM_GETMINREQRECT) failed\n"); OffsetRect(&r1, -r1.left, -r1.top); OffsetRect(&r2, -r2.left, -r2.top); ok(r1.bottom < r2.bottom, "Failed to get larger rect with larger font\n"); + + DestroyWindow(hwnd); +} + +static void test_monthcal_create(void) +{ + HWND hwnd; + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + hwnd = create_monthcal_control(0); + ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_control_seq, "create monthcal control", TRUE); + + DestroyWindow(hwnd); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + hwnd = create_monthcal_control(MCS_MULTISELECT); + ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_multi_sel_style_seq, "create monthcal (multi sel style)", TRUE); + DestroyWindow(hwnd); +} + +static void test_monthcal_destroy(void) +{ + HWND hwnd; + + hwnd = create_monthcal_control(0); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(hwnd); + ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_monthcal_parent_msgs_seq, "Destroy monthcal (parent msg)", FALSE); + ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_child_msgs_seq, "Destroy monthcal (child msg)", FALSE); + + /* MCS_MULTISELECT */ + hwnd = create_monthcal_control(MCS_MULTISELECT); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(hwnd); + ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_multi_sel_style_seq, "Destroy monthcal (multi sel style)", FALSE); +} + +static void test_monthcal_selrange(void) +{ + HWND hwnd; + SYSTEMTIME st, range[2], range2[2]; + BOOL ret, old_comctl32 = FALSE; + + hwnd = create_monthcal_control(MCS_MULTISELECT); + + /* just after creation selection should start and end today */ + ret = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st); + expect(TRUE, ret); + + memset(range, 0xcc, sizeof(range)); + ret = SendMessage(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range); + expect(TRUE, ret); + expect(st.wYear, range[0].wYear); + expect(st.wMonth, range[0].wMonth); + expect(st.wDay, range[0].wDay); + if (range[0].wDayOfWeek != st.wDayOfWeek) + { + win_skip("comctl32 <= 4.70 doesn't set some values\n"); + old_comctl32 = TRUE; + } + else + { + expect(st.wDayOfWeek, range[0].wDayOfWeek); + expect(st.wHour, range[0].wHour); + expect(st.wMinute, range[0].wMinute); + expect(st.wSecond, range[0].wSecond); + expect(st.wMilliseconds, range[0].wMilliseconds); + } + + expect(st.wYear, range[1].wYear); + expect(st.wMonth, range[1].wMonth); + expect(st.wDay, range[1].wDay); + if (!old_comctl32) + { + expect(st.wDayOfWeek, range[1].wDayOfWeek); + expect(st.wHour, range[1].wHour); + expect(st.wMinute, range[1].wMinute); + expect(st.wSecond, range[1].wSecond); + expect(st.wMilliseconds, range[1].wMilliseconds); + } + + /* bounds are swapped if min > max */ + memset(&range[0], 0, sizeof(range[0])); + range[0].wYear = 2009; + range[0].wMonth = 10; + range[0].wDay = 5; + range[1] = range[0]; + range[1].wDay = 3; + + ret = SendMessage(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); + expect(TRUE, ret); + + ret = SendMessage(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range2); + expect(TRUE, ret); + + expect(range[1].wYear, range2[0].wYear); + expect(range[1].wMonth, range2[0].wMonth); + expect(range[1].wDay, range2[0].wDay); + expect(6, range2[0].wDayOfWeek); + expect(range[1].wHour, range2[0].wHour); + expect(range[1].wMinute, range2[0].wMinute); + expect(range[1].wSecond, range2[0].wSecond); + expect(range[1].wMilliseconds, range2[0].wMilliseconds); + + expect(range[0].wYear, range2[1].wYear); + expect(range[0].wMonth, range2[1].wMonth); + expect(range[0].wDay, range2[1].wDay); + expect(1, range2[1].wDayOfWeek); + expect(range[0].wHour, range2[1].wHour); + expect(range[0].wMinute, range2[1].wMinute); + expect(range[0].wSecond, range2[1].wSecond); + expect(range[0].wMilliseconds, range2[1].wMilliseconds); + + /* try with range larger than maximum configured */ + memset(&range[0], 0, sizeof(range[0])); + range[0].wYear = 2009; + range[0].wMonth = 10; + range[0].wDay = 1; + range[1] = range[0]; + + ret = SendMessage(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); + expect(TRUE, ret); + + range[1] = range[0]; + /* default max. range is 7 days */ + range[1].wDay = 8; + + ret = SendMessage(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); + expect(FALSE, ret); + + ret = SendMessage(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range2); + expect(TRUE, ret); + + expect(range[0].wYear, range2[0].wYear); + expect(range[0].wMonth, range2[0].wMonth); + expect(range[0].wDay, range2[0].wDay); + expect(range[0].wYear, range2[1].wYear); + expect(range[0].wMonth, range2[1].wMonth); + expect(range[0].wDay, range2[1].wDay); + + DestroyWindow(hwnd); +} + +static void test_killfocus(void) +{ + HWND hwnd; + DWORD style; + + hwnd = create_monthcal_control(0); + + /* make parent invisible */ + style = GetWindowLong(parent_wnd, GWL_STYLE); + SetWindowLong(parent_wnd, GWL_STYLE, style &~ WS_VISIBLE); + + SendMessage(hwnd, WM_KILLFOCUS, (WPARAM)GetDesktopWindow(), 0); + + style = GetWindowLong(hwnd, GWL_STYLE); + ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n"); + + style = GetWindowLong(parent_wnd, GWL_STYLE); + SetWindowLong(parent_wnd, GWL_STYLE, style | WS_VISIBLE); + + DestroyWindow(hwnd); } START_TEST(monthcal) @@ -1132,7 +1685,6 @@ START_TEST(monthcal) HMODULE hComctl32; BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); INITCOMMONCONTROLSEX iccex; - HWND hwnd, parent_wnd; hComctl32 = GetModuleHandleA("comctl32.dll"); pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); @@ -1151,39 +1703,21 @@ START_TEST(monthcal) parent_wnd = create_parent_window(); - flush_sequences(sequences, NUM_MSG_SEQUENCES); - hwnd = create_monthcal_control(WS_CHILD | WS_BORDER | WS_VISIBLE, parent_wnd); - assert(hwnd); - ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_control_seq, "create monthcal control", TRUE); - - SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0); - - test_monthcal_color(hwnd); - test_monthcal_currDate(hwnd); - test_monthcal_firstDay(hwnd); - test_monthcal_unicode(hwnd); - test_monthcal_today(hwnd); - test_monthcal_scroll(hwnd); - test_monthcal_monthrange(hwnd); - test_monthcal_HitTest(hwnd); - test_monthcal_todaylink(hwnd); - test_monthcal_size(hwnd); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - DestroyWindow(hwnd); - ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_monthcal_parent_msgs_seq, "Destroy monthcal (parent msg)", FALSE); - ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_child_msgs_seq, "Destroy monthcal (child msg)", FALSE); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - hwnd = create_monthcal_control(MCS_MULTISELECT, parent_wnd); - assert(hwnd); - ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_multi_sel_style_seq, "create monthcal (multi sel style)", TRUE); - - test_monthcal_MaxSelDay(hwnd); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - DestroyWindow(hwnd); - ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_multi_sel_style_seq, "Destroy monthcal (multi sel style)", FALSE); + test_monthcal_create(); + test_monthcal_destroy(); + test_monthcal_color(); + test_monthcal_currdate(); + test_monthcal_firstDay(); + test_monthcal_unicode(); + test_monthcal_today(); + test_monthcal_scroll(); + test_monthcal_monthrange(); + test_monthcal_hittest(); + test_monthcal_todaylink(); + test_monthcal_size(); + test_monthcal_maxselday(); + test_monthcal_selrange(); + test_killfocus(); flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(parent_wnd); diff --git a/rostests/winetests/comctl32/mru.c b/rostests/winetests/comctl32/mru.c index 8ebec86f148..24fcff56d68 100644 --- a/rostests/winetests/comctl32/mru.c +++ b/rostests/winetests/comctl32/mru.c @@ -69,11 +69,27 @@ static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA); static void (WINAPI *pFreeMRUList)(HANDLE); static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR); static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD); +static INT (WINAPI *pEnumMRUListW)(HANDLE,INT,LPVOID,DWORD); +static HANDLE (WINAPI *pCreateMRUListLazyA)(LPCREATEMRULISTA, DWORD, DWORD, DWORD); +static INT (WINAPI *pFindMRUData)(HANDLE, LPCVOID, DWORD, LPINT); +static INT (WINAPI *pAddMRUData)(HANDLE, LPCVOID, DWORD); /* static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT); */ +static void InitPointers(void) +{ + pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151); + pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152); + pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153); + pEnumMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)154); + pCreateMRUListLazyA = (void*)GetProcAddress(hComctl32,(LPCSTR)157); + pAddMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)167); + pFindMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)169); + pEnumMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)403); +} + /* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey) { @@ -227,11 +243,6 @@ static void test_MRUListA(void) HKEY hKey; INT iRet; - pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151); - pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152); - pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153); - pEnumMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)154); - if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUList) { skip("MRU entry points not found\n"); @@ -374,7 +385,7 @@ static void test_MRUListA(void) /* check entry 0 */ buffer[0] = 0; iRet = pEnumMRUList(hMRU, 0, buffer, 255); - todo_wine ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet); + ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet); ok(strcmp(buffer, checks[3]) == 0, "EnumMRUList expected %s, got %s\n", checks[3], buffer); /* check entry 0 with a too small buffer */ @@ -383,21 +394,21 @@ static void test_MRUListA(void) buffer[2] = 'A'; /* unchanged */ buffer[3] = 0; /* unchanged */ iRet = pEnumMRUList(hMRU, 0, buffer, 2); - todo_wine ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet); - todo_wine ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer); + ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet); + ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer); /* make sure space after buffer has old values */ ok(buffer[2] == 'A', "EnumMRUList expected %02x, got %02x\n", 'A', buffer[2]); /* check entry 1 */ buffer[0] = 0; iRet = pEnumMRUList(hMRU, 1, buffer, 255); - todo_wine ok(iRet == lstrlen(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[1]), iRet); + ok(iRet == lstrlen(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[1]), iRet); ok(strcmp(buffer, checks[1]) == 0, "EnumMRUList expected %s, got %s\n", checks[1], buffer); /* check entry 2 */ buffer[0] = 0; iRet = pEnumMRUList(hMRU, 2, buffer, 255); - todo_wine ok(iRet == lstrlen(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[2]), iRet); + ok(iRet == lstrlen(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[2]), iRet); ok(strcmp(buffer, checks[2]) == 0, "EnumMRUList expected %s, got %s\n", checks[2], buffer); /* check out of bounds entry 3 */ @@ -413,6 +424,89 @@ static void test_MRUListA(void) /* FreeMRUList(NULL) crashes on Win98 OSR0 */ } +static void test_CreateMRUListLazyA(void) +{ + HANDLE hMRU; + HKEY hKey; + CREATEMRULISTA listA = { 0 }; + + if (!pCreateMRUListLazyA || !pFreeMRUList) + { + win_skip("CreateMRUListLazyA or FreeMRUList entry points not found\n"); + return; + } + + /* wrong size */ + listA.cbSize = sizeof(listA) + 1; + hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0); + ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU); + listA.cbSize = 4; + hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0); + ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU); + /* NULL hKey */ + listA.cbSize = sizeof(listA); + listA.hKey = NULL; + hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0); + ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU); + /* NULL subkey */ + ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey), + "Couldn't create test key \"%s\"\n", REG_TEST_KEYA); + listA.cbSize = sizeof(listA); + listA.hKey = hKey; + listA.lpszSubKey = NULL; + hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0); + ok(hMRU == NULL || broken(hMRU != NULL), /* Win9x */ + "Expected NULL handle, got %p\n", hMRU); + if (hMRU) pFreeMRUList(hMRU); +} + +static void test_EnumMRUList(void) +{ + if (!pEnumMRUList || !pEnumMRUListW) + { + win_skip("EnumMRUListA/EnumMRUListW entry point not found\n"); + return; + } + + /* NULL handle */ + if (0) + { + /* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */ + pEnumMRUList(NULL, 0, NULL, 0); + pEnumMRUListW(NULL, 0, NULL, 0); + } +} + +static void test_FindMRUData(void) +{ + INT iRet; + + if (!pFindMRUData) + { + win_skip("FindMRUData entry point not found\n"); + return; + } + + /* NULL handle */ + iRet = pFindMRUData(NULL, NULL, 0, NULL); + ok(iRet == -1, "FindMRUData expected -1, got %d\n", iRet); +} + +static void test_AddMRUData(void) +{ + INT iRet; + + if (!pAddMRUData) + { + win_skip("AddMRUData entry point not found\n"); + return; + } + + /* NULL handle */ + iRet = pFindMRUData(NULL, NULL, 0, NULL); + ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet); +} + START_TEST(mru) { hComctl32 = GetModuleHandleA("comctl32.dll"); @@ -421,7 +515,13 @@ START_TEST(mru) if (!create_reg_entries()) return; + InitPointers(); + test_MRUListA(); + test_CreateMRUListLazyA(); + test_EnumMRUList(); + test_FindMRUData(); + test_AddMRUData(); delete_reg_entries(); } diff --git a/rostests/winetests/comctl32/msg.c b/rostests/winetests/comctl32/msg.c deleted file mode 100644 index 2129f222e01..00000000000 --- a/rostests/winetests/comctl32/msg.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Message Sequence Testing Code - * - * Copyright (C) 2007 James Hawkins - * Copyright (C) 2007 Lei Zhang - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "msg.h" - -void add_message(struct msg_sequence **seq, int sequence_index, - const struct message *msg) -{ - struct msg_sequence *msg_seq = seq[sequence_index]; - - if (!msg_seq->sequence) - { - msg_seq->size = 10; - msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0, - msg_seq->size * sizeof (struct message)); - } - - if (msg_seq->count == msg_seq->size) - { - msg_seq->size *= 2; - msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0, - msg_seq->sequence, - msg_seq->size * sizeof (struct message)); - } - - assert(msg_seq->sequence); - - msg_seq->sequence[msg_seq->count].message = msg->message; - msg_seq->sequence[msg_seq->count].flags = msg->flags; - msg_seq->sequence[msg_seq->count].wParam = msg->wParam; - msg_seq->sequence[msg_seq->count].lParam = msg->lParam; - msg_seq->sequence[msg_seq->count].id = msg->id; - - msg_seq->count++; -} - -void flush_sequence(struct msg_sequence **seg, int sequence_index) -{ - struct msg_sequence *msg_seq = seg[sequence_index]; - HeapFree(GetProcessHeap(), 0, msg_seq->sequence); - msg_seq->sequence = NULL; - msg_seq->count = msg_seq->size = 0; -} - -void flush_sequences(struct msg_sequence **seq, int n) -{ - int i; - - for (i = 0; i < n; i++) - flush_sequence(seq, i); -} - -void ok_sequence_(struct msg_sequence **seq, int sequence_index, - const struct message *expected, const char *context, int todo, - const char *file, int line) -{ - struct msg_sequence *msg_seq = seq[sequence_index]; - static const struct message end_of_sequence = {0, 0, 0, 0}; - const struct message *actual, *sequence; - int failcount = 0; - - add_message(seq, sequence_index, &end_of_sequence); - - sequence = msg_seq->sequence; - actual = sequence; - - while (expected->message && actual->message) - { - trace_( file, line)("expected %04x - actual %04x\n", expected->message, actual->message); - - if (expected->message == actual->message) - { - if (expected->flags & wparam) - { - if (expected->wParam != actual->wParam && todo) - { - todo_wine - { - failcount++; - ok_(file, line) (FALSE, - "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", - context, expected->message, expected->wParam, actual->wParam); - } - } - else - { - ok_(file, line) (expected->wParam == actual->wParam, - "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", - context, expected->message, expected->wParam, actual->wParam); - } - } - - if (expected->flags & lparam) - { - if (expected->lParam != actual->lParam && todo) - { - todo_wine - { - failcount++; - ok_(file, line) (FALSE, - "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", - context, expected->message, expected->lParam, actual->lParam); - } - } - else - { - ok_(file, line) (expected->lParam == actual->lParam, - "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", - context, expected->message, expected->lParam, actual->lParam); - } - } - - if (expected->flags & id) - { - if (expected->id != actual->id && todo) - { - todo_wine - { - failcount++; - ok_(file, line) (FALSE, - "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n", - context, expected->message, expected->id, actual->id); - } - } - else - { - ok_(file, line) (expected->id == actual->id, - "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n", - context, expected->message, expected->id, actual->id); - } - } - - if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo) - { - todo_wine - { - failcount++; - ok_(file, line) (FALSE, - "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n", - context, expected->message, (expected->flags & defwinproc) ? "" : "NOT "); - } - } - else - { - ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc), - "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n", - context, expected->message, (expected->flags & defwinproc) ? "" : "NOT "); - } - - ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint), - "%s: the msg 0x%04x should %shave been sent by BeginPaint\n", - context, expected->message, (expected->flags & beginpaint) ? "" : "NOT "); - ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)), - "%s: the msg 0x%04x should have been %s\n", - context, expected->message, (expected->flags & posted) ? "posted" : "sent"); - ok_(file, line) ((expected->flags & parent) == (actual->flags & parent), - "%s: the msg 0x%04x was expected in %s\n", - context, expected->message, (expected->flags & parent) ? "parent" : "child"); - ok_(file, line) ((expected->flags & hook) == (actual->flags & hook), - "%s: the msg 0x%04x should have been sent by a hook\n", - context, expected->message); - ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook), - "%s: the msg 0x%04x should have been sent by a winevent hook\n", - context, expected->message); - expected++; - actual++; - } - else if (expected->flags & optional) - expected++; - else if (todo) - { - failcount++; - todo_wine - { - ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n", - context, expected->message, actual->message); - } - - flush_sequence(seq, sequence_index); - return; - } - else - { - ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n", - context, expected->message, actual->message); - expected++; - actual++; - } - } - - /* skip all optional trailing messages */ - while (expected->message && ((expected->flags & optional))) - expected++; - - if (todo) - { - todo_wine - { - if (expected->message || actual->message) - { - failcount++; - ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n", - context, expected->message, actual->message); - } - } - } - else if (expected->message || actual->message) - { - ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n", - context, expected->message, actual->message); - } - - if(todo && !failcount) /* succeeded yet marked todo */ - { - todo_wine - { - ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context); - } - } - - flush_sequence(seq, sequence_index); -} - -void init_msg_sequences(struct msg_sequence **seq, int n) -{ - int i; - - for (i = 0; i < n; i++) - seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence)); -} - -START_TEST(msg) -{ -} diff --git a/rostests/winetests/comctl32/msg.h b/rostests/winetests/comctl32/msg.h index 2ec3ea17a85..361ccdbf598 100644 --- a/rostests/winetests/comctl32/msg.h +++ b/rostests/winetests/comctl32/msg.h @@ -47,7 +47,8 @@ struct message msg_flags_t flags; /* message props */ WPARAM wParam; /* expected value of wParam */ LPARAM lParam; /* expected value of lParam */ - UINT id; /* id of the window */ + UINT id; /* extra message data: id of the window, + notify code etc. */ }; struct msg_sequence @@ -57,17 +58,237 @@ struct msg_sequence struct message *sequence; }; -void add_message(struct msg_sequence **seq, int sequence_index, - const struct message *msg); -void flush_sequence(struct msg_sequence **seg, int sequence_index); -void flush_sequences(struct msg_sequence **seq, int n); +static void add_message(struct msg_sequence **seq, int sequence_index, + const struct message *msg) +{ + struct msg_sequence *msg_seq = seq[sequence_index]; + + if (!msg_seq->sequence) + { + msg_seq->size = 10; + msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0, + msg_seq->size * sizeof (struct message)); + } + + if (msg_seq->count == msg_seq->size) + { + msg_seq->size *= 2; + msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0, + msg_seq->sequence, + msg_seq->size * sizeof (struct message)); + } + + assert(msg_seq->sequence); + + msg_seq->sequence[msg_seq->count].message = msg->message; + msg_seq->sequence[msg_seq->count].flags = msg->flags; + msg_seq->sequence[msg_seq->count].wParam = msg->wParam; + msg_seq->sequence[msg_seq->count].lParam = msg->lParam; + msg_seq->sequence[msg_seq->count].id = msg->id; + + msg_seq->count++; +} + +static void flush_sequence(struct msg_sequence **seg, int sequence_index) +{ + struct msg_sequence *msg_seq = seg[sequence_index]; + HeapFree(GetProcessHeap(), 0, msg_seq->sequence); + msg_seq->sequence = NULL; + msg_seq->count = msg_seq->size = 0; +} + +static void flush_sequences(struct msg_sequence **seq, int n) +{ + int i; + + for (i = 0; i < n; i++) + flush_sequence(seq, i); +} + +static void ok_sequence_(struct msg_sequence **seq, int sequence_index, + const struct message *expected, const char *context, int todo, + const char *file, int line) +{ + struct msg_sequence *msg_seq = seq[sequence_index]; + static const struct message end_of_sequence = {0, 0, 0, 0}; + const struct message *actual, *sequence; + int failcount = 0; + + add_message(seq, sequence_index, &end_of_sequence); + + sequence = msg_seq->sequence; + actual = sequence; + + while (expected->message && actual->message) + { + trace_( file, line)("expected %04x - actual %04x\n", expected->message, actual->message); + + if (expected->message == actual->message) + { + if (expected->flags & wparam) + { + if (expected->wParam != actual->wParam && todo) + { + todo_wine + { + failcount++; + ok_(file, line) (FALSE, + "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", + context, expected->message, expected->wParam, actual->wParam); + } + } + else + { + ok_(file, line) (expected->wParam == actual->wParam, + "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", + context, expected->message, expected->wParam, actual->wParam); + } + } + + if (expected->flags & lparam) + { + if (expected->lParam != actual->lParam && todo) + { + todo_wine + { + failcount++; + ok_(file, line) (FALSE, + "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", + context, expected->message, expected->lParam, actual->lParam); + } + } + else + { + ok_(file, line) (expected->lParam == actual->lParam, + "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", + context, expected->message, expected->lParam, actual->lParam); + } + } + + if (expected->flags & id) + { + if (expected->id != actual->id && expected->flags & optional) + { + expected++; + continue; + } + if (expected->id != actual->id && todo) + { + todo_wine + { + failcount++; + ok_(file, line) (FALSE, + "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n", + context, expected->message, expected->id, actual->id); + } + } + else + { + ok_(file, line) (expected->id == actual->id, + "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n", + context, expected->message, expected->id, actual->id); + } + } + + if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo) + { + todo_wine + { + failcount++; + ok_(file, line) (FALSE, + "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n", + context, expected->message, (expected->flags & defwinproc) ? "" : "NOT "); + } + } + else + { + ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc), + "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n", + context, expected->message, (expected->flags & defwinproc) ? "" : "NOT "); + } + + ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint), + "%s: the msg 0x%04x should %shave been sent by BeginPaint\n", + context, expected->message, (expected->flags & beginpaint) ? "" : "NOT "); + ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)), + "%s: the msg 0x%04x should have been %s\n", + context, expected->message, (expected->flags & posted) ? "posted" : "sent"); + ok_(file, line) ((expected->flags & parent) == (actual->flags & parent), + "%s: the msg 0x%04x was expected in %s\n", + context, expected->message, (expected->flags & parent) ? "parent" : "child"); + ok_(file, line) ((expected->flags & hook) == (actual->flags & hook), + "%s: the msg 0x%04x should have been sent by a hook\n", + context, expected->message); + ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook), + "%s: the msg 0x%04x should have been sent by a winevent hook\n", + context, expected->message); + expected++; + actual++; + } + else if (expected->flags & optional) + expected++; + else if (todo) + { + failcount++; + todo_wine + { + ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n", + context, expected->message, actual->message); + } + + flush_sequence(seq, sequence_index); + return; + } + else + { + ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n", + context, expected->message, actual->message); + expected++; + actual++; + } + } + + /* skip all optional trailing messages */ + while (expected->message && ((expected->flags & optional))) + expected++; + + if (todo) + { + todo_wine + { + if (expected->message || actual->message) + { + failcount++; + ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n", + context, expected->message, actual->message); + } + } + } + else if (expected->message || actual->message) + { + ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n", + context, expected->message, actual->message); + } + + if(todo && !failcount) /* succeeded yet marked todo */ + { + todo_wine + { + ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context); + } + } + + flush_sequence(seq, sequence_index); +} #define ok_sequence(seq, index, exp, contx, todo) \ ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__) -void ok_sequence_(struct msg_sequence **seq, int sequence_index, - const struct message *expected, const char *context, int todo, - const char *file, int line); +static void init_msg_sequences(struct msg_sequence **seq, int n) +{ + int i; -void init_msg_sequences(struct msg_sequence **seq, int n); + for (i = 0; i < n; i++) + seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence)); +} diff --git a/rostests/winetests/comctl32/progress.c b/rostests/winetests/comctl32/progress.c index 10bbbef8a28..3083e8ba2e5 100644 --- a/rostests/winetests/comctl32/progress.c +++ b/rostests/winetests/comctl32/progress.c @@ -163,6 +163,7 @@ static void cleanup(void) static void test_redraw(void) { RECT client_rect; + LRESULT ret; SendMessageA(hProgressWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); SendMessageA(hProgressWnd, PBM_SETPOS, 10, 0); @@ -184,7 +185,11 @@ static void test_redraw(void) /* PBM_STEPIT */ ok(SendMessageA(hProgressWnd, PBM_STEPIT, 0, 0) == 80, "PBM_STEPIT must return the previous position\n"); ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_STEPIT: The progress bar should be redrawn immediately\n"); - ok((UINT)SendMessageA(hProgressWnd, PBM_GETPOS, 0, 0) == 100, "PBM_GETPOS returned a wrong position\n"); + ret = SendMessageA(hProgressWnd, PBM_GETPOS, 0, 0); + if (ret == 0) + win_skip("PBM_GETPOS needs comctl32 > 4.70\n"); + else + ok(ret == 100, "PBM_GETPOS returned a wrong position : %d\n", (UINT)ret); /* PBM_SETRANGE and PBM_SETRANGE32: Usually the progress bar doesn't repaint itself immediately. If the diff --git a/rostests/winetests/comctl32/propsheet.c b/rostests/winetests/comctl32/propsheet.c index 4164f68c60e..bf40db4f6ec 100644 --- a/rostests/winetests/comctl32/propsheet.c +++ b/rostests/winetests/comctl32/propsheet.c @@ -1,6 +1,7 @@ /* Unit test suite for property sheet control. * * Copyright 2006 Huw Davies + * Copyright 2009 Jan de Mooij * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +21,16 @@ #include #include +#include "resources.h" + #include "wine/test.h" static HWND parent; +static HWND sheethwnd; + +static LONG active_page = -1; + +#define IDC_APPLY_BUTTON 12321 static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam) { @@ -33,12 +41,13 @@ static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam) char caption[256]; GetWindowTextA(hwnd, caption, sizeof(caption)); ok(!strcmp(caption,"test caption"), "caption: %s\n", caption); + sheethwnd = hwnd; return 0; } } return 0; } - + static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -64,6 +73,10 @@ static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, return FALSE; } } + case WM_NCDESTROY: + ok(!SendMessageA(sheethwnd, PSM_INDEXTOHWND, 400, 0),"Should always be 0\n"); + return TRUE; + default: return FALSE; } @@ -79,7 +92,7 @@ static void test_title(void) memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags = 0; - psp.hInstance = GetModuleHandleW(NULL); + psp.hInstance = GetModuleHandleA(NULL); U(psp).pszTemplate = "prop_page1"; U2(psp).pszIcon = NULL; psp.pfnDlgProc = page_dlg_proc; @@ -97,6 +110,12 @@ static void test_title(void) psh.pfnCallback = sheet_callback; hdlg = (HWND)PropertySheetA(&psh); + if (hdlg == INVALID_HANDLE_VALUE) + { + win_skip("comctl32 4.70 needs dwSize adjustment\n"); + psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP); + hdlg = (HWND)PropertySheetA(&psh); + } DestroyWindow(hdlg); } @@ -110,7 +129,7 @@ static void test_nopage(void) memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags = 0; - psp.hInstance = GetModuleHandleW(NULL); + psp.hInstance = GetModuleHandleA(NULL); U(psp).pszTemplate = "prop_page1"; U2(psp).pszIcon = NULL; psp.pfnDlgProc = page_dlg_proc; @@ -128,6 +147,12 @@ static void test_nopage(void) psh.pfnCallback = sheet_callback; hdlg = (HWND)PropertySheetA(&psh); + if (hdlg == INVALID_HANDLE_VALUE) + { + win_skip("comctl32 4.70 needs dwSize adjustment\n"); + psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP); + hdlg = (HWND)PropertySheetA(&psh); + } ShowWindow(hdlg,SW_NORMAL); SendMessage(hdlg, PSM_REMOVEPAGE, 0, 0); RedrawWindow(hdlg,NULL,NULL,RDW_UPDATENOW|RDW_ERASENOW); @@ -170,6 +195,7 @@ static void test_disableowner(void) HPROPSHEETPAGE hpsp[1]; PROPSHEETPAGEA psp; PROPSHEETHEADERA psh; + INT_PTR p; register_parent_wnd_class(); parent = CreateWindowA("parent class", "", WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 100, 100, 100, 100, GetDesktopWindow(), NULL, GetModuleHandleA(NULL), 0); @@ -177,7 +203,7 @@ static void test_disableowner(void) memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags = 0; - psp.hInstance = GetModuleHandleW(NULL); + psp.hInstance = GetModuleHandleA(NULL); U(psp).pszTemplate = "prop_page1"; U2(psp).pszIcon = NULL; psp.pfnDlgProc = NULL; @@ -194,14 +220,227 @@ static void test_disableowner(void) U3(psh).phpage = hpsp; psh.pfnCallback = disableowner_callback; - PropertySheetA(&psh); + p = PropertySheetA(&psh); + todo_wine + ok(p == 0, "Expected 0, got %ld\n", p); ok(IsWindowEnabled(parent) != 0, "parent window should be enabled\n"); DestroyWindow(parent); } +static INT_PTR CALLBACK nav_page_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch(msg){ + case WM_NOTIFY: + { + LPNMHDR hdr = (LPNMHDR)lparam; + switch(hdr->code){ + case PSN_SETACTIVE: + active_page = PropSheet_HwndToIndex(hdr->hwndFrom, hwnd); + return TRUE; + case PSN_KILLACTIVE: + /* prevent navigation away from the fourth page */ + if(active_page == 3){ + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); + return TRUE; + } + } + break; + } + } + return FALSE; +} + +static void test_wiznavigation(void) +{ + HPROPSHEETPAGE hpsp[4]; + PROPSHEETPAGEA psp[4]; + PROPSHEETHEADERA psh; + HWND hdlg, control; + LONG_PTR controlID; + LRESULT defidres; + BOOL hwndtoindex_supported = TRUE; + const INT nextID = 12324; + const INT backID = 12323; + + /* create the property sheet pages */ + memset(psp, 0, sizeof(PROPSHEETPAGEA) * 4); + + psp[0].dwSize = sizeof(PROPSHEETPAGEA); + psp[0].hInstance = GetModuleHandleA(NULL); + U(psp[0]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO); + psp[0].pfnDlgProc = nav_page_proc; + hpsp[0] = CreatePropertySheetPageA(&psp[0]); + + psp[1].dwSize = sizeof(PROPSHEETPAGEA); + psp[1].hInstance = GetModuleHandleA(NULL); + U(psp[1]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT); + psp[1].pfnDlgProc = nav_page_proc; + hpsp[1] = CreatePropertySheetPageA(&psp[1]); + + psp[2].dwSize = sizeof(PROPSHEETPAGEA); + psp[2].hInstance = GetModuleHandleA(NULL); + U(psp[2]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO); + psp[2].pfnDlgProc = nav_page_proc; + hpsp[2] = CreatePropertySheetPageA(&psp[2]); + + psp[3].dwSize = sizeof(PROPSHEETPAGEA); + psp[3].hInstance = GetModuleHandleA(NULL); + U(psp[3]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT); + psp[3].pfnDlgProc = nav_page_proc; + hpsp[3] = CreatePropertySheetPageA(&psp[3]); + + /* set up the property sheet dialog */ + memset(&psh, 0, sizeof(psh)); + psh.dwSize = sizeof(psh); + psh.dwFlags = PSH_MODELESS | PSH_WIZARD; + psh.pszCaption = "A Wizard"; + psh.nPages = 4; + psh.hwndParent = GetDesktopWindow(); + U3(psh).phpage = hpsp; + hdlg = (HWND)PropertySheetA(&psh); + if (hdlg == INVALID_HANDLE_VALUE) + { + win_skip("comctl32 4.70 needs dwSize adjustment\n"); + psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP); + hdlg = (HWND)PropertySheetA(&psh); + } + + ok(active_page == 0, "Active page should be 0. Is: %d\n", active_page); + + control = GetFocus(); + controlID = GetWindowLongPtr(control, GWLP_ID); + ok(controlID == nextID, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID, controlID); + + /* simulate pressing the Next button */ + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0); + if (!active_page) hwndtoindex_supported = FALSE; + if (hwndtoindex_supported) + ok(active_page == 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page); + + control = GetFocus(); + controlID = GetWindowLongPtr(control, GWLP_ID); + ok(controlID == IDC_PS_EDIT1, "Focus should be set to the first item on the second page. Expected: %d, Found: %ld\n", IDC_PS_EDIT1, controlID); + + defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0); + ok(defidres == MAKELRESULT(nextID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", nextID, LOWORD(defidres)); + + /* set the focus to the second edit box on this page */ + SetFocus(GetNextDlgTabItem(hdlg, control, FALSE)); + + /* press next again */ + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0); + if (hwndtoindex_supported) + ok(active_page == 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page); + + control = GetFocus(); + controlID = GetWindowLongPtr(control, GWLP_ID); + ok(controlID == IDC_PS_RADIO1, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1, controlID); + + /* back button */ + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_BACK, 0); + if (hwndtoindex_supported) + ok(active_page == 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page); + + control = GetFocus(); + controlID = GetWindowLongPtr(control, GWLP_ID); + ok(controlID == IDC_PS_EDIT1, "Focus should have been set to the first item on second page. Expected: %d, Found %ld\n", IDC_PS_EDIT1, controlID); + + defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0); + ok(defidres == MAKELRESULT(backID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", backID, LOWORD(defidres)); + + /* press next twice */ + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0); + if (hwndtoindex_supported) + ok(active_page == 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page); + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0); + if (hwndtoindex_supported) + ok(active_page == 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page); + else + active_page = 3; + + control = GetFocus(); + controlID = GetWindowLongPtr(control, GWLP_ID); + ok(controlID == nextID, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID, controlID); + + /* try to navigate away, but shouldn't be able to */ + SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_BACK, 0); + ok(active_page == 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page); + + defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0); + ok(defidres == MAKELRESULT(nextID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", nextID, LOWORD(defidres)); + + DestroyWindow(hdlg); +} +static void test_buttons(void) +{ + HPROPSHEETPAGE hpsp[1]; + PROPSHEETPAGEA psp; + PROPSHEETHEADERA psh; + HWND hdlg; + HWND button; + RECT rc; + int prevRight, top; + + memset(&psp, 0, sizeof(psp)); + psp.dwSize = sizeof(psp); + psp.dwFlags = 0; + psp.hInstance = GetModuleHandleA(NULL); + U(psp).pszTemplate = "prop_page1"; + U2(psp).pszIcon = NULL; + psp.pfnDlgProc = page_dlg_proc; + psp.lParam = 0; + + hpsp[0] = CreatePropertySheetPageA(&psp); + + memset(&psh, 0, sizeof(psh)); + psh.dwSize = sizeof(psh); + psh.dwFlags = PSH_MODELESS | PSH_USECALLBACK; + psh.pszCaption = "test caption"; + psh.nPages = 1; + psh.hwndParent = GetDesktopWindow(); + U3(psh).phpage = hpsp; + psh.pfnCallback = sheet_callback; + + hdlg = (HWND)PropertySheetA(&psh); + if (hdlg == INVALID_HANDLE_VALUE) + { + win_skip("comctl32 4.70 needs dwSize adjustment\n"); + psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP); + hdlg = (HWND)PropertySheetA(&psh); + } + + /* OK button */ + button = GetDlgItem(hdlg, IDOK); + GetWindowRect(button, &rc); + prevRight = rc.right; + top = rc.top; + + /* Cancel button */ + button = GetDlgItem(hdlg, IDCANCEL); + GetWindowRect(button, &rc); + ok(rc.top == top, "Cancel button should have same top as OK button\n"); + ok(rc.left > prevRight, "Cancel button should be to the right of OK button\n"); + prevRight = rc.right; + + button = GetDlgItem(hdlg, IDC_APPLY_BUTTON); + GetWindowRect(button, &rc); + ok(rc.top == top, "Apply button should have same top as OK button\n"); + ok(rc.left > prevRight, "Apply button should be to the right of Cancel button\n"); + prevRight = rc.right; + + button = GetDlgItem(hdlg, IDHELP); + GetWindowRect(button, &rc); + ok(rc.top == top, "Help button should have same top as OK button\n"); + ok(rc.left > prevRight, "Help button should be to the right of Apply button\n"); + + DestroyWindow(hdlg); +} + START_TEST(propsheet) { test_title(); test_nopage(); test_disableowner(); + test_wiznavigation(); + test_buttons(); } diff --git a/rostests/winetests/comctl32/rebar.c b/rostests/winetests/comctl32/rebar.c index d055d8aec8f..a75a0647f95 100644 --- a/rostests/winetests/comctl32/rebar.c +++ b/rostests/winetests/comctl32/rebar.c @@ -32,7 +32,6 @@ RECT height_change_notify_rect; static HWND hMainWnd; -static HWND hRebar; #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \ @@ -66,14 +65,17 @@ static BOOL is_font_installed(const char *name) return ret; } -static void rebuild_rebar(HWND *hRebar) +static HWND create_rebar_control(void) { - if (*hRebar) - DestroyWindow(*hRebar); + HWND hwnd; - *hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, + hwnd = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hMainWnd, (HMENU)17, GetModuleHandle(NULL), NULL); - SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0); + ok(hwnd != NULL, "Failed to create Rebar\n"); + + SendMessageA(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0); + + return hwnd; } static HWND build_toolbar(int nr, HWND hParent) @@ -85,7 +87,7 @@ static HWND build_toolbar(int nr, HWND hParent) int i; ok(hToolbar != NULL, "Toolbar creation problem\n"); - ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n"); + ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n"); ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n"); ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n"); @@ -104,7 +106,7 @@ static HWND build_toolbar(int nr, HWND hParent) case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break; case 2: iBitmapId = IDB_STD_SMALL_COLOR; break; } - ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGE failed\n"); + ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGES failed\n"); ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n"); return hToolbar; } @@ -117,7 +119,7 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa { NMHDR *lpnm = (NMHDR *)lParam; if (lpnm->code == RBN_HEIGHTCHANGE) - GetClientRect(hRebar, &height_change_notify_rect); + GetClientRect(lpnm->hwndFrom, &height_change_notify_rect); } break; } @@ -150,7 +152,7 @@ static void dump_sizes(HWND hRebar) for (i=0; inBands, "%d"); \ for (i=0; inBands); i++) { \ - ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_ITEMRECT\n"); \ + ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \ if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \ check_rect("band", rc, res->bands[i].rc); \ - rbi.cbSize = sizeof(REBARBANDINFO); \ + rbi.cbSize = REBARBANDINFOA_V6_SIZE; \ rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \ ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \ compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \ @@ -329,11 +331,11 @@ static int rbsize_numtests = 0; static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal) { CHAR buffer[MAX_PATH]; - REBARBANDINFO rbi; + REBARBANDINFOA rbi; if (lpszText != NULL) strcpy(buffer, lpszText); - rbi.cbSize = sizeof(rbi); + rbi.cbSize = REBARBANDINFOA_V6_SIZE; rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT; rbi.cx = cx; rbi.cxMinChild = cxMinChild; @@ -344,16 +346,16 @@ static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi); } -static void layout_test(void) +static void test_layout(void) { - HWND hRebar = NULL; + HWND hRebar; REBARBANDINFO rbi; HIMAGELIST himl; REBARINFO ri; - rebuild_rebar(&hRebar); + hRebar = create_rebar_control(); check_sizes(); - rbi.cbSize = sizeof(rbi); + rbi.cbSize = REBARBANDINFOA_V6_SIZE; rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD; rbi.cx = 200; rbi.cxMinChild = 100; @@ -409,7 +411,9 @@ static void layout_test(void) SendMessageA(hRebar, RB_DELETEBAND, 1, 0); check_sizes(); - rebuild_rebar(&hRebar); + DestroyWindow(hRebar); + + hRebar = create_rebar_control(); add_band_w(hRebar, "ABC", 70, 40, 100); add_band_w(hRebar, NULL, 40, 70, 100); add_band_w(hRebar, NULL, 170, 240, 100); @@ -448,8 +452,10 @@ static void layout_test(void) SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi); check_sizes(); + DestroyWindow(hRebar); + /* VARHEIGHT resizing test on a horizontal rebar */ - rebuild_rebar(&hRebar); + hRebar = create_rebar_control(); SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE); check_sizes(); rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE; @@ -474,8 +480,10 @@ static void layout_test(void) SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi); check_sizes(); + DestroyWindow(hRebar); + /* VARHEIGHT resizing on a vertical rebar */ - rebuild_rebar(&hRebar); + hRebar = create_rebar_control(); SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE); check_sizes(); rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE; @@ -503,6 +511,7 @@ static void layout_test(void) check_sizes(); DestroyWindow(hRebar); + ImageList_Destroy(himl); } #if 0 /* use this to generate more tests */ @@ -684,7 +693,7 @@ static int resize_numtests = 0; #endif -static void resize_test(void) +static void test_resize(void) { DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT, CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT, @@ -696,6 +705,8 @@ static void resize_test(void) for (i = 0; i < styles_count; i++) { + HWND hRebar; + comment("style %08x", dwStyles[i]); SetRect(&height_change_notify_rect, -1, -1, -1, -1); hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0); @@ -735,17 +746,17 @@ static void resize_test(void) } } -static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore, +static void expect_band_content(HWND hRebar, UINT uBand, INT fStyle, COLORREF clrFore, COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild, INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID, INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam, - INT cxHeader) + INT cxHeader, INT cxHeader_broken) { CHAR buf[MAX_PATH] = "abc"; - REBARBANDINFO rb; + REBARBANDINFOA rb; memset(&rb, 0xdd, sizeof(rb)); - rb.cbSize = sizeof(rb); + rb.cbSize = REBARBANDINFOA_V6_SIZE; rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT; @@ -753,8 +764,8 @@ static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore, rb.cch = MAX_PATH; ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n"); expect_eq(rb.fStyle, fStyle, int, "%x"); - todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x"); - todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x"); + expect_eq(rb.clrFore, clrFore, COLORREF, "%x"); + expect_eq(rb.clrBack, clrBack, COLORREF, "%x"); expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d"); expect_eq(rb.iImage, iImage, int, "%x"); expect_eq(rb.hwndChild, hwndChild, HWND, "%p"); @@ -769,20 +780,27 @@ static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore, expect_eq(rb.cyIntegral, cyIntegral, int, "%x"); expect_eq(rb.cxIdeal, cxIdeal, int, "%d"); expect_eq(rb.lParam, lParam, LPARAM, "%ld"); - expect_eq(rb.cxHeader, cxHeader, int, "%d"); + ok( rb.cxHeader == cxHeader || broken(rb.cxHeader == cxHeader_broken), + "expected %d for %d\n", cxHeader, rb.cxHeader ); } -static void bandinfo_test(void) +static void test_bandinfo(void) { REBARBANDINFOA rb; CHAR szABC[] = "ABC"; CHAR szABCD[] = "ABCD"; + HWND hRebar; - rebuild_rebar(&hRebar); - rb.cbSize = sizeof(REBARBANDINFO); + hRebar = create_rebar_control(); + rb.cbSize = REBARBANDINFOA_V6_SIZE; rb.fMask = 0; - ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0); + if (!SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb)) + { + win_skip( "V6 info not supported\n" ); + DestroyWindow(hRebar); + return; + } + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1); rb.fMask = RBBIM_CHILDSIZE; rb.cxMinChild = 15; @@ -790,62 +808,93 @@ static void bandinfo_test(void) rb.cyChild = 30; rb.cyMaxChild = 20; rb.cyIntegral = 10; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1); rb.fMask = RBBIM_TEXT; rb.lpText = szABC; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35, -1); - rb.cbSize = sizeof(REBARBANDINFO); + rb.cbSize = REBARBANDINFOA_V6_SIZE; rb.fMask = 0; ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9); - expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40); + expect_band_content(hRebar, 1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1); + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40, -1); rb.fMask = RBBIM_HEADERSIZE; rb.cxHeader = 50; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50, -1); rb.cxHeader = 5; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1); rb.fMask = RBBIM_TEXT; rb.lpText = szABCD; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1); rb.fMask = RBBIM_STYLE | RBBIM_TEXT; rb.fStyle = RBBS_VARIABLEHEIGHT; rb.lpText = szABC; - ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n"); - expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40); + ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n"); + expect_band_content(hRebar, 0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40, 5); DestroyWindow(hRebar); } -START_TEST(rebar) +static void test_colors(void) { - HMODULE hComctl32; - BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); - INITCOMMONCONTROLSEX iccex; - WNDCLASSA wc; - MSG msg; - RECT rc; + COLORSCHEME scheme; + COLORREF clr; + BOOL ret; + HWND hRebar; + REBARBANDINFOA bi; - /* LoadLibrary is needed. This file has no references to functions in comctl32 */ - hComctl32 = LoadLibraryA("comctl32.dll"); - pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); - if (!pInitCommonControlsEx) + hRebar = create_rebar_control(); + + /* test default colors */ + clr = SendMessage(hRebar, RB_GETTEXTCOLOR, 0, 0); + compare(clr, CLR_NONE, "%x"); + clr = SendMessage(hRebar, RB_GETBKCOLOR, 0, 0); + compare(clr, CLR_NONE, "%x"); + + scheme.dwSize = sizeof(scheme); + scheme.clrBtnHighlight = 0; + scheme.clrBtnShadow = 0; + ret = SendMessage(hRebar, RB_GETCOLORSCHEME, 0, (LPARAM)&scheme); + if (ret) { - skip("InitCommonControlsEx() is missing. Skipping the tests\n"); - return; + compare(scheme.clrBtnHighlight, CLR_DEFAULT, "%x"); + compare(scheme.clrBtnShadow, CLR_DEFAULT, "%x"); } - iccex.dwSize = sizeof(iccex); - iccex.dwICC = ICC_COOL_CLASSES; - pInitCommonControlsEx(&iccex); + else + skip("RB_GETCOLORSCHEME not supported\n"); + + /* check default band colors */ + add_band_w(hRebar, "", 0, 10, 10); + bi.cbSize = REBARBANDINFOA_V6_SIZE; + bi.fMask = RBBIM_COLORS; + bi.clrFore = bi.clrBack = 0xc0ffe; + ret = SendMessage(hRebar, RB_GETBANDINFO, 0, (LPARAM)&bi); + ok(ret, "RB_GETBANDINFO failed\n"); + compare(bi.clrFore, RGB(0, 0, 0), "%x"); + compare(bi.clrBack, GetSysColor(COLOR_3DFACE), "%x"); + + SendMessage(hRebar, RB_SETTEXTCOLOR, 0, RGB(255, 0, 0)); + bi.clrFore = bi.clrBack = 0xc0ffe; + ret = SendMessage(hRebar, RB_GETBANDINFO, 0, (LPARAM)&bi); + ok(ret, "RB_GETBANDINFO failed\n"); + compare(bi.clrFore, RGB(0, 0, 0), "%x"); + + DestroyWindow(hRebar); +} + + +static BOOL register_parent_wnd_class(void) +{ + WNDCLASSA wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; @@ -857,23 +906,59 @@ START_TEST(rebar) wc.lpszMenuName = NULL; wc.lpszClassName = "MyTestWnd"; wc.lpfnWndProc = MyWndProc; - RegisterClassA(&wc); - hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, + + return RegisterClassA(&wc); +} + +static HWND create_parent_window(void) +{ + HWND hwnd; + + if (!register_parent_wnd_class()) return NULL; + + hwnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME), 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME), NULL, NULL, GetModuleHandleA(NULL), 0); - GetClientRect(hMainWnd, &rc); - ShowWindow(hMainWnd, SW_SHOW); - bandinfo_test(); + ShowWindow(hwnd, SW_SHOW); + return hwnd; +} - if(is_font_installed("System") && is_font_installed("Tahoma")) +START_TEST(rebar) +{ + HMODULE hComctl32; + BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); + INITCOMMONCONTROLSEX iccex; + MSG msg; + + /* LoadLibrary is needed. This file has no references to functions in comctl32 */ + hComctl32 = LoadLibraryA("comctl32.dll"); + pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); + if (!pInitCommonControlsEx) { - layout_test(); - resize_test(); - } else - skip("Missing System or Tahoma font\n"); + win_skip("InitCommonControlsEx() is missing. Skipping the tests\n"); + return; + } + iccex.dwSize = sizeof(iccex); + iccex.dwICC = ICC_COOL_CLASSES; + pInitCommonControlsEx(&iccex); + hMainWnd = create_parent_window(); + + test_bandinfo(); + test_colors(); + + if(!is_font_installed("System") || !is_font_installed("Tahoma")) + { + skip("Missing System or Tahoma font\n"); + goto out; + } + + test_layout(); + test_resize(); + +out: PostQuitMessage(0); while(GetMessageA(&msg,0,0,0)) { TranslateMessage(&msg); diff --git a/rostests/winetests/comctl32/resources.h b/rostests/winetests/comctl32/resources.h index c99633d342d..8459fc81c16 100644 --- a/rostests/winetests/comctl32/resources.h +++ b/rostests/winetests/comctl32/resources.h @@ -31,4 +31,14 @@ #define IDS_TBADD5 20 #define IDS_TBADD7 22 +#define IDD_PROP_PAGE_INTRO 30 +#define IDD_PROP_PAGE_EDIT 31 +#define IDD_PROP_PAGE_RADIO 32 +#define IDD_PROP_PAGE_EXIT 33 + +#define IDC_PS_EDIT1 1000 +#define IDC_PS_EDIT2 1001 +#define IDC_PS_RADIO1 1010 +#define IDC_PS_RADIO2 1011 + #endif /* __WINE_COMCTL32_TEST_RESOURCES_H */ diff --git a/rostests/winetests/comctl32/rsrc.rc b/rostests/winetests/comctl32/rsrc.rc index bf195b661d1..06e382e3c4a 100644 --- a/rostests/winetests/comctl32/rsrc.rc +++ b/rostests/winetests/comctl32/rsrc.rc @@ -30,6 +30,40 @@ FONT 8, "MS Shell Dlg" LTEXT "Test", -1, 10, 6, 100, 8 } +IDD_PROP_PAGE_INTRO DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215 +STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE +CAPTION "Edit Control Page" +FONT 8, "MS Shell Dlg" +{ + LTEXT "This is a test property sheet!", -1, 10, 6, 100, 8 +} + +IDD_PROP_PAGE_EDIT DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215 +STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE +CAPTION "Edit Control Page" +FONT 8, "MS Shell Dlg" +{ + EDITTEXT IDC_PS_EDIT1, 5, 5, 150, 140, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE + EDITTEXT IDC_PS_EDIT2, 5, 160, 150, 28, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE +} + +IDD_PROP_PAGE_RADIO DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215 +STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE +CAPTION "Edit Control Page" +FONT 8, "MS Shell Dlg" +{ + CONTROL "Radio1", IDC_PS_RADIO1, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 20, 20, 39, 10 + CONTROL "Radio2", IDC_PS_RADIO2, "Button", BS_AUTORADIOBUTTON, 20, 40, 39, 10 +} + +IDD_PROP_PAGE_EXIT DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215 +STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE +CAPTION "Edit Control Page" +FONT 8, "MS Shell Dlg" +{ + LTEXT "This has been a test property sheet!", -1, 10, 6, 170, 8 +} + STRINGTABLE { IDS_TBADD1 "abc" diff --git a/rostests/winetests/comctl32/status.c b/rostests/winetests/comctl32/status.c index f1cbda47f0d..839b138bb40 100644 --- a/rostests/winetests/comctl32/status.c +++ b/rostests/winetests/comctl32/status.c @@ -466,6 +466,112 @@ static void test_status_ownerdraw(void) SetWindowLongPtr( g_hMainWnd, GWLP_WNDPROC, (LONG_PTR)g_wndproc_saved ); } +static void test_gettext(void) +{ + HWND hwndStatus = CreateWindow(SUBCLASS_NAME, NULL, WS_CHILD|WS_VISIBLE, + 0, 0, 300, 20, g_hMainWnd, NULL, NULL, NULL); + char buf[5]; + int r; + + r = SendMessage(hwndStatus, SB_SETTEXT, 0, (LPARAM)"Text"); + expect(TRUE, r); + r = SendMessage(hwndStatus, WM_GETTEXTLENGTH, 0, 0); + expect(4, r); + /* A size of 0 returns the length of the text */ + r = SendMessage(hwndStatus, WM_GETTEXT, 0, 0); + expect(4, r); + /* A size of 1 only stores the NULL terminator */ + buf[0] = 0xa; + r = SendMessage(hwndStatus, WM_GETTEXT, 1, (LPARAM)buf); + ok( r == 0 || broken(r == 4), "Expected 0 got %d\n", r ); + if (!r) ok(!buf[0], "expected empty buffer\n"); + /* A size of 2 returns a length 1 */ + r = SendMessage(hwndStatus, WM_GETTEXT, 2, (LPARAM)buf); + ok( r == 1 || broken(r == 4), "Expected 1 got %d\n", r ); + r = SendMessage(hwndStatus, WM_GETTEXT, sizeof(buf), (LPARAM)buf); + expect(4, r); + ok(!strcmp(buf, "Text"), "expected Text, got %s\n", buf); + DestroyWindow(hwndStatus); +} + +/* Notify events to parent */ +static BOOL g_got_dblclk; +static BOOL g_got_click; +static BOOL g_got_rdblclk; +static BOOL g_got_rclick; + +/* Messages to parent */ +static BOOL g_got_contextmenu; + +static LRESULT WINAPI test_notify_parent_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_NOTIFY: + { + NMHDR *hdr = ((LPNMHDR)lParam); + switch(hdr->code) + { + case NM_DBLCLK: g_got_dblclk = TRUE; break; + case NM_CLICK: g_got_click = TRUE; break; + case NM_RDBLCLK: g_got_rdblclk = TRUE; break; + case NM_RCLICK: g_got_rclick = TRUE; break; + } + + /* Return zero to indicate default processing */ + return 0; + } + + case WM_CONTEXTMENU: g_got_contextmenu = TRUE; return 0; + + default: + return( DefWindowProcA(hwnd, msg, wParam, lParam)); + } + + return 0; +} + +/* Test that WM_NOTIFY messages from the status control works correctly */ +static void test_notify(void) +{ + HWND hwndParent; + HWND hwndStatus; + ATOM atom; + WNDCLASSA wclass = {0}; + wclass.lpszClassName = "TestNotifyParentClass"; + wclass.lpfnWndProc = test_notify_parent_proc; + atom = RegisterClassA(&wclass); + ok(atom, "RegisterClass failed\n"); + + /* create parent */ + hwndParent = CreateWindow(wclass.lpszClassName, "parent", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, 300, 20, NULL, NULL, NULL, NULL); + ok(hwndParent != NULL, "Parent creation failed!\n"); + + /* create status bar */ + hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, WS_VISIBLE | WS_CHILD, + 0, 0, 300, 20, hwndParent, NULL, NULL, NULL); + ok(hwndStatus != NULL, "Status creation failed!\n"); + + /* Send various mouse event, and check that we get them */ + g_got_dblclk = FALSE; + SendMessage(hwndStatus, WM_LBUTTONDBLCLK, 0, 0); + ok(g_got_dblclk, "WM_LBUTTONDBLCLK was not processed correctly!\n"); + g_got_rdblclk = FALSE; + SendMessage(hwndStatus, WM_RBUTTONDBLCLK, 0, 0); + ok(g_got_rdblclk, "WM_RBUTTONDBLCLK was not processed correctly!\n"); + g_got_click = FALSE; + SendMessage(hwndStatus, WM_LBUTTONUP, 0, 0); + ok(g_got_click, "WM_LBUTTONUP was not processed correctly!\n"); + + /* For R-UP, check that we also get the context menu from the default processing */ + g_got_contextmenu = FALSE; + g_got_rclick = FALSE; + SendMessage(hwndStatus, WM_RBUTTONUP, 0, 0); + ok(g_got_rclick, "WM_RBUTTONUP was not processed correctly!\n"); + ok(g_got_contextmenu, "WM_RBUTTONUP did not activate the context menu!\n"); +} + START_TEST(status) { hinst = GetModuleHandleA(NULL); @@ -483,4 +589,6 @@ START_TEST(status) test_create(); test_height(); test_status_ownerdraw(); + test_gettext(); + test_notify(); } diff --git a/rostests/winetests/comctl32/subclass.c b/rostests/winetests/comctl32/subclass.c index f4d0b727794..8511275c8f9 100644 --- a/rostests/winetests/comctl32/subclass.c +++ b/rostests/winetests/comctl32/subclass.c @@ -279,21 +279,49 @@ static BOOL RegisterWindowClasses(void) return TRUE; } -START_TEST(subclass) +static int init_function_pointers(void) { - HMODULE hdll; - - hdll = GetModuleHandleA("comctl32.dll"); - assert(hdll); + HMODULE hmod; + void *ptr; + + hmod = GetModuleHandleA("comctl32.dll"); + assert(hmod); + /* Functions have to be loaded by ordinal. Only XP and W2K3 export * them by name. */ - pSetWindowSubclass = (void*)GetProcAddress(hdll, (LPSTR)410); - pRemoveWindowSubclass = (void*)GetProcAddress(hdll, (LPSTR)412); - pDefSubclassProc = (void*)GetProcAddress(hdll, (LPSTR)413); - +#define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord))) + MAKEFUNC_ORD(SetWindowSubclass, 410); + MAKEFUNC_ORD(RemoveWindowSubclass, 412); + MAKEFUNC_ORD(DefSubclassProc, 413); +#undef MAKEFUNC_ORD + if(!pSetWindowSubclass || !pRemoveWindowSubclass || !pDefSubclassProc) - return; + { + win_skip("SetWindowSubclass and friends are not available\n"); + return 0; + } + + /* test named exports */ + ptr = GetProcAddress(hmod, "SetWindowSubclass"); + ok(broken(ptr == 0) || ptr != 0, "expected named export for SetWindowSubclass\n"); + if(ptr) + { +#define TESTNAMED(f) \ + ptr = (void*)GetProcAddress(hmod, #f); \ + ok(ptr != 0, "expected named export for " #f "\n"); + TESTNAMED(RemoveWindowSubclass); + TESTNAMED(DefSubclassProc); + /* GetWindowSubclass exported for V6 only */ +#undef TESTNAMED + } + + return 1; +} + +START_TEST(subclass) +{ + if(!init_function_pointers()) return; if(!RegisterWindowClasses()) assert(0); diff --git a/rostests/winetests/comctl32/tab.c b/rostests/winetests/comctl32/tab.c index 3bf68945120..6774d51a1a5 100644 --- a/rostests/winetests/comctl32/tab.c +++ b/rostests/winetests/comctl32/tab.c @@ -89,13 +89,14 @@ static const struct message create_parent_wnd_seq[] = { static const struct message add_tab_to_parent[] = { { TCM_INSERTITEMA, sent }, - { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent|optional }, { WM_NOTIFYFORMAT, sent|defwinproc }, { WM_QUERYUISTATE, sent|wparam|lparam|defwinproc|optional, 0, 0 }, { WM_PARENTNOTIFY, sent|defwinproc }, { TCM_INSERTITEMA, sent }, { TCM_INSERTITEMA, sent }, { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent|optional }, { 0 } }; @@ -236,12 +237,15 @@ static const struct message insert_focus_seq[] = { { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 }, { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, { TCM_INSERTITEM, sent|wparam, 1 }, + { WM_NOTIFYFORMAT, sent|defwinproc|optional }, + { WM_QUERYUISTATE, sent|defwinproc|optional }, + { WM_PARENTNOTIFY, sent|defwinproc|optional }, { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 }, { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, { TCM_INSERTITEM, sent|wparam, 2 }, - { WM_NOTIFYFORMAT, sent|defwinproc, }, + { WM_NOTIFYFORMAT, sent|defwinproc|optional }, { WM_QUERYUISTATE, sent|defwinproc|optional, }, - { WM_PARENTNOTIFY, sent|defwinproc, }, + { WM_PARENTNOTIFY, sent|defwinproc|optional }, { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 }, { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, { TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 }, @@ -370,14 +374,9 @@ static HWND createParentWindow(void) GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); } -struct subclass_info -{ - WNDPROC oldproc; -}; - static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -402,7 +401,7 @@ static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam, } defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; @@ -412,14 +411,10 @@ static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT { HWND tabHandle; TCITEM tcNewTab; - struct subclass_info *info; + WNDPROC oldproc; RECT rect; INT i; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - GetClientRect(parent_wnd, &rect); tabHandle = CreateWindow ( @@ -431,8 +426,8 @@ static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT assert(tabHandle); - info->oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess); - SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess); + SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)oldproc); tcNewTab.mask = mask; @@ -505,7 +500,7 @@ static void test_tab(INT nMinTabWidth) SIZE size; HDC hdc; HFONT hOldFont; - INT i, dpi; + INT i, dpi, exp; hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); @@ -585,8 +580,11 @@ static void test_tab(INT nMinTabWidth) SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); trace (" non fixed width, with text...\n"); - CheckSize(hwTab, max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth), -1, - "no icon, default width"); + exp = max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth); + SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab ); + ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH), + "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left ); + for (i=0; i<8; i++) { INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth; @@ -610,7 +608,11 @@ static void test_tab(INT nMinTabWidth) SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); trace (" non fixed width, no text...\n"); - CheckSize(hwTab, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth, -1, "no icon, default width"); + exp = (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth; + SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab ); + ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH), + "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left ); + for (i=0; i<8; i++) { INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth; @@ -636,7 +638,290 @@ static void test_tab(INT nMinTabWidth) DeleteObject(hFont); } -static void test_getters_setters(HWND parent_wnd, INT nTabs) +static void test_curfocus(HWND parent_wnd, INT nTabs) +{ + INT focusIndex; + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* Testing CurFocus with largest appropriate value */ + SendMessage(hTab, TCM_SETCURFOCUS, nTabs-1, 0); + focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); + expect(nTabs-1, focusIndex); + + /* Testing CurFocus with negative value */ + SendMessage(hTab, TCM_SETCURFOCUS, -10, 0); + focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); + expect(-1, focusIndex); + + /* Testing CurFocus with value larger than number of tabs */ + focusIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0); + expect(-1, focusIndex); + + SendMessage(hTab, TCM_SETCURFOCUS, nTabs+1, 0); + focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); + expect(1, focusIndex); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Getset curFoc test sequence", FALSE); + + DestroyWindow(hTab); +} + +static void test_cursel(HWND parent_wnd, INT nTabs) +{ + INT selectionIndex; + INT focusIndex; + TCITEM tcItem; + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* Testing CurSel with largest appropriate value */ + selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0); + expect(0, selectionIndex); + selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + expect(nTabs-1, selectionIndex); + + /* Focus should switch with selection */ + focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); + expect(nTabs-1, focusIndex); + + /* Testing CurSel with negative value */ + SendMessage(hTab, TCM_SETCURSEL, -10, 0); + selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + expect(-1, selectionIndex); + + /* Testing CurSel with value larger than number of tabs */ + selectionIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0); + expect(-1, selectionIndex); + + selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs+1, 0); + expect(-1, selectionIndex); + selectionIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); + expect(1, selectionIndex); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE); + + /* selected item should have TCIS_BUTTONPRESSED state + It doesn't depend on button state */ + memset(&tcItem, 0, sizeof(TCITEM)); + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = TCIS_BUTTONPRESSED; + selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + SendMessage(hTab, TCM_GETITEM, selectionIndex, (LPARAM) &tcItem); + ok (tcItem.dwState & TCIS_BUTTONPRESSED || broken(tcItem.dwState == 0), /* older comctl32 */ + "Selected item should have TCIS_BUTTONPRESSED\n"); + + DestroyWindow(hTab); +} + +static void test_extendedstyle(HWND parent_wnd, INT nTabs) +{ + DWORD prevExtendedStyle; + DWORD extendedStyle; + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* Testing Flat Separators */ + extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); + prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS); + expect(extendedStyle, prevExtendedStyle); + + extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); + expect(TCS_EX_FLATSEPARATORS, extendedStyle); + + /* Testing Register Drop */ + prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP); + expect(extendedStyle, prevExtendedStyle); + + extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); + todo_wine{ + expect(TCS_EX_REGISTERDROP, extendedStyle); + } + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE); + + DestroyWindow(hTab); +} + +static void test_unicodeformat(HWND parent_wnd, INT nTabs) +{ + INT unicodeFormat; + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); + todo_wine{ + expect(0, unicodeFormat); + } + unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0); + expect(1, unicodeFormat); + + unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, FALSE, 0); + expect(1, unicodeFormat); + unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0); + expect(0, unicodeFormat); + + unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); + expect(0, unicodeFormat); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE); + + DestroyWindow(hTab); +} + +static void test_getset_item(HWND parent_wnd, INT nTabs) +{ + TCITEM tcItem; + DWORD ret; + char szText[32] = "New Label"; + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + /* passing invalid index should result in initialization to zero + for members mentioned in mask requested */ + + /* valid range here is [0,4] */ + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_PARAM; + ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem); + expect(FALSE, ret); + ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam); + + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_IMAGE; + ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem); + expect(FALSE, ret); + expect(0, tcItem.iImage); + + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_TEXT; + tcItem.pszText = szText; + szText[0] = 'a'; + ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem); + expect(FALSE, ret); + expect('a', szText[0]); + + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = 0; + tcItem.dwState = TCIS_BUTTONPRESSED; + ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem); + expect(FALSE, ret); + ok(tcItem.dwState == 0, "Expected zero dwState, got %u\n", tcItem.dwState); + + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = TCIS_BUTTONPRESSED; + tcItem.dwState = TCIS_BUTTONPRESSED; + ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem); + expect(FALSE, ret); + ok(tcItem.dwState == 0, "Expected zero dwState\n"); + + /* check with negative index to be sure */ + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_PARAM; + ret = SendMessage(hTab, TCM_GETITEM, -1, (LPARAM)&tcItem); + expect(FALSE, ret); + ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam); + + memset(&tcItem, 0xcc, sizeof(tcItem)); + tcItem.mask = TCIF_PARAM; + ret = SendMessage(hTab, TCM_GETITEM, -2, (LPARAM)&tcItem); + expect(FALSE, ret); + ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + tcItem.mask = TCIF_TEXT; + tcItem.pszText = &szText[0]; + tcItem.cchTextMax = sizeof(szText); + + strcpy(szText, "New Label"); + ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); + ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); + expect_str("New Label", tcItem.pszText); + + ok ( SendMessage(hTab, TCM_GETITEM, 1, (LPARAM) &tcItem), "Getting item failed.\n"); + expect_str("Tab 2", tcItem.pszText); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE); + + /* TCIS_BUTTONPRESSED doesn't depend on tab style */ + memset(&tcItem, 0, sizeof(tcItem)); + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = TCIS_BUTTONPRESSED; + tcItem.dwState = TCIS_BUTTONPRESSED; + ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); + tcItem.dwState = 0; + ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); + if (tcItem.dwState) + { + ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n"); + /* next highlight item, test that dwStateMask actually masks */ + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = TCIS_HIGHLIGHTED; + tcItem.dwState = TCIS_HIGHLIGHTED; + ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); + tcItem.dwState = 0; + ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); + ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n"); + tcItem.mask = TCIF_STATE; + tcItem.dwStateMask = TCIS_BUTTONPRESSED; + tcItem.dwState = 0; + ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); + ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n"); + } + else win_skip( "Item state mask not supported\n" ); + + DestroyWindow(hTab); +} + +static void test_getset_tooltips(HWND parent_wnd, INT nTabs) +{ + HWND hTab, toolTip; + char toolTipText[32] = "ToolTip Text Test"; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + toolTip = create_tooltip(hTab, toolTipText); + SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) toolTip, 0); + ok (toolTip == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); + + SendMessage(hTab, TCM_SETTOOLTIPS, 0, 0); + ok (NULL == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_tooltip_seq, "Getset tooltip test sequence", TRUE); + ok_sequence(sequences, PARENT_SEQ_INDEX, getset_tooltip_parent_seq, "Getset tooltip test parent sequence", TRUE); + + DestroyWindow(hTab); +} + +static void test_misc(HWND parent_wnd, INT nTabs) { HWND hTab; RECT rTab; @@ -694,196 +979,6 @@ static void test_getters_setters(HWND parent_wnd, INT nTabs) ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE); - /* Testing CurFocus */ - { - INT focusIndex; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - /* Testing CurFocus with largest appropriate value */ - SendMessage(hTab, TCM_SETCURFOCUS, nTabs-1, 0); - focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); - expect(nTabs-1, focusIndex); - - /* Testing CurFocus with negative value */ - SendMessage(hTab, TCM_SETCURFOCUS, -10, 0); - focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); - expect(-1, focusIndex); - - /* Testing CurFocus with value larger than number of tabs */ - focusIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0); - todo_wine{ - expect(-1, focusIndex); - } - - SendMessage(hTab, TCM_SETCURFOCUS, nTabs+1, 0); - focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); - expect(1, focusIndex); - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Getset curFoc test sequence", FALSE); - } - - /* Testing CurSel */ - { - INT selectionIndex; - INT focusIndex; - TCITEM tcItem; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - /* Testing CurSel with largest appropriate value */ - selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0); - expect(1, selectionIndex); - selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); - expect(nTabs-1, selectionIndex); - - /* Focus should switch with selection */ - focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); - expect(nTabs-1, focusIndex); - - /* Testing CurSel with negative value */ - SendMessage(hTab, TCM_SETCURSEL, -10, 0); - selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); - expect(-1, selectionIndex); - - /* Testing CurSel with value larger than number of tabs */ - selectionIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0); - expect(-1, selectionIndex); - - selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs+1, 0); - expect(-1, selectionIndex); - selectionIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); - expect(1, selectionIndex); - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE); - - /* selected item should have TCIS_BUTTONPRESSED state - It doesn't depend on button state */ - memset(&tcItem, 0, sizeof(TCITEM)); - tcItem.mask = TCIF_STATE; - tcItem.dwStateMask = TCIS_BUTTONPRESSED; - selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0); - SendMessage(hTab, TCM_GETITEM, selectionIndex, (LPARAM) &tcItem); - ok (tcItem.dwState & TCIS_BUTTONPRESSED, "Selected item should have TCIS_BUTTONPRESSED\n"); - } - - /* Testing ExtendedStyle */ - { - DWORD prevExtendedStyle; - DWORD extendedStyle; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - /* Testing Flat Separators */ - extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); - prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS); - expect(extendedStyle, prevExtendedStyle); - - extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); - expect(TCS_EX_FLATSEPARATORS, extendedStyle); - - /* Testing Register Drop */ - prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP); - expect(extendedStyle, prevExtendedStyle); - - extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); - todo_wine{ - expect(TCS_EX_REGISTERDROP, extendedStyle); - } - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE); - } - - /* Testing UnicodeFormat */ - { - INT unicodeFormat; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); - todo_wine{ - expect(0, unicodeFormat); - } - unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0); - expect(1, unicodeFormat); - - unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, FALSE, 0); - expect(1, unicodeFormat); - unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0); - expect(0, unicodeFormat); - - unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); - expect(0, unicodeFormat); - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE); - } - - /* Testing GetSet Item */ - { - TCITEM tcItem; - char szText[32] = "New Label"; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - tcItem.mask = TCIF_TEXT; - tcItem.pszText = &szText[0]; - tcItem.cchTextMax = sizeof(szText); - - ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); - ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); - expect_str("New Label", tcItem.pszText); - - ok ( SendMessage(hTab, TCM_GETITEM, 1, (LPARAM) &tcItem), "Getting item failed.\n"); - expect_str("Tab 2", tcItem.pszText); - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE); - - /* TCIS_BUTTONPRESSED doesn't depend on tab style */ - memset(&tcItem, 0, sizeof(tcItem)); - tcItem.mask = TCIF_STATE; - tcItem.dwStateMask = TCIS_BUTTONPRESSED; - tcItem.dwState = TCIS_BUTTONPRESSED; - ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); - tcItem.dwState = 0; - ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); - ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n"); - /* next highlight item, test that dwStateMask actually masks */ - tcItem.mask = TCIF_STATE; - tcItem.dwStateMask = TCIS_HIGHLIGHTED; - tcItem.dwState = TCIS_HIGHLIGHTED; - ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n"); - tcItem.dwState = 0; - ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); - ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n"); - tcItem.mask = TCIF_STATE; - tcItem.dwStateMask = TCIS_BUTTONPRESSED; - tcItem.dwState = 0; - ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n"); - ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n"); - } - - /* Testing GetSet ToolTip */ - { - HWND toolTip; - char toolTipText[32] = "ToolTip Text Test"; - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - toolTip = create_tooltip(hTab, toolTipText); - SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) toolTip, 0); - ok (toolTip == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); - - SendMessage(hTab, TCM_SETTOOLTIPS, 0, 0); - ok (NULL == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); - - ok_sequence(sequences, TAB_SEQ_INDEX, getset_tooltip_seq, "Getset tooltip test sequence", TRUE); - ok_sequence(sequences, PARENT_SEQ_INDEX, getset_tooltip_parent_seq, "Getset tooltip test parent sequence", TRUE); - } - DestroyWindow(hTab); } @@ -903,6 +998,7 @@ static void test_adjustrect(HWND parent_wnd) r = SendMessage(hTab, TCM_ADJUSTRECT, TRUE, 0); expect(-1, r); } + static void test_insert_focus(HWND parent_wnd) { HWND hTab; @@ -960,8 +1056,8 @@ static void test_insert_focus(HWND parent_wnd) r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); expect(2, r); - ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", TRUE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", FALSE); + ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", TRUE); DestroyWindow(hTab); } @@ -1010,7 +1106,7 @@ static void test_delete_focus(HWND parent_wnd) expect(-1, r); ok_sequence(sequences, TAB_SEQ_INDEX, delete_focus_seq, "delete_focus test sequence", FALSE); - ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", TRUE); DestroyWindow(hTab); } @@ -1078,6 +1174,28 @@ static void test_removeimage(HWND parent_wnd) DestroyIcon(hicon); } +static void test_delete_selection(HWND parent_wnd) +{ + HWND hTab; + DWORD ret; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4); + ok(hTab != NULL, "Failed to create tab control\n"); + + ret = SendMessage(hTab, TCM_SETCURSEL, 3, 0); + expect(0, ret); + ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + expect(3, ret); + /* delete selected item - selection goes to -1 */ + ret = SendMessage(hTab, TCM_DELETEITEM, 3, 0); + expect(TRUE, ret); + + ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + expect(-1, ret); + + DestroyWindow(hTab); +} + START_TEST(tab) { HWND parent_wnd; @@ -1108,13 +1226,19 @@ START_TEST(tab) parent_wnd = createParentWindow(); ok(parent_wnd != NULL, "Failed to create parent window!\n"); - /* Testing getters and setters with 5 tabs */ - test_getters_setters(parent_wnd, 5); + test_curfocus(parent_wnd, 5); + test_cursel(parent_wnd, 5); + test_extendedstyle(parent_wnd, 5); + test_unicodeformat(parent_wnd, 5); + test_getset_item(parent_wnd, 5); + test_getset_tooltips(parent_wnd, 5); + test_misc(parent_wnd, 5); test_adjustrect(parent_wnd); test_insert_focus(parent_wnd); test_delete_focus(parent_wnd); + test_delete_selection(parent_wnd); test_removeimage(parent_wnd); DestroyWindow(parent_wnd); diff --git a/rostests/winetests/comctl32/testlist.c b/rostests/winetests/comctl32/testlist.c index 7e32af490c3..1789e5c4812 100644 --- a/rostests/winetests/comctl32/testlist.c +++ b/rostests/winetests/comctl32/testlist.c @@ -15,7 +15,6 @@ extern void func_listview(void); extern void func_misc(void); extern void func_monthcal(void); extern void func_mru(void); -extern void func_msg(void); extern void func_progress(void); extern void func_propsheet(void); extern void func_rebar(void); @@ -40,7 +39,6 @@ const struct test winetest_testlist[] = { "misc", func_misc }, { "monthcal", func_monthcal }, { "mru", func_mru }, - { "msg", func_msg }, { "progress", func_progress }, { "propsheet", func_propsheet }, { "rebar", func_rebar }, diff --git a/rostests/winetests/comctl32/toolbar.c b/rostests/winetests/comctl32/toolbar.c index 19460952349..8311df575ec 100644 --- a/rostests/winetests/comctl32/toolbar.c +++ b/rostests/winetests/comctl32/toolbar.c @@ -33,12 +33,27 @@ #include "wine/test.h" +#include "msg.h" + +#define PARENT_SEQ_INDEX 0 +#define NUM_MSG_SEQUENCES 1 + +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; + static HWND hMainWnd; static BOOL g_fBlockHotItemChange; static BOOL g_fReceivedHotItemChange; static BOOL g_fExpectedHotItemOld; static BOOL g_fExpectedHotItemNew; static DWORD g_dwExpectedDispInfoMask; +static BOOL g_ResetDispTextPtr; + +static const struct message ttgetdispinfo_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, TBN_GETINFOTIPA }, + /* next line is todo, currently TTN_GETDISPINFOW is raised here */ + { WM_NOTIFY, sent|id, 0, 0, TTN_GETDISPINFOA }, + { 0 } +}; #define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT)) @@ -56,7 +71,7 @@ static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) { p->iString = nString; } -static LRESULT MyWnd_Notify(LPARAM lParam) +static LRESULT parent_wnd_notify(LPARAM lParam) { NMHDR *hdr = (NMHDR *)lParam; NMTBHOTITEM *nmhi; @@ -79,25 +94,65 @@ static LRESULT MyWnd_Notify(LPARAM lParam) ok(FALSE, "TBN_GETDISPINFOA received\n"); break; + case TBN_GETINFOTIPA: + { + NMTBGETINFOTIPA *tbgit = (NMTBGETINFOTIPA*)lParam; + + if (g_ResetDispTextPtr) + { + tbgit->pszText = NULL; + return 0; + } + break; + } case TBN_GETDISPINFOW: nmdisp = (NMTBDISPINFOA *)lParam; compare(nmdisp->dwMask, g_dwExpectedDispInfoMask, "%x"); - compare(nmdisp->iImage, -1, "%d"); ok(nmdisp->pszText == NULL, "pszText is not NULL\n"); break; } return 0; } -static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (msg) + static LONG defwndproc_counter = 0; + struct message msg; + LRESULT ret; + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code; + + /* log system messages, except for painting */ + if (message < WM_USER && + message != WM_PAINT && + message != WM_ERASEBKGND && + message != WM_NCPAINT && + message != WM_NCHITTEST && + message != WM_GETTEXT && + message != WM_GETICON && + message != WM_DEVICECHANGE) + { + trace("parent: %p, %04x, %08lx, %08lx\n", hWnd, message, wParam, lParam); + add_message(sequences, PARENT_SEQ_INDEX, &msg); + } + + switch (message) { case WM_NOTIFY: - return MyWnd_Notify(lParam); + return parent_wnd_notify(lParam); } - return DefWindowProcA(hWnd, msg, wParam, lParam); + + defwndproc_counter++; + ret = DefWindowProcA(hWnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; } static void basic_test(void) @@ -163,7 +218,7 @@ static void basic_test(void) static void rebuild_toolbar(HWND *hToolbar) { - if (*hToolbar != NULL) + if (*hToolbar) DestroyWindow(*hToolbar); *hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hMainWnd, (HMENU)5, GetModuleHandle(NULL), NULL); @@ -374,6 +429,8 @@ static void test_add_bitmap(void) addbmp.hInst = HINST_COMMCTRL; addbmp.nID = IDB_STD_SMALL_COLOR; rebuild_toolbar(&hToolbar); + ImageList_Destroy(himl); + ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n"); CHECK_IMAGELIST(15, 16, 16); compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x"); @@ -415,7 +472,7 @@ static void test_add_bitmap(void) ok(strcmp(_buf, (tab)[_i]) == 0, "Invalid string #%d - '%s' vs '%s'\n", _i, (tab)[_i], _buf); \ } \ ok(SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, (count)), (LPARAM)_buf) == -1, \ - "Too many string in table\n"); \ + "Too many strings in table\n"); \ } static void test_add_string(void) @@ -432,10 +489,17 @@ static void test_add_string(void) HWND hToolbar = NULL; TBBUTTON button; int ret; + CHAR buf[260]; rebuild_toolbar(&hToolbar); ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test1); ok(ret == 0, "TB_ADDSTRINGA - unexpected return %d\n", ret); + ret = SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, 1), (LPARAM)buf); + if (ret == 0) + { + win_skip("TB_GETSTRING needs 5.80\n"); + return; + } CHECK_STRING_TABLE(2, ret1); ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test2); ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret); @@ -734,6 +798,22 @@ static tbsize_result_t tbsize_results[] = static int tbsize_numtests = 0; +typedef struct +{ + int test_num; + int rect_index; + RECT rcButton; +} tbsize_alt_result_t; + +static tbsize_alt_result_t tbsize_alt_results[] = +{ + { 5, 2, { 0, 24, 8, 29 } }, + { 20, 1, { 100, 2, 107, 102 } }, + { 20, 2, { 107, 2, 207, 102 } } +}; + +static int tbsize_alt_numtests = 0; + #define check_sizes_todo(todomask) { \ RECT rc; \ int buttonCount, i, mask=(todomask); \ @@ -745,7 +825,11 @@ static int tbsize_numtests = 0; compare(buttonCount, res->nButtons, "%d"); \ for (i=0; inButtons); i++) { \ ok(SendMessageA(hToolbar, TB_GETITEMRECT, i, (LPARAM)&rc) == 1, "TB_GETITEMRECT\n"); \ - if (!(mask&1)) { \ + if (broken(tbsize_alt_numtests < sizeof(tbsize_alt_results)/sizeof(tbsize_alt_results[0]) && \ + memcmp(&rc, &tbsize_alt_results[tbsize_alt_numtests].rcButton, sizeof(RECT)) == 0)) { \ + win_skip("Alternate rect found\n"); \ + tbsize_alt_numtests++; \ + } else if (!(mask&1)) { \ check_rect("button", rc, res->rcButtons[i]); \ } else {\ todo_wine { check_rect("button", rc, res->rcButtons[i]); } \ @@ -954,6 +1038,7 @@ static void test_sizes(void) rebuild_toolbar(&hToolbar); ImageList_Destroy(himl); + ImageList_Destroy(himl2); SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons3[3]); ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 39), "Unexpected button size\n"); @@ -995,10 +1080,17 @@ static void test_sizes(void) tbinfo.cx = 672; tbinfo.cbSize = sizeof(TBBUTTONINFO); tbinfo.dwMask = TBIF_SIZE | TBIF_BYINDEX; - ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 0, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n"); - ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n"); - SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0); - check_sizes(); + if (SendMessageA(hToolbar, TB_SETBUTTONINFO, 0, (LPARAM)&tbinfo)) + { + ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n"); + SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0); + check_sizes(); + } + else /* TBIF_BYINDEX probably not supported, confirm that this was the reason for the failure */ + { + tbinfo.dwMask = TBIF_SIZE; + ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 33, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n"); + } DestroyWindow(hToolbar); } @@ -1049,21 +1141,24 @@ static void restore_recalc_state(HWND hToolbar) static void test_recalc(void) { - HWND hToolbar; + HWND hToolbar = NULL; TBBUTTONINFO bi; CHAR test[] = "Test"; const int EX_STYLES_COUNT = 5; int i; + BOOL recalc; /* Like TB_ADDBUTTONS tested in test_sized, inserting a button without text * results in a relayout, while adding one with text forces a recalc */ prepare_recalc_test(&hToolbar); SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[0]); - ok(!did_recalc(hToolbar), "Unexpected recalc - adding button without text\n"); + recalc = did_recalc(hToolbar); + ok(!recalc, "Unexpected recalc - adding button without text\n"); prepare_recalc_test(&hToolbar); SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[3]); - ok(did_recalc(hToolbar), "Expected a recalc - adding button with text\n"); + recalc = did_recalc(hToolbar); + ok(recalc, "Expected a recalc - adding button with text\n"); /* TB_SETBUTTONINFO, even when adding a text, results only in a relayout */ prepare_recalc_test(&hToolbar); @@ -1071,7 +1166,8 @@ static void test_recalc(void) bi.dwMask = TBIF_TEXT; bi.pszText = test; SendMessage(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&bi); - ok(!did_recalc(hToolbar), "Unexpected recalc - setting a button text\n"); + recalc = did_recalc(hToolbar); + ok(!recalc, "Unexpected recalc - setting a button text\n"); /* most extended styled doesn't force a recalc (testing all the bits gives * the same results, but prints some ERRs while testing) */ @@ -1082,22 +1178,31 @@ static void test_recalc(void) prepare_recalc_test(&hToolbar); expect(0, (int)SendMessage(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0)); SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, (1 << i)); - ok(!did_recalc(hToolbar), "Unexpected recalc - setting bit %d\n", i); + recalc = did_recalc(hToolbar); + ok(!recalc, "Unexpected recalc - setting bit %d\n", i); SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0); - ok(!did_recalc(hToolbar), "Unexpected recalc - clearing bit %d\n", i); + recalc = did_recalc(hToolbar); + ok(!recalc, "Unexpected recalc - clearing bit %d\n", i); expect(0, (int)SendMessage(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0)); } /* TBSTYLE_EX_MIXEDBUTTONS does a recalc on change */ prepare_recalc_test(&hToolbar); SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS); - ok(did_recalc(hToolbar), "Expected a recalc - setting TBSTYLE_EX_MIXEDBUTTONS\n"); - restore_recalc_state(hToolbar); - SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS); - ok(!did_recalc(hToolbar), "Unexpected recalc - setting TBSTYLE_EX_MIXEDBUTTONS again\n"); - restore_recalc_state(hToolbar); - SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0); - ok(did_recalc(hToolbar), "Expected a recalc - clearing TBSTYLE_EX_MIXEDBUTTONS\n"); + recalc = did_recalc(hToolbar); + if (recalc) + { + ok(recalc, "Expected a recalc - setting TBSTYLE_EX_MIXEDBUTTONS\n"); + restore_recalc_state(hToolbar); + SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS); + recalc = did_recalc(hToolbar); + ok(!recalc, "Unexpected recalc - setting TBSTYLE_EX_MIXEDBUTTONS again\n"); + restore_recalc_state(hToolbar); + SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0); + recalc = did_recalc(hToolbar); + ok(recalc, "Expected a recalc - clearing TBSTYLE_EX_MIXEDBUTTONS\n"); + } + else win_skip( "No recalc on TBSTYLE_EX_MIXEDBUTTONS\n" ); /* undocumented exstyle 0x2 seems to changes the top margin, what * interferes with these tests */ @@ -1117,8 +1222,8 @@ static void test_getbuttoninfo(void) int ret; tbi.cbSize = i; - tbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND; - ret = (int)SendMessage(hToolbar, TB_GETBUTTONINFO, 0, (LPARAM)&tbi); + tbi.dwMask = TBIF_COMMAND; + ret = (int)SendMessage(hToolbar, TB_GETBUTTONINFO, 1, (LPARAM)&tbi); if (i == sizeof(TBBUTTONINFO)) { compare(ret, 0, "%d"); } else { @@ -1189,7 +1294,7 @@ static void test_dispinfo(void) rebuild_toolbar(&hToolbar); SendMessageA(hToolbar, TB_LOADIMAGES, IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL); SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons_disp); - g_dwExpectedDispInfoMask = 1; + g_dwExpectedDispInfoMask = TBNF_IMAGE; /* Some TBN_GETDISPINFO tests will be done in MyWnd_Notify function. * We will receive TBN_GETDISPINFOW even if the control is ANSI */ compare((BOOL)SendMessageA(hToolbar, CCM_GETUNICODEFORMAT, 0, 0), 0, "%d"); @@ -1281,6 +1386,12 @@ static void test_getstring(void) ok(hToolbar != NULL, "Toolbar creation problem\n"); r = SendMessage(hToolbar, TB_GETSTRING, MAKEWPARAM(0, 0), 0); + if (r == 0) + { + win_skip("TB_GETSTRING and TB_GETSTRINGW need 5.80\n"); + DestroyWindow(hToolbar); + return; + } expect(-1, r); r = SendMessage(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), 0); expect(-1, r); @@ -1300,12 +1411,46 @@ static void test_getstring(void) DestroyWindow(hToolbar); } +static void test_tooltip(void) +{ + HWND hToolbar = NULL; + const TBBUTTON buttons_disp[] = { + {-1, 20, TBSTATE_ENABLED, 0, {0, }, 0, -1}, + {0, 21, TBSTATE_ENABLED, 0, {0, }, 0, -1}, + }; + NMTTDISPINFOW nmtti; + + rebuild_toolbar(&hToolbar); + + SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons_disp); + + /* W used to get through toolbar code that assumes tooltip is always Unicode */ + memset(&nmtti, 0, sizeof(nmtti)); + nmtti.hdr.code = TTN_GETDISPINFOW; + nmtti.hdr.idFrom = 20; + + SendMessageA(hToolbar, CCM_SETUNICODEFORMAT, FALSE, 0); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti); + ok_sequence(sequences, PARENT_SEQ_INDEX, ttgetdispinfo_parent_seq, + "dispinfo from tooltip", TRUE); + + g_ResetDispTextPtr = TRUE; + SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti); + g_ResetDispTextPtr = FALSE; + + DestroyWindow(hToolbar); +} + START_TEST(toolbar) { WNDCLASSA wc; MSG msg; RECT rc; - + + init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + InitCommonControls(); wc.style = CS_HREDRAW | CS_VREDRAW; @@ -1316,11 +1461,11 @@ START_TEST(toolbar) wc.hCursor = LoadCursorA(NULL, IDC_IBEAM); wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW); wc.lpszMenuName = NULL; - wc.lpszClassName = "MyTestWnd"; - wc.lpfnWndProc = MyWndProc; + wc.lpszClassName = "Toolbar test parent"; + wc.lpfnWndProc = parent_wnd_proc; RegisterClassA(&wc); - hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, + hMainWnd = CreateWindowExA(0, "Toolbar test parent", "Blah", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0); GetClientRect(hMainWnd, &rc); ShowWindow(hMainWnd, SW_SHOW); @@ -1336,6 +1481,7 @@ START_TEST(toolbar) test_dispinfo(); test_setrows(); test_getstring(); + test_tooltip(); PostQuitMessage(0); while(GetMessageA(&msg,0,0,0)) { diff --git a/rostests/winetests/comctl32/tooltips.c b/rostests/winetests/comctl32/tooltips.c index 2b4f43ffd1b..8ca3f7bb903 100644 --- a/rostests/winetests/comctl32/tooltips.c +++ b/rostests/winetests/comctl32/tooltips.c @@ -23,6 +23,8 @@ #include "wine/test.h" +#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) + static void test_create_tooltip(void) { HWND parent, hwnd; @@ -42,7 +44,8 @@ static void test_create_tooltip(void) trace("style = %08x\n", style); exp_style = 0x7fffffff | WS_POPUP; exp_style &= ~(WS_CHILD | WS_MAXIMIZE | WS_BORDER | WS_DLGFRAME); - ok(style == exp_style,"wrong style %08x/%08x\n", style, exp_style); + ok(style == exp_style || broken(style == (exp_style | WS_BORDER)), /* nt4 */ + "wrong style %08x/%08x\n", style, exp_style); DestroyWindow(hwnd); @@ -142,7 +145,6 @@ static void test_customdraw(void) { /* Invalid notification responses */ {CDRF_NOTIFYITEMDRAW, TEST_CDDS_PREPAINT}, {CDRF_NOTIFYPOSTERASE, TEST_CDDS_PREPAINT}, - {CDRF_NOTIFYSUBITEMDRAW, TEST_CDDS_PREPAINT}, {CDRF_NEWFONT, TEST_CDDS_PREPAINT} }; @@ -168,6 +170,7 @@ static void test_customdraw(void) { iterationNumber++) { HWND parent, hwndTip; + RECT rect; TOOLINFO toolInfo = { 0 }; /* Create a main window */ @@ -201,7 +204,7 @@ static void test_customdraw(void) { SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); /* Create a tool */ - toolInfo.cbSize = sizeof(TOOLINFO); + toolInfo.cbSize = TTTOOLINFO_V1_SIZE; toolInfo.hwnd = parent; toolInfo.hinst = GetModuleHandleA(NULL); toolInfo.uFlags = TTF_SUBCLASS; @@ -216,13 +219,18 @@ static void test_customdraw(void) { SendMessage(hwndTip, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(1,0)); /* Put cursor inside window, tooltip will appear immediately */ - SetCursorPos(100, 100); + GetWindowRect( parent, &rect ); + SetCursorPos( (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2 ); flush_events(200); - /* Check CustomDraw results */ - ok(CD_Stages == expectedResults[iterationNumber].ExpectedCalls, - "CustomDraw run %d stages %x, expected %x\n", iterationNumber, CD_Stages, - expectedResults[iterationNumber].ExpectedCalls); + if (CD_Stages) + { + /* Check CustomDraw results */ + ok(CD_Stages == expectedResults[iterationNumber].ExpectedCalls || + broken(CD_Stages == (expectedResults[iterationNumber].ExpectedCalls & ~TEST_CDDS_POSTPAINT)), /* nt4 */ + "CustomDraw run %d stages %x, expected %x\n", iterationNumber, CD_Stages, + expectedResults[iterationNumber].ExpectedCalls); + } /* Clean up */ DestroyWindow(hwndTip); @@ -232,14 +240,63 @@ static void test_customdraw(void) { } +static const CHAR testcallbackA[] = "callback"; + +static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_NOTIFY && lParam) + { + NMTTDISPINFOA *ttnmdi = (NMTTDISPINFOA*)lParam; + + if (ttnmdi->hdr.code == TTN_GETDISPINFOA) + lstrcpy(ttnmdi->lpszText, testcallbackA); + } + + return DefWindowProcA(hwnd, message, wParam, lParam); +} + +static BOOL register_parent_wnd_class(void) +{ + WNDCLASSA cls; + + cls.style = 0; + cls.lpfnWndProc = parent_wnd_proc; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(NULL); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "Tooltips test parent class"; + return RegisterClassA(&cls); +} + +static HWND create_parent_window(void) +{ + if (!register_parent_wnd_class()) + return NULL; + + return CreateWindowEx(0, "Tooltips test parent class", + "Tooltips test parent window", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); +} + static void test_gettext(void) { - HWND hwnd; + HWND hwnd, notify; TTTOOLINFOA toolinfoA; TTTOOLINFOW toolinfoW; LRESULT r; - char bufA[10] = ""; + CHAR bufA[10] = ""; WCHAR bufW[10] = { 0 }; + static const CHAR testtipA[] = "testtip"; + + notify = create_parent_window(); + ok(notify != NULL, "Expected notification window to be created\n"); /* For bug 14790 - lpszText is NULL */ hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, @@ -247,6 +304,8 @@ static void test_gettext(void) NULL, NULL, NULL, 0); assert(hwnd); + /* use sizeof(TTTOOLINFOA) instead of TTTOOLINFOA_V1_SIZE so that adding it fails on Win9x */ + /* otherwise it crashes on the NULL lpszText */ toolinfoA.cbSize = sizeof(TTTOOLINFOA); toolinfoA.hwnd = NULL; toolinfoA.hinst = GetModuleHandleA(NULL); @@ -256,7 +315,6 @@ static void test_gettext(void) toolinfoA.lParam = 0xdeadbeef; GetClientRect(hwnd, &toolinfoA.rect); r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA); - ok(r, "Adding the tool to the tooltip failed\n"); if (r) { toolinfoA.hwnd = NULL; @@ -265,8 +323,65 @@ static void test_gettext(void) SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA); ok(strcmp(toolinfoA.lpszText, "") == 0, "lpszText should be an empty string\n"); } + else + { + win_skip( "Old comctl32, not testing NULL text\n" ); + DestroyWindow( hwnd ); + return; + } + + /* add another tool with text */ + toolinfoA.cbSize = sizeof(TTTOOLINFOA); + toolinfoA.hwnd = NULL; + toolinfoA.hinst = GetModuleHandleA(NULL); + toolinfoA.uFlags = 0; + toolinfoA.uId = 0x1235ABCD; + strcpy(bufA, testtipA); + toolinfoA.lpszText = bufA; + toolinfoA.lParam = 0xdeadbeef; + GetClientRect(hwnd, &toolinfoA.rect); + r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA); + ok(r, "Adding the tool to the tooltip failed\n"); + if (r) + { + DWORD length; + + length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + ok(length == 0, "Expected 0, got %d\n", length); + + toolinfoA.hwnd = NULL; + toolinfoA.uId = 0x1235ABCD; + toolinfoA.lpszText = bufA; + SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA); + ok(strcmp(toolinfoA.lpszText, testtipA) == 0, "lpszText should be an empty string\n"); + + length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + ok(length == 0, "Expected 0, got %d\n", length); + } + + /* add another with callback text */ + toolinfoA.cbSize = sizeof(TTTOOLINFOA); + toolinfoA.hwnd = notify; + toolinfoA.hinst = GetModuleHandleA(NULL); + toolinfoA.uFlags = 0; + toolinfoA.uId = 0x1236ABCD; + toolinfoA.lpszText = LPSTR_TEXTCALLBACKA; + toolinfoA.lParam = 0xdeadbeef; + GetClientRect(hwnd, &toolinfoA.rect); + r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA); + ok(r, "Adding the tool to the tooltip failed\n"); + if (r) + { + toolinfoA.hwnd = notify; + toolinfoA.uId = 0x1236ABCD; + toolinfoA.lpszText = bufA; + SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA); + ok(strcmp(toolinfoA.lpszText, testcallbackA) == 0, + "lpszText should be an (%s) string\n", testcallbackA); + } DestroyWindow(hwnd); + DestroyWindow(notify); SetLastError(0xdeadbeef); hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0, @@ -303,6 +418,208 @@ static void test_gettext(void) DestroyWindow(hwnd); } +static void test_ttm_gettoolinfo(void) +{ + TTTOOLINFOA ti; + TTTOOLINFOW tiW; + HWND hwnd; + DWORD r; + + hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, + 10, 10, 300, 100, + NULL, NULL, NULL, 0); + + ti.cbSize = TTTOOLINFOA_V2_SIZE; + ti.hwnd = NULL; + ti.hinst = GetModuleHandleA(NULL); + ti.uFlags = 0; + ti.uId = 0x1234ABCD; + ti.lpszText = NULL; + ti.lParam = 0xdeadbeef; + GetClientRect(hwnd, &ti.rect); + r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti); + ok(r, "Adding the tool to the tooltip failed\n"); + + ti.cbSize = TTTOOLINFOA_V2_SIZE; + ti.lParam = 0xaaaaaaaa; + r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti); + ok(r, "Getting tooltip info failed\n"); + ok(0xdeadbeef == ti.lParam || + broken(0xdeadbeef != ti.lParam), /* comctl32 < 5.81 */ + "Expected 0xdeadbeef, got %lx\n", ti.lParam); + + tiW.cbSize = TTTOOLINFOW_V2_SIZE; + tiW.hwnd = NULL; + tiW.uId = 0x1234ABCD; + tiW.lParam = 0xaaaaaaaa; + r = SendMessageA(hwnd, TTM_GETTOOLINFOW, 0, (LPARAM)&tiW); + ok(r, "Getting tooltip info failed\n"); + ok(0xdeadbeef == tiW.lParam || + broken(0xdeadbeef != tiW.lParam), /* comctl32 < 5.81 */ + "Expected 0xdeadbeef, got %lx\n", tiW.lParam); + + ti.cbSize = TTTOOLINFOA_V2_SIZE; + ti.uId = 0x1234ABCD; + ti.lParam = 0xaaaaaaaa; + SendMessageA(hwnd, TTM_SETTOOLINFOA, 0, (LPARAM)&ti); + + ti.cbSize = TTTOOLINFOA_V2_SIZE; + ti.lParam = 0xdeadbeef; + r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti); + ok(r, "Getting tooltip info failed\n"); + ok(0xaaaaaaaa == ti.lParam || + broken(0xaaaaaaaa != ti.lParam), /* comctl32 < 5.81 */ + "Expected 0xaaaaaaaa, got %lx\n", ti.lParam); + + DestroyWindow(hwnd); + + /* 1. test size parameter validation rules (ansi messages) */ + hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, + 10, 10, 300, 100, + NULL, NULL, NULL, 0); + + ti.cbSize = TTTOOLINFOA_V1_SIZE - 1; + ti.hwnd = NULL; + ti.hinst = GetModuleHandleA(NULL); + ti.uFlags = 0; + ti.uId = 0x1234ABCD; + ti.lpszText = NULL; + ti.lParam = 0xdeadbeef; + GetClientRect(hwnd, &ti.rect); + r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + ti.cbSize = TTTOOLINFOA_V1_SIZE - 1; + ti.hwnd = NULL; + ti.uId = 0x1234ABCD; + SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + ti.cbSize = TTTOOLINFOA_V2_SIZE - 1; + ti.hwnd = NULL; + ti.hinst = GetModuleHandleA(NULL); + ti.uFlags = 0; + ti.uId = 0x1234ABCD; + ti.lpszText = NULL; + ti.lParam = 0xdeadbeef; + GetClientRect(hwnd, &ti.rect); + r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + ti.cbSize = TTTOOLINFOA_V2_SIZE - 1; + ti.hwnd = NULL; + ti.uId = 0x1234ABCD; + SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + ti.cbSize = TTTOOLINFOA_V2_SIZE + 1; + ti.hwnd = NULL; + ti.hinst = GetModuleHandleA(NULL); + ti.uFlags = 0; + ti.uId = 0x1234ABCD; + ti.lpszText = NULL; + ti.lParam = 0xdeadbeef; + GetClientRect(hwnd, &ti.rect); + r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + ti.cbSize = TTTOOLINFOA_V2_SIZE + 1; + ti.hwnd = NULL; + ti.uId = 0x1234ABCD; + SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti); + r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + DestroyWindow(hwnd); + + /* 2. test size parameter validation rules (w-messages) */ + hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0, + 10, 10, 300, 100, + NULL, NULL, NULL, 0); + if(!hwnd) + { + win_skip("CreateWindowExW() not supported. Skipping.\n"); + return; + } + + tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1; + tiW.hwnd = NULL; + tiW.hinst = GetModuleHandleA(NULL); + tiW.uFlags = 0; + tiW.uId = 0x1234ABCD; + tiW.lpszText = NULL; + tiW.lParam = 0xdeadbeef; + GetClientRect(hwnd, &tiW.rect); + r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1; + tiW.hwnd = NULL; + tiW.uId = 0x1234ABCD; + SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1; + tiW.hwnd = NULL; + tiW.hinst = GetModuleHandleA(NULL); + tiW.uFlags = 0; + tiW.uId = 0x1234ABCD; + tiW.lpszText = NULL; + tiW.lParam = 0xdeadbeef; + GetClientRect(hwnd, &tiW.rect); + r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1; + tiW.hwnd = NULL; + tiW.uId = 0x1234ABCD; + SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1; + tiW.hwnd = NULL; + tiW.hinst = GetModuleHandleA(NULL); + tiW.uFlags = 0; + tiW.uId = 0x1234ABCD; + tiW.lpszText = NULL; + tiW.lParam = 0xdeadbeef; + GetClientRect(hwnd, &tiW.rect); + r = SendMessageW(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&tiW); + ok(r, "Adding the tool to the tooltip failed\n"); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + /* looks like TTM_DELTOOLW doesn't work with invalid size */ + tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1; + tiW.hwnd = NULL; + tiW.uId = 0x1234ABCD; + SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(1, r); + + tiW.cbSize = TTTOOLINFOW_V2_SIZE; + tiW.hwnd = NULL; + tiW.uId = 0x1234ABCD; + SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW); + r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0); + expect(0, r); + + DestroyWindow(hwnd); +} + START_TEST(tooltips) { InitCommonControls(); @@ -310,4 +627,5 @@ START_TEST(tooltips) test_create_tooltip(); test_customdraw(); test_gettext(); + test_ttm_gettoolinfo(); } diff --git a/rostests/winetests/comctl32/trackbar.c b/rostests/winetests/comctl32/trackbar.c index d94ffe9a28c..68261d833fb 100644 --- a/rostests/winetests/comctl32/trackbar.c +++ b/rostests/winetests/comctl32/trackbar.c @@ -30,32 +30,10 @@ #define PARENT_SEQ_INDEX 0 #define TRACKBAR_SEQ_INDEX 1 +HWND hWndParent; static struct msg_sequence *sequences[NUM_MSG_SEQUENCE]; -static const struct message create_parent_wnd_seq[] = { - { WM_GETMINMAXINFO, sent }, - { WM_NCCREATE, sent }, - { WM_NCCALCSIZE, sent|wparam, 0 }, - { WM_CREATE, sent }, - { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_QUERYNEWPALETTE, sent|optional }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_ACTIVATEAPP, sent|wparam, 1 }, - { WM_NCACTIVATE, sent|wparam, 1 }, - { WM_ACTIVATE, sent|wparam, 1 }, - { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, - { WM_IME_NOTIFY, sent|defwinproc|optional }, - { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, - /* Win9x adds SWP_NOZORDER below */ - { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, - { WM_NCCALCSIZE, sent|wparam|optional, 1 }, - { WM_SIZE, sent }, - { WM_MOVE, sent }, - { 0 } -}; - static const struct message create_trackbar_wnd_seq[] = { {0} }; @@ -81,12 +59,12 @@ static const struct message parent_create_trackbar_wnd_seq[] = { static const struct message parent_new_window_test_seq[] = { { WM_QUERYNEWPALETTE, sent|optional }, - { WM_WINDOWPOSCHANGING, sent}, - { WM_NCACTIVATE, sent}, - { PBT_APMRESUMECRITICAL, sent}, + { WM_WINDOWPOSCHANGING, sent|optional}, + { WM_NCACTIVATE, sent|optional}, + { PBT_APMRESUMECRITICAL, sent|optional}, { WM_IME_SETCONTEXT, sent|defwinproc|optional}, { WM_IME_NOTIFY, sent|defwinproc|optional}, - { WM_SETFOCUS, sent|defwinproc}, + { WM_SETFOCUS, sent|defwinproc|optional}, { WM_NOTIFYFORMAT, sent}, { WM_QUERYUISTATE, sent|optional}, {0} @@ -386,11 +364,6 @@ static const struct message ignore_selection_test_seq[] = { {0} }; -struct subclass_info -{ - WNDPROC oldproc; -}; - static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static LONG defwndproc_counter = 0; LRESULT ret; @@ -452,7 +425,7 @@ static HWND create_parent_window(void){ } static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ - struct subclass_info *info = (struct subclass_info *) GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -467,36 +440,27 @@ static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wPa add_message(sequences, TRACKBAR_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } static HWND create_trackbar(DWORD style, HWND parent){ - struct subclass_info *info; HWND hWndTrack; + WNDPROC oldproc; RECT rect; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - GetClientRect(parent, &rect); hWndTrack = CreateWindowEx( 0, TRACKBAR_CLASS,"Trackbar Control", style, rect.right,rect.bottom, 100, 50, parent, NULL,GetModuleHandleA(NULL) ,NULL); - if (!hWndTrack) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!hWndTrack) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrack, GWLP_WNDPROC, (LONG_PTR)trackbar_subclass_proc); - - SetWindowLongPtrA(hWndTrack, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrack, GWLP_WNDPROC, (LONG_PTR)trackbar_subclass_proc); + SetWindowLongPtrA(hWndTrack, GWLP_USERDATA, (LONG_PTR)oldproc); return hWndTrack; } @@ -785,40 +749,63 @@ static void test_thumb_length(HWND hWndTrackbar){ static void test_tic_settings(HWND hWndTrackbar){ int r; - flush_sequences(sequences, NUM_MSG_SEQUENCE); /* testing TBM_SETTIC */ /* Set tics at 5 and 10 */ /* 0 and 20 are out of range and should not be set */ + r = SendMessage(hWndTrackbar, TBM_GETRANGEMAX, 0, 0); + expect(10, r); + r = SendMessage(hWndTrackbar, TBM_GETRANGEMIN, 0, 0); + expect(5, r); + + flush_sequences(sequences, NUM_MSG_SEQUENCE); r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 0); ok(r == FALSE, "Expected FALSE, got %d\n", r); r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 5); - todo_wine{ - ok(r == TRUE, "Expected TRUE, got %d\n", r); - r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 10); - ok(r == TRUE, "Expected TRUE, got %d\n", r); - } + ok(r == TRUE, "Expected TRUE, got %d\n", r); + r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 10); + ok(r == TRUE, "Expected TRUE, got %d\n", r); + r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 20); ok(r == FALSE, "Expected False, got %d\n", r); /* test TBM_SETTICFREQ */ SendMessage(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10)); SendMessage(hWndTrackbar, TBM_SETTICFREQ, 2, 0); - r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); expect(6, r); SendMessage(hWndTrackbar, TBM_SETTICFREQ, 5, 0); - r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); expect(3, r); SendMessage(hWndTrackbar, TBM_SETTICFREQ, 15, 0); - r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); expect(2, r); /* test TBM_GETNUMTICS */ /* since TIC FREQ is 15, there should be only 2 tics now */ - r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); expect(2, r); ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_settings_test_seq, "tic settings test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_tic_settings_test_seq, "parent tic settings test sequence", TRUE); + + /* range [0,0], freq = 1 */ + SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 0); + SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0); + SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); + expect(2, r); + /* range [0,1], freq = 1 */ + SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 1); + SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0); + SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); + expect(2, r); + /* range [0,2], freq = 1 */ + SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 2); + SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0); + SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0); + r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0); + expect(3, r); } static void test_tic_placement(HWND hWndTrackbar){ @@ -846,9 +833,7 @@ static void test_tic_placement(HWND hWndTrackbar){ r = SendMessage(hWndTrackbar, TBM_GETTIC, 2,0); expect(4, r); r = SendMessage(hWndTrackbar, TBM_GETTIC, 4,0); - todo_wine{ - expect(-1, r); - } + expect(-1, r); /* test TBM_GETTICPIC */ r = SendMessage(hWndTrackbar, TBM_GETTICPOS, 0, 0); @@ -869,15 +854,13 @@ static void test_tool_tips(HWND hWndTrackbar){ flush_sequences(sequences, NUM_MSG_SEQUENCE); /* testing TBM_SETTIPSIDE */ r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_TOP, 0); - todo_wine{ - expect(0, r); - } + expect(TBTS_TOP, r); r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_LEFT, 0); - expect(0, r); + expect(TBTS_TOP, r); r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_BOTTOM, 0); - expect(1, r); + expect(TBTS_LEFT, r); r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_RIGHT, 0); - expect(2, r); + expect(TBTS_BOTTOM, r); /* testing TBM_SETTOOLTIPS */ hWndTooltip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, 0, @@ -967,17 +950,31 @@ static void test_ignore_selection(HWND hWndTrackbar){ ok_sequence(sequences, PARENT_SEQ_INDEX, parent_empty_test_seq, "parent ignore selection setting test sequence", FALSE); } +static void test_initial_state(void) +{ + HWND hWnd; + DWORD ret; + + hWnd = create_trackbar(0, hWndParent); + + ret = SendMessage(hWnd, TBM_GETNUMTICS, 0, 0); + expect(2, ret); + ret = SendMessage(hWnd, TBM_GETTIC, 0, 0); + expect(-1, ret); + ret = SendMessage(hWnd, TBM_GETTICPOS, 0, 0); + expect(-1, ret); + + DestroyWindow(hWnd); +} + START_TEST(trackbar) { DWORD style = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS; HWND hWndTrackbar; - HWND hWndParent; init_msg_sequences(sequences, NUM_MSG_SEQUENCE); InitCommonControls(); - flush_sequences(sequences, NUM_MSG_SEQUENCE); - /* create parent window */ hWndParent = create_parent_window(); ok(hWndParent != NULL, "Failed to create parent Window!\n"); @@ -987,7 +984,6 @@ START_TEST(trackbar) return; } - ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create Parent Window", TRUE); flush_sequences(sequences, NUM_MSG_SEQUENCE); /* create trackbar with set styles */ @@ -1036,5 +1032,7 @@ START_TEST(trackbar) DestroyWindow(hWndTrackbar); + test_initial_state(); + DestroyWindow(hWndParent); } diff --git a/rostests/winetests/comctl32/treeview.c b/rostests/winetests/comctl32/treeview.c index 05a52373ac3..848d4ca1d8e 100644 --- a/rostests/winetests/comctl32/treeview.c +++ b/rostests/winetests/comctl32/treeview.c @@ -35,110 +35,103 @@ const char *TEST_CALLBACK_TEXT = "callback_text"; #define NUM_MSG_SEQUENCES 1 -#define LISTVIEW_SEQ_INDEX 0 +#define TREEVIEW_SEQ_INDEX 0 + +#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) static struct msg_sequence *MsgSequences[NUM_MSG_SEQUENCES]; static const struct message FillRootSeq[] = { { TVM_INSERTITEM, sent }, - { TVM_GETITEM, sent }, { TVM_INSERTITEM, sent }, { 0 } }; -static const struct message DoTest1Seq[] = { - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, +static const struct message rootnone_select_seq[] = { + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, { 0 } }; -static const struct message DoTest2Seq[] = { - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, +static const struct message rootchild_select_seq[] = { + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, + { TVM_SELECTITEM, sent|wparam, 9 }, { 0 } }; -static const struct message DoTest3Seq[] = { +static const struct message getitemtext_seq[] = { { TVM_INSERTITEM, sent }, { TVM_GETITEM, sent }, { TVM_DELETEITEM, sent }, { 0 } }; -static const struct message DoFocusTestSeq[] = { +static const struct message focus_seq[] = { { TVM_INSERTITEM, sent }, { TVM_INSERTITEM, sent }, + { TVM_SELECTITEM, sent|wparam, 9 }, + /* The following end up out of order in wine */ { WM_WINDOWPOSCHANGING, sent|defwinproc }, - { WM_NCCALCSIZE, sent|wparam|defwinproc, 0x00000001 }, + { WM_NCCALCSIZE, sent|wparam|defwinproc, TRUE }, { WM_WINDOWPOSCHANGED, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, - { WM_WINDOWPOSCHANGING, sent }, - { WM_NCCALCSIZE, sent|wparam, 0x00000001 }, - { WM_WINDOWPOSCHANGED, sent }, - { WM_SIZE, sent|defwinproc }, - { WM_WINDOWPOSCHANGING, sent|defwinproc|optional }, - { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 0x00000001 }, - { WM_WINDOWPOSCHANGED, sent|defwinproc|optional }, - { WM_SIZE, sent|defwinproc|optional }, - { TVM_SELECTITEM, sent|wparam, 0x00000009 }, - /* The following end up out of order in wine */ { WM_PAINT, sent|defwinproc }, - { WM_NCPAINT, sent|wparam|defwinproc, 0x00000001 }, + { WM_NCPAINT, sent|wparam|defwinproc, 1 }, { WM_ERASEBKGND, sent|defwinproc }, { TVM_EDITLABEL, sent }, - { WM_COMMAND, sent|wparam|defwinproc, 0x04000000 }, - { WM_COMMAND, sent|wparam|defwinproc, 0x03000000 }, - { WM_PARENTNOTIFY, sent|wparam|defwinproc, 0x00000001 }, + { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_UPDATE) }, + { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_CHANGE) }, + { WM_PARENTNOTIFY, sent|wparam|defwinproc, MAKEWPARAM(WM_CREATE, 0) }, { WM_KILLFOCUS, sent|defwinproc }, { WM_PAINT, sent|defwinproc }, { WM_IME_SETCONTEXT, sent|defwinproc|optional }, - { WM_COMMAND, sent|wparam|defwinproc, 0x01000000}, - { WM_ERASEBKGND, sent|defwinproc }, + { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_SETFOCUS) }, + { WM_ERASEBKGND, sent|defwinproc|optional }, { WM_CTLCOLOREDIT, sent|defwinproc|optional }, { WM_CTLCOLOREDIT, sent|defwinproc|optional }, { 0 } }; -static const struct message TestGetSetBkColorSeq[] = { - { TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff }, - { TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, -1 }, +static const struct message test_get_set_bkcolor_seq[] = { + { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETBKCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETBKCOLOR, sent|wparam|lparam, 0, 0x00ffffff }, + { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETBKCOLOR, sent|wparam|lparam, 0, -1 }, { 0 } }; -static const struct message TestGetSetImageListSeq[] = { - { TVM_SETIMAGELIST, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETIMAGELIST, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_imagelist_seq[] = { + { TVM_SETIMAGELIST, sent|wparam|lparam, 0, 0 }, + { TVM_GETIMAGELIST, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetIndentSeq[] = { - { TVM_SETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_indent_seq[] = { + { TVM_SETINDENT, sent|wparam|lparam, 0, 0 }, + { TVM_GETINDENT, sent|wparam|lparam, 0, 0 }, /* The actual amount to indent is dependent on the system for this message */ { TVM_SETINDENT, sent }, - { TVM_GETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 }, + { TVM_GETINDENT, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetInsertMarkColorSeq[] = { - { TVM_SETINSERTMARKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETINSERTMARKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_insertmarkcolor_seq[] = { + { TVM_SETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_GETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetItemSeq[] = { +static const struct message test_get_set_item_seq[] = { { TVM_GETITEM, sent }, { TVM_SETITEM, sent }, { TVM_GETITEM, sent }, @@ -146,57 +139,53 @@ static const struct message TestGetSetItemSeq[] = { { 0 } }; -static const struct message TestGetSetItemHeightSeq[] = { - { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETITEMHEIGHT, sent|wparam|lparam, -1, 0x00000000 }, - { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETITEMHEIGHT, sent|lparam, 0xcccccccc, 0x00000000 }, - { TVM_GETITEMHEIGHT, sent|wparam|lparam|optional, 0x00000000, 0x00000000 }, - { TVM_SETITEMHEIGHT, sent|wparam|lparam|optional, 0x00000009, 0x00000000 }, - { WM_WINDOWPOSCHANGING, sent|defwinproc }, - { WM_NCCALCSIZE, sent|wparam|defwinproc, 0x00000001 }, - { WM_WINDOWPOSCHANGED, sent|defwinproc }, - { WM_SIZE, sent|defwinproc }, - { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_itemheight_seq[] = { + { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, + { TVM_SETITEMHEIGHT, sent|wparam|lparam, -1, 0 }, + { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, + { TVM_SETITEMHEIGHT, sent|lparam, 0xcccccccc, 0 }, + { TVM_GETITEMHEIGHT, sent|wparam|lparam|optional, 0, 0 }, + { TVM_SETITEMHEIGHT, sent|wparam|lparam|optional, 9, 0 }, + { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetScrollTimeSeq[] = { - { TVM_SETSCROLLTIME, sent|wparam|lparam, 0x00000014, 0x00000000 }, - { TVM_GETSCROLLTIME, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_scrolltime_seq[] = { + { TVM_SETSCROLLTIME, sent|wparam|lparam, 20, 0 }, + { TVM_GETSCROLLTIME, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetTextColorSeq[] = { - { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff }, - { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, -1 }, +static const struct message test_get_set_textcolor_seq[] = { + { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, RGB(255, 255, 255) }, + { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, + { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, CLR_NONE }, { 0 } }; -static const struct message TestGetSetToolTipsSeq[] = { - { WM_COMMAND, sent|wparam, 0x02000000 }, - { WM_PARENTNOTIFY, sent|wparam|defwinproc, 0x00020002 }, - { TVM_SETTOOLTIPS, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETTOOLTIPS, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_tooltips_seq[] = { + { WM_KILLFOCUS, sent }, + { WM_IME_SETCONTEXT, sent|optional }, + { WM_IME_NOTIFY, sent|optional }, + { TVM_SETTOOLTIPS, sent|wparam|lparam, 0, 0 }, + { TVM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetUnicodeFormatSeq[] = { - { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000001, 0x00000000 }, - { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 }, - { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 }, +static const struct message test_get_set_unicodeformat_seq[] = { + { TVM_SETUNICODEFORMAT, sent|wparam|lparam, TRUE, 0 }, + { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, + { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, + { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, + { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, { 0 } }; static HWND hMainWnd; -static HWND hTree, hEdit; static HTREEITEM hRoot, hChild; static int pos = 0; @@ -231,21 +220,84 @@ static void IdentifyItem(HTREEITEM hItem) AddItem('?'); } -static void FillRoot(void) +/* This function hooks in and records all messages to the treeview control */ +static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static LONG defwndproc_counter = 0; + LRESULT ret; + struct message msg; + WNDPROC lpOldProc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + add_message(MsgSequences, TREEVIEW_SEQ_INDEX, &msg); + + defwndproc_counter++; + ret = CallWindowProcA(lpOldProc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static HWND create_treeview_control(void) +{ + WNDPROC pOldWndProc; + HWND hTree; + + hTree = CreateWindowExA(WS_EX_CLIENTEDGE, WC_TREEVIEWA, NULL, WS_CHILD|WS_VISIBLE| + TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS, + 0, 0, 120, 100, hMainWnd, (HMENU)100, GetModuleHandleA(0), 0); + + SetFocus(hTree); + + /* Record the old WNDPROC so we can call it after recording the messages */ + pOldWndProc = (WNDPROC)SetWindowLongPtrA(hTree, GWLP_WNDPROC, (LONG_PTR)TreeviewWndProc); + SetWindowLongPtrA(hTree, GWLP_USERDATA, (LONG_PTR)pOldWndProc); + + return hTree; +} + +static void fill_tree(HWND hTree) { TVINSERTSTRUCTA ins; - TVITEM tvi; static CHAR root[] = "Root", child[] = "Child"; - Clear(); - AddItem('A'); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_ROOT; U(ins).item.mask = TVIF_TEXT; U(ins).item.pszText = root; hRoot = TreeView_InsertItem(hTree, &ins); + + ins.hParent = hRoot; + ins.hInsertAfter = TVI_FIRST; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = child; + hChild = TreeView_InsertItem(hTree, &ins); +} + +static void test_fillroot(void) +{ + TVITEM tvi; + HWND hTree; + + hTree = create_treeview_control(); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + + fill_tree(hTree); + + Clear(); + AddItem('A'); assert(hRoot); + AddItem('B'); + assert(hChild); + AddItem('.'); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE); + ok(!strcmp(sequence, "AB."), "Item creation\n"); /* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */ tvi.hItem = hRoot; @@ -254,19 +306,10 @@ static void FillRoot(void) ok(tvi.iImage == 0, "tvi.iImage=%d\n", tvi.iImage); ok(tvi.iSelectedImage == 0, "tvi.iSelectedImage=%d\n", tvi.iSelectedImage); - AddItem('B'); - ins.hParent = hRoot; - ins.hInsertAfter = TVI_FIRST; - U(ins).item.mask = TVIF_TEXT; - U(ins).item.pszText = child; - hChild = TreeView_InsertItem(hTree, &ins); - assert(hChild); - AddItem('.'); - - ok(!strcmp(sequence, "AB."), "Item creation\n"); + DestroyWindow(hTree); } -static void TestCallback(void) +static void test_callback(void) { HTREEITEM hRoot; HTREEITEM hItem1, hItem2; @@ -275,8 +318,13 @@ static void TestCallback(void) CHAR test_string[] = "Test_string"; CHAR buf[128]; LRESULT ret; + HWND hTree; - TreeView_DeleteAllItems(hTree); + hTree = create_treeview_control(); + fill_tree(hTree); + + ret = TreeView_DeleteAllItems(hTree); + ok(ret == TRUE, "ret\n"); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_ROOT; U(ins).item.mask = TVIF_TEXT; @@ -301,7 +349,8 @@ static void TestCallback(void) assert(hItem1); tvi.hItem = hItem1; - TreeView_GetItem(hTree, &tvi); + ret = TreeView_GetItem(hTree, &tvi); + ok(ret == TRUE, "ret\n"); ok(strcmp(tvi.pszText, test_string) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, test_string); @@ -310,7 +359,8 @@ static void TestCallback(void) ret = TreeView_SetItem(hTree, &tvi); ok(ret == 1, "Expected SetItem return 1, got %ld\n", ret); tvi.pszText = buf; - TreeView_GetItem(hTree, &tvi); + ret = TreeView_GetItem(hTree, &tvi); + ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret); ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, TEST_CALLBACK_TEXT); @@ -319,57 +369,90 @@ static void TestCallback(void) assert(hItem2); tvi.hItem = hItem2; memset(buf, 0, sizeof(buf)); - TreeView_GetItem(hTree, &tvi); + ret = TreeView_GetItem(hTree, &tvi); + ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret); ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, TEST_CALLBACK_TEXT); + + DestroyWindow(hTree); } -static void DoTest1(void) +static void test_select(void) { BOOL r; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + /* root-none select tests */ + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); r = TreeView_SelectItem(hTree, NULL); + expect(TRUE, r); Clear(); AddItem('1'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('2'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('3'); r = TreeView_SelectItem(hTree, NULL); + expect(TRUE, r); AddItem('4'); r = TreeView_SelectItem(hTree, NULL); + expect(TRUE, r); AddItem('5'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('.'); ok(!strcmp(sequence, "1(nR)nR23(Rn)Rn45(nR)nR."), "root-none select test\n"); -} + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, rootnone_select_seq, + "root-none select seq", FALSE); -static void DoTest2(void) -{ - BOOL r; + /* root-child select tests */ + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); r = TreeView_SelectItem(hTree, NULL); + expect(TRUE, r); + Clear(); AddItem('1'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('2'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('3'); r = TreeView_SelectItem(hTree, hChild); + expect(TRUE, r); AddItem('4'); r = TreeView_SelectItem(hTree, hChild); + expect(TRUE, r); AddItem('5'); r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); AddItem('.'); ok(!strcmp(sequence, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n"); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, rootchild_select_seq, + "root-child select seq", FALSE); + + DestroyWindow(hTree); } -static void DoTest3(void) +static void test_getitemtext(void) { TVINSERTSTRUCTA ins; HTREEITEM hChild; TVITEM tvi; + HWND hTree; - int nBufferSize = 80; CHAR szBuffer[80] = "Blah"; + int nBufferSize = sizeof(szBuffer)/sizeof(CHAR); + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* add an item without TVIF_TEXT mask and pszText == NULL */ ins.hParent = hRoot; @@ -389,14 +472,24 @@ static void DoTest3(void) SendMessageA( hTree, TVM_GETITEM, 0, (LPARAM)&tvi ); ok(!strcmp(szBuffer, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer); ok(SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild), "DeleteItem failed\n"); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, getitemtext_seq, "get item text seq", FALSE); + + DestroyWindow(hTree); } -static void DoFocusTest(void) +static void test_focus(void) { TVINSERTSTRUCTA ins; static CHAR child1[] = "Edit", child2[] = "A really long string"; HTREEITEM hChild1, hChild2; + HWND hTree; + HWND hEdit; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* This test verifies that when a label is being edited, scrolling * the treeview does not cause the label to lose focus. To test @@ -416,38 +509,57 @@ static void DoFocusTest(void) assert(hChild2); ShowWindow(hMainWnd,SW_SHOW); - /* Using SendMessageA since Win98 doesn't have default unicode support */ SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); hEdit = TreeView_EditLabel(hTree, hChild); ScrollWindowEx(hTree, -10, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN); ok(GetFocus() == hEdit, "Edit control should have focus\n"); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, focus_seq, "focus test", TRUE); + + DestroyWindow(hTree); } -static void TestGetSetBkColor(void) +static void test_get_set_bkcolor(void) { COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* If the value is -1, the control is using the system color for the background color. */ crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor); /* Test for black background */ - SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(0,0,0) ); + SendMessage( hTree, TVM_SETBKCOLOR, 0, RGB(0,0,0) ); crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); ok(crColor == RGB(0,0,0), "Black background color reported as 0x%.8x\n", crColor); /* Test for white background */ - SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(255,255,255) ); + SendMessage( hTree, TVM_SETBKCOLOR, 0, RGB(255,255,255) ); crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); ok(crColor == RGB(255,255,255), "White background color reported as 0x%.8x\n", crColor); /* Reset the default background */ SendMessage( hTree, TVM_SETBKCOLOR, 0, -1 ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_bkcolor_seq, + "test get set bkcolor", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetImageList(void) +static void test_get_set_imagelist(void) { HIMAGELIST hImageList = NULL; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Test a NULL HIMAGELIST */ SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList ); @@ -455,13 +567,24 @@ static void TestGetSetImageList(void) ok(hImageList == NULL, "NULL image list, reported as 0x%p, expected 0.\n", hImageList); /* TODO: Test an actual image list */ + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_imagelist_seq, + "test get imagelist", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetIndent(void) +static void test_get_set_indent(void) { int ulIndent = -1; int ulMinIndent = -1; int ulMoreThanTwiceMin = -1; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Finding the minimum indent */ SendMessage( hTree, TVM_SETINDENT, 0, 0 ); @@ -472,21 +595,44 @@ static void TestGetSetIndent(void) SendMessage( hTree, TVM_SETINDENT, ulMoreThanTwiceMin, 0 ); ulIndent = (DWORD)SendMessage( hTree, TVM_GETINDENT, 0, 0 ); ok(ulIndent == ulMoreThanTwiceMin, "Indent reported as %d, expected %d\n", ulIndent, ulMoreThanTwiceMin); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_indent_seq, + "test get set indent", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetInsertMarkColor(void) +static void test_get_set_insertmark(void) { COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + SendMessage( hTree, TVM_SETINSERTMARKCOLOR, 0, crColor ); crColor = (COLORREF)SendMessage( hTree, TVM_GETINSERTMARKCOLOR, 0, 0 ); ok(crColor == RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_insertmarkcolor_seq, + "test get set insertmark color", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetItem(void) +static void test_get_set_item(void) { TVITEM tviRoot = {0}; int nBufferSize = 80; char szBuffer[80] = {0}; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Test the root item */ tviRoot.hItem = hRoot; @@ -507,12 +653,23 @@ static void TestGetSetItem(void) memset(szBuffer, 0, nBufferSize); strncpy(szBuffer, "Root", nBufferSize); SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq, + "test get set item", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetItemHeight(void) +static void test_get_set_itemheight(void) { int ulOldHeight = 0; int ulNewHeight = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Assuming default height to begin with */ ulOldHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); @@ -531,42 +688,77 @@ static void TestGetSetItemHeight(void) SendMessage( hTree, TVM_SETITEMHEIGHT, 9, 0 ); ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); ok(ulNewHeight == 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight, 8); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq, + "test get set item height", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetScrollTime(void) +static void test_get_set_scrolltime(void) { int ulExpectedTime = 20; int ulTime = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + SendMessage( hTree, TVM_SETSCROLLTIME, ulExpectedTime, 0 ); ulTime = (int)SendMessage( hTree, TVM_GETSCROLLTIME, 0, 0 ); ok(ulTime == ulExpectedTime, "Scroll time reported as %d, expected %d\n", ulTime, ulExpectedTime); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_scrolltime_seq, + "test get set scroll time", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetTextColor(void) +static void test_get_set_textcolor(void) { /* If the value is -1, the control is using the system color for the text color. */ COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 ); ok(crColor == -1, "Default text color reported as 0x%.8x\n", crColor); /* Test for black text */ - SendMessage( hTree, TVM_SETTEXTCOLOR, 0, (LPARAM)RGB(0,0,0) ); + SendMessage( hTree, TVM_SETTEXTCOLOR, 0, RGB(0,0,0) ); crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 ); ok(crColor == RGB(0,0,0), "Black text color reported as 0x%.8x\n", crColor); /* Test for white text */ - SendMessage( hTree, TVM_SETTEXTCOLOR, 0, (LPARAM)RGB(255,255,255) ); + SendMessage( hTree, TVM_SETTEXTCOLOR, 0, RGB(255,255,255) ); crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 ); ok(crColor == RGB(255,255,255), "White text color reported as 0x%.8x\n", crColor); /* Reset the default text color */ - SendMessage( hTree, TVM_SETTEXTCOLOR, 0, -1 ); + SendMessage( hTree, TVM_SETTEXTCOLOR, 0, CLR_NONE ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_textcolor_seq, + "test get set text color", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetToolTips(void) +static void test_get_set_tooltips(void) { HWND hwndLastToolTip = NULL; HWND hPopupTreeView; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */ hPopupTreeView = CreateWindow(WC_TREEVIEW, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100, hMainWnd, NULL, NULL, NULL); @@ -577,13 +769,23 @@ static void TestGetSetToolTips(void) hwndLastToolTip = (HWND)SendMessage( hTree, TVM_GETTOOLTIPS, 0, 0 ); ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq, + "test get set tooltips", TRUE); + /* TODO: Add a test of an actual tooltip */ + DestroyWindow(hTree); } -static void TestGetSetUnicodeFormat(void) +static void test_get_set_unicodeformat(void) { BOOL bPreviousSetting = 0; BOOL bNewSetting = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Set to Unicode */ bPreviousSetting = (BOOL)SendMessage( hTree, TVM_SETUNICODEFORMAT, 1, 0 ); @@ -596,114 +798,17 @@ static void TestGetSetUnicodeFormat(void) ok(bNewSetting == 0, "ANSI setting did not work.\n"); /* Revert to original setting */ - SendMessage( hTree, TVM_SETUNICODEFORMAT, (LPARAM)bPreviousSetting, 0 ); -} + SendMessage( hTree, TVM_SETUNICODEFORMAT, bPreviousSetting, 0 ); -static void TestGetSet(void) -{ - /* TVM_GETBKCOLOR and TVM_SETBKCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetBkColor(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetBkColorSeq, - "TestGetSetBkColor", FALSE); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_unicodeformat_seq, + "test get set unicode format", FALSE); - /* TVM_GETIMAGELIST and TVM_SETIMAGELIST */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetImageList(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetImageListSeq, - "TestGetImageList", FALSE); - - /* TVM_SETINDENT and TVM_GETINDENT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetIndent(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetIndentSeq, - "TestGetSetIndent", FALSE); - - /* TVM_GETINSERTMARKCOLOR and TVM_GETINSERTMARKCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetInsertMarkColor(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetInsertMarkColorSeq, - "TestGetSetInsertMarkColor", FALSE); - - /* TVM_GETITEM and TVM_SETITEM */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetItem(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetItemSeq, - "TestGetSetItem", FALSE); - - /* TVM_GETITEMHEIGHT and TVM_SETITEMHEIGHT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetItemHeight(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetItemHeightSeq, - "TestGetSetItemHeight", FALSE); - - /* TVM_GETSCROLLTIME and TVM_SETSCROLLTIME */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetScrollTime(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetScrollTimeSeq, - "TestGetSetScrollTime", FALSE); - - /* TVM_GETTEXTCOLOR and TVM_SETTEXTCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetTextColor(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetTextColorSeq, - "TestGetSetTextColor", FALSE); - - /* TVM_GETTOOLTIPS and TVM_SETTOOLTIPS */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetToolTips(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetToolTipsSeq, - "TestGetSetToolTips", TRUE); - - /* TVM_GETUNICODEFORMAT and TVM_SETUNICODEFORMAT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetUnicodeFormat(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetUnicodeFormatSeq, - "TestGetSetUnicodeFormat", FALSE); -} - -/* This function hooks in and records all messages to the treeview control */ -static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - static LONG defwndproc_counter = 0; - LRESULT ret; - struct message msg; - WNDPROC lpOldProc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); - - msg.message = message; - msg.flags = sent|wparam|lparam; - if (defwndproc_counter) msg.flags |= defwinproc; - msg.wParam = wParam; - msg.lParam = lParam; - add_message(MsgSequences, LISTVIEW_SEQ_INDEX, &msg); - - defwndproc_counter++; - ret = CallWindowProcA(lpOldProc, hwnd, message, wParam, lParam); - defwndproc_counter--; - - return ret; + DestroyWindow(hTree); } static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - WNDPROC pOldWndProc; - switch(msg) { - - case WM_CREATE: - { - hTree = CreateWindowExA(WS_EX_CLIENTEDGE, WC_TREEVIEWA, NULL, WS_CHILD|WS_VISIBLE| - TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS, - 0, 0, 120, 100, hWnd, (HMENU)100, GetModuleHandleA(0), 0); - - SetFocus(hTree); - - /* Record the old WNDPROC so we can call it after recording the messages */ - pOldWndProc = (WNDPROC)SetWindowLongPtrA(hTree, GWLP_WNDPROC, (LONG_PTR)TreeviewWndProc); - SetWindowLongPtrA(hTree, GWLP_USERDATA, (LONG_PTR)pOldWndProc); - - return 0; - } case WM_NOTIFY: { NMHDR *pHdr = (NMHDR *)lParam; @@ -729,15 +834,12 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa } return 0; } + case TVN_ENDLABELEDIT: return TRUE; } } return 0; } - case WM_SIZE: - MoveWindow(hTree, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); - break; - case WM_DESTROY: PostQuitMessage(0); break; @@ -748,13 +850,17 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa return 0L; } -static void TestExpandInvisible(void) +static void test_expandinvisible(void) { static CHAR nodeText[][5] = {"0", "1", "2", "3", "4"}; TVINSERTSTRUCTA ins; HTREEITEM node[5]; RECT dummyRect; BOOL nodeVisible; + LRESULT ret; + HWND hTree; + + hTree = create_treeview_control(); /* The test builds the following tree and expands then node 1, while node 0 is collapsed. * @@ -766,8 +872,8 @@ static void TestExpandInvisible(void) * */ - TreeView_DeleteAllItems(hTree); - + ret = TreeView_DeleteAllItems(hTree); + ok(ret == TRUE, "ret\n"); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_ROOT; U(ins).item.mask = TVIF_TEXT; @@ -815,8 +921,121 @@ static void TestExpandInvisible(void) ok(!nodeVisible, "Node 3 should not be visible.\n"); nodeVisible = TreeView_GetItemRect(hTree, node[4], &dummyRect, FALSE); ok(!nodeVisible, "Node 4 should not be visible.\n"); + + DestroyWindow(hTree); } +static void test_itemedit(void) +{ + DWORD r; + HWND edit; + TVITEMA item; + CHAR buff[2]; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + /* try with null item */ + edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, 0); + ok(!IsWindow(edit), "Expected valid handle\n"); + + /* trigger edit */ + edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + /* item shouldn't be selected automatically after TVM_EDITLABEL */ + r = SendMessage(hTree, TVM_GETITEMSTATE, (WPARAM)hRoot, TVIS_SELECTED); + expect(0, r); + /* try to cancel with wrong edit handle */ + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), 0); + expect(0, r); + ok(IsWindow(edit), "Expected edit control to be valid\n"); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); + expect(0, r); + ok(!IsWindow(edit), "Expected edit control to be destroyed\n"); + /* try to cancel without creating edit */ + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), 0); + expect(0, r); + + /* try to cancel with wrong (not null) handle */ + edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hTree); + expect(0, r); + ok(IsWindow(edit), "Expected edit control to be valid\n"); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); + expect(0, r); + + /* remove selection after starting edit */ + r = TreeView_SelectItem(hTree, hRoot); + expect(TRUE, r); + edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + r = TreeView_SelectItem(hTree, NULL); + expect(TRUE, r); + /* alter text */ + strncpy(buff, "x", sizeof(buff)/sizeof(CHAR)); + r = SendMessage(edit, WM_SETTEXT, 0, (LPARAM)buff); + expect(TRUE, r); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); + expect(0, r); + ok(!IsWindow(edit), "Expected edit control to be destroyed\n"); + /* check that text is saved */ + item.mask = TVIF_TEXT; + item.hItem = hRoot; + item.pszText = buff; + item.cchTextMax = sizeof(buff)/sizeof(CHAR); + r = SendMessage(hTree, TVM_GETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + ok(!strcmp("x", buff), "Expected item text to change\n"); + + DestroyWindow(hTree); +} + +static void test_treeview_classinfo(void) +{ + WNDCLASSA cls; + + memset(&cls, 0, sizeof(cls)); + GetClassInfo(GetModuleHandleA("comctl32.dll"), WC_TREEVIEWA, &cls); + ok(cls.hbrBackground == NULL, "Expected NULL background brush, got %p\n", cls.hbrBackground); + ok(cls.style == (CS_GLOBALCLASS | CS_DBLCLKS), "Expected got %x\n", cls.style); + expect(0, cls.cbClsExtra); +} + +static void test_get_linecolor(void) +{ + COLORREF clr; + HWND hTree; + + hTree = create_treeview_control(); + + /* newly created control has default color */ + clr = (COLORREF)SendMessage(hTree, TVM_GETLINECOLOR, 0, 0); + if (clr == 0) + win_skip("TVM_GETLINECOLOR is not supported on comctl32 < 5.80\n"); + else + expect(CLR_DEFAULT, clr); + + DestroyWindow(hTree); +} + +static void test_get_insertmarkcolor(void) +{ + COLORREF clr; + HWND hTree; + + hTree = create_treeview_control(); + + /* newly created control has default color */ + clr = (COLORREF)SendMessage(hTree, TVM_GETINSERTMARKCOLOR, 0, 0); + if (clr == 0) + win_skip("TVM_GETINSERTMARKCOLOR is not supported on comctl32 < 5.80\n"); + else + expect(CLR_DEFAULT, clr); + + DestroyWindow(hTree); +} START_TEST(treeview) { @@ -851,41 +1070,32 @@ START_TEST(treeview) wc.lpfnWndProc = MyWndProc; RegisterClassA(&wc); - hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0); - if ( !ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n") ) - return; + ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n"); + if (!hMainWnd) return; - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - FillRoot(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE); - - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - DoTest1(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest1Seq, "DoTest1", FALSE); - - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - DoTest2(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest2Seq, "DoTest2", FALSE); - - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - DoTest3(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest3Seq, "DoTest3", FALSE); - - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - DoFocusTest(); - ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoFocusTestSeq, "DoFocusTest", TRUE); - - /* Sequences tested inside due to number */ - TestGetSet(); - - /* Clears all the previous items */ - TestCallback(); - - /* Clears all the previous items */ - TestExpandInvisible(); + test_fillroot(); + test_select(); + test_getitemtext(); + test_focus(); + test_get_set_bkcolor(); + test_get_set_imagelist(); + test_get_set_indent(); + test_get_set_insertmark(); + test_get_set_item(); + test_get_set_itemheight(); + test_get_set_scrolltime(); + test_get_set_textcolor(); + test_get_linecolor(); + test_get_insertmarkcolor(); + test_get_set_tooltips(); + test_get_set_unicodeformat(); + test_callback(); + test_expandinvisible(); + test_itemedit(); + test_treeview_classinfo(); PostMessageA(hMainWnd, WM_CLOSE, 0, 0); while(GetMessageA(&msg,0,0,0)) { diff --git a/rostests/winetests/comctl32/updown.c b/rostests/winetests/comctl32/updown.c index 433c190ae97..859b3a0a988 100644 --- a/rostests/winetests/comctl32/updown.c +++ b/rostests/winetests/comctl32/updown.c @@ -59,38 +59,15 @@ #define EDIT_SEQ_INDEX 1 #define UPDOWN_SEQ_INDEX 2 -static HWND parent_wnd, edit, updown; +#define UPDOWN_ID 0 +#define BUDDY_ID 1 + +static HWND parent_wnd, g_edit; + +static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR); static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; -static const struct message create_parent_wnd_seq[] = { - { WM_GETMINMAXINFO, sent }, - { WM_NCCREATE, sent }, - { WM_NCCALCSIZE, sent|wparam, 0 }, - { WM_CREATE, sent }, - { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_QUERYNEWPALETTE, sent|optional }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_ACTIVATEAPP, sent|wparam, 1 }, - { WM_NCACTIVATE, sent|wparam, 1 }, - { WM_ACTIVATE, sent|wparam, 1 }, - { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, - { WM_IME_NOTIFY, sent|defwinproc|optional }, - { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, - /* Win9x adds SWP_NOZORDER below */ - { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, - { WM_NCCALCSIZE, sent|wparam|optional, 1 }, - { WM_SIZE, sent }, - { WM_MOVE, sent }, - { 0 } -}; - -static const struct message add_edit_to_parent_seq[] = { - { WM_PARENTNOTIFY, sent|wparam, WM_CREATE }, - { 0 } -}; - static const struct message add_updown_with_edit_seq[] = { { WM_WINDOWPOSCHANGING, sent }, { WM_NCCALCSIZE, sent|wparam, TRUE }, @@ -182,12 +159,8 @@ static const struct message test_updown_unicode_seq[] = { { 0 } }; -static const struct message test_updown_destroy_seq[] = { - { WM_SHOWWINDOW, sent|wparam|lparam, 0, 0 }, - { WM_WINDOWPOSCHANGING, sent}, - { WM_WINDOWPOSCHANGED, sent}, - { WM_DESTROY, sent}, - { WM_NCDESTROY, sent}, +static const struct message test_updown_pos_nochange_seq[] = { + { WM_GETTEXT, sent|id, 0, 0, BUDDY_ID }, { 0 } }; @@ -254,14 +227,9 @@ static HWND create_parent_window(void) GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); } -struct subclass_info -{ - WNDPROC oldproc; -}; - static LRESULT WINAPI edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -273,43 +241,37 @@ static LRESULT WINAPI edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; + msg.id = BUDDY_ID; add_message(sequences, EDIT_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } static HWND create_edit_control(void) { - struct subclass_info *info; + WNDPROC oldproc; + HWND hwnd; RECT rect; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - GetClientRect(parent_wnd, &rect); - edit = CreateWindowExA(0, "EDIT", NULL, WS_CHILD | WS_BORDER | WS_VISIBLE, + hwnd = CreateWindowExA(0, WC_EDITA, NULL, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, rect.right, rect.bottom, parent_wnd, NULL, GetModuleHandleA(NULL), NULL); - if (!edit) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!hwnd) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC, - (LONG_PTR)edit_subclass_proc); - SetWindowLongPtrA(edit, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, + (LONG_PTR)edit_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); - return edit; + return hwnd; } static LRESULT WINAPI updown_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; LRESULT ret; struct message msg; @@ -321,46 +283,42 @@ static LRESULT WINAPI updown_subclass_proc(HWND hwnd, UINT message, WPARAM wPara if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; + msg.id = UPDOWN_ID; add_message(sequences, UPDOWN_SEQ_INDEX, &msg); defwndproc_counter++; - ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); defwndproc_counter--; return ret; } -static HWND create_updown_control(void) +static HWND create_updown_control(DWORD style, HWND buddy) { - struct subclass_info *info; + WNDPROC oldproc; HWND updown; RECT rect; - info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); - if (!info) - return NULL; - GetClientRect(parent_wnd, &rect); - updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_ALIGNRIGHT, - 0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), edit, + updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | style, + 0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), buddy, 100, 0, 50); - if (!updown) - { - HeapFree(GetProcessHeap(), 0, info); - return NULL; - } + if (!updown) return NULL; - info->oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC, - (LONG_PTR)updown_subclass_proc); - SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)info); + oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC, + (LONG_PTR)updown_subclass_proc); + SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)oldproc); return updown; } static void test_updown_pos(void) { + HWND updown; int r; + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); + flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Set Range from 0 to 100 */ @@ -410,24 +368,63 @@ static void test_updown_pos(void) expect(1,HIWORD(r)); ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos_seq , "test updown pos", FALSE); + + DestroyWindow(updown); + + /* there's no attempt to update buddy Edit if text didn't change */ + SetWindowTextA(g_edit, "50"); + updown = create_updown_control(UDS_ALIGNRIGHT | UDS_SETBUDDYINT, g_edit); + + /* test sequence only on 5.8x versions */ + r = SendMessage(updown, UDM_GETPOS32, 0, 0); + if (r) + { + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + r = SendMessage(updown, UDM_SETPOS, 0, 50); + expect(50,r); + + ok_sequence(sequences, EDIT_SEQ_INDEX, test_updown_pos_nochange_seq, + "test updown pos, no change", FALSE); + } + + DestroyWindow(updown); } static void test_updown_pos32(void) { + HWND updown; int r; int low, high; + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); + flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Set the position to 0 to 1000 */ SendMessage(updown, UDM_SETRANGE32, 0 , 1000 ); + low = high = -1; r = SendMessage(updown, UDM_GETRANGE32, (WPARAM) &low , (LPARAM) &high ); + if (low == -1) + { + win_skip("UDM_SETRANGE32/UDM_GETRANGE32 not available\n"); + DestroyWindow(updown); + return; + } + expect(0,low); expect(1000,high); - /* Set position to 500, don't check return since it is unset*/ - SendMessage(updown, UDM_SETPOS32, 0 , 500 ); + /* Set position to 500 */ + r = SendMessage(updown, UDM_SETPOS32, 0 , 500 ); + if (!r) + { + win_skip("UDM_SETPOS32 and UDM_GETPOS32 need 5.80\n"); + DestroyWindow(updown); + return; + } + expect(50,r); /* Since UDM_SETBUDDYINT was not set at creation bRet will always be true as a return from UDM_GETPOS32 */ @@ -464,30 +461,83 @@ static void test_updown_pos32(void) expect(1,high); ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos32_seq, "test updown pos32", FALSE); + + DestroyWindow(updown); + + /* there's no attempt to update buddy Edit if text didn't change */ + SetWindowTextA(g_edit, "50"); + updown = create_updown_control(UDS_ALIGNRIGHT | UDS_SETBUDDYINT, g_edit); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + r = SendMessage(updown, UDM_SETPOS32, 0, 50); + expect(50,r); + ok_sequence(sequences, EDIT_SEQ_INDEX, test_updown_pos_nochange_seq, + "test updown pos, no change", FALSE); + + DestroyWindow(updown); } static void test_updown_buddy(void) { - HWND buddyReturn; + HWND updown, buddyReturn, buddy; + WNDPROC proc; + DWORD style; + + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); flush_sequences(sequences, NUM_MSG_SEQUENCES); buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 ); - ok(buddyReturn == edit, "Expected edit handle\n"); + ok(buddyReturn == g_edit, "Expected edit handle\n"); - buddyReturn = (HWND)SendMessage(updown, UDM_SETBUDDY, (WPARAM) edit, 0); - ok(buddyReturn == edit, "Expected edit handle\n"); + buddyReturn = (HWND)SendMessage(updown, UDM_SETBUDDY, (WPARAM) g_edit, 0); + ok(buddyReturn == g_edit, "Expected edit handle\n"); buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 ); - ok(buddyReturn == edit, "Expected edit handle\n"); + ok(buddyReturn == g_edit, "Expected edit handle\n"); ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_buddy_seq, "test updown buddy", TRUE); ok_sequence(sequences, EDIT_SEQ_INDEX, add_updown_with_edit_seq, "test updown buddy_edit", FALSE); + + DestroyWindow(updown); + + buddy = create_edit_control(); + proc = (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC); + + updown= create_updown_control(UDS_ALIGNRIGHT, buddy); + ok(proc == (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "No subclassing expected\n"); + + style = GetWindowLongA(updown, GWL_STYLE); + SetWindowLongA(updown, GWL_STYLE, style | UDS_ARROWKEYS); + style = GetWindowLongA(updown, GWL_STYLE); + ok(style & UDS_ARROWKEYS, "Expected UDS_ARROWKEYS\n"); + /* no subclass if UDS_ARROWKEYS set after creation */ + ok(proc == (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "No subclassing expected\n"); + + DestroyWindow(updown); + + updown= create_updown_control(UDS_ALIGNRIGHT | UDS_ARROWKEYS, buddy); + ok(proc != (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "Subclassing expected\n"); + + if (pSetWindowSubclass) + { + /* updown uses subclass helpers for buddy on >5.8x systems */ + ok(GetPropA(buddy, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n"); + } + + DestroyWindow(updown); + + DestroyWindow(buddy); } static void test_updown_base(void) { + HWND updown; int r; + CHAR text[10]; + + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -520,12 +570,36 @@ static void test_updown_base(void) expect(10,r); ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_base_seq, "test updown base", FALSE); + + DestroyWindow(updown); + + /* switch base with buddy attached */ + updown = create_updown_control(UDS_SETBUDDYINT | UDS_ALIGNRIGHT, g_edit); + + r = SendMessage(updown, UDM_SETPOS, 0, 10); + expect(50, r); + + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + ok(lstrcmpA(text, "10") == 0, "Expected '10', got '%s'\n", text); + + r = SendMessage(updown, UDM_SETBASE, 16, 0); + expect(10, r); + + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + /* FIXME: currently hex output isn't properly formatted, but for this + test only change from initial text matters */ + ok(lstrcmpA(text, "10") != 0, "Expected '0x000A', got '%s'\n", text); + + DestroyWindow(updown); } static void test_updown_unicode(void) { + HWND updown; int r; + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); + flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Set it to ANSI, don't check return as we don't know previous state */ @@ -537,6 +611,12 @@ static void test_updown_unicode(void) r = SendMessage(updown, UDM_SETUNICODEFORMAT, 1 , 0); expect(0,r); r = SendMessage(updown, UDM_GETUNICODEFORMAT, 0 , 0); + if (!r) + { + win_skip("UDM_SETUNICODEFORMAT not available\n"); + DestroyWindow(updown); + return; + } expect(1,r); /* And now set it back to ANSI */ @@ -546,49 +626,161 @@ static void test_updown_unicode(void) expect(0,r); ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_unicode_seq, "test updown unicode", FALSE); + + DestroyWindow(updown); } - -static void test_create_updown_control(void) +static void test_updown_create(void) { CHAR text[MAX_PATH]; - - parent_wnd = create_parent_window(); - ok(parent_wnd != NULL, "Failed to create parent window!\n"); - ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create parent window", TRUE); + HWND updown; + RECT r; flush_sequences(sequences, NUM_MSG_SEQUENCES); - edit = create_edit_control(); - ok(edit != NULL, "Failed to create edit control\n"); - ok_sequence(sequences, PARENT_SEQ_INDEX, add_edit_to_parent_seq, "add edit control to parent", FALSE); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - updown = create_updown_control(); + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); ok(updown != NULL, "Failed to create updown control\n"); ok_sequence(sequences, PARENT_SEQ_INDEX, add_updown_to_parent_seq, "add updown control to parent", TRUE); ok_sequence(sequences, EDIT_SEQ_INDEX, add_updown_with_edit_seq, "add updown control with edit", FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); - GetWindowTextA(edit, text, MAX_PATH); + GetWindowTextA(g_edit, text, MAX_PATH); ok(lstrlenA(text) == 0, "Expected empty string\n"); ok_sequence(sequences, EDIT_SEQ_INDEX, get_edit_text_seq, "get edit text", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + DestroyWindow(updown); + /* create with zero width */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.right = 0; + GetClientRect(updown, &r); + ok(r.right > 0, "Expected default width, got %d\n", r.right); + DestroyWindow(updown); + /* create with really small width */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 2, 0, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.right = 0; + GetClientRect(updown, &r); + ok(r.right != 2 && r.right > 0, "Expected default width, got %d\n", r.right); + DestroyWindow(updown); + /* create with width greater than default */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 100, 0, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.right = 0; + GetClientRect(updown, &r); + ok(r.right < 100 && r.right > 0, "Expected default width, got %d\n", r.right); + DestroyWindow(updown); + /* create with zero height, UDS_HORZ */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.bottom = 0; + GetClientRect(updown, &r); + ok(r.bottom == 0, "Expected zero height, got %d\n", r.bottom); + DestroyWindow(updown); + /* create with really small height, UDS_HORZ */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 2, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.bottom = 0; + GetClientRect(updown, &r); + ok(r.bottom == 0, "Expected zero height, got %d\n", r.bottom); + DestroyWindow(updown); + /* create with height greater than default, UDS_HORZ */ + updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 100, + parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0); + ok(updown != NULL, "Failed to create updown control\n"); + r.bottom = 0; + GetClientRect(updown, &r); + ok(r.bottom < 100 && r.bottom > 0, "Expected default height, got %d\n", r.bottom); + DestroyWindow(updown); +} + +static void test_UDS_SETBUDDYINT(void) +{ + HWND updown; + DWORD style, ret; + CHAR text[10]; + + /* cleanup buddy */ + text[0] = '\0'; + SetWindowTextA(g_edit, text); + + /* creating without UDS_SETBUDDYINT */ + updown = create_updown_control(UDS_ALIGNRIGHT, g_edit); + /* try to set UDS_SETBUDDYINT after creation */ + style = GetWindowLongA(updown, GWL_STYLE); + SetWindowLongA(updown, GWL_STYLE, style | UDS_SETBUDDYINT); + style = GetWindowLongA(updown, GWL_STYLE); + ok(style & UDS_SETBUDDYINT, "Expected UDS_SETBUDDY to be set\n"); + SendMessage(updown, UDM_SETPOS, 0, 20); + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + ok(lstrlenA(text) == 0, "Expected empty string\n"); + DestroyWindow(updown); + + /* creating with UDS_SETBUDDYINT */ + updown = create_updown_control(UDS_SETBUDDYINT | UDS_ALIGNRIGHT, g_edit); + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + /* 50 is initial value here */ + ok(lstrcmpA(text, "50") == 0, "Expected '50', got '%s'\n", text); + /* now remove style flag */ + style = GetWindowLongA(updown, GWL_STYLE); + SetWindowLongA(updown, GWL_STYLE, style & ~UDS_SETBUDDYINT); + SendMessage(updown, UDM_SETPOS, 0, 20); + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + ok(lstrcmpA(text, "20") == 0, "Expected '20', got '%s'\n", text); + /* set edit text directly, check position */ + strcpy(text, "10"); + SetWindowTextA(g_edit, text); + ret = SendMessageA(updown, UDM_GETPOS, 0, 0); + expect(10, ret); + strcpy(text, "11"); + SetWindowTextA(g_edit, text); + ret = SendMessageA(updown, UDM_GETPOS, 0, 0); + expect(11, LOWORD(ret)); + expect(0, HIWORD(ret)); + /* set to invalid value */ + strcpy(text, "21st"); + SetWindowTextA(g_edit, text); + ret = SendMessageA(updown, UDM_GETPOS, 0, 0); + expect(11, LOWORD(ret)); + expect(TRUE, HIWORD(ret)); + /* set style back */ + style = GetWindowLongA(updown, GWL_STYLE); + SetWindowLongA(updown, GWL_STYLE, style | UDS_SETBUDDYINT); + SendMessage(updown, UDM_SETPOS, 0, 30); + GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR)); + ok(lstrcmpA(text, "30") == 0, "Expected '30', got '%s'\n", text); + DestroyWindow(updown); +} + +START_TEST(updown) +{ + HMODULE mod = GetModuleHandleA("comctl32.dll"); + + pSetWindowSubclass = (void*)GetProcAddress(mod, (LPSTR)410); + + InitCommonControls(); + init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + + parent_wnd = create_parent_window(); + ok(parent_wnd != NULL, "Failed to create parent window!\n"); + g_edit = create_edit_control(); + ok(g_edit != NULL, "Failed to create edit control\n"); + + test_updown_create(); test_updown_pos(); test_updown_pos32(); test_updown_buddy(); test_updown_base(); test_updown_unicode(); -} + test_UDS_SETBUDDYINT(); -START_TEST(updown) -{ - InitCommonControls(); - init_msg_sequences(sequences, NUM_MSG_SEQUENCES); - - test_create_updown_control(); + DestroyWindow(g_edit); + DestroyWindow(parent_wnd); } diff --git a/rostests/winetests/comctl32/v6util.h b/rostests/winetests/comctl32/v6util.h new file mode 100644 index 00000000000..848e95b9225 --- /dev/null +++ b/rostests/winetests/comctl32/v6util.h @@ -0,0 +1,142 @@ +/* + * Utility routines for comctl32 v6 tests + * + * Copyright 2006 Mike McCormack for CodeWeavers + * Copyright 2007 George Gov + * Copyright 2009 Owen Rudge for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) + +#ifdef __i386__ +#define ARCH "x86" +#elif defined __x86_64__ +#define ARCH "amd64" +#else +#define ARCH "none" +#endif + +static const CHAR manifest_name[] = "cc6.manifest"; + +static const CHAR manifest[] = + "\n" + "\n" + " \n" + "Wine comctl32 test suite\n" + "\n" + " \n" + " \n" + "\n" + "\n" + "\n"; + +static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx) +{ + HANDLE hKernel32; + BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR); + VOID (WINAPI *pReleaseActCtx)(HANDLE); + + hKernel32 = GetModuleHandleA("kernel32.dll"); + pDeactivateActCtx = (void*)GetProcAddress(hKernel32, "DeactivateActCtx"); + pReleaseActCtx = (void*)GetProcAddress(hKernel32, "ReleaseActCtx"); + if (!pDeactivateActCtx || !pReleaseActCtx) + { + win_skip("Activation contexts unsupported\n"); + return; + } + + pDeactivateActCtx(0, cookie); + pReleaseActCtx(hCtx); + + DeleteFileA(manifest_name); +} + +static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx) +{ + HANDLE hKernel32; + HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*); + BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*); + + ACTCTXA ctx; + BOOL ret; + HANDLE file; + DWORD written; + + hKernel32 = GetModuleHandleA("kernel32.dll"); + pCreateActCtxA = (void*)GetProcAddress(hKernel32, "CreateActCtxA"); + pActivateActCtx = (void*)GetProcAddress(hKernel32, "ActivateActCtx"); + if (!(pCreateActCtxA && pActivateActCtx)) + { + win_skip("Activation contexts unsupported. No version 6 tests possible.\n"); + return FALSE; + } + + /* create manifest */ + file = CreateFileA( manifest_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL ); + if (file != INVALID_HANDLE_VALUE) + { + ret = (WriteFile( file, manifest, sizeof(manifest)-1, &written, NULL ) && + written == sizeof(manifest)-1); + CloseHandle( file ); + if (!ret) + { + DeleteFileA( manifest_name ); + skip("Failed to fill manifest file. Skipping comctl32 V6 tests.\n"); + return FALSE; + } + else + trace("created %s\n", manifest_name); + } + else + { + skip("Failed to create manifest file. Skipping comctl32 V6 tests.\n"); + return FALSE; + } + + memset(&ctx, 0, sizeof(ctx)); + ctx.cbSize = sizeof(ctx); + ctx.lpSource = manifest_name; + + *hCtx = pCreateActCtxA(&ctx); + ok(*hCtx != 0, "Expected context handle\n"); + + ret = pActivateActCtx(*hCtx, pcookie); + expect(TRUE, ret); + + if (!ret) + { + win_skip("A problem during context activation occurred.\n"); + DeleteFileA(manifest_name); + } + + return ret; +} + +#undef expect +#undef ARCH From 8e44cb3688ce99711c4dadc70e1ca35f0896863f Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 15:37:32 +0000 Subject: [PATCH 120/292] [WINE] partial sync of test.h svn path=/trunk/; revision=47449 --- reactos/include/reactos/wine/test.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/reactos/include/reactos/wine/test.h b/reactos/include/reactos/wine/test.h index d0d8208926c..313e46a4ccb 100644 --- a/reactos/include/reactos/wine/test.h +++ b/reactos/include/reactos/wine/test.h @@ -80,14 +80,14 @@ extern void winetest_vskip( const char *msg, va_list ap ); #ifdef __GNUC__ -extern int winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) )); +extern void winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) )); extern void winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); extern void winetest_win_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); extern void winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2))); #else /* __GNUC__ */ -extern int winetest_ok( int condition, const char *msg, ... ); +extern void winetest_ok( int condition, const char *msg, ... ); extern void winetest_skip( const char *msg, ... ); extern void winetest_win_skip( const char *msg, ... ); extern void winetest_trace( const char *msg, ... ); @@ -322,15 +322,13 @@ int winetest_vok( int condition, const char *msg, va_list args ) } } -int winetest_ok( int condition, const char *msg, ... ) +void winetest_ok( int condition, const char *msg, ... ) { va_list valist; - int rc; - + va_start(valist, msg); - rc=winetest_vok(condition, msg, valist); + winetest_vok(condition, msg, valist); va_end(valist); - return rc; } void winetest_trace( const char *msg, ... ) From 25b2c670c4fc967ac5f863f05ea002456b85827d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 16:24:51 +0000 Subject: [PATCH 121/292] [WINE] Cast the unused 0 in the ok macro to void to make clang happy svn path=/trunk/; revision=47450 --- reactos/include/reactos/wine/test.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/include/reactos/wine/test.h b/reactos/include/reactos/wine/test.h index 313e46a4ccb..bbd0c6b2d74 100644 --- a/reactos/include/reactos/wine/test.h +++ b/reactos/include/reactos/wine/test.h @@ -94,7 +94,7 @@ extern void winetest_trace( const char *msg, ... ); #endif /* __GNUC__ */ -#define ok_(file, line) (winetest_set_location(file, line), 0) ? 0 : winetest_ok +#define ok_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok #define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip #define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip #define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace From cbb1f9480b4c49cd85acb94a72550c3279b09ac8 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 18:34:29 +0000 Subject: [PATCH 122/292] [KBDLV] Latvian keyboard fixes by Arturs B., See issue #5385 for more details. svn path=/trunk/; revision=47452 --- reactos/dll/keyboard/kbdlv/kbdlv.c | 298 ++++++++++------------------- 1 file changed, 101 insertions(+), 197 deletions(-) diff --git a/reactos/dll/keyboard/kbdlv/kbdlv.c b/reactos/dll/keyboard/kbdlv/kbdlv.c index d2befa16a2e..a9954371b5d 100644 --- a/reactos/dll/keyboard/kbdlv/kbdlv.c +++ b/reactos/dll/keyboard/kbdlv/kbdlv.c @@ -1,7 +1,7 @@ /* - * ReactOS Latvian Keyboard layout + * ReactOS latvian Keyboard layout * Copyright (C) 2008 ReactOS - * Author: Dmitry Chapyshev + * Author: Dmitry Chapyshev, Arthurs B. * License: LGPL, see: LGPL.txt * * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php @@ -33,8 +33,6 @@ #define KNUMS 0xc00 /* Special + number pad */ #define KMEXT 0x300 /* Multi + ext */ -#define SHFT_INVALID 0x0F - ROSDATA USHORT scancode_to_vk[] = { /* Numbers Row */ /* - 00 - */ @@ -60,10 +58,10 @@ ROSDATA USHORT scancode_to_vk[] = { /* Third letters row */ 'Z', 'X', 'C', 'V', 'B', 'N', 'M', VK_OEM_COMMA, - VK_OEM_PERIOD,VK_OEM_2, VK_RSHIFT | KEXT, + VK_OEM_PERIOD,VK_OEM_2, VK_RSHIFT, /* - 37 - */ /* Bottom Row */ - 0x26a, VK_LMENU, VK_SPACE, VK_CAPITAL, + VK_MULTIPLY, VK_LMENU, VK_SPACE, VK_CAPITAL, /* - 3b - */ /* F-Keys */ @@ -86,8 +84,8 @@ ROSDATA USHORT scancode_to_vk[] = { /* Oddities, and the remaining standard F-Keys */ VK_EMPTY, VK_OEM_102, VK_F11, VK_F12, /* - 59 - */ - VK_CLEAR, VK_OEM_WSCTRL,VK_OEM_FINISH,VK_OEM_JUMP, VK_EREOF, /* EREOF */ - VK_OEM_BACKTAB, VK_OEM_AUTO, VK_EMPTY, VK_ZOOM, /* ZOOM */ + VK_CLEAR, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* EREOF */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* ZOOM */ VK_HELP, /* - 64 - */ /* Even more F-Keys (for example, NCR keyboards from the early 90's) */ @@ -95,64 +93,25 @@ ROSDATA USHORT scancode_to_vk[] = { VK_F21, VK_F22, VK_F23, /* - 6f - */ /* Not sure who uses these codes */ - VK_OEM_PA3, VK_EMPTY, VK_OEM_RESET, + VK_EMPTY, VK_EMPTY, VK_EMPTY, /* - 72 - */ - VK_EMPTY, 0xc1, VK_EMPTY, VK_EMPTY, + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* - 76 - */ /* One more f-key */ VK_F24, /* - 77 - */ VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, - VK_OEM_PA1, VK_TAB, 0xc2, 0, /* PA1 */ - 0, + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* PA1 */ + VK_EMPTY, /* - 80 - */ 0 }; ROSDATA VSC_VK extcode0_to_vk[] = { - { 0x10, VK_MEDIA_PREV_TRACK | KEXT }, - { 0x19, VK_MEDIA_NEXT_TRACK | KEXT }, - { 0x1D, VK_RCONTROL | KEXT }, - { 0x20, VK_VOLUME_MUTE | KEXT }, - { 0x21, VK_LAUNCH_APP2 | KEXT }, - { 0x22, VK_MEDIA_PLAY_PAUSE | KEXT }, - { 0x24, VK_MEDIA_STOP | KEXT }, - { 0x2E, VK_VOLUME_DOWN | KEXT }, - { 0x30, VK_VOLUME_UP | KEXT }, - { 0x32, VK_BROWSER_HOME | KEXT }, - { 0x35, VK_DIVIDE | KEXT }, - { 0x37, VK_SNAPSHOT | KEXT }, - { 0x38, VK_RMENU | KEXT }, - { 0x47, VK_HOME | KEXT }, - { 0x48, VK_UP | KEXT }, - { 0x49, VK_PRIOR | KEXT }, - { 0x4B, VK_LEFT | KEXT }, - { 0x4D, VK_RIGHT | KEXT }, - { 0x4F, VK_END | KEXT }, - { 0x50, VK_DOWN | KEXT }, - { 0x51, VK_NEXT | KEXT }, - { 0x52, VK_INSERT | KEXT }, - { 0x53, VK_DELETE | KEXT }, - { 0x5B, VK_LWIN | KEXT }, - { 0x5C, VK_RWIN | KEXT }, - { 0x5D, VK_APPS | KEXT }, - { 0x5F, VK_SLEEP | KEXT }, - { 0x65, VK_BROWSER_SEARCH | KEXT }, - { 0x66, VK_BROWSER_FAVORITES | KEXT }, - { 0x67, VK_BROWSER_REFRESH | KEXT }, - { 0x68, VK_BROWSER_STOP | KEXT }, - { 0x69, VK_BROWSER_FORWARD | KEXT }, - { 0x6A, VK_BROWSER_BACK | KEXT }, - { 0x6B, VK_LAUNCH_APP1 | KEXT }, - { 0x6C, VK_LAUNCH_MAIL | KEXT }, - { 0x6D, VK_LAUNCH_MEDIA_SELECT | KEXT }, - { 0x1C, VK_RETURN | KEXT }, - { 0x46, VK_CANCEL | KEXT }, { 0, 0 }, }; ROSDATA VSC_VK extcode1_to_vk[] = { - { 0x1d, VK_PAUSE}, { 0, 0 }, }; @@ -165,91 +124,93 @@ ROSDATA VK_TO_BIT modifier_keys[] = { ROSDATA MODIFIERS modifier_bits = { modifier_keys, - 7, - { 0, 1, 4, 5, SHFT_INVALID, SHFT_INVALID, 2, 3 } + 3, + { 0, 1, 2, 3 } /* Modifier bit order, NONE, SHIFT, CTRL, ALT */ }; #define NOCAPS 0 #define CAPS KSHIFT /* Caps -> shift */ ROSDATA VK_TO_WCHARS2 key_to_chars_2mod[] = { - { VK_OEM_3, NOCAPS, {0x00ad, '?' } }, - { '9', NOCAPS, {'9', '(' } }, - { '0', NOCAPS, {'0', ')' } }, - { 'J', CAPS, {'j', 'J' } }, - { 'N', CAPS, {'n', 'N' } }, - { 'Z', CAPS, {'z', 'Z' } }, - { 'W', CAPS, {0x0113, 0x0112} }, - { 'X', CAPS, {0x010d, 0x010c} }, - { VK_OEM_1, CAPS, {0x0161, 0x0160} }, - { 'U', CAPS, {'u', 'U' } }, - { 'S', CAPS, {'s', 'S' } }, - { 'I', CAPS, {'i', 'I' } }, - { 'L', CAPS, {'l', 'L' } }, - { 'D', CAPS, {'d', 'D' } }, - { 'A', CAPS, {'a', 'A' } }, - { 'T', CAPS, {'t', 'T' } }, - { 'C', CAPS, {'c', 'C' } }, - { 'P', CAPS, {'p', 'P' } }, - { VK_OEM_8, CAPS, {0x0101, 0x0100} }, - { VK_OEM_2, CAPS, {0x013c, 0x013b} }, - { VK_DECIMAL, NOCAPS, {',', ',' } }, - { VK_TAB, NOCAPS, {'\t', '\t' } }, - { VK_ADD, NOCAPS, {'+', '+' } }, - { VK_DIVIDE, NOCAPS, {'/', '/' } }, - { VK_MULTIPLY, NOCAPS, {'*', '*' } }, - { VK_SUBTRACT, NOCAPS, {'-', '-' } }, + /* Normal vs Shifted */ + /* The numbers */ + { '1', NOCAPS, {'1', '!'} }, + /* Ctrl-2 generates NUL */ + { '3', NOCAPS, {'3', '#'} }, + { '4', NOCAPS, {'4', '$'} }, + { '5', NOCAPS, {'5', '%'} }, + /* Ctrl-6 generates RS */ + { '7', NOCAPS, {'7', '&'} }, + { '8', NOCAPS, {'8', '*'} }, + { '9', NOCAPS, {'9', '('} }, + { '0', NOCAPS, {'0', ')'} }, + + /* Specials */ + /* Ctrl-_ generates US */ + { VK_OEM_PLUS ,NOCAPS, {'=', '+'} }, + { VK_OEM_1 ,NOCAPS, {';', ':'} }, + { VK_OEM_7 ,NOCAPS, {'\'','\"'} }, + { VK_OEM_3 ,NOCAPS, {'`', '~'} }, + { VK_OEM_COMMA ,NOCAPS, {',', '<'} }, + { VK_OEM_PERIOD ,NOCAPS, {'.', '>'} }, + { VK_OEM_2 ,NOCAPS, {'/', '?'} }, + /* Keys that do not have shift states */ + { VK_TAB ,NOCAPS, {'\t','\t'} }, + { VK_ADD ,NOCAPS, {'+', '+'} }, + { VK_SUBTRACT,NOCAPS, {'-', '-'} }, + { VK_MULTIPLY,NOCAPS, {'*', '*'} }, + { VK_DIVIDE ,NOCAPS, {'/', '/'} }, + { VK_ESCAPE ,NOCAPS, {'\x1b','\x1b'} }, + { VK_SPACE ,NOCAPS, {' ', ' '} }, { 0, 0 } }; ROSDATA VK_TO_WCHARS3 key_to_chars_3mod[] = { - { '1', NOCAPS, {'1', '!', 0x00ab} }, - { '8', NOCAPS, {'8', 0x00d7, ':' } }, - { 'E', CAPS, {'e', 'E', 0x20ac} }, - { VK_OEM_COMMA, NOCAPS, {',', ';', '<' } }, - { VK_OEM_PERIOD, NOCAPS, {'.', ':', '>' } }, - { 0, 0 } + /* Normal, Shifted, Ctrl */ + /* Legacy (telnet-style) ascii escapes */ + { VK_OEM_4, 0, {'[', '{', 0x1b /* ESC */} }, + { VK_OEM_6, 0, {']', '}', 0x1d /* GS */} }, + { VK_OEM_5, 0, {'\\','|', 0x1c /* FS */} }, + { VK_OEM_102,0,{'\\','|', 0x1c /* FS */} }, + { VK_RETURN,0, {'\r', '\r', '\n'} }, + { 0,0 } }; ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] = { - { '2', NOCAPS, {'2', 0x00ab, WCH_NONE, '@' } }, - { '3', NOCAPS, {'3', 0x00bb, WCH_NONE, '#' } }, - { '4', NOCAPS, {'4', '$', 0x20ac, '$' } }, - { '5', NOCAPS, {'5', '%', '\"', WCH_DEAD} }, - { 0xff, NOCAPS, {WCH_NONE, WCH_NONE, WCH_NONE, '~' } }, - { '7', NOCAPS, {'7', '&', WCH_NONE, 0x00b1 } }, - { 'F', CAPS, {'f', 'F', '=', ';' } }, - { 'Q', CAPS, {0x016b, 0x016a, 'q', 'Q' } }, - { 'G', CAPS, {'g', 'G', 0x0123, 0x0122 } }, - { 'R', CAPS, {'r', 'R', 0x0157, 0x0156 } }, - { 'M', CAPS, {'m', 'M', 'w', 'W' } }, - { 'V', CAPS, {'v', 'V', 'y', 'Y' } }, - { 'Y', CAPS, {0x017e, 0x017d, '[', '{' } }, - { 'H', CAPS, {'h', 'H', ']', '}' } }, - { VK_OEM_7, NOCAPS, {WCH_DEAD, WCH_DEAD, WCH_DEAD, WCH_DEAD} }, - { 0xff, NOCAPS, {0x00b4, 0x00b0, 0x00b4, 0x00a8 } }, - { 'B', CAPS, {'b', 'B', 'x', 'X' } }, - { 'K', CAPS, {'k', 'K', 0x0137, 0x0136 } }, - { 'O', CAPS, {'o', 'O', 0x00f5, 0x00d5 } }, - { 0, 0 } -}; + /* Normal, Shifted, Ctrl, C-S-x */ -ROSDATA VK_TO_WCHARS5 key_to_chars_5mod[] = { - { VK_OEM_5, CAPS, {0x0137, 0x0136, WCH_NONE, WCH_NONE, 0x001c} }, - { VK_OEM_4, CAPS, {0x0146, 0x0145, WCH_NONE, WCH_NONE, 0x001b} }, - { VK_OEM_6, CAPS, {0x012b, 0x012a, WCH_NONE, WCH_NONE, 0x001d} }, - { VK_OEM_102, CAPS, {0x0123, 0x0122, '\\', '|', 0x001c} }, - { VK_BACK, NOCAPS, {'\b', '\b', WCH_NONE, WCH_NONE, 0x007f} }, - { VK_ESCAPE, NOCAPS, {0x001b, 0x001b, WCH_NONE, WCH_NONE, 0x001b} }, - { VK_RETURN, NOCAPS, {'\r', '\r', WCH_NONE, WCH_NONE, '\n' } }, - { VK_SPACE, NOCAPS, {' ', ' ', WCH_NONE, WCH_NONE, ' ' } }, - { VK_CANCEL, NOCAPS, {0x0003, 0x0003, WCH_NONE, WCH_NONE, 0x0003} }, - { 0, 0 } -}; + /* The alphabet */ + { 'A', CAPS, {'a', 'A', 0x101, 0x100} }, + { 'B', CAPS, {'b', 'B', 0x02, 0x02} }, + { 'C', CAPS, {'c', 'C', 0x10d, 0x10c} }, + { 'D', CAPS, {'d', 'D', 0x04, 0x04} }, + { 'E', CAPS, {'e', 'E', 0x113, 0x112} }, + { 'F', CAPS, {'f', 'F', 0x06, 0x06} }, + { 'G', CAPS, {'g', 'G', 0x123, 0x122} }, + { 'H', CAPS, {'h', 'H', 0x08, 0x08} }, + { 'I', CAPS, {'i', 'I', 0x12b, 0x12a} }, + { 'J', CAPS, {'j', 'J', 0x0a, 0x0a} }, + { 'K', CAPS, {'k', 'K', 0x137, 0x136} }, + { 'L', CAPS, {'l', 'L', 0x13c, 0x13b} }, + { 'M', CAPS, {'m', 'M', 0x0d, 0x0d} }, + { 'N', CAPS, {'n', 'N', 0x146, 0x145} }, + { 'O', CAPS, {'o', 'O', 0x0f, 0x0f} }, + { 'P', CAPS, {'p', 'P', 0x10, 0x10} }, + { 'Q', CAPS, {'q', 'Q', 0x11, 0x11} }, + { 'R', CAPS, {'r', 'R', 0x12, 0x12} }, + { 'S', CAPS, {'s', 'S', 0x161, 0x160} }, + { 'T', CAPS, {'t', 'T', 0x14, 0x14} }, + { 'U', CAPS, {'u', 'U', 0x16b, 0x16a} }, + { 'V', CAPS, {'v', 'V', 0x16, 0x16} }, + { 'W', CAPS, {'w', 'W', 0x17, 0x17} }, + { 'X', CAPS, {'x', 'X', 0x18, 0x18} }, + { 'Y', CAPS, {'y', 'Y', 0x19, 0x19} }, + { 'Z', CAPS, {'z', 'Z', 0x17e, 0x17d} }, -ROSDATA VK_TO_WCHARS6 key_to_chars_6mod[] = { - { '6', NOCAPS, {'6', '/', 0x2019, '^', WCH_NONE, 0x001e} }, - { VK_OEM_MINUS, NOCAPS, {'-', '_', 0x2013, 0x2014, WCH_NONE, 0x001f} }, + /* Legacy Ascii generators */ + { '2', NOCAPS, {'2', '@', WCH_NONE, 0} }, + { '6', NOCAPS, {'6', '^', WCH_NONE, 0x1e /* RS */} }, + { VK_OEM_MINUS, NOCAPS, {'-', '_', WCH_NONE, 0x1f /* US */} }, { 0, 0 } }; @@ -264,22 +225,23 @@ ROSDATA VK_TO_WCHARS1 keypad_numbers[] = { { VK_NUMPAD7, 0, {'7'} }, { VK_NUMPAD8, 0, {'8'} }, { VK_NUMPAD9, 0, {'9'} }, - { 0, 0 } + { VK_DECIMAL, 0, {'.'} }, + { VK_BACK, 0, {'\010'} }, + { 0,0 } }; #define vk_master(n,x) { (PVK_TO_WCHARS1)x, n, sizeof(x[0]) } ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table[] = { + vk_master(1,keypad_numbers), + vk_master(2,key_to_chars_2mod), vk_master(3,key_to_chars_3mod), vk_master(4,key_to_chars_4mod), - vk_master(5,key_to_chars_5mod), - vk_master(6,key_to_chars_6mod), - vk_master(2,key_to_chars_2mod), - vk_master(1,keypad_numbers), { 0,0,0 } }; ROSDATA VSC_LPWSTR key_names[] = { + { 0x00, L"" }, { 0x01, L"Esc" }, { 0x0e, L"Backspace" }, { 0x0f, L"Tab" }, @@ -331,12 +293,12 @@ ROSDATA VSC_LPWSTR key_names[] = { { 0x85, L"F22" }, { 0x86, L"F23" }, { 0x87, L"F24" }, - { 0, NULL } + { 0, NULL }, }; ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x1c, L"Num Enter" }, - { 0x1d, L"Right Control" }, + { 0x1d, L"Right Ctrl" }, { 0x35, L"Num /" }, { 0x37, L"Prnt Scrn" }, { 0x38, L"Right Alt" }, @@ -345,7 +307,8 @@ ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x47, L"Home" }, { 0x48, L"Up" }, { 0x49, L"Page Up" }, - { 0x4b, L"Left" }, + { 0x4a, L"Left" }, + { 0x4c, L"Center" }, { 0x4d, L"Right" }, { 0x4f, L"End" }, { 0x50, L"Down" }, @@ -353,60 +316,10 @@ ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x52, L"Insert" }, { 0x53, L"Delete" }, { 0x54, L"" }, - { 0x56, L"Help" }, - { 0x5b, L"Left " }, - { 0x5c, L"Right " }, - { 0x5d, L"Application" }, - { 0, NULL } -}; - -ROSDATA DEADKEY_LPWSTR dead_key_names[] = { - L"\x00b4" L"ACUTE", - L"\x00a8" L"DIAERESIS", - L"\x00b0" L"RING", - L"~" L"TILDE", - NULL -}; - -#define DEADTRANS(ch, accent, comp, flags) MAKELONG(ch, accent), comp, flags - -ROSDATA DEADKEY dead_key[] = { - { DEADTRANS(L'n', 0x00b4, 0x0144, 0x0000) }, - { DEADTRANS(L'c', 0x00b4, 0x0107, 0x0000) }, - { DEADTRANS(L'o', 0x00b4, 0x00f3, 0x0000) }, - { DEADTRANS(L'e', 0x00b4, 0x00e9, 0x0000) }, - { DEADTRANS(L's', 0x00b4, 0x015b, 0x0000) }, - { DEADTRANS(L'z', 0x00b4, 0x017a, 0x0000) }, - { DEADTRANS(L'N', 0x00b4, 0x0143, 0x0000) }, - { DEADTRANS(L'C', 0x00b4, 0x0106, 0x0000) }, - { DEADTRANS(L'O', 0x00b4, 0x00d3, 0x0000) }, - { DEADTRANS(L'E', 0x00b4, 0x00c9, 0x0000) }, - { DEADTRANS(L'S', 0x00b4, 0x015a, 0x0000) }, - { DEADTRANS(L'Z', 0x00b4, 0x0179, 0x0000) }, - { DEADTRANS(L' ', 0x00b4, 0x00b4, 0x0000) }, - - { DEADTRANS(L'a', 0x00a8, 0x00e4, 0x0000) }, - { DEADTRANS(L'u', 0x00a8, 0x00fc, 0x0000) }, - { DEADTRANS(L'o', 0x00a8, 0x00f6, 0x0000) }, - { DEADTRANS(L'A', 0x00a8, 0x00c4, 0x0000) }, - { DEADTRANS(L'U', 0x00a8, 0x00dc, 0x0000) }, - { DEADTRANS(L'O', 0x00a8, 0x00d6, 0x0000) }, - { DEADTRANS(L' ', 0x00a8, 0x00a8, 0x0000) }, - - { DEADTRANS(L'a', 0x00b0, 0x00e5, 0x0000) }, - { DEADTRANS(L'A', 0x00b0, 0x00c5, 0x0000) }, - { DEADTRANS(L'e', 0x00b0, 0x0117, 0x0000) }, - { DEADTRANS(L'E', 0x00b0, 0x0116, 0x0000) }, - { DEADTRANS(L'z', 0x00b0, 0x017c, 0x0000) }, - { DEADTRANS(L'Z', 0x00b0, 0x017b, 0x0000) }, - { DEADTRANS(L'g', 0x00b0, 0x0121, 0x0000) }, - { DEADTRANS(L' ', 0x00b0, 0x00b0, 0x0000) }, - - { DEADTRANS(L'o', L'~', 0x00f5, 0x0000) }, - { DEADTRANS(L'O', L'~', 0x00d5, 0x0000) }, - { DEADTRANS(L' ', L'~', L'~', 0x0000) }, - - {0, 0} + { 0x55, L"Help" }, + { 0x56, L"Left Windows" }, + { 0x5b, L"Right Windows" }, + { 0, NULL }, }; /* Finally, the master table */ @@ -417,13 +330,13 @@ ROSDATA KBDTABLES keyboard_layout_table = { /* character from vk tables */ vk_to_wchar_master_table, - /* diacritical marks */ - dead_key, + /* diacritical marks -- currently implemented by wine code */ + NULL, /* Key names */ (VSC_LPWSTR *)key_names, (VSC_LPWSTR *)extended_key_names, - dead_key_names, /* Dead key names */ + NULL, /* Dead key names */ /* scan code to virtual key maps */ scancode_to_vk, @@ -431,9 +344,9 @@ ROSDATA KBDTABLES keyboard_layout_table = { extcode0_to_vk, extcode1_to_vk, - MAKELONG(1,1), /* Version 1.0 */ + MAKELONG(0,1), /* Version 1.0 */ - /* Ligatures */ + /* Ligatures -- Latvian doesn't have any */ 0, 0, NULL @@ -443,12 +356,3 @@ PKBDTABLES WINAPI KbdLayerDescriptor(VOID) { return &keyboard_layout_table; } -INT WINAPI -DllMain( - PVOID hinstDll, - ULONG dwReason, - PVOID reserved) -{ - return 1; -} - From b99bfa42f2680122ec144ccc74db704472f5e074 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 18:46:02 +0000 Subject: [PATCH 123/292] - partly revert r47442 and apply a working fix by guarding some prototypes of functions that exist as intrinsics in #ifdefs, so we don't use them for gcc/clang - remove duplicated prototypes, when an inline function exists already svn path=/trunk/; revision=47453 --- reactos/include/crt/math.h | 3 --- reactos/include/crt/mingw32/intrin_x86.h | 10 +++++----- reactos/include/crt/stdlib.h | 8 +++++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/reactos/include/crt/math.h b/reactos/include/crt/math.h index 9b645c15a51..fe4b4bc65b8 100644 --- a/reactos/include/crt/math.h +++ b/reactos/include/crt/math.h @@ -435,8 +435,6 @@ __CRT_INLINE int isinf (double d) { return res; } - extern long double __cdecl modfl (long double, long double*); - /* 7.12.6.13 */ extern double __cdecl scalbn (double, int); extern float __cdecl scalbnf (float, int); @@ -458,7 +456,6 @@ __CRT_INLINE int isinf (double d) { extern long double __cdecl expl(long double); extern long double expm1l(long double); extern long double __cdecl coshl(long double); - extern long double __cdecl fabsl (long double); extern long double __cdecl acosl(long double); extern long double __cdecl asinl(long double); extern long double __cdecl atanl(long double); diff --git a/reactos/include/crt/mingw32/intrin_x86.h b/reactos/include/crt/mingw32/intrin_x86.h index bf9470e1237..5b6f32d18a3 100644 --- a/reactos/include/crt/mingw32/intrin_x86.h +++ b/reactos/include/crt/mingw32/intrin_x86.h @@ -879,14 +879,14 @@ __INTRIN_INLINE unsigned short _rotl16(unsigned short value, unsigned char shift return retval; } -__INTRIN_INLINE unsigned int __cdecl _rotl(unsigned int value, int shift) +__INTRIN_INLINE unsigned int _rotl(unsigned int value, int shift) { unsigned long retval; __asm__("roll %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); return retval; } -__INTRIN_INLINE unsigned int __cdecl _rotr(unsigned int value, int shift) +__INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift) { unsigned long retval; __asm__("rorl %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); @@ -956,14 +956,14 @@ __INTRIN_INLINE unsigned long long __ull_rshift(const unsigned long long Mask, i return retval; } -__INTRIN_INLINE unsigned short __cdecl _byteswap_ushort(unsigned short value) +__INTRIN_INLINE unsigned short _byteswap_ushort(unsigned short value) { unsigned short retval; __asm__("rorw $8, %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value)); return retval; } -__INTRIN_INLINE unsigned long __cdecl _byteswap_ulong(unsigned long value) +__INTRIN_INLINE unsigned long _byteswap_ulong(unsigned long value) { unsigned long retval; __asm__("bswapl %[retval]" : [retval] "=r" (retval) : "[retval]" (value)); @@ -971,7 +971,7 @@ __INTRIN_INLINE unsigned long __cdecl _byteswap_ulong(unsigned long value) } #ifdef _M_AMD64 -__INTRIN_INLINE unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 value) +__INTRIN_INLINE unsigned __int64 _byteswap_uint64(unsigned __int64 value) { unsigned __int64 retval; __asm__("bswapq %[retval]" : [retval] "=r" (retval) : "[retval]" (value)); diff --git a/reactos/include/crt/stdlib.h b/reactos/include/crt/stdlib.h index d4846fa2c71..0efd5cc4321 100644 --- a/reactos/include/crt/stdlib.h +++ b/reactos/include/crt/stdlib.h @@ -345,11 +345,15 @@ extern "C" { void *__cdecl bsearch(const void *_Key,const void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); void __cdecl qsort(void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); #endif + +#if !defined(__GNUC__) && !defined(__clang) unsigned short __cdecl _byteswap_ushort(unsigned short _Short); - /*unsigned long __cdecl _byteswap_ulong (unsigned long _Long); */ + unsigned long __cdecl _byteswap_ulong (unsigned long _Long); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 _Int64); #endif +#endif + div_t __cdecl div(int _Numerator,int _Denominator); char *__cdecl getenv(const char *_VarName); _CRTIMP char *__cdecl _itoa(int _Value,char *_Dest,int _Radix); @@ -478,6 +482,7 @@ extern "C" { void __cdecl perror(const char *_ErrMsg); #endif _CRTIMP int __cdecl _putenv(const char *_EnvString); +#if !defined(__GNUC__) && !defined(__clang) unsigned int __cdecl _rotl(unsigned int _Val,int _Shift); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val,int _Shift); @@ -485,6 +490,7 @@ extern "C" { unsigned int __cdecl _rotr(unsigned int _Val,int _Shift); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _rotr64(unsigned __int64 _Val,int _Shift); +#endif #endif _CRTIMP void __cdecl _searchenv(const char *_Filename,const char *_EnvVar,char *_ResultPath); _CRTIMP void __cdecl _splitpath(const char *_FullPath,char *_Drive,char *_Dir,char *_Filename,char *_Ext); From 3f536523c1993c1faaa00415a721d49acab1b118 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 18:55:28 +0000 Subject: [PATCH 124/292] [CALC] Add units and conversion factors, patch by Andrea Maiani; nanoseconds entry added to resource files See issue #5340 for more details. svn path=/trunk/; revision=47454 --- reactos/base/applications/calc/convert.c | 145 ++++++++++--------- reactos/base/applications/calc/lang/bg-BG.rc | 1 + reactos/base/applications/calc/lang/cs-CZ.rc | 1 + reactos/base/applications/calc/lang/de-DE.rc | 1 + reactos/base/applications/calc/lang/el-GR.rc | 1 + reactos/base/applications/calc/lang/en-US.rc | 1 + reactos/base/applications/calc/lang/es-ES.rc | 1 + reactos/base/applications/calc/lang/fr-FR.rc | 1 + reactos/base/applications/calc/lang/it-IT.rc | 1 + reactos/base/applications/calc/lang/ko-KR.rc | 1 + reactos/base/applications/calc/lang/nl-NL.rc | 1 + reactos/base/applications/calc/lang/no-NO.rc | 1 + reactos/base/applications/calc/lang/pl-PL.rc | 1 + reactos/base/applications/calc/lang/ro-RO.rc | 1 + reactos/base/applications/calc/lang/ru-RU.rc | 1 + reactos/base/applications/calc/lang/sk-SK.rc | 1 + reactos/base/applications/calc/lang/th-TH.rc | 1 + reactos/base/applications/calc/lang/uk-UA.rc | 1 + reactos/base/applications/calc/resource.h | 9 +- 19 files changed, 96 insertions(+), 75 deletions(-) diff --git a/reactos/base/applications/calc/convert.c b/reactos/base/applications/calc/convert.c index c1de5558a94..26383080328 100644 --- a/reactos/base/applications/calc/convert.c +++ b/reactos/base/applications/calc/convert.c @@ -56,35 +56,35 @@ static const conv_t conv_ANGLE[] = { /* 1 acre ................ = 4840 square yd = 4046,8564224 mq - 1 acre brazil ......... = - 1 acre france ......... = + 1 acre brazil ......... = + 1 acre france ......... = 1 acre scots .......... = 5000 mq 1 acre us ............. = 4840*(36/39.37)^2 m = 6272640/1549.9969 m 1 are ................. = 100 mq 1 chou ................ = 108000*(10/33)^2 mq - 1 danbo ............... = + 1 danbo ............... = 1 ha .................. = 10000 mq - 1 jeongbo ............. = - 1 morgen hungary ...... = - 1 mu .................. = - 1 ping ................ = - 1 pyeong .............. = - 1 pyeongbangja ........ = - 1 rai ................. = + 1 jeongbo ............. = + 1 morgen hungary ...... = + 1 mu .................. = 2000/3 mq + 1 ping ................ = + 1 pyeong .............. = + 1 pyeongbangja ........ = + 1 rai ................. = 1600 mq 1 se .................. = 1080*(10/33)^2 mq 1 square cm ........... = 0.0001 mq - 1 square chr .......... = + 1 square chr .......... = 1 square fathom ....... = 1.8288^2 = 3.34450944 mq 1 square fathom hungary = 1.8964838^2 = 3.59665080366244 mq 1 square ft ........... = 0,09290304 mq 1 square in ........... = 0,00064516 mq 1 square km ........... = 1000000 mq - 1 square lar .......... = + 1 square lar .......... = 1 square mile ......... = 1609.344^2 = 2589988.110336 mq 1 square mm ........... = 0,000001 mq 1 square shaku ........ = (10/33)^2 mq - 1 square tsuen ........ = - 1 square va ........... = + 1 square tsuen ........ = + 1 square va ........... = 1 square yard ......... = 0,83612736 mq 1 tan ................. = 10800*(10/33)^2 mq 1 tsubo ............... = 36*(10/33)^2 mq @@ -101,11 +101,11 @@ static const conv_t conv_AREA[] = { DECLARE_CONV_UNIT(AREA, HECTARES, "$*10000", "$/10000") // DECLARE_CONV_UNIT(AREA, JEONGBO, "$", "$") // DECLARE_CONV_UNIT(AREA, MORGEN_HUNGARY, "$", "$") -// DECLARE_CONV_UNIT(AREA, MU, "$", "$") + DECLARE_CONV_UNIT(AREA, MU, "$*(2000/3)", "$/(2000/3)") // DECLARE_CONV_UNIT(AREA, PING, "$", "$") // DECLARE_CONV_UNIT(AREA, PYEONG, "$", "$") // DECLARE_CONV_UNIT(AREA, PYEONGBANGJA, "$", "$") -// DECLARE_CONV_UNIT(AREA, RAI, "$", "$") + DECLARE_CONV_UNIT(AREA, RAI, "$*1600", "$/1600") DECLARE_CONV_UNIT(AREA, SE, "$*108000/1089", "$*1089/108000") DECLARE_CONV_UNIT(AREA, SQUARE_CENTIMETERS, "$*0,0001", "$/0,0001") // DECLARE_CONV_UNIT(AREA, SQUARE_CHR, "$", "$") @@ -197,46 +197,47 @@ static const conv_t conv_ENERGY[] = { 1 barleycorn ..... = 1/3 inch = 0.9144/108 m 1 cm ............. = 1/100 m 1 chain uk ....... = 22 yards = 22*0.9144 m - 1 chi ............ = + 1 chi ............ = 1/3 m 1 chou ........... = 3600/33 m - 1 chr ............ = + 1 chr ............ = + 1 cun ............ = 1/10 chi = 1/30 m 1 fathom ......... = 2 yard = 2*0.9144 m 1 fathom ungary .. = 1.8964838 m (fixed) 1 feet ........... = 12 inch = 0.9144/3 m 1 furlong ........ = 10 chains = 220*0.9144 m - 1 gan ............ = + 1 gan ............ = 1 hand ........... = 4 inches = 0.9144/9 m - 1 hunh ........... = + 1 hunh ........... = 1 inch ........... = yard/36 = 0.9144/36 m - 1 ja ............. = - 1 jeong .......... = - 1 kabiet ......... = + 1 ja ............. = + 1 jeong .......... = + 1 kabiet ......... = 1 ken ............ = 60/33 m - 1 keub ........... = + 1 keub ........... = 1 km ............. = 1000 m - 1 lar ............ = + 1 lar ............ = 1 light year ..... = 9460730472580800 m 1 link uk ........ = 0.01 chains = 0.22*0.9144 m 1 micron ......... = 0.000001 m 1 mile ........... = 1760 yards = 1609.344 m 1 millimeter ..... = 1/1000 m 1 nautical mile .. = 1852 m - 1 nieu ........... = + 1 nieu ........... = 1 parsec ......... = 30856800000000000 m 1 pica ........... = yard/216 = 0.9144/216 m - 1 ri japan ....... = - 1 ri korea ....... = + 1 ri japan ....... = + 1 ri korea ....... = 1 rod ............ = 5.0292 m - 1 sawk ........... = - 1 sen ............ = + 1 sawk ........... = + 1 sen ............ = 1 shaku .......... = 10/33 m 1 span ........... = 9 inches = 0.9144/4 m - 1 sun ............ = 10/330 m - 1 tsuen .......... = - 1 va ............. = + 1 sun ............ = 1/33 m + 1 tsuen .......... = + 1 va ............. = 1 yard ........... = 0.9144 m - 1 yote ........... = - 1 zhang .......... = + 1 yote ........... = + 1 zhang .......... = */ static const conv_t conv_LENGTH[] = { DECLARE_CONV_UNIT(LENGTH, ANGSTROMS, "$*0.0000000001", "$/0.0000000001") @@ -244,10 +245,10 @@ static const conv_t conv_LENGTH[] = { DECLARE_CONV_UNIT(LENGTH, BARLEYCORNS, "$*0.9144/108", "$/0.9144*108") DECLARE_CONV_UNIT(LENGTH, CENTIMETERS, "$/100", "$*100") DECLARE_CONV_UNIT(LENGTH, CHAINS_UK, "$*20.1168", "$/20.1168") -// DECLARE_CONV_UNIT(LENGTH, CHI, "$", "$") + DECLARE_CONV_UNIT(LENGTH, CHI, "$/3", "$*3") DECLARE_CONV_UNIT(LENGTH, CHOU, "$*3600/33", "$*33/3600") // DECLARE_CONV_UNIT(LENGTH, CHR, "$", "$") -// DECLARE_CONV_UNIT(LENGTH, CUN, "$", "$") + DECLARE_CONV_UNIT(LENGTH, CUN, "$/30", "$*30") DECLARE_CONV_UNIT(LENGTH, FATHOMS, "$*1.8288", "$/1.8288") DECLARE_CONV_UNIT(LENGTH, FATHOMS_HUNGARY, "$*1.8964838", "$/1.8964838") DECLARE_CONV_UNIT(LENGTH, FEET, "$*0.3048", "$/0.3048") @@ -280,7 +281,7 @@ static const conv_t conv_LENGTH[] = { // DECLARE_CONV_UNIT(LENGTH, SEN, "$", "$") DECLARE_CONV_UNIT(LENGTH, SHAKU, "$*10/33", "$*33/10") DECLARE_CONV_UNIT(LENGTH, SPAN, "$*0.9144/4", "$*4/0.9144") - DECLARE_CONV_UNIT(LENGTH, SUN, "$*10/330", "$*330/10") + DECLARE_CONV_UNIT(LENGTH, SUN, "$*1/33", "$*33") // DECLARE_CONV_UNIT(LENGTH, TSUEN, "$", "$") // DECLARE_CONV_UNIT(LENGTH, VA, "$", "$") DECLARE_CONV_UNIT(LENGTH, YARDS, "$*0.9144", "$/0.9144") @@ -312,7 +313,7 @@ static const conv_t conv_POWER[] = { 1 hPa = 100 Pa 1 kPa = 1000 Pa 1 mm HG = 133.322 Pa - 1 psi = 6894.757 Pa + 1 psi = 6894.757 Pa */ static const conv_t conv_PRESSURE[] = { DECLARE_CONV_UNIT(PRESSURE, ATMOSPHERES, "$*101325", "$/101325") @@ -330,18 +331,20 @@ static const conv_t conv_PRESSURE[] = { 1 hour ...... = 3600 s 1 microsecond = 0.000001 s 1 millisecond = 0.001 s + 1 nanosecond. = 0.000000001 s 1 minute .... = 60 s 1 week ...... = 669600 s */ static const conv_t conv_TIME[] = { - DECLARE_CONV_UNIT(TIME, MINUTES, "$*60", "$/60") - DECLARE_CONV_UNIT(TIME, DAYS, "$*86400", "$/86400") - DECLARE_CONV_UNIT(TIME, HOURS, "$*3600", "$/3600") - DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001", "$/0.001") - DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001", "$/0.000001") - DECLARE_CONV_UNIT(TIME, SECONDS, "$", "$") - DECLARE_CONV_UNIT(TIME, WEEKS, "$*604800", "$/604800") - DECLARE_CONV_UNIT(TIME, YEARS, "$*31556952", "$/31556952") + DECLARE_CONV_UNIT(TIME, MINUTES, "$*60", "$/60") + DECLARE_CONV_UNIT(TIME, DAYS, "$*86400", "$/86400") + DECLARE_CONV_UNIT(TIME, HOURS, "$*3600", "$/3600") + DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001", "$/0.001") + DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001", "$/0.000001") + DECLARE_CONV_UNIT(TIME, NANOSECONDS, "$*0.000000001", "$/0.000000001") + DECLARE_CONV_UNIT(TIME, SECONDS, "$", "$") + DECLARE_CONV_UNIT(TIME, WEEKS, "$*604800", "$/604800") + DECLARE_CONV_UNIT(TIME, YEARS, "$*31556952", "$/31556952") DECLARE_CONV_END }; @@ -382,7 +385,7 @@ static const conv_t conv_VELOCITY[] = { /* 1 barrel uk ...... = 163.65924 l 1 barrel oil ..... = 158.987295 l - 1 bun ............ = + 1 bun ............ = 1 bushel uk ...... = 36.36872 l 1 bushel us ...... = 35.23907017 l 1 cubic cm ...... = 0.001 l @@ -390,17 +393,17 @@ static const conv_t conv_VELOCITY[] = { 1 cubic inch ..... = 0.016387064 l 1 cubic meter .... = 1000 l 1 cubic yard ..... = 764.554857 l - 1 doe ............ = + 1 doe ............ = 1 fluid ounce uk = 0.0284130625 l 1 fluid ounce us = 0.0295735295625 l 1 gallon uk ...... = 4.54609 l 1 gallon dry us .. = 4.40488377086 l 1 gallon liquid us = 3.785411784 l 1 gou ............ = 0.1809 l - 1 hop ............ = - 1 icce ........... = - 1 kwian .......... = - 1 mal ............ = + 1 hop ............ = + 1 icce ........... = + 1 kwian .......... = + 1 mal ............ = 1 milliliter ..... = 0.001 l 1 pint uk ........ = 0.56826125 l 1 pint dry us .... = 0.5506104713575 l @@ -408,10 +411,10 @@ static const conv_t conv_VELOCITY[] = { 1 quart uk ....... = 1.1365225 l 1 quart dry us ... = 1.101220942715 l 1 quart liquid us = 0.946352946 l - 1 seki ........... = - 1 syou ........... = - 1 tananloung ..... = - 1 tang ........... = + 1 seki ........... = + 1 syou ........... = + 1 tananloung ..... = + 1 tang ........... = 1 to ............. = 18040 l */ static const conv_t conv_VOLUME[] = { @@ -455,16 +458,16 @@ static const conv_t conv_VOLUME[] = { /* 1 baht ............ = 12.244 g 1 carat ........... = 0.2 g - 1 chung ........... = - 1 don ............. = - 1 geun ............ = - 1 gwan ............ = - 1 harb ............ = - 1 jin china ....... = - 1 jin taiwan ...... = - 1 Kan ............. = + 1 chung ........... = + 1 don ............. = + 1 geun ............ = + 1 gwan ............ = + 1 harb ............ = + 1 jin china ....... = + 1 jin taiwan ...... = + 1 Kan ............. = 3750 g 1 Kilograms ....... = 1000 g - 1 Kin ............. = + 1 Kin ............. = 600 g 1 Liang China ..... = 1 Liang Taiwan .... = 1 monme ........... = 3.75 g @@ -472,9 +475,9 @@ static const conv_t conv_VOLUME[] = { 1 ounce troy ...... = 31.1034768 g 1 pound ........... = 453.59237 g 1 quintal metric .. = 100000 g - 1 saloung ......... = + 1 saloung ......... = 1 stone ........... = 6350.29318 g - 1 tamlung ......... = + 1 tamlung ......... = 1 ton ............. = 1000000 g 1 ton uk .......... = 1016046.9088 g // long ton 1 ton us .......... = 907184.74 g // short ton @@ -490,9 +493,9 @@ static const conv_t conv_WEIGHT[] = { // DECLARE_CONV_UNIT(WEIGHT, HARB, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, JIN_CHINA, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, JIN_TAIWAN, "$", "$") -// DECLARE_CONV_UNIT(WEIGHT, KAN, "$", "$") + DECLARE_CONV_UNIT(WEIGHT, KAN, "$*3750", "$/3750") DECLARE_CONV_UNIT(WEIGHT, KILOGRAMS, "$*1000", "$/1000") -// DECLARE_CONV_UNIT(WEIGHT, KIN, "$", "$") + DECLARE_CONV_UNIT(WEIGHT, KIN, "$*600", "$/600") // DECLARE_CONV_UNIT(WEIGHT, LIANG_CHINA, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, LIANG_TAIWAN, "$", "$") DECLARE_CONV_UNIT(WEIGHT, MONME, "$*3.75", "$/3.75") @@ -548,7 +551,7 @@ void ConvExecute(HWND hWnd) break; } } - + /* The units can be sorted, so I must search the exact match */ item = items; SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETLBTEXT, from, (LPARAM)txt_cb); diff --git a/reactos/base/applications/calc/lang/bg-BG.rc b/reactos/base/applications/calc/lang/bg-BG.rc index dc9faab1628..19f411df033 100644 --- a/reactos/base/applications/calc/lang/bg-BG.rc +++ b/reactos/base/applications/calc/lang/bg-BG.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Äíè" IDS_TIME_HOURS "×àñè" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Ìèêðîñåêóíäè" IDS_TIME_MILLISECONDS "Ìèëèñåêóíäè" IDS_TIME_MINUTES "Ìèíóòè" diff --git a/reactos/base/applications/calc/lang/cs-CZ.rc b/reactos/base/applications/calc/lang/cs-CZ.rc index 278cc562783..c1f842282de 100644 --- a/reactos/base/applications/calc/lang/cs-CZ.rc +++ b/reactos/base/applications/calc/lang/cs-CZ.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dny" IDS_TIME_HOURS "Hodiny" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Mikrosekundy" IDS_TIME_MILLISECONDS "Milisekundy" IDS_TIME_MINUTES "Minuty" diff --git a/reactos/base/applications/calc/lang/de-DE.rc b/reactos/base/applications/calc/lang/de-DE.rc index f6513aa6dfe..d3aa5436a8f 100644 --- a/reactos/base/applications/calc/lang/de-DE.rc +++ b/reactos/base/applications/calc/lang/de-DE.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Tagen" IDS_TIME_HOURS "Stunden" + IDS_TIME_NANOSECONDS "Nanosekunden" IDS_TIME_MICROSECONDS "Mikrosekunden" IDS_TIME_MILLISECONDS "Millisekunden" IDS_TIME_MINUTES "Minuten" diff --git a/reactos/base/applications/calc/lang/el-GR.rc b/reactos/base/applications/calc/lang/el-GR.rc index 89ce2d13c64..5f88a9465e1 100644 --- a/reactos/base/applications/calc/lang/el-GR.rc +++ b/reactos/base/applications/calc/lang/el-GR.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "ÌÝñåò" IDS_TIME_HOURS "¿ñåò" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Ìéêñïäåõôåñüëåðôá" IDS_TIME_MILLISECONDS "Ìéëéäåõôåñüëåðôá" IDS_TIME_MINUTES "ËåðôÜ" diff --git a/reactos/base/applications/calc/lang/en-US.rc b/reactos/base/applications/calc/lang/en-US.rc index 756244ef64b..402991ab06d 100644 --- a/reactos/base/applications/calc/lang/en-US.rc +++ b/reactos/base/applications/calc/lang/en-US.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/reactos/base/applications/calc/lang/es-ES.rc b/reactos/base/applications/calc/lang/es-ES.rc index faba06c0b03..88e89a384fe 100644 --- a/reactos/base/applications/calc/lang/es-ES.rc +++ b/reactos/base/applications/calc/lang/es-ES.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Días" IDS_TIME_HOURS "Horas" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsegundos" IDS_TIME_MILLISECONDS "Milisegundos" IDS_TIME_MINUTES "Minutos" diff --git a/reactos/base/applications/calc/lang/fr-FR.rc b/reactos/base/applications/calc/lang/fr-FR.rc index 4cd589992cb..8536cdb8d9d 100644 --- a/reactos/base/applications/calc/lang/fr-FR.rc +++ b/reactos/base/applications/calc/lang/fr-FR.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Jours" IDS_TIME_HOURS "Heures" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsecondes" IDS_TIME_MILLISECONDS "Millisecondes" IDS_TIME_MINUTES "Minutes" diff --git a/reactos/base/applications/calc/lang/it-IT.rc b/reactos/base/applications/calc/lang/it-IT.rc index 0294303512a..fb0f8b6c12f 100644 --- a/reactos/base/applications/calc/lang/it-IT.rc +++ b/reactos/base/applications/calc/lang/it-IT.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Giorni" IDS_TIME_HOURS "Ore" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsecondi" IDS_TIME_MILLISECONDS "Millisecondi" IDS_TIME_MINUTES "Minuti" diff --git a/reactos/base/applications/calc/lang/ko-KR.rc b/reactos/base/applications/calc/lang/ko-KR.rc index 51d70687527..8ab51ed6496 100644 --- a/reactos/base/applications/calc/lang/ko-KR.rc +++ b/reactos/base/applications/calc/lang/ko-KR.rc @@ -643,6 +643,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/reactos/base/applications/calc/lang/nl-NL.rc b/reactos/base/applications/calc/lang/nl-NL.rc index 510352f6ee2..bad67ab7a32 100644 --- a/reactos/base/applications/calc/lang/nl-NL.rc +++ b/reactos/base/applications/calc/lang/nl-NL.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dagen" IDS_TIME_HOURS "Uren" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconden" IDS_TIME_MILLISECONDS "Milliseconden" IDS_TIME_MINUTES "Minuten" diff --git a/reactos/base/applications/calc/lang/no-NO.rc b/reactos/base/applications/calc/lang/no-NO.rc index 3bb0857dc8e..8e590be8ac3 100644 --- a/reactos/base/applications/calc/lang/no-NO.rc +++ b/reactos/base/applications/calc/lang/no-NO.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "**" IDS_TIME_HOURS "**" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "**" IDS_TIME_MILLISECONDS "**" IDS_TIME_MINUTES "**" diff --git a/reactos/base/applications/calc/lang/pl-PL.rc b/reactos/base/applications/calc/lang/pl-PL.rc index 8fdfa4bdad9..fac1f7975af 100644 --- a/reactos/base/applications/calc/lang/pl-PL.rc +++ b/reactos/base/applications/calc/lang/pl-PL.rc @@ -646,6 +646,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dni" IDS_TIME_HOURS "Godzin" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Mikrosekund" IDS_TIME_MILLISECONDS "Milisekund" IDS_TIME_MINUTES "Minut" diff --git a/reactos/base/applications/calc/lang/ro-RO.rc b/reactos/base/applications/calc/lang/ro-RO.rc index 1680780befb..4c353ea9c0f 100644 --- a/reactos/base/applications/calc/lang/ro-RO.rc +++ b/reactos/base/applications/calc/lang/ro-RO.rc @@ -641,6 +641,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Zile" IDS_TIME_HOURS "Ore" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsecunde" IDS_TIME_MILLISECONDS "Milisecunde" IDS_TIME_MINUTES "Minute" diff --git a/reactos/base/applications/calc/lang/ru-RU.rc b/reactos/base/applications/calc/lang/ru-RU.rc index 63b478b2f33..6d2d41c3612 100644 --- a/reactos/base/applications/calc/lang/ru-RU.rc +++ b/reactos/base/applications/calc/lang/ru-RU.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "äåíü" IDS_TIME_HOURS "÷àñ" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "ìèêðîñåêóíäà" IDS_TIME_MILLISECONDS "ìèëëèñåêóíäà" IDS_TIME_MINUTES "ìèíóòà" diff --git a/reactos/base/applications/calc/lang/sk-SK.rc b/reactos/base/applications/calc/lang/sk-SK.rc index 3f93b953ef0..4951a860320 100644 --- a/reactos/base/applications/calc/lang/sk-SK.rc +++ b/reactos/base/applications/calc/lang/sk-SK.rc @@ -647,6 +647,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dni" IDS_TIME_HOURS "Hodiny" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Mikrosekundy" IDS_TIME_MILLISECONDS "Milisekundy" IDS_TIME_MINUTES "Minúty" diff --git a/reactos/base/applications/calc/lang/th-TH.rc b/reactos/base/applications/calc/lang/th-TH.rc index 214bd80b185..ade4a12b17e 100644 --- a/reactos/base/applications/calc/lang/th-TH.rc +++ b/reactos/base/applications/calc/lang/th-TH.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/reactos/base/applications/calc/lang/uk-UA.rc b/reactos/base/applications/calc/lang/uk-UA.rc index b4c7f19c933..9d73142142a 100644 --- a/reactos/base/applications/calc/lang/uk-UA.rc +++ b/reactos/base/applications/calc/lang/uk-UA.rc @@ -647,6 +647,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Äîáà" IDS_TIME_HOURS "Ãîäèíà" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "̳êðîñåêóíäà" IDS_TIME_MILLISECONDS "̳ë³ñåêóíäà" IDS_TIME_MINUTES "Õâèëèíà" diff --git a/reactos/base/applications/calc/resource.h b/reactos/base/applications/calc/resource.h index 1886cc74109..8039671361e 100644 --- a/reactos/base/applications/calc/resource.h +++ b/reactos/base/applications/calc/resource.h @@ -276,10 +276,11 @@ #define IDS_TIME_HOURS 3002 #define IDS_TIME_MICROSECONDS 3003 #define IDS_TIME_MILLISECONDS 3004 -#define IDS_TIME_MINUTES 3005 -#define IDS_TIME_SECONDS 3006 -#define IDS_TIME_WEEKS 3007 -#define IDS_TIME_YEARS 3008 +#define IDS_TIME_NANOSECONDS 3005 +#define IDS_TIME_MINUTES 3006 +#define IDS_TIME_SECONDS 3007 +#define IDS_TIME_WEEKS 3008 +#define IDS_TIME_YEARS 3009 /* TYPES OF VELOCITIES */ #define IDS_VELOCITY_CMS_SECOND 3100 From 2e0bbab8ca50140b1365c5906d41a3ac92738f34 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 30 May 2010 19:37:27 +0000 Subject: [PATCH 125/292] [KMTEST] cast the unused 0 in the ok macro to void to make clang happy as done for wine test.h svn path=/trunk/; revision=47455 --- rostests/drivers/kmtest/kmtest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rostests/drivers/kmtest/kmtest.h b/rostests/drivers/kmtest/kmtest.h index c244d303841..f57e85d3eb9 100644 --- a/rostests/drivers/kmtest/kmtest.h +++ b/rostests/drivers/kmtest/kmtest.h @@ -44,7 +44,7 @@ extern int kmtest_ok( int condition, const char *msg, ... ); #endif /* __GNUC__ */ -#define ok_(file, line) (kmtest_set_location(file, line), 0) ? 0 : kmtest_ok +#define ok_(file, line) (kmtest_set_location(file, line), 0) ? (void)0 : kmtest_ok #define ok ok_(__FILE__, __LINE__) PDEVICE_OBJECT AttachDeviceObject; From dfc4dcb9b5c30a1de568eb82677763743dc663f1 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 30 May 2010 19:46:02 +0000 Subject: [PATCH 126/292] [NTOSKRNL] Make NtDuplicateToken fail if the caller tries to create a new impersonation token with a raised impersonation level. This fixes a winetest. svn path=/trunk/; revision=47456 --- reactos/ntoskrnl/se/token.c | 76 ++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 30f7fc84bef..04fe7c2a5b0 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1844,39 +1844,61 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, PreviousMode, (PVOID*)&Token, NULL); + if (!NT_SUCCESS(Status)) + { + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return Status; + } + + /* + * Fail, if the original token is an impersonation token and the caller + * tries to raise the impersonation level of the new token above the + * impersonation level of the original token. + */ + if (Token->TokenType == TokenImpersonation) + { + if (QoSPresent && + CapturedSecurityQualityOfService->ImpersonationLevel >Token->ImpersonationLevel) + { + ObDereferenceObject(Token); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + } + + Status = SepDuplicateToken(Token, + ObjectAttributes, + EffectiveOnly, + TokenType, + (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), + PreviousMode, + &NewToken); + + ObDereferenceObject(Token); + if (NT_SUCCESS(Status)) { - Status = SepDuplicateToken(Token, - ObjectAttributes, - EffectiveOnly, - TokenType, - (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), - PreviousMode, - &NewToken); - - ObDereferenceObject(Token); - + Status = ObInsertObject((PVOID)NewToken, + NULL, + DesiredAccess, + 0, + NULL, + &hToken); if (NT_SUCCESS(Status)) { - Status = ObInsertObject((PVOID)NewToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - - if (NT_SUCCESS(Status)) + _SEH2_TRY { - _SEH2_TRY - { - *NewTokenHandle = hToken; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; + *NewTokenHandle = hToken; } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; } } From d27f068a199d9ea217e3ae9145d6e3ccfecde54f Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 30 May 2010 20:00:17 +0000 Subject: [PATCH 127/292] [FORMATTING] Standardize win32csr to 4-space indents. Based on a patch by Adam Kachwalla [Bug 5380]. No code changes. svn path=/trunk/; revision=47457 --- .../subsystems/win32/csrss/win32csr/alias.c | 182 +- .../win32/csrss/win32csr/appswitch.c | 170 +- .../subsystems/win32/csrss/win32csr/conio.c | 3445 +++++++++-------- .../win32/csrss/win32csr/desktopbg.c | 104 +- .../subsystems/win32/csrss/win32csr/dllmain.c | 46 +- .../subsystems/win32/csrss/win32csr/exitros.c | 998 ++--- .../win32/csrss/win32csr/guiconsole.c | 2176 +++++------ .../subsystems/win32/csrss/win32csr/handle.c | 6 +- .../win32/csrss/win32csr/harderror.c | 102 +- .../win32/csrss/win32csr/tuiconsole.c | 446 +-- 10 files changed, 3838 insertions(+), 3837 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/alias.c b/reactos/subsystems/win32/csrss/win32csr/alias.c index 1432be1be53..569948a4f41 100644 --- a/reactos/subsystems/win32/csrss/win32csr/alias.c +++ b/reactos/subsystems/win32/csrss/win32csr/alias.c @@ -5,7 +5,7 @@ * PURPOSE: CSRSS alias support functions * COPYRIGHT: Christoph Wittich * Johannes Anderwald - * + * */ @@ -17,10 +17,10 @@ typedef struct tagALIAS_ENTRY { - LPCWSTR lpSource; - LPCWSTR lpTarget; - struct tagALIAS_ENTRY * Next; -}ALIAS_ENTRY, *PALIAS_ENTRY; + LPCWSTR lpSource; + LPCWSTR lpTarget; + struct tagALIAS_ENTRY * Next; +} ALIAS_ENTRY, *PALIAS_ENTRY; typedef struct tagALIAS_HEADER @@ -29,7 +29,7 @@ typedef struct tagALIAS_HEADER PALIAS_ENTRY Data; struct tagALIAS_HEADER * Next; -}ALIAS_HEADER, *PALIAS_HEADER; +} ALIAS_HEADER, *PALIAS_HEADER; /* Ensure that a buffer is contained within the process's shared memory section. */ static BOOL @@ -37,10 +37,10 @@ ValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, ULONG Size) { ULONG Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; if (Offset >= ProcessData->CsrSectionViewSize - || Size > (ProcessData->CsrSectionViewSize - Offset)) + || Size > (ProcessData->CsrSectionViewSize - Offset)) { DPRINT1("Invalid buffer %p %d; not within %p %d\n", - Buffer, Size, ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); + Buffer, Size, ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); return FALSE; } return TRUE; @@ -67,38 +67,38 @@ IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName) PALIAS_HEADER IntCreateAliasHeader(LPCWSTR lpExeName) { - PALIAS_HEADER Entry; - UINT dwLength = wcslen(lpExeName) + 1; + PALIAS_HEADER Entry; + UINT dwLength = wcslen(lpExeName) + 1; - Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength); - if (!Entry) - return Entry; - - Entry->lpExeName = (LPCWSTR)(Entry + 1); - wcscpy((WCHAR*)Entry->lpExeName, lpExeName); - Entry->Data = NULL; - Entry->Next = NULL; - return Entry; + Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength); + if (!Entry) + return Entry; + + Entry->lpExeName = (LPCWSTR)(Entry + 1); + wcscpy((WCHAR*)Entry->lpExeName, lpExeName); + Entry->Data = NULL; + Entry->Next = NULL; + return Entry; } VOID IntInsertAliasHeader(PALIAS_HEADER * RootHeader, PALIAS_HEADER NewHeader) { - PALIAS_HEADER CurrentHeader; - PALIAS_HEADER *LastLink = RootHeader; + PALIAS_HEADER CurrentHeader; + PALIAS_HEADER *LastLink = RootHeader; - while ((CurrentHeader = *LastLink) != NULL) - { - INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName); - if (Diff < 0) - { - break; - } - LastLink = &CurrentHeader->Next; - } + while ((CurrentHeader = *LastLink) != NULL) + { + INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName); + if (Diff < 0) + { + break; + } + LastLink = &CurrentHeader->Next; + } - *LastLink = NewHeader; - NewHeader->Next = CurrentHeader; + *LastLink = NewHeader; + NewHeader->Next = CurrentHeader; } PALIAS_ENTRY @@ -130,60 +130,60 @@ IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName) VOID IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry) { - PALIAS_ENTRY CurrentEntry; - PALIAS_ENTRY *LastLink = &Header->Data; + PALIAS_ENTRY CurrentEntry; + PALIAS_ENTRY *LastLink = &Header->Data; - while ((CurrentEntry = *LastLink) != NULL) - { - INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource); - if (Diff < 0) + while ((CurrentEntry = *LastLink) != NULL) { - break; + INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource); + if (Diff < 0) + { + break; + } + LastLink = &CurrentEntry->Next; } - LastLink = &CurrentEntry->Next; - } - *LastLink = NewEntry; - NewEntry->Next = CurrentEntry; + *LastLink = NewEntry; + NewEntry->Next = CurrentEntry; } PALIAS_ENTRY IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget) { - UINT dwSource; - UINT dwTarget; - PALIAS_ENTRY Entry; + UINT dwSource; + UINT dwTarget; + PALIAS_ENTRY Entry; - dwSource = wcslen(lpSource) + 1; - dwTarget = wcslen(lpTarget) + 1; + dwSource = wcslen(lpSource) + 1; + dwTarget = wcslen(lpTarget) + 1; - Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget)); - if (!Entry) - return Entry; + Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget)); + if (!Entry) + return Entry; - Entry->lpSource = (LPCWSTR)(Entry + 1); - wcscpy((LPWSTR)Entry->lpSource, lpSource); - Entry->lpTarget = Entry->lpSource + dwSource; - wcscpy((LPWSTR)Entry->lpTarget, lpTarget); - Entry->Next = NULL; + Entry->lpSource = (LPCWSTR)(Entry + 1); + wcscpy((LPWSTR)Entry->lpSource, lpSource); + Entry->lpTarget = Entry->lpSource + dwSource; + wcscpy((LPWSTR)Entry->lpTarget, lpTarget); + Entry->Next = NULL; - return Entry; + return Entry; } UINT IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader) { - UINT length = 0; + UINT length = 0; - while(RootHeader) - { - length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR); - RootHeader = RootHeader->Next; - } - if (length) - length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes + while(RootHeader) + { + length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR); + RootHeader = RootHeader->Next; + } + if (length) + length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes - return length; + return length; } UINT @@ -215,22 +215,22 @@ IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT Tar UINT IntGetAllConsoleAliasesLength(PALIAS_HEADER Header) { - UINT Length = 0; - PALIAS_ENTRY CurEntry = Header->Data; + UINT Length = 0; + PALIAS_ENTRY CurEntry = Header->Data; - while(CurEntry) - { - Length += wcslen(CurEntry->lpSource); - Length += wcslen(CurEntry->lpTarget); - Length += 2; // zero byte and '=' - CurEntry = CurEntry->Next; - } + while(CurEntry) + { + Length += wcslen(CurEntry->lpSource); + Length += wcslen(CurEntry->lpTarget); + Length += 2; // zero byte and '=' + CurEntry = CurEntry->Next; + } - if (Length) - { - return (Length+1) * sizeof(WCHAR); - } - return 0; + if (Length) + { + return (Length+1) * sizeof(WCHAR); + } + return 0; } UINT IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength) @@ -316,7 +316,7 @@ CSR_API(CsrAddConsoleAlias) { return STATUS_INVALID_PARAMETER; } - + Request->Status = ConioConsoleFromProcessData(ProcessData, &Console); if (!NT_SUCCESS(Request->Status)) { @@ -379,11 +379,11 @@ CSR_API(CsrGetConsoleAlias) lpTarget = Request->Data.GetConsoleAlias.TargetBuffer; - DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n", - lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength); - - if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL || - Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0) + DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n", + lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength); + + if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL || + Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0) { return STATUS_INVALID_PARAMETER; } @@ -465,7 +465,7 @@ CSR_API(CsrGetAllConsoleAliases) return STATUS_ACCESS_VIOLATION; } - BytesWritten = IntGetAllConsoleAliases(Header, + BytesWritten = IntGetAllConsoleAliases(Header, Request->Data.GetAllConsoleAlias.AliasBuffer, Request->Data.GetAllConsoleAlias.AliasBufferLength); @@ -509,7 +509,7 @@ CSR_API(CsrGetConsoleAliasesExes) PCSRSS_CONSOLE Console; UINT BytesWritten; UINT ExesLength; - + DPRINT("CsrGetConsoleAliasesExes entered\n"); Request->Status = ConioConsoleFromProcessData(ProcessData, &Console); @@ -519,7 +519,7 @@ CSR_API(CsrGetConsoleAliasesExes) } ExesLength = IntGetConsoleAliasesExesLength(Console->Aliases); - + if (ExesLength > Request->Data.GetConsoleAliasesExes.Length) { ConioUnlockConsole(Console); @@ -531,7 +531,7 @@ CSR_API(CsrGetConsoleAliasesExes) ConioUnlockConsole(Console); return STATUS_INVALID_PARAMETER; } - + if (!ValidateBuffer(ProcessData, Request->Data.GetConsoleAliasesExes.ExeNames, Request->Data.GetConsoleAliasesExes.Length)) @@ -540,7 +540,7 @@ CSR_API(CsrGetConsoleAliasesExes) return STATUS_ACCESS_VIOLATION; } - BytesWritten = IntGetConsoleAliasesExes(Console->Aliases, + BytesWritten = IntGetConsoleAliasesExes(Console->Aliases, Request->Data.GetConsoleAliasesExes.ExeNames, Request->Data.GetConsoleAliasesExes.Length); diff --git a/reactos/subsystems/win32/csrss/win32csr/appswitch.c b/reactos/subsystems/win32/csrss/win32csr/appswitch.c index 3d372a199f1..f816a8303ad 100644 --- a/reactos/subsystems/win32/csrss/win32csr/appswitch.c +++ b/reactos/subsystems/win32/csrss/win32csr/appswitch.c @@ -19,7 +19,7 @@ typedef struct APPSWITCH_ITEM BOOL bFocus; struct APPSWITCH_ITEM * Next; WCHAR szText[1]; -}APPSWITCH_ITEM, *PAPPSWITCH_ITEM; +} APPSWITCH_ITEM, *PAPPSWITCH_ITEM; static PAPPSWITCH_ITEM pRoot = NULL; static DWORD NumOfWindows = 0; @@ -30,7 +30,7 @@ UINT WINAPI PrivateExtractIconExW(LPCWSTR,int,HICON*,HICON*,UINT); BOOL -CALLBACK +CALLBACK EnumWindowEnumProc( HWND hwnd, LPARAM lParam @@ -51,21 +51,21 @@ EnumWindowEnumProc( hIcon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0); if (!hIcon) { - GetWindowThreadProcessId(hwnd, &dwPid); - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwPid); - if (hProcess) - { - if (GetModuleFileNameExW(hProcess, NULL, szFileName, MAX_PATH)) - { - szFileName[MAX_PATH-1] = L'\0'; - PrivateExtractIconExW(szFileName, 0, &hIcon, NULL, 1); - } - } + GetWindowThreadProcessId(hwnd, &dwPid); + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwPid); + if (hProcess) + { + if (GetModuleFileNameExW(hProcess, NULL, szFileName, MAX_PATH)) + { + szFileName[MAX_PATH-1] = L'\0'; + PrivateExtractIconExW(szFileName, 0, &hIcon, NULL, 1); + } + } } else { - /* icons from WM_GETICON need to be copied */ - hIcon = CopyIcon(hIcon); + /* icons from WM_GETICON need to be copied */ + hIcon = CopyIcon(hIcon); } /* get the text length */ Length = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); @@ -88,9 +88,9 @@ EnumWindowEnumProc( if (!pRoot) { - /* first item */ - pRoot = pItem; - return TRUE; + /* first item */ + pRoot = pItem; + return TRUE; } /* enumerate the last item */ @@ -107,16 +107,16 @@ EnumWindowEnumProc( VOID EnumerateAppWindows(HDESK hDesk, HWND hwndDlg) { - /* initialize defaults */ - pRoot = NULL; - NumOfWindows = 0; - hAppWindowDlg = hwndDlg; - /* enumerate all windows */ - EnumDesktopWindows(hDesk, EnumWindowEnumProc, (LPARAM)NULL); - if (NumOfWindows > 7) - { - /* FIXME resize window */ - } + /* initialize defaults */ + pRoot = NULL; + NumOfWindows = 0; + hAppWindowDlg = hwndDlg; + /* enumerate all windows */ + EnumDesktopWindows(hDesk, EnumWindowEnumProc, (LPARAM)NULL); + if (NumOfWindows > 7) + { + /* FIXME resize window */ + } } VOID @@ -126,7 +126,7 @@ MarkNextEntryAsActive() pItem = pRoot; if (!pRoot) - return; + return; while(pItem) { @@ -153,82 +153,82 @@ KeyboardHookProc( LPARAM lParam ) { - PKBDLLHOOKSTRUCT hk = (PKBDLLHOOKSTRUCT) lParam; + PKBDLLHOOKSTRUCT hk = (PKBDLLHOOKSTRUCT) lParam; - if (wParam == WM_SYSKEYUP) - { - /* is tab key pressed */ - if (hk->vkCode == VK_TAB) - { - if (hAppWindowDlg == NULL) - { - /* FIXME - * launch window - */ - DPRINT1("launch alt-tab window\n"); - } - else - { - MarkNextEntryAsActive(); - } - } - } - return CallNextHookEx(hhk, nCode, wParam, lParam); + if (wParam == WM_SYSKEYUP) + { + /* is tab key pressed */ + if (hk->vkCode == VK_TAB) + { + if (hAppWindowDlg == NULL) + { + /* FIXME + * launch window + */ + DPRINT1("launch alt-tab window\n"); + } + else + { + MarkNextEntryAsActive(); + } + } + } + return CallNextHookEx(hhk, nCode, wParam, lParam); } VOID PaintAppWindows(HWND hwndDlg, HDC hDc) { - DWORD dwIndex, X, Y; - PAPPSWITCH_ITEM pCurItem; - RECT Rect; - DWORD XSize, YSize, XMax; - HBRUSH hBrush; + DWORD dwIndex, X, Y; + PAPPSWITCH_ITEM pCurItem; + RECT Rect; + DWORD XSize, YSize, XMax; + HBRUSH hBrush; - X = 10; - Y = 10; - XSize = GetSystemMetrics(SM_CXICON); - YSize = GetSystemMetrics(SM_CYICON); - XMax = (XSize+(XSize/2)) * 7 + X; - pCurItem = pRoot; + X = 10; + Y = 10; + XSize = GetSystemMetrics(SM_CXICON); + YSize = GetSystemMetrics(SM_CYICON); + XMax = (XSize+(XSize/2)) * 7 + X; + pCurItem = pRoot; - for (dwIndex = 0; dwIndex < NumOfWindows; dwIndex++) - { - if (X >= XMax) - { - X = 10; - Y += YSize + (YSize/2); - } - if (pCurItem->bFocus) - { + for (dwIndex = 0; dwIndex < NumOfWindows; dwIndex++) + { + if (X >= XMax) + { + X = 10; + Y += YSize + (YSize/2); + } + if (pCurItem->bFocus) + { hBrush = CreateSolidBrush(RGB(30, 30, 255)); SetRect(&Rect, X-5, Y-5, X + XSize + 5, Y + YSize + 5); FillRect(hDc, &Rect, hBrush); DeleteObject((HGDIOBJ)hBrush); SendDlgItemMessageW(hwndDlg, IDC_STATIC_CUR_APP, WM_SETTEXT, 0, (LPARAM)pCurItem->szText); - } + } - DrawIcon(hDc, X, Y, pCurItem->hIcon); - pCurItem = pCurItem->Next; - X += XSize +(XSize/2); - } + DrawIcon(hDc, X, Y, pCurItem->hIcon); + pCurItem = pCurItem->Next; + X += XSize +(XSize/2); + } } VOID DestroyAppWindows() { - PAPPSWITCH_ITEM pCurItem, pNextItem; + PAPPSWITCH_ITEM pCurItem, pNextItem; - pCurItem = pRoot; - while(pCurItem) - { - pNextItem = pCurItem->Next; - DestroyIcon(pCurItem->hIcon); - HeapFree(Win32CsrApiHeap, 0, pCurItem); - pCurItem = pNextItem; - } - pRoot = NULL; - hAppWindowDlg = NULL; - NumOfWindows = 0; + pCurItem = pRoot; + while(pCurItem) + { + pNextItem = pCurItem->Next; + DestroyIcon(pCurItem->hIcon); + HeapFree(Win32CsrApiHeap, 0, pCurItem); + pCurItem = pNextItem; + } + pRoot = NULL; + hAppWindowDlg = NULL; + NumOfWindows = 0; } INT_PTR diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 51e320fdcef..f3a15157db0 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -15,25 +15,25 @@ /* GLOBALS *******************************************************************/ #define ConioInitRect(Rect, top, left, bottom, right) \ - ((Rect)->Top) = top; \ - ((Rect)->Left) = left; \ - ((Rect)->Bottom) = bottom; \ - ((Rect)->Right) = right + ((Rect)->Top) = top; \ + ((Rect)->Left) = left; \ + ((Rect)->Bottom) = bottom; \ + ((Rect)->Right) = right #define ConioIsRectEmpty(Rect) \ - (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) + (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) #define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) + MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) #define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) #define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) + MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) /* FUNCTIONS *****************************************************************/ @@ -41,72 +41,72 @@ NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) { - PCSRSS_CONSOLE ProcessConsole; + PCSRSS_CONSOLE ProcessConsole; - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - ProcessConsole = ProcessData->Console; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + ProcessConsole = ProcessData->Console; - if (!ProcessConsole) + if (!ProcessConsole) { - *Console = NULL; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; + *Console = NULL; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; } - InterlockedIncrement(&ProcessConsole->ReferenceCount); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - EnterCriticalSection(&(ProcessConsole->Lock)); - *Console = ProcessConsole; + InterlockedIncrement(&ProcessConsole->ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + EnterCriticalSection(&(ProcessConsole->Lock)); + *Console = ProcessConsole; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout) { - HANDLE Thread; + HANDLE Thread; - DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); + DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); - if (ProcessData->CtrlDispatcher) + if (ProcessData->CtrlDispatcher) { - Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, - (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, - UlongToPtr(Event), 0, NULL); - if (NULL == Thread) + Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, + (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, + UlongToPtr(Event), 0, NULL); + if (NULL == Thread) { - DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); - return; + DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); + return; } - WaitForSingleObject(Thread, Timeout); - CloseHandle(Thread); + WaitForSingleObject(Thread, Timeout); + CloseHandle(Thread); } } VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData) { - ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); + ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); } PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y) { - return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; + return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; } static VOID FASTCALL ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff) { - PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); - UINT Pos; + PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); + UINT Pos; - for (Pos = 0; Pos < Buff->MaxX; Pos++) + for (Pos = 0; Pos < Buff->MaxX; Pos++) { - /* Fill the cell */ - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; + /* Fill the cell */ + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; } } @@ -114,130 +114,130 @@ static NTSTATUS FASTCALL CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); + DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); - Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; - Buffer->Header.Console = Console; - Buffer->Header.HandleCount = 0; - Buffer->ShowX = 0; - Buffer->ShowY = 0; - Buffer->VirtualY = 0; - Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); - if (NULL == Buffer->Buffer) + Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; + Buffer->Header.Console = Console; + Buffer->Header.HandleCount = 0; + Buffer->ShowX = 0; + Buffer->ShowY = 0; + Buffer->VirtualY = 0; + Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); + if (NULL == Buffer->Buffer) { - return STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; } - ConioInitScreenBuffer(Console, Buffer); - /* initialize buffer to be empty with default attributes */ - for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) + ConioInitScreenBuffer(Console, Buffer); + /* initialize buffer to be empty with default attributes */ + for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) { - ClearLineBuffer(Buffer); + ClearLineBuffer(Buffer); } - Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; - Buffer->CurrentX = 0; - Buffer->CurrentY = 0; + Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + Buffer->CurrentX = 0; + Buffer->CurrentY = 0; - InsertHeadList(&Console->BufferList, &Buffer->ListEntry); - return STATUS_SUCCESS; + InsertHeadList(&Console->BufferList, &Buffer->ListEntry); + return STATUS_SUCCESS; } static NTSTATUS WINAPI CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { - NTSTATUS Status; - SECURITY_ATTRIBUTES SecurityAttributes; - PCSRSS_SCREEN_BUFFER NewBuffer; - BOOL GuiMode; + NTSTATUS Status; + SECURITY_ATTRIBUTES SecurityAttributes; + PCSRSS_SCREEN_BUFFER NewBuffer; + BOOL GuiMode; - Console->Title.MaximumLength = Console->Title.Length = 0; - Console->Title.Buffer = NULL; + Console->Title.MaximumLength = Console->Title.Length = 0; + Console->Title.Buffer = NULL; - //FIXME - RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); + //FIXME + RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); - Console->ReferenceCount = 0; - Console->WaitingChars = 0; - Console->WaitingLines = 0; - Console->EchoCount = 0; - Console->Header.Type = CONIO_CONSOLE_MAGIC; - Console->Header.Console = Console; - Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - Console->EarlyReturn = FALSE; - InitializeListHead(&Console->BufferList); - Console->ActiveBuffer = NULL; - InitializeListHead(&Console->InputEvents); - Console->CodePage = GetOEMCP(); - Console->OutputCodePage = GetOEMCP(); + Console->ReferenceCount = 0; + Console->WaitingChars = 0; + Console->WaitingLines = 0; + Console->EchoCount = 0; + Console->Header.Type = CONIO_CONSOLE_MAGIC; + Console->Header.Console = Console; + Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; + Console->EarlyReturn = FALSE; + InitializeListHead(&Console->BufferList); + Console->ActiveBuffer = NULL; + InitializeListHead(&Console->InputEvents); + Console->CodePage = GetOEMCP(); + Console->OutputCodePage = GetOEMCP(); - SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - SecurityAttributes.lpSecurityDescriptor = NULL; - SecurityAttributes.bInheritHandle = TRUE; + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = TRUE; - Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); - if (NULL == Console->ActiveEvent) + Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); + if (NULL == Console->ActiveEvent) { - RtlFreeUnicodeString(&Console->Title); - return STATUS_UNSUCCESSFUL; + RtlFreeUnicodeString(&Console->Title); + return STATUS_UNSUCCESSFUL; } - Console->PrivateData = NULL; - InitializeCriticalSection(&Console->Lock); + Console->PrivateData = NULL; + InitializeCriticalSection(&Console->Lock); - GuiMode = DtbgIsDesktopVisible(); + GuiMode = DtbgIsDesktopVisible(); - /* allocate console screen buffer */ - NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - if (NULL == NewBuffer) + /* allocate console screen buffer */ + NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + if (NULL == NewBuffer) { - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - return STATUS_INSUFFICIENT_RESOURCES; + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + return STATUS_INSUFFICIENT_RESOURCES; } - /* init screen buffer with defaults */ - NewBuffer->CursorInfo.bVisible = TRUE; - NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - /* make console active, and insert into console list */ - Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; + /* init screen buffer with defaults */ + NewBuffer->CursorInfo.bVisible = TRUE; + NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + /* make console active, and insert into console list */ + Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; - if (! GuiMode) + if (! GuiMode) { - Status = TuiInitConsole(Console); - if (! NT_SUCCESS(Status)) + Status = TuiInitConsole(Console); + if (! NT_SUCCESS(Status)) { - DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); - GuiMode = TRUE; + DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); + GuiMode = TRUE; } } - if (GuiMode) + if (GuiMode) { - Status = GuiInitConsole(Console, Visible); - if (! NT_SUCCESS(Status)) + Status = GuiInitConsole(Console, Visible); + if (! NT_SUCCESS(Status)) { - HeapFree(Win32CsrApiHeap,0, NewBuffer); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - DPRINT1("GuiInitConsole: failed\n"); - return Status; + HeapFree(Win32CsrApiHeap,0, NewBuffer); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + DPRINT1("GuiInitConsole: failed\n"); + return Status; } } - Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); - if (! NT_SUCCESS(Status)) + Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); + if (! NT_SUCCESS(Status)) { - ConioCleanupConsole(Console); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - HeapFree(Win32CsrApiHeap, 0, NewBuffer); - DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); - return Status; + ConioCleanupConsole(Console); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + HeapFree(Win32CsrApiHeap, 0, NewBuffer); + DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); + return Status; } - /* copy buffer contents to screen */ - ConioDrawConsole(Console); + /* copy buffer contents to screen */ + ConioDrawConsole(Console); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } @@ -270,7 +270,7 @@ CSR_API(CsrAllocConsole) /* If we already have one, then don't create a new one... */ if (!Request->Data.AllocConsoleRequest.Console || - Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) + Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) { /* Allocate a console structure */ NewConsole = TRUE; @@ -385,361 +385,362 @@ CSR_API(CsrAllocConsole) CSR_API(CsrFreeConsole) { - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return Win32CsrReleaseConsole(ProcessData); + return Win32CsrReleaseConsole(ProcessData); } static VOID FASTCALL ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines) { - /* If we hit bottom, slide the viewable screen */ - if (++Buff->CurrentY == Buff->MaxY) + /* If we hit bottom, slide the viewable screen */ + if (++Buff->CurrentY == Buff->MaxY) { - Buff->CurrentY--; - if (++Buff->VirtualY == Buff->MaxY) + Buff->CurrentY--; + if (++Buff->VirtualY == Buff->MaxY) { - Buff->VirtualY = 0; + Buff->VirtualY = 0; } - (*ScrolledLines)++; - ClearLineBuffer(Buff); - if (UpdateRect->Top != 0) + (*ScrolledLines)++; + ClearLineBuffer(Buff); + if (UpdateRect->Top != 0) { - UpdateRect->Top--; + UpdateRect->Top--; } } - UpdateRect->Left = 0; - UpdateRect->Right = Buff->MaxX - 1; - UpdateRect->Bottom = Buff->CurrentY; + UpdateRect->Left = 0; + UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Bottom = Buff->CurrentY; } static NTSTATUS FASTCALL ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib) { - UINT i; - PBYTE Ptr; - SMALL_RECT UpdateRect; - LONG CursorStartX, CursorStartY; - UINT ScrolledLines; + UINT i; + PBYTE Ptr; + SMALL_RECT UpdateRect; + LONG CursorStartX, CursorStartY; + UINT ScrolledLines; - CursorStartX = Buff->CurrentX; - CursorStartY = Buff->CurrentY; - UpdateRect.Left = Buff->MaxX; - UpdateRect.Top = Buff->CurrentY; - UpdateRect.Right = -1; - UpdateRect.Bottom = Buff->CurrentY; - ScrolledLines = 0; + CursorStartX = Buff->CurrentX; + CursorStartY = Buff->CurrentY; + UpdateRect.Left = Buff->MaxX; + UpdateRect.Top = Buff->CurrentY; + UpdateRect.Right = -1; + UpdateRect.Bottom = Buff->CurrentY; + ScrolledLines = 0; - for (i = 0; i < Length; i++) + for (i = 0; i < Length; i++) { - if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) + if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) { - /* --- LF --- */ - if (Buffer[i] == '\n') + /* --- LF --- */ + if (Buffer[i] == '\n') { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - continue; + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + continue; } - /* --- BS --- */ - else if (Buffer[i] == '\b') + /* --- BS --- */ + else if (Buffer[i] == '\b') { - /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CurrentX || 0 != Buff->CurrentY) + /* Only handle BS if we're not on the first pos of the first line */ + if (0 != Buff->CurrentX || 0 != Buff->CurrentY) { - if (0 == Buff->CurrentX) + if (0 == Buff->CurrentX) { - /* slide virtual position up */ - Buff->CurrentX = Buff->MaxX - 1; - Buff->CurrentY--; - UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); + /* slide virtual position up */ + Buff->CurrentX = Buff->MaxX - 1; + Buff->CurrentY--; + UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); } - else + else { - Buff->CurrentX--; + Buff->CurrentX--; } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = ' '; - Ptr[1] = Buff->DefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = ' '; + Ptr[1] = Buff->DefaultAttrib; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); } continue; } - /* --- CR --- */ - else if (Buffer[i] == '\r') + /* --- CR --- */ + else if (Buffer[i] == '\r') { - Buff->CurrentX = 0; - UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); - continue; + Buff->CurrentX = 0; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + continue; } - /* --- TAB --- */ - else if (Buffer[i] == '\t') + /* --- TAB --- */ + else if (Buffer[i] == '\t') { - UINT EndX; + UINT EndX; - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - EndX = (Buff->CurrentX + 8) & ~7; - if (EndX > Buff->MaxX) + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + EndX = (Buff->CurrentX + 8) & ~7; + if (EndX > Buff->MaxX) { - EndX = Buff->MaxX; + EndX = Buff->MaxX; } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - while (Buff->CurrentX < EndX) + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + while (Buff->CurrentX < EndX) { - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - Buff->CurrentX++; + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; + Buff->CurrentX++; } - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); - if (Buff->CurrentX == Buff->MaxX) + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); + if (Buff->CurrentX == Buff->MaxX) { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } - else + else { - Buff->CurrentX--; + Buff->CurrentX--; } } - continue; + continue; } } - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = Buffer[i]; - if (Attrib) + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = Buffer[i]; + if (Attrib) { - Ptr[1] = Buff->DefaultAttrib; + Ptr[1] = Buff->DefaultAttrib; } - Buff->CurrentX++; - if (Buff->CurrentX == Buff->MaxX) + Buff->CurrentX++; + if (Buff->CurrentX == Buff->MaxX) { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } - else + else { - Buff->CurrentX = CursorStartX; + Buff->CurrentX = CursorStartX; } } } - if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) + if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) { - ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, - Buffer, Length); + ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, + Buffer, Length); } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrReadConsole) { - PLIST_ENTRY CurrentEntry; - ConsoleInput *Input; - PUCHAR Buffer; - PWCHAR UnicodeBuffer; - ULONG i; - ULONG nNumberOfCharsToRead, CharSize; - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PLIST_ENTRY CurrentEntry; + ConsoleInput *Input; + PUCHAR Buffer; + PWCHAR UnicodeBuffer; + ULONG i; + ULONG nNumberOfCharsToRead, CharSize; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrReadConsole\n"); + DPRINT("CsrReadConsole\n"); - CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ - nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ + nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Buffer = Request->Data.ReadConsoleRequest.Buffer; - UnicodeBuffer = (PWCHAR)Buffer; - Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, - &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Buffer = Request->Data.ReadConsoleRequest.Buffer; + UnicodeBuffer = (PWCHAR)Buffer; + Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, + &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; - for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) + Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; + for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) { - /* remove input event from queue */ - CurrentEntry = RemoveHeadList(&Console->InputEvents); - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) { - /* - * backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 - != (Console->Mode & ENABLE_ECHO_INPUT)) + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to valid ascii chars, on key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown + && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') + { + /* + * backspace handling - if we are in charge of echoing it then we handle it here + * otherwise we treat it like a normal char. + */ + if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 + != (Console->Mode & ENABLE_ECHO_INPUT)) { - /* echo if it has not already been done, and either we or the client has chars to be deleted */ - if (! Input->Echoed - && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) + /* echo if it has not already been done, and either we or the client has chars to be deleted */ + if (! Input->Echoed + && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + ConioWriteConsole(Console, Console->ActiveBuffer, + &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); } - if (0 != i) + if (0 != i) { - i -= 2; /* if we already have something to return, just back it up by 2 */ + i -= 2; /* if we already have something to return, just back it up by 2 */ } - else - { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ - Console->WaitingChars--; - ConioUnlockConsole(Console); - HeapFree(Win32CsrApiHeap, 0, Input); - Request->Data.ReadConsoleRequest.NrCharactersRead = 0; - return STATUS_NOTIFY_CLEANUP; + else + { + /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ + Console->WaitingChars--; + ConioUnlockConsole(Console); + HeapFree(Win32CsrApiHeap, 0, Input); + Request->Data.ReadConsoleRequest.NrCharactersRead = 0; + return STATUS_NOTIFY_CLEANUP; } - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; - Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ + Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; + Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ } - /* do not copy backspace to buffer */ - else + /* do not copy backspace to buffer */ + else { - if(Request->Data.ReadConsoleRequest.Unicode) - ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); - else - Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; + if(Request->Data.ReadConsoleRequest.Unicode) + ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); + else + Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; } - /* echo to screen if enabled and we did not already echo the char */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) - && ! Input->Echoed - && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + /* echo to screen if enabled and we did not already echo the char */ + if (0 != (Console->Mode & ENABLE_ECHO_INPUT) + && ! Input->Echoed + && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + ConioWriteConsole(Console, Console->ActiveBuffer, + &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); } } - else + else { - i--; + i--; } - Console->WaitingChars--; - HeapFree(Win32CsrApiHeap, 0, Input); + Console->WaitingChars--; + HeapFree(Win32CsrApiHeap, 0, Input); } - Request->Data.ReadConsoleRequest.NrCharactersRead = i; - if (0 == i) + Request->Data.ReadConsoleRequest.NrCharactersRead = i; + if (0 == i) { - Status = STATUS_PENDING; /* we didn't read anything */ + Status = STATUS_PENDING; /* we didn't read anything */ } - else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) + else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) { - if (0 == Console->WaitingLines || - (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) + if (0 == Console->WaitingLines || + (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) { - Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ + Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ } - else + else { - Console->WaitingLines--; - Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ + Console->WaitingLines--; + Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ } } - else + else { - Status = STATUS_SUCCESS; /* not line buffered, did read something */ + Status = STATUS_SUCCESS; /* not line buffered, did read something */ } - if (Status == STATUS_PENDING) + if (Status == STATUS_PENDING) { - Console->EchoCount = nNumberOfCharsToRead - i; + Console->EchoCount = nNumberOfCharsToRead - i; } - else + else { - Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ + Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) + if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) { - Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); } - return Status; + return Status; } __inline BOOLEAN ConioGetIntersection( - SMALL_RECT *Intersection, - SMALL_RECT *Rect1, - SMALL_RECT *Rect2) + SMALL_RECT *Intersection, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) { - if (ConioIsRectEmpty(Rect1) || - (ConioIsRectEmpty(Rect2)) || - (Rect1->Top > Rect2->Bottom) || - (Rect1->Left > Rect2->Right) || - (Rect1->Bottom < Rect2->Top) || - (Rect1->Right < Rect2->Left)) - { - /* The rectangles do not intersect */ - ConioInitRect(Intersection, 0, -1, 0, -1); - return FALSE; - } + if (ConioIsRectEmpty(Rect1) || + (ConioIsRectEmpty(Rect2)) || + (Rect1->Top > Rect2->Bottom) || + (Rect1->Left > Rect2->Right) || + (Rect1->Bottom < Rect2->Top) || + (Rect1->Right < Rect2->Left)) + { + /* The rectangles do not intersect */ + ConioInitRect(Intersection, 0, -1, 0, -1); + return FALSE; + } - ConioInitRect(Intersection, - max(Rect1->Top, Rect2->Top), - max(Rect1->Left, Rect2->Left), - min(Rect1->Bottom, Rect2->Bottom), - min(Rect1->Right, Rect2->Right)); + ConioInitRect(Intersection, + max(Rect1->Top, Rect2->Top), + max(Rect1->Left, Rect2->Left), + min(Rect1->Bottom, Rect2->Bottom), + min(Rect1->Right, Rect2->Right)); - return TRUE; + return TRUE; } __inline BOOLEAN ConioGetUnion( - SMALL_RECT *Union, - SMALL_RECT *Rect1, - SMALL_RECT *Rect2) + SMALL_RECT *Union, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) { - if (ConioIsRectEmpty(Rect1)) + if (ConioIsRectEmpty(Rect1)) { - if (ConioIsRectEmpty(Rect2)) + if (ConioIsRectEmpty(Rect2)) { - ConioInitRect(Union, 0, -1, 0, -1); - return FALSE; + ConioInitRect(Union, 0, -1, 0, -1); + return FALSE; } - else + else { - *Union = *Rect2; + *Union = *Rect2; } } - else if (ConioIsRectEmpty(Rect2)) + else if (ConioIsRectEmpty(Rect2)) { - *Union = *Rect1; + *Union = *Rect1; } - else + else { - ConioInitRect(Union, - min(Rect1->Top, Rect2->Top), - min(Rect1->Left, Rect2->Left), - max(Rect1->Bottom, Rect2->Bottom), - max(Rect1->Right, Rect2->Right)); + ConioInitRect(Union, + min(Rect1->Top, Rect2->Top), + min(Rect1->Left, Rect2->Left), + max(Rect1->Bottom, Rect2->Bottom), + max(Rect1->Right, Rect2->Right)); } - return TRUE; + return TRUE; } /* Move from one rectangle to another. We must be careful about the order that @@ -751,158 +752,158 @@ ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, SMALL_RECT *ClipRegion, WORD Fill) { - int Width = ConioRectWidth(SrcRegion); - int Height = ConioRectHeight(SrcRegion); - int SX, SY; - int DX, DY; - int XDelta, YDelta; - int i, j; + int Width = ConioRectWidth(SrcRegion); + int Height = ConioRectHeight(SrcRegion); + int SX, SY; + int DX, DY; + int XDelta, YDelta; + int i, j; - SY = SrcRegion->Top; - DY = DstRegion->Top; - YDelta = 1; - if (SY < DY) + SY = SrcRegion->Top; + DY = DstRegion->Top; + YDelta = 1; + if (SY < DY) { - /* Moving down: work from bottom up */ - SY = SrcRegion->Bottom; - DY = DstRegion->Bottom; - YDelta = -1; + /* Moving down: work from bottom up */ + SY = SrcRegion->Bottom; + DY = DstRegion->Bottom; + YDelta = -1; } - for (i = 0; i < Height; i++) + for (i = 0; i < Height; i++) { - PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); - PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); + PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); + PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); - SX = SrcRegion->Left; - DX = DstRegion->Left; - XDelta = 1; - if (SX < DX) + SX = SrcRegion->Left; + DX = DstRegion->Left; + XDelta = 1; + if (SX < DX) { - /* Moving right: work from right to left */ - SX = SrcRegion->Right; - DX = DstRegion->Right; - XDelta = -1; + /* Moving right: work from right to left */ + SX = SrcRegion->Right; + DX = DstRegion->Right; + XDelta = -1; } - for (j = 0; j < Width; j++) + for (j = 0; j < Width; j++) { - WORD Cell = SRow[SX]; - if (SX >= ClipRegion->Left && SX <= ClipRegion->Right - && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) + WORD Cell = SRow[SX]; + if (SX >= ClipRegion->Left && SX <= ClipRegion->Right + && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) { - SRow[SX] = Fill; + SRow[SX] = Fill; } - if (DX >= ClipRegion->Left && DX <= ClipRegion->Right - && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) + if (DX >= ClipRegion->Left && DX <= ClipRegion->Right + && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) { - DRow[DX] = Cell; + DRow[DX] = Cell; } - SX += XDelta; - DX += XDelta; + SX += XDelta; + DX += XDelta; } - SY += YDelta; - DY += YDelta; + SY += YDelta; + DY += YDelta; } } static VOID FASTCALL ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) { - if (InputEvent->EventType == KEY_EVENT) + if (InputEvent->EventType == KEY_EVENT) { - WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; - InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; - ConsoleInputUnicodeCharToAnsiChar(Console, - &InputEvent->Event.KeyEvent.uChar.AsciiChar, - &UnicodeChar); + WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; + InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; + ConsoleInputUnicodeCharToAnsiChar(Console, + &InputEvent->Event.KeyEvent.uChar.AsciiChar, + &UnicodeChar); } } CSR_API(CsrWriteConsole) { - NTSTATUS Status; - PCHAR Buffer; - PCSRSS_SCREEN_BUFFER Buff; - PCSRSS_CONSOLE Console; - DWORD Written = 0; - ULONG Length; - ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + NTSTATUS Status; + PCHAR Buffer; + PCSRSS_SCREEN_BUFFER Buff; + PCSRSS_CONSOLE Console; + DWORD Written = 0; + ULONG Length; + ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - DPRINT("CsrWriteConsole\n"); + DPRINT("CsrWriteConsole\n"); - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) - + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - if (Console->UnpauseEvent) + if (Console->UnpauseEvent) { - Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, - ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, - SYNCHRONIZE, 0, 0); - ConioUnlockScreenBuffer(Buff); - return NT_SUCCESS(Status) ? STATUS_PENDING : Status; + Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, + ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, + SYNCHRONIZE, 0, 0); + ConioUnlockScreenBuffer(Buff); + return NT_SUCCESS(Status) ? STATUS_PENDING : Status; } - if(Request->Data.WriteConsoleRequest.Unicode) + if(Request->Data.WriteConsoleRequest.Unicode) { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - NULL, 0, NULL, NULL); - Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (Buffer) + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + NULL, 0, NULL, NULL); + Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (Buffer) { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - Buffer, Length, NULL, NULL); + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + Buffer, Length, NULL, NULL); } - else + else { - Status = STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; } } - else + else { - Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; + Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; } - if (Buffer) + if (Buffer) { - if (NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { - Status = ConioWriteConsole(Console, Buff, Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); - if (NT_SUCCESS(Status)) + Status = ConioWriteConsole(Console, Buff, Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); + if (NT_SUCCESS(Status)) { - Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; + Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; } } - if (Request->Data.WriteConsoleRequest.Unicode) + if (Request->Data.WriteConsoleRequest.Unicode) { - RtlFreeHeap(GetProcessHeap(), 0, Buffer); + RtlFreeHeap(GetProcessHeap(), 0, Buffer); } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; + Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; - return Status; + return Status; } VOID WINAPI @@ -929,52 +930,52 @@ ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console) { - SMALL_RECT Region; + SMALL_RECT Region; - ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); + ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); - ConioDrawRegion(Console, &Region); + ConioDrawRegion(Console, &Region); } VOID WINAPI ConioDeleteConsole(Object_t *Object) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; - ConsoleInput *Event; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; + ConsoleInput *Event; - DPRINT("ConioDeleteConsole\n"); + DPRINT("ConioDeleteConsole\n"); - /* Drain input event queue */ - while (Console->InputEvents.Flink != &Console->InputEvents) + /* Drain input event queue */ + while (Console->InputEvents.Flink != &Console->InputEvents) { - Event = (ConsoleInput *) Console->InputEvents.Flink; - Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; - Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; - HeapFree(Win32CsrApiHeap, 0, Event); + Event = (ConsoleInput *) Console->InputEvents.Flink; + Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; + Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; + HeapFree(Win32CsrApiHeap, 0, Event); } - ConioCleanupConsole(Console); - ConioDeleteScreenBuffer(Console->ActiveBuffer); - if (!IsListEmpty(&Console->BufferList)) + ConioCleanupConsole(Console); + ConioDeleteScreenBuffer(Console->ActiveBuffer); + if (!IsListEmpty(&Console->BufferList)) { - DPRINT1("BUG: screen buffer list not empty\n"); + DPRINT1("BUG: screen buffer list not empty\n"); } - CloseHandle(Console->ActiveEvent); - if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); - DeleteCriticalSection(&Console->Lock); - RtlFreeUnicodeString(&Console->Title); - IntDeleteAllAliases(Console->Aliases); - HeapFree(Win32CsrApiHeap, 0, Console); + CloseHandle(Console->ActiveEvent); + if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); + DeleteCriticalSection(&Console->Lock); + RtlFreeUnicodeString(&Console->Title); + IntDeleteAllAliases(Console->Aliases); + HeapFree(Win32CsrApiHeap, 0, Console); } VOID WINAPI CsrInitConsoleSupport(VOID) { - DPRINT("CSR: CsrInitConsoleSupport()\n"); + DPRINT("CSR: CsrInitConsoleSupport()\n"); - /* Should call LoadKeyboardLayout */ + /* Should call LoadKeyboardLayout */ } VOID FASTCALL @@ -1001,43 +1002,43 @@ static VOID FASTCALL ConioProcessChar(PCSRSS_CONSOLE Console, ConsoleInput *KeyEventRecord) { - BOOL updown; - ConsoleInput *TempInput; + BOOL updown; + ConsoleInput *TempInput; - if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && + KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) { - WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; - if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) + WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; + if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) { - DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; - if (Console->Mode & ENABLE_LINE_INPUT && - (vk == VK_PAUSE || (vk == 'S' && - (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && - !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) + DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; + if (Console->Mode & ENABLE_LINE_INPUT && + (vk == VK_PAUSE || (vk == 'S' && + (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && + !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) { - ConioPause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; + ConioPause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; } } - else + else { - if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && - vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) { - ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; } } } - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) + if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) { - case '\r': + case '\r': /* first add the \r */ KeyEventRecord->InputEvent.EventType = KEY_EVENT; updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; @@ -1048,10 +1049,10 @@ ConioProcessChar(PCSRSS_CONSOLE Console, Console->WaitingChars++; KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); if (NULL == KeyEventRecord) - { + { DPRINT1("Failed to allocate KeyEventRecord\n"); return; - } + } KeyEventRecord->InputEvent.EventType = KEY_EVENT; KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; @@ -1061,1733 +1062,1733 @@ ConioProcessChar(PCSRSS_CONSOLE Console, break; } } - /* add event to the queue */ - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - /* if line input mode is enabled, only wake the client on enter key down */ - if (0 == (Console->Mode & ENABLE_LINE_INPUT) - || Console->EarlyReturn - || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) + /* add event to the queue */ + InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); + Console->WaitingChars++; + /* if line input mode is enabled, only wake the client on enter key down */ + if (0 == (Console->Mode & ENABLE_LINE_INPUT) + || Console->EarlyReturn + || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) { - if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) { - Console->WaitingLines++; + Console->WaitingLines++; } } - KeyEventRecord->Echoed = FALSE; - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + KeyEventRecord->Echoed = FALSE; + if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) + && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) { - /* walk the input queue looking for a char to backspace */ - for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; - TempInput != (ConsoleInput *) &Console->InputEvents - && (KEY_EVENT == TempInput->InputEvent.EventType - || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); - TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) + /* walk the input queue looking for a char to backspace */ + for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; + TempInput != (ConsoleInput *) &Console->InputEvents + && (KEY_EVENT == TempInput->InputEvent.EventType + || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown + || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); + TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) { - /* NOP */; + /* NOP */; } - /* if we found one, delete it, otherwise, wake the client */ - if (TempInput != (ConsoleInput *) &Console->InputEvents) + /* if we found one, delete it, otherwise, wake the client */ + if (TempInput != (ConsoleInput *) &Console->InputEvents) { - /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ - RemoveEntryList(&TempInput->ListEntry); - if (TempInput->Echoed) + /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ + RemoveEntryList(&TempInput->ListEntry); + if (TempInput->Echoed) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); + ConioWriteConsole(Console, Console->ActiveBuffer, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, + 1, TRUE); } - HeapFree(Win32CsrApiHeap, 0, TempInput); - RemoveEntryList(&KeyEventRecord->ListEntry); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - Console->WaitingChars -= 2; - return; + HeapFree(Win32CsrApiHeap, 0, TempInput); + RemoveEntryList(&KeyEventRecord->ListEntry); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + Console->WaitingChars -= 2; + return; } } - else + else { - /* echo chars if we are supposed to and client is waiting for some */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + /* echo chars if we are supposed to and client is waiting for some */ + if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount + && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown + && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) { - /* mark the char as already echoed */ - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); - Console->EchoCount--; - KeyEventRecord->Echoed = TRUE; + /* mark the char as already echoed */ + ConioWriteConsole(Console, Console->ActiveBuffer, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, + 1, TRUE); + Console->EchoCount--; + KeyEventRecord->Echoed = TRUE; } } - /* Console->WaitingChars++; */ - SetEvent(Console->ActiveEvent); + /* Console->WaitingChars++; */ + SetEvent(Console->ActiveEvent); } static DWORD FASTCALL ConioGetShiftState(PBYTE KeyState) { - DWORD ssOut = 0; + DWORD ssOut = 0; - if (KeyState[VK_CAPITAL] & 1) - ssOut |= CAPSLOCK_ON; + if (KeyState[VK_CAPITAL] & 1) + ssOut |= CAPSLOCK_ON; - if (KeyState[VK_NUMLOCK] & 1) - ssOut |= NUMLOCK_ON; + if (KeyState[VK_NUMLOCK] & 1) + ssOut |= NUMLOCK_ON; - if (KeyState[VK_SCROLL] & 1) - ssOut |= SCROLLLOCK_ON; + if (KeyState[VK_SCROLL] & 1) + ssOut |= SCROLLLOCK_ON; - if (KeyState[VK_SHIFT] & 0x80) - ssOut |= SHIFT_PRESSED; + if (KeyState[VK_SHIFT] & 0x80) + ssOut |= SHIFT_PRESSED; - if (KeyState[VK_LCONTROL] & 0x80) - ssOut |= LEFT_CTRL_PRESSED; - if (KeyState[VK_RCONTROL] & 0x80) - ssOut |= RIGHT_CTRL_PRESSED; + if (KeyState[VK_LCONTROL] & 0x80) + ssOut |= LEFT_CTRL_PRESSED; + if (KeyState[VK_RCONTROL] & 0x80) + ssOut |= RIGHT_CTRL_PRESSED; - if (KeyState[VK_LMENU] & 0x80) - ssOut |= LEFT_ALT_PRESSED; - if (KeyState[VK_RMENU] & 0x80) - ssOut |= RIGHT_ALT_PRESSED; + if (KeyState[VK_LMENU] & 0x80) + ssOut |= LEFT_ALT_PRESSED; + if (KeyState[VK_RMENU] & 0x80) + ssOut |= RIGHT_ALT_PRESSED; - return ssOut; + return ssOut; } VOID WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) { - static BYTE KeyState[256] = { 0 }; - /* MSDN mentions that you should use the last virtual key code received - * when putting a virtual key identity to a WM_CHAR message since multiple - * or translated keys may be involved. */ - static UINT LastVirtualKey = 0; - DWORD ShiftState; - ConsoleInput *ConInRec; - UINT RepeatCount; - CHAR AsciiChar; - WCHAR UnicodeChar; - UINT VirtualKeyCode; - UINT VirtualScanCode; - BOOL Down = FALSE; - INPUT_RECORD er; - ULONG ResultSize = 0; + static BYTE KeyState[256] = { 0 }; + /* MSDN mentions that you should use the last virtual key code received + * when putting a virtual key identity to a WM_CHAR message since multiple + * or translated keys may be involved. */ + static UINT LastVirtualKey = 0; + DWORD ShiftState; + ConsoleInput *ConInRec; + UINT RepeatCount; + CHAR AsciiChar; + WCHAR UnicodeChar; + UINT VirtualKeyCode; + UINT VirtualScanCode; + BOOL Down = FALSE; + INPUT_RECORD er; + ULONG ResultSize = 0; - RepeatCount = 1; - VirtualScanCode = (msg->lParam >> 16) & 0xff; - Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || - msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; + RepeatCount = 1; + VirtualScanCode = (msg->lParam >> 16) & 0xff; + Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || + msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; - GetKeyboardState(KeyState); - ShiftState = ConioGetShiftState(KeyState); + GetKeyboardState(KeyState); + ShiftState = ConioGetShiftState(KeyState); - if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) + if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) { - VirtualKeyCode = LastVirtualKey; - UnicodeChar = msg->wParam; + VirtualKeyCode = LastVirtualKey; + UnicodeChar = msg->wParam; } - else + else { - WCHAR Chars[2]; - INT RetChars = 0; + WCHAR Chars[2]; + INT RetChars = 0; - VirtualKeyCode = msg->wParam; - RetChars = ToUnicodeEx(VirtualKeyCode, - VirtualScanCode, - KeyState, - Chars, - 2, - 0, - 0); - UnicodeChar = (1 == RetChars ? Chars[0] : 0); + VirtualKeyCode = msg->wParam; + RetChars = ToUnicodeEx(VirtualKeyCode, + VirtualScanCode, + KeyState, + Chars, + 2, + 0, + 0); + UnicodeChar = (1 == RetChars ? Chars[0] : 0); } - if (0 == ResultSize) + if (0 == ResultSize) { - AsciiChar = 0; + AsciiChar = 0; } - er.EventType = KEY_EVENT; - er.Event.KeyEvent.bKeyDown = Down; - er.Event.KeyEvent.wRepeatCount = RepeatCount; - er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; - er.Event.KeyEvent.dwControlKeyState = ShiftState; - er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; - er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; + er.EventType = KEY_EVENT; + er.Event.KeyEvent.bKeyDown = Down; + er.Event.KeyEvent.wRepeatCount = RepeatCount; + er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; + er.Event.KeyEvent.dwControlKeyState = ShiftState; + er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; + er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - if (TextMode) + if (TextMode) { - if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && VK_TAB == VirtualKeyCode) + if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && VK_TAB == VirtualKeyCode) { - if (Down) + if (Down) { - TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); + TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); } - return; + return; } - else if (VK_MENU == VirtualKeyCode && ! Down) + else if (VK_MENU == VirtualKeyCode && ! Down) { - if (TuiSwapConsole(0)) + if (TuiSwapConsole(0)) { - return; + return; } } } - if (NULL == Console) + if (NULL == Console) { - DPRINT1("No Active Console!\n"); - return; + DPRINT1("No Active Console!\n"); + return; } - ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == ConInRec) + if (NULL == ConInRec) { - return; + return; } - ConInRec->InputEvent = er; - ConInRec->Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - ConInRec->Echoed = FALSE; - if (ConInRec->NotChar) - LastVirtualKey = msg->wParam; + ConInRec->InputEvent = er; + ConInRec->Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + ConInRec->Echoed = FALSE; + if (ConInRec->NotChar) + LastVirtualKey = msg->wParam; - DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", - Down ? "down" : "up ", - (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? - "char" : "key ", - ConInRec->Fake ? "fake" : "real", - ConInRec->NotChar ? "notc" : "char", - VirtualScanCode, - VirtualKeyCode, - (AsciiChar >= ' ') ? AsciiChar : '.', - ShiftState); + DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", + Down ? "down" : "up ", + (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? + "char" : "key ", + ConInRec->Fake ? "fake" : "real", + ConInRec->NotChar ? "notc" : "char", + VirtualScanCode, + VirtualKeyCode, + (AsciiChar >= ' ') ? AsciiChar : '.', + ShiftState); - if (ConInRec->Fake && ConInRec->NotChar) + if (ConInRec->Fake && ConInRec->NotChar) { - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; } - /* process Ctrl-C and Ctrl-Break */ - if (Console->Mode & ENABLE_PROCESSED_INPUT && - er.Event.KeyEvent.bKeyDown && - ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || - (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && - (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) + /* process Ctrl-C and Ctrl-Break */ + if (Console->Mode & ENABLE_PROCESSED_INPUT && + er.Event.KeyEvent.bKeyDown && + ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || + (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && + (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) { - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DPRINT1("Console_Api Ctrl-C\n"); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; - ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); - } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - - if (0 != (er.Event.KeyEvent.dwControlKeyState - & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode - || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) - { - if (er.Event.KeyEvent.bKeyDown) + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DPRINT1("Console_Api Ctrl-C\n"); + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) { - /* scroll up or down */ - if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; + ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); + } + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; + } + + if (0 != (er.Event.KeyEvent.dwControlKeyState + & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode + || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) + { + if (er.Event.KeyEvent.bKeyDown) + { + /* scroll up or down */ + if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) { - /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) + /* only scroll up if there is room to scroll up into */ + if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->MaxY - 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY++; + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + + Console->ActiveBuffer->MaxY - 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY++; } } - else + else { - /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CurrentY != 0) + /* only scroll down if there is room to scroll down into */ + if (Console->ActiveBuffer->CurrentY != 0) { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY--; + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY--; } } - ConioDrawConsole(Console); + ConioDrawConsole(Console); } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; } - /* FIXME - convert to ascii */ - ConioProcessChar(Console, ConInRec); + /* FIXME - convert to ascii */ + ConioProcessChar(Console, ConInRec); } CSR_API(CsrGetScreenBufferInfo) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PCONSOLE_SCREEN_BUFFER_INFO pInfo; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PCONSOLE_SCREEN_BUFFER_INFO pInfo; - DPRINT("CsrGetScreenBufferInfo\n"); + DPRINT("CsrGetScreenBufferInfo\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; - pInfo = &Request->Data.ScreenBufferInfoRequest.Info; - pInfo->dwSize.X = Buff->MaxX; - pInfo->dwSize.Y = Buff->MaxY; - pInfo->dwCursorPosition.X = Buff->CurrentX; - pInfo->dwCursorPosition.Y = Buff->CurrentY; - pInfo->wAttributes = Buff->DefaultAttrib; - pInfo->srWindow.Left = Buff->ShowX; - pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; - pInfo->srWindow.Top = Buff->ShowY; - pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; - pInfo->dwMaximumWindowSize.X = Buff->MaxX; - pInfo->dwMaximumWindowSize.Y = Buff->MaxY; - ConioUnlockScreenBuffer(Buff); + Console = Buff->Header.Console; + pInfo = &Request->Data.ScreenBufferInfoRequest.Info; + pInfo->dwSize.X = Buff->MaxX; + pInfo->dwSize.Y = Buff->MaxY; + pInfo->dwCursorPosition.X = Buff->CurrentX; + pInfo->dwCursorPosition.Y = Buff->CurrentY; + pInfo->wAttributes = Buff->DefaultAttrib; + pInfo->srWindow.Left = Buff->ShowX; + pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; + pInfo->srWindow.Top = Buff->ShowY; + pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; + pInfo->dwMaximumWindowSize.X = Buff->MaxX; + pInfo->dwMaximumWindowSize.Y = Buff->MaxY; + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetCursor) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - LONG OldCursorX, OldCursorY; - LONG NewCursorX, NewCursorY; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + LONG OldCursorX, OldCursorY; + LONG NewCursorX, NewCursorY; - DPRINT("CsrSetCursor\n"); + DPRINT("CsrSetCursor\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } Console = Buff->Header.Console; - NewCursorX = Request->Data.SetCursorRequest.Position.X; - NewCursorY = Request->Data.SetCursorRequest.Position.Y; - if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || - NewCursorY < 0 || NewCursorY >= Buff->MaxY) + NewCursorX = Request->Data.SetCursorRequest.Position.X; + NewCursorY = Request->Data.SetCursorRequest.Position.Y; + if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || + NewCursorY < 0 || NewCursorY >= Buff->MaxY) { - ConioUnlockScreenBuffer(Buff); - return STATUS_INVALID_PARAMETER; + ConioUnlockScreenBuffer(Buff); + return STATUS_INVALID_PARAMETER; } - OldCursorX = Buff->CurrentX; - OldCursorY = Buff->CurrentY; - Buff->CurrentX = NewCursorX; - Buff->CurrentY = NewCursorY; - if (Buff == Console->ActiveBuffer) + OldCursorX = Buff->CurrentX; + OldCursorY = Buff->CurrentY; + Buff->CurrentX = NewCursorX; + Buff->CurrentY = NewCursorY; + if (Buff == Console->ActiveBuffer) { - if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) + if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } static VOID FASTCALL ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length) { - if (Buff->MaxX <= Start->X + Length) + if (Buff->MaxX <= Start->X + Length) { - UpdateRect->Left = 0; + UpdateRect->Left = 0; } - else + else { - UpdateRect->Left = Start->X; + UpdateRect->Left = Start->X; } - if (Buff->MaxX <= Start->X + Length) + if (Buff->MaxX <= Start->X + Length) { - UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Right = Buff->MaxX - 1; } - else + else { - UpdateRect->Right = Start->X + Length - 1; + UpdateRect->Right = Start->X + Length - 1; } - UpdateRect->Top = Start->Y; - UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; - if (Buff->MaxY <= UpdateRect->Bottom) + UpdateRect->Top = Start->Y; + UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; + if (Buff->MaxY <= UpdateRect->Bottom) { - UpdateRect->Bottom = Buff->MaxY - 1; + UpdateRect->Bottom = Buff->MaxY - 1; } } CSR_API(CsrWriteConsoleOutputChar) { - NTSTATUS Status; - PCHAR String, tmpString = NULL; - PBYTE Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, CharSize, Written = 0; - SMALL_RECT UpdateRect; + NTSTATUS Status; + PCHAR String, tmpString = NULL; + PBYTE Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, CharSize, Written = 0; + SMALL_RECT UpdateRect; - DPRINT("CsrWriteConsoleOutputChar\n"); + DPRINT("CsrWriteConsoleOutputChar\n"); - CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; } - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (NT_SUCCESS(Status)) { - Console = Buff->Header.Console; - if(Request->Data.WriteConsoleOutputCharRequest.Unicode) + Console = Buff->Header.Console; + if(Request->Data.WriteConsoleOutputCharRequest.Unicode) { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - NULL, 0, NULL, NULL); - tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (String) + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + NULL, 0, NULL, NULL); + tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (String) { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - String, Length, NULL, NULL); + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + String, Length, NULL, NULL); } - else + else { - Status = STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; } } - else + else { - String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; + String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; } - if (String) + if (String) { - if (NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { - X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputCharRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - while (Length--) + X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputCharRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + while (Length--) { - *Buffer = *String++; - Written++; - Buffer += 2; - if (++X == Buff->MaxX) + *Buffer = *String++; + Written++; + Buffer += 2; + if (++X == Buff->MaxX) { - if (++Y == Buff->MaxY) + if (++Y == Buff->MaxY) { - Y = 0; - Buffer = Buff->Buffer; + Y = 0; + Buffer = Buff->Buffer; } - X = 0; + X = 0; } } - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, - Request->Data.WriteConsoleOutputCharRequest.Length); - ConioDrawRegion(Console, &UpdateRect); + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, + Request->Data.WriteConsoleOutputCharRequest.Length); + ConioDrawRegion(Console, &UpdateRect); } Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; } - if (Request->Data.WriteConsoleRequest.Unicode) + if (Request->Data.WriteConsoleRequest.Unicode) { - RtlFreeHeap(GetProcessHeap(), 0, tmpString); + RtlFreeHeap(GetProcessHeap(), 0, tmpString); } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); } - Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; - return Status; + Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; + return Status; } CSR_API(CsrFillOutputChar) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, Written = 0; - CHAR Char; - PBYTE Buffer; - SMALL_RECT UpdateRect; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, Written = 0; + CHAR Char; + PBYTE Buffer; + SMALL_RECT UpdateRect; - DPRINT("CsrFillOutputChar\n"); + DPRINT("CsrFillOutputChar\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - X = Request->Data.FillOutputRequest.Position.X; - Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - if(Request->Data.FillOutputRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); - else - Char = Request->Data.FillOutputRequest.Char.AsciiChar; - Length = Request->Data.FillOutputRequest.Length; - while (Length--) + X = Request->Data.FillOutputRequest.Position.X; + Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + if(Request->Data.FillOutputRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); + else + Char = Request->Data.FillOutputRequest.Char.AsciiChar; + Length = Request->Data.FillOutputRequest.Length; + while (Length--) { - *Buffer = Char; - Buffer += 2; - Written++; - if (++X == Buff->MaxX) + *Buffer = Char; + Buffer += 2; + Written++; + if (++X == Buff->MaxX) { - if (++Y == Buff->MaxY) + if (++Y == Buff->MaxY) { - Y = 0; - Buffer = Buff->Buffer; + Y = 0; + Buffer = Buff->Buffer; } - X = 0; + X = 0; } } - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, - Request->Data.FillOutputRequest.Length); - ConioDrawRegion(Console, &UpdateRect); + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, + Request->Data.FillOutputRequest.Length); + ConioDrawRegion(Console, &UpdateRect); } - ConioUnlockScreenBuffer(Buff); - Length = Request->Data.FillOutputRequest.Length; - Request->Data.FillOutputRequest.NrCharactersWritten = Length; - return STATUS_SUCCESS; + ConioUnlockScreenBuffer(Buff); + Length = Request->Data.FillOutputRequest.Length; + Request->Data.FillOutputRequest.NrCharactersWritten = Length; + return STATUS_SUCCESS; } CSR_API(CsrReadInputEvent) { - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - BOOLEAN Done = FALSE; - ConsoleInput *Input; + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + BOOLEAN Done = FALSE; + ConsoleInput *Input; - DPRINT("CsrReadInputEvent\n"); + DPRINT("CsrReadInputEvent\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; - Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - /* only get input if there is any */ - CurrentEntry = Console->InputEvents.Flink; - while (CurrentEntry != &Console->InputEvents) + /* only get input if there is any */ + CurrentEntry = Console->InputEvents.Flink; + while (CurrentEntry != &Console->InputEvents) { - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - CurrentEntry = CurrentEntry->Flink; + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + CurrentEntry = CurrentEntry->Flink; - if (Done && !Input->Fake) + if (Done && !Input->Fake) { - Request->Data.ReadInputRequest.MoreEvents = TRUE; - break; + Request->Data.ReadInputRequest.MoreEvents = TRUE; + break; } - RemoveEntryList(&Input->ListEntry); + RemoveEntryList(&Input->ListEntry); - if (!Done && !Input->Fake) + if (!Done && !Input->Fake) { - Request->Data.ReadInputRequest.Input = Input->InputEvent; - if (Request->Data.ReadInputRequest.Unicode == FALSE) + Request->Data.ReadInputRequest.Input = Input->InputEvent; + if (Request->Data.ReadInputRequest.Unicode == FALSE) { - ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); + ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); } - Done = TRUE; + Done = TRUE; } - if (Input->InputEvent.EventType == KEY_EVENT) + if (Input->InputEvent.EventType == KEY_EVENT) { - if (0 != (Console->Mode & ENABLE_LINE_INPUT) - && Input->InputEvent.Event.KeyEvent.bKeyDown - && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + if (0 != (Console->Mode & ENABLE_LINE_INPUT) + && Input->InputEvent.Event.KeyEvent.bKeyDown + && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) { - Console->WaitingLines--; + Console->WaitingLines--; } - Console->WaitingChars--; + Console->WaitingChars--; } - HeapFree(Win32CsrApiHeap, 0, Input); + HeapFree(Win32CsrApiHeap, 0, Input); } - if (Done) + if (Done) { - Status = STATUS_SUCCESS; - Console->EarlyReturn = FALSE; + Status = STATUS_SUCCESS; + Console->EarlyReturn = FALSE; } - else + else { - Status = STATUS_PENDING; - Console->EarlyReturn = TRUE; /* mark for early return */ + Status = STATUS_PENDING; + Console->EarlyReturn = TRUE; /* mark for early return */ } - if (IsListEmpty(&Console->InputEvents)) + if (IsListEmpty(&Console->InputEvents)) { - ResetEvent(Console->ActiveEvent); + ResetEvent(Console->ActiveEvent); } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - return Status; + return Status; } CSR_API(CsrWriteConsoleOutputAttrib) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - PWORD Attribute; - int X, Y, Length; - NTSTATUS Status; - SMALL_RECT UpdateRect; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + PWORD Attribute; + int X, Y, Length; + NTSTATUS Status; + SMALL_RECT UpdateRect; - DPRINT("CsrWriteConsoleOutputAttrib\n"); + DPRINT("CsrWriteConsoleOutputAttrib\n"); - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputAttribRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; - Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; - while (Length--) + X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputAttribRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; + Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; + while (Length--) { - *Buffer = (UCHAR)(*Attribute++); - Buffer += 2; - if (++X == Buff->MaxX) + *Buffer = (UCHAR)(*Attribute++); + Buffer += 2; + if (++X == Buff->MaxX) { - if (++Y == Buff->MaxY) + if (++Y == Buff->MaxY) { - Y = 0; - Buffer = Buff->Buffer + 1; + Y = 0; + Buffer = Buff->Buffer + 1; } - X = 0; + X = 0; } } - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, - Request->Data.WriteConsoleOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, + Request->Data.WriteConsoleOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); } - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrFillOutputAttrib) { - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - NTSTATUS Status; - int X, Y, Length; - UCHAR Attr; - SMALL_RECT UpdateRect; - PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + NTSTATUS Status; + int X, Y, Length; + UCHAR Attr; + SMALL_RECT UpdateRect; + PCSRSS_CONSOLE Console; - DPRINT("CsrFillOutputAttrib\n"); + DPRINT("CsrFillOutputAttrib\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - X = Request->Data.FillOutputAttribRequest.Coord.X; - Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.FillOutputAttribRequest.Length; - Attr = Request->Data.FillOutputAttribRequest.Attribute; - Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; - while (Length--) + X = Request->Data.FillOutputAttribRequest.Coord.X; + Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.FillOutputAttribRequest.Length; + Attr = Request->Data.FillOutputAttribRequest.Attribute; + Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; + while (Length--) { - *Buffer = Attr; - Buffer += 2; - if (++X == Buff->MaxX) + *Buffer = Attr; + Buffer += 2; + if (++X == Buff->MaxX) { - if (++Y == Buff->MaxY) + if (++Y == Buff->MaxY) { - Y = 0; - Buffer = Buff->Buffer + 1; + Y = 0; + Buffer = Buff->Buffer + 1; } - X = 0; + X = 0; } } - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, - Request->Data.FillOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, + Request->Data.FillOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrGetCursorInfo) { - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; - DPRINT("CsrGetCursorInfo\n"); + DPRINT("CsrGetCursorInfo\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; - Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; - ConioUnlockScreenBuffer(Buff); + Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; + Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetCursorInfo) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - BOOL Visible; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Size; + BOOL Visible; + NTSTATUS Status; - DPRINT("CsrSetCursorInfo\n"); + DPRINT("CsrSetCursorInfo\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - Size = Request->Data.SetCursorInfoRequest.Info.dwSize; - Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; - if (Size < 1) + Size = Request->Data.SetCursorInfoRequest.Info.dwSize; + Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; + if (Size < 1) { - Size = 1; + Size = 1; } - if (100 < Size) + if (100 < Size) { - Size = 100; + Size = 100; } - if (Size != Buff->CursorInfo.dwSize - || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) + if (Size != Buff->CursorInfo.dwSize + || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) { - Buff->CursorInfo.dwSize = Size; - Buff->CursorInfo.bVisible = Visible; + Buff->CursorInfo.dwSize = Size; + Buff->CursorInfo.bVisible = Visible; - if (! ConioSetCursorInfo(Console, Buff)) + if (! ConioSetCursorInfo(Console, Buff)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetTextAttrib) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; - DPRINT("CsrSetTextAttrib\n"); + DPRINT("CsrSetTextAttrib\n"); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } Console = Buff->Header.Console; - Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; - if (Buff == Console->ActiveBuffer) + Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; + if (Buff == Console->ActiveBuffer) { - if (! ConioUpdateScreenInfo(Console, Buff)) + if (! ConioUpdateScreenInfo(Console, Buff)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetConsoleMode) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; - DPRINT("CsrSetConsoleMode\n"); + DPRINT("CsrSetConsoleMode\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrLockObject(ProcessData, - Request->Data.SetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_WRITE, 0); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, + Request->Data.SetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_WRITE, 0); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Buff = (PCSRSS_SCREEN_BUFFER)Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + Buff = (PCSRSS_SCREEN_BUFFER)Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) { - Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; + Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; } - else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) + else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) { - Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; + Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; } - else + else { - Status = STATUS_INVALID_HANDLE; + Status = STATUS_INVALID_HANDLE; } - Win32CsrUnlockObject((Object_t *)Console); + Win32CsrUnlockObject((Object_t *)Console); - return Status; + return Status; } CSR_API(CsrGetConsoleMode) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ - DPRINT("CsrGetConsoleMode\n"); + DPRINT("CsrGetConsoleMode\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_READ, 0); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_READ, 0); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Status = STATUS_SUCCESS; - Buff = (PCSRSS_SCREEN_BUFFER) Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + Status = STATUS_SUCCESS; + Buff = (PCSRSS_SCREEN_BUFFER) Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) { - Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; + Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; } - else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) + else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) { - Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; + Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; } - else + else { - Status = STATUS_INVALID_HANDLE; + Status = STATUS_INVALID_HANDLE; } - Win32CsrUnlockObject((Object_t *)Console); - return Status; + Win32CsrUnlockObject((Object_t *)Console); + return Status; } CSR_API(CsrCreateScreenBuffer) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; - DPRINT("CsrCreateScreenBuffer\n"); + DPRINT("CsrCreateScreenBuffer\n"); - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - if (Buff != NULL) + if (Buff != NULL) { - if (Console->ActiveBuffer) + if (Console->ActiveBuffer) { - Buff->MaxX = Console->ActiveBuffer->MaxX; - Buff->MaxY = Console->ActiveBuffer->MaxY; - Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; - Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; + Buff->MaxX = Console->ActiveBuffer->MaxX; + Buff->MaxY = Console->ActiveBuffer->MaxY; + Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; + Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; } - else + else { - Buff->CursorInfo.bVisible = TRUE; - Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + Buff->CursorInfo.bVisible = TRUE; + Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; } - if (Buff->MaxX == 0) + if (Buff->MaxX == 0) { - Buff->MaxX = 80; + Buff->MaxX = 80; } - if (Buff->MaxY == 0) + if (Buff->MaxY == 0) { - Buff->MaxY = 25; + Buff->MaxY = 25; } - Status = CsrInitConsoleScreenBuffer(Console, Buff); - if(NT_SUCCESS(Status)) + Status = CsrInitConsoleScreenBuffer(Console, Buff); + if (NT_SUCCESS(Status)) { - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.CreateScreenBufferRequest.OutputHandle, - &Buff->Header, - Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable, - Request->Data.CreateScreenBufferRequest.ShareMode); + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.CreateScreenBufferRequest.OutputHandle, + &Buff->Header, + Request->Data.CreateScreenBufferRequest.Access, + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); } } - else + else { - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INSUFFICIENT_RESOURCES; } - ConioUnlockConsole(Console); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; + ConioUnlockConsole(Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; } CSR_API(CsrSetScreenBuffer) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; - DPRINT("CsrSetScreenBuffer\n"); + DPRINT("CsrSetScreenBuffer\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; } - /* If old buffer has no handles, it's now unreferenced */ - if (Console->ActiveBuffer->Header.HandleCount == 0) + /* If old buffer has no handles, it's now unreferenced */ + if (Console->ActiveBuffer->Header.HandleCount == 0) { - ConioDeleteScreenBuffer(Console->ActiveBuffer); + ConioDeleteScreenBuffer(Console->ActiveBuffer); } - /* tie console to new buffer */ - Console->ActiveBuffer = Buff; - /* Redraw the console */ - ConioDrawConsole(Console); + /* tie console to new buffer */ + Console->ActiveBuffer = Buff; + /* Redraw the console */ + ConioDrawConsole(Console); - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetTitle) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PWCHAR Buffer; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PWCHAR Buffer; - DPRINT("CsrSetTitle\n"); + DPRINT("CsrSetTitle\n"); - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) - + Request->Data.SetTitleRequest.Length) + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + + Request->Data.SetTitleRequest.Length) { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; } - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if(NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if(NT_SUCCESS(Status)) { - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); - if (Buffer) + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); + if (Buffer) { - /* copy title to console */ - RtlFreeUnicodeString(&Console->Title); - Console->Title.Buffer = Buffer; - Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; - memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); - if (! ConioChangeTitle(Console)) + /* copy title to console */ + RtlFreeUnicodeString(&Console->Title); + Console->Title.Buffer = Buffer; + Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; + memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); + if (! ConioChangeTitle(Console)) { - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_UNSUCCESSFUL; } - else + else { - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; } } - else + else { - Status = STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); } - return Status; + return Status; } CSR_API(CsrGetTitle) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Length; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Length; - DPRINT("CsrGetTitle\n"); + DPRINT("CsrGetTitle\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - DPRINT1("Can't get console\n"); - return Status; + DPRINT1("Can't get console\n"); + return Status; } - /* Copy title of the console to the user title buffer */ - RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); - Request->Data.GetTitleRequest.Length = Console->Title.Length; - memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, - Console->Title.Length); - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; + /* Copy title of the console to the user title buffer */ + RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); + Request->Data.GetTitleRequest.Length = Console->Title.Length; + memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, + Console->Title.Length); + Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - if (Length > sizeof(CSR_API_MESSAGE)) + if (Length > sizeof(CSR_API_MESSAGE)) { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = Length; + Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrWriteConsoleOutput) { - SHORT i, X, Y, SizeX, SizeY; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - SMALL_RECT ScreenBuffer; - CHAR_INFO* CurCharInfo; - SMALL_RECT WriteRegion; - CHAR_INFO* CharInfo; - COORD BufferCoord; - COORD BufferSize; - NTSTATUS Status; - PBYTE Ptr; - DWORD PSize; + SHORT i, X, Y, SizeX, SizeY; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + CHAR_INFO* CurCharInfo; + SMALL_RECT WriteRegion; + CHAR_INFO* CharInfo; + COORD BufferCoord; + COORD BufferSize; + NTSTATUS Status; + PBYTE Ptr; + DWORD PSize; - DPRINT("CsrWriteConsoleOutput\n"); + DPRINT("CsrWriteConsoleOutput\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; - PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); - BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; - CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || - (((ULONG_PTR)CharInfo + PSize) > - ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; + PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); + BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; + CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; + if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || + (((ULONG_PTR)CharInfo + PSize) > + ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) { - ConioUnlockScreenBuffer(Buff); - return STATUS_ACCESS_VIOLATION; + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; } - WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; + WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); - WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - WriteRegion.Right = WriteRegion.Left + SizeX - 1; + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); + WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + WriteRegion.Right = WriteRegion.Left + SizeX - 1; - /* Make sure WriteRegion is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) + /* Make sure WriteRegion is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) { - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - /* It is okay to have a WriteRegion completely outside the screen buffer. - No data is written then. */ - return STATUS_SUCCESS; + /* It is okay to have a WriteRegion completely outside the screen buffer. + No data is written then. */ + return STATUS_SUCCESS; } - for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) + for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); - for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) + CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; + Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); + for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) { - CHAR AsciiChar; - if (Request->Data.WriteConsoleOutputRequest.Unicode) + CHAR AsciiChar; + if (Request->Data.WriteConsoleOutputRequest.Unicode) { - ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); + ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); } - else + else { - AsciiChar = CurCharInfo->Char.AsciiChar; + AsciiChar = CurCharInfo->Char.AsciiChar; } - *Ptr++ = AsciiChar; - *Ptr++ = CurCharInfo->Attributes; - CurCharInfo++; + *Ptr++ = AsciiChar; + *Ptr++ = CurCharInfo->Attributes; + CurCharInfo++; } } - ConioDrawRegion(Console, &WriteRegion); + ConioDrawRegion(Console, &WriteRegion); - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrFlushInputBuffer) { - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - ConsoleInput* Input; - NTSTATUS Status; + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + ConsoleInput* Input; + NTSTATUS Status; - DPRINT("CsrFlushInputBuffer\n"); + DPRINT("CsrFlushInputBuffer\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, - Request->Data.FlushInputBufferRequest.ConsoleInput, - &Console, - GENERIC_WRITE); - if(! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockConsole(ProcessData, + Request->Data.FlushInputBufferRequest.ConsoleInput, + &Console, + GENERIC_WRITE); + if(! NT_SUCCESS(Status)) { - return Status; + return Status; } - /* Discard all entries in the input event queue */ - while (!IsListEmpty(&Console->InputEvents)) + /* Discard all entries in the input event queue */ + while (!IsListEmpty(&Console->InputEvents)) { - CurrentEntry = RemoveHeadList(&Console->InputEvents); - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - /* Destroy the event */ - HeapFree(Win32CsrApiHeap, 0, Input); + CurrentEntry = RemoveHeadList(&Console->InputEvents); + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + /* Destroy the event */ + HeapFree(Win32CsrApiHeap, 0, Input); } - ResetEvent(Console->ActiveEvent); - Console->WaitingChars=0; + ResetEvent(Console->ActiveEvent); + Console->WaitingChars=0; - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrScrollConsoleScreenBuffer) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - SMALL_RECT ScreenBuffer; - SMALL_RECT SrcRegion; - SMALL_RECT DstRegion; - SMALL_RECT UpdateRegion; - SMALL_RECT ScrollRectangle; - SMALL_RECT ClipRectangle; - NTSTATUS Status; - HANDLE ConsoleHandle; - BOOLEAN UseClipRectangle; - COORD DestinationOrigin; - CHAR_INFO Fill; - CHAR FillChar; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + SMALL_RECT SrcRegion; + SMALL_RECT DstRegion; + SMALL_RECT UpdateRegion; + SMALL_RECT ScrollRectangle; + SMALL_RECT ClipRectangle; + NTSTATUS Status; + HANDLE ConsoleHandle; + BOOLEAN UseClipRectangle; + COORD DestinationOrigin; + CHAR_INFO Fill; + CHAR FillChar; - DPRINT("CsrScrollConsoleScreenBuffer\n"); + DPRINT("CsrScrollConsoleScreenBuffer\n"); - ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; - UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; - DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; - Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; + ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; + UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; + DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; + Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; + ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; - /* Make sure source rectangle is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) + /* Make sure source rectangle is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; } - /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.Left < 0) + /* If the source was clipped on the left or top, adjust the destination accordingly */ + if (ScrollRectangle.Left < 0) { - DestinationOrigin.X -= ScrollRectangle.Left; + DestinationOrigin.X -= ScrollRectangle.Left; } - if (ScrollRectangle.Top < 0) + if (ScrollRectangle.Top < 0) { - DestinationOrigin.Y -= ScrollRectangle.Top; + DestinationOrigin.Y -= ScrollRectangle.Top; } - if (UseClipRectangle) + if (UseClipRectangle) { - ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; - if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) + ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; + if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } } - else + else { - ClipRectangle = ScreenBuffer; + ClipRectangle = ScreenBuffer; } - ConioInitRect(&DstRegion, - DestinationOrigin.Y, - DestinationOrigin.X, - DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, - DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); + ConioInitRect(&DstRegion, + DestinationOrigin.Y, + DestinationOrigin.X, + DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, + DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); - if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); - else - FillChar = Fill.Char.AsciiChar; + if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); + else + FillChar = Fill.Char.AsciiChar; - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); + ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); - if (Buff == Console->ActiveBuffer) + if (Buff == Console->ActiveBuffer) { - ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); - if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) + ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); + if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) { - /* Draw update region */ - ConioDrawRegion(Console, &UpdateRegion); + /* Draw update region */ + ConioDrawRegion(Console, &UpdateRegion); } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrReadConsoleOutputChar) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PCHAR ReadBuffer; - DWORD i; - ULONG CharSize; - CHAR Char; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PCHAR ReadBuffer; + DWORD i; + ULONG CharSize; + CHAR Char; - DPRINT("CsrReadConsoleOutputChar\n"); + DPRINT("CsrReadConsoleOutputChar\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; - CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Console = Buff->Header.Console; + Console = Buff->Header.Console; - Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) + for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) { - Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; + Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; - if(Request->Data.ReadConsoleOutputCharRequest.Unicode) - { - ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); - ReadBuffer += sizeof(WCHAR); - } - else - *(ReadBuffer++) = Char; - - Xpos++; - - if (Xpos == Buff->MaxX) + if(Request->Data.ReadConsoleOutputCharRequest.Unicode) { - Xpos = 0; - Ypos++; + ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); + ReadBuffer += sizeof(WCHAR); + } + else + *(ReadBuffer++) = Char; - if (Ypos == Buff->MaxY) + Xpos++; + + if (Xpos == Buff->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->MaxY) { - Ypos = 0; + Ypos = 0; } } } - *ReadBuffer = 0; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + *ReadBuffer = 0; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; - if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) + Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; + if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) { - Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrReadConsoleOutputAttrib) { - NTSTATUS Status; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PWORD ReadBuffer; - DWORD i; - DWORD CurrentLength; + NTSTATUS Status; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PWORD ReadBuffer; + DWORD i; + DWORD CurrentLength; - DPRINT("CsrReadConsoleOutputAttrib\n"); + DPRINT("CsrReadConsoleOutputAttrib\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) + for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) { - *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; + *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; - ReadBuffer++; - Xpos++; + ReadBuffer++; + Xpos++; - if (Xpos == Buff->MaxX) + if (Xpos == Buff->MaxX) { - Xpos = 0; - Ypos++; + Xpos = 0; + Ypos++; - if (Ypos == Buff->MaxY) + if (Ypos == Buff->MaxY) { - Ypos = 0; + Ypos = 0; } } } - *ReadBuffer = 0; + *ReadBuffer = 0; - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); - if (CurrentLength > sizeof(CSR_API_MESSAGE)) + CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); + if (CurrentLength > sizeof(CSR_API_MESSAGE)) { - Request->Header.u1.s1.TotalLength = CurrentLength; - Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = CurrentLength; + Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrGetNumberOfConsoleInputEvents) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PLIST_ENTRY CurrentItem; - DWORD NumEvents; - ConsoleInput *Input; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PLIST_ENTRY CurrentItem; + DWORD NumEvents; + ConsoleInput *Input; - DPRINT("CsrGetNumberOfConsoleInputEvents\n"); + DPRINT("CsrGetNumberOfConsoleInputEvents\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - CurrentItem = Console->InputEvents.Flink; - NumEvents = 0; + CurrentItem = Console->InputEvents.Flink; + NumEvents = 0; - /* If there are any events ... */ - while (CurrentItem != &Console->InputEvents) + /* If there are any events ... */ + while (CurrentItem != &Console->InputEvents) { - Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - CurrentItem = CurrentItem->Flink; - if (!Input->Fake) + Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); + CurrentItem = CurrentItem->Flink; + if (!Input->Fake) { - NumEvents++; + NumEvents++; } } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; + Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrPeekConsoleInput) { - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Size; - DWORD Length; - PLIST_ENTRY CurrentItem; - PINPUT_RECORD InputRecord; - ConsoleInput* Item; - UINT NumItems; + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Size; + DWORD Length; + PLIST_ENTRY CurrentItem; + PINPUT_RECORD InputRecord; + ConsoleInput* Item; + UINT NumItems; - DPRINT("CsrPeekConsoleInput\n"); + DPRINT("CsrPeekConsoleInput\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if(! NT_SUCCESS(Status)) + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if(! NT_SUCCESS(Status)) { - return Status; + return Status; } - InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; - Length = Request->Data.PeekConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); + InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; + Length = Request->Data.PeekConsoleInputRequest.Length; + Size = Length * sizeof(INPUT_RECORD); - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; } - NumItems = 0; + NumItems = 0; - if (! IsListEmpty(&Console->InputEvents)) + if (! IsListEmpty(&Console->InputEvents)) { - CurrentItem = Console->InputEvents.Flink; + CurrentItem = Console->InputEvents.Flink; - while (CurrentItem != &Console->InputEvents && NumItems < Length) + while (CurrentItem != &Console->InputEvents && NumItems < Length) { - Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); + Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - if (Item->Fake) + if (Item->Fake) { - CurrentItem = CurrentItem->Flink; - continue; + CurrentItem = CurrentItem->Flink; + continue; } - ++NumItems; - *InputRecord = Item->InputEvent; + ++NumItems; + *InputRecord = Item->InputEvent; - if (Request->Data.ReadInputRequest.Unicode == FALSE) + if (Request->Data.ReadInputRequest.Unicode == FALSE) { - ConioInputEventToAnsi(Console, InputRecord); + ConioInputEventToAnsi(Console, InputRecord); } - InputRecord++; - CurrentItem = CurrentItem->Flink; + InputRecord++; + CurrentItem = CurrentItem->Flink; } } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - Request->Data.PeekConsoleInputRequest.Length = NumItems; + Request->Data.PeekConsoleInputRequest.Length = NumItems; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrReadConsoleOutput) { - PCHAR_INFO CharInfo; - PCHAR_INFO CurCharInfo; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - DWORD Length; - DWORD SizeX, SizeY; - NTSTATUS Status; - COORD BufferSize; - COORD BufferCoord; - SMALL_RECT ReadRegion; - SMALL_RECT ScreenRect; - DWORD i; - PBYTE Ptr; - LONG X, Y; - UINT CodePage; + PCHAR_INFO CharInfo; + PCHAR_INFO CurCharInfo; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Size; + DWORD Length; + DWORD SizeX, SizeY; + NTSTATUS Status; + COORD BufferSize; + COORD BufferCoord; + SMALL_RECT ReadRegion; + SMALL_RECT ScreenRect; + DWORD i; + PBYTE Ptr; + LONG X, Y; + UINT CodePage; - DPRINT("CsrReadConsoleOutput\n"); + DPRINT("CsrReadConsoleOutput\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; - ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; - BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; - BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; - Length = BufferSize.X * BufferSize.Y; - Size = Length * sizeof(CHAR_INFO); + CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; + ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; + BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; + BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; + Length = BufferSize.X * BufferSize.Y; + Size = Length * sizeof(CHAR_INFO); - /* FIXME: Is this correct? */ - CodePage = ProcessData->Console->OutputCodePage; + /* FIXME: Is this correct? */ + CodePage = ProcessData->Console->OutputCodePage; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) { - ConioUnlockScreenBuffer(Buff); - return STATUS_ACCESS_VIOLATION; + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; } - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); - ReadRegion.Bottom = ReadRegion.Top + SizeY; - ReadRegion.Right = ReadRegion.Left + SizeX; + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); + ReadRegion.Bottom = ReadRegion.Top + SizeY; + ReadRegion.Right = ReadRegion.Left + SizeX; - ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); - if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) + ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); + if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; } - for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) + for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) { - CurCharInfo = CharInfo + (i * BufferSize.X); + CurCharInfo = CharInfo + (i * BufferSize.X); - Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); - for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) + Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); + for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) { - if (Request->Data.ReadConsoleOutputRequest.Unicode) + if (Request->Data.ReadConsoleOutputRequest.Unicode) { - MultiByteToWideChar(CodePage, 0, - (PCHAR)Ptr++, 1, - &CurCharInfo->Char.UnicodeChar, 1); + MultiByteToWideChar(CodePage, 0, + (PCHAR)Ptr++, 1, + &CurCharInfo->Char.UnicodeChar, 1); } - else + else { - CurCharInfo->Char.AsciiChar = *Ptr++; + CurCharInfo->Char.AsciiChar = *Ptr++; } - CurCharInfo->Attributes = *Ptr++; - ++CurCharInfo; + CurCharInfo->Attributes = *Ptr++; + ++CurCharInfo; } } - ConioUnlockScreenBuffer(Buff); + ConioUnlockScreenBuffer(Buff); - Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrWriteConsoleInput) { - PINPUT_RECORD InputRecord; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - DWORD Length; - DWORD Size; - DWORD i; - ConsoleInput* Record; + PINPUT_RECORD InputRecord; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + DWORD Length; + DWORD Size; + DWORD i; + ConsoleInput* Record; - DPRINT("CsrWriteConsoleInput\n"); + DPRINT("CsrWriteConsoleInput\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; - Length = Request->Data.WriteConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); + InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; + Length = Request->Data.WriteConsoleInputRequest.Length; + Size = Length * sizeof(INPUT_RECORD); - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; } - for (i = 0; i < Length; i++) + for (i = 0; i < Length; i++) { - Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == Record) + Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (NULL == Record) { - ConioUnlockConsole(Console); - return STATUS_INSUFFICIENT_RESOURCES; + ConioUnlockConsole(Console); + return STATUS_INSUFFICIENT_RESOURCES; } - Record->Echoed = FALSE; - Record->Fake = FALSE; - //Record->InputEvent = *InputRecord++; - memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); - if (KEY_EVENT == Record->InputEvent.EventType) + Record->Echoed = FALSE; + Record->Fake = FALSE; + //Record->InputEvent = *InputRecord++; + memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); + if (KEY_EVENT == Record->InputEvent.EventType) { - /* FIXME - convert from unicode to ascii!! */ - ConioProcessChar(Console, Record); + /* FIXME - convert from unicode to ascii!! */ + ConioProcessChar(Console, Record); } } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - Request->Data.WriteConsoleInputRequest.Length = i; + Request->Data.WriteConsoleInputRequest.Length = i; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /********************************************************************** @@ -2807,285 +2808,285 @@ CSR_API(CsrWriteConsoleInput) static NTSTATUS FASTCALL SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) { - DPRINT1("Console Hardware State: %d\n", ConsoleHwState); + DPRINT1("Console Hardware State: %d\n", ConsoleHwState); - if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) - ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) + if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) + ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) { - if (Console->HardwareState != ConsoleHwState) + if (Console->HardwareState != ConsoleHwState) { - /* TODO: implement switching from full screen to windowed mode */ - /* TODO: or back; now simply store the hardware state */ - Console->HardwareState = ConsoleHwState; + /* TODO: implement switching from full screen to windowed mode */ + /* TODO: or back; now simply store the hardware state */ + Console->HardwareState = ConsoleHwState; } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ + return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ } CSR_API(CsrHardwareStateProperty) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrHardwareStateProperty\n"); + DPRINT("CsrHardwareStateProperty\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, - Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, - &Console, - GENERIC_READ); - if (! NT_SUCCESS(Status)) + Status = ConioLockConsole(ProcessData, + Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, + &Console, + GENERIC_READ); + if (! NT_SUCCESS(Status)) { - DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); - return Status; + DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); + return Status; } - switch (Request->Data.ConsoleHardwareStateRequest.SetGet) + switch (Request->Data.ConsoleHardwareStateRequest.SetGet) { - case CONSOLE_HARDWARE_STATE_GET: + case CONSOLE_HARDWARE_STATE_GET: Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState; break; - case CONSOLE_HARDWARE_STATE_SET: + case CONSOLE_HARDWARE_STATE_SET: DPRINT("Setting console hardware state.\n"); Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State); break; - default: + default: Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */ break; } - ConioUnlockConsole(Console); + ConioUnlockConsole(Console); - return Status; + return Status; } CSR_API(CsrGetConsoleWindow) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrGetConsoleWindow\n"); + DPRINT("CsrGetConsoleWindow\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; - ConioUnlockConsole(Console); + Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; + ConioUnlockConsole(Console); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetConsoleIcon) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrSetConsoleIcon\n"); + DPRINT("CsrSetConsoleIcon\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) - ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); - ConioUnlockConsole(Console); + Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); + ConioUnlockConsole(Console); - return Status; + return Status; } CSR_API(CsrGetConsoleCodePage) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrGetConsoleCodePage\n"); + DPRINT("CsrGetConsoleCodePage\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; } CSR_API(CsrSetConsoleCodePage) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrSetConsoleCodePage\n"); + DPRINT("CsrSetConsoleCodePage\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) + if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) { - Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; + Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; } - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; } CSR_API(CsrGetConsoleOutputCodePage) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrGetConsoleOutputCodePage\n"); + DPRINT("CsrGetConsoleOutputCodePage\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; } CSR_API(CsrSetConsoleOutputCodePage) { - PCSRSS_CONSOLE Console; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + NTSTATUS Status; - DPRINT("CsrSetConsoleOutputCodePage\n"); + DPRINT("CsrSetConsoleOutputCodePage\n"); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - return Status; + return Status; } - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) + if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) { - Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; + Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; } - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; } CSR_API(CsrGetProcessList) { - PDWORD Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - ULONG nItems = 0; - NTSTATUS Status; - ULONG_PTR Offset; + PDWORD Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + ULONG nItems = 0; + NTSTATUS Status; + ULONG_PTR Offset; - DPRINT("CsrGetProcessList\n"); + DPRINT("CsrGetProcessList\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Buffer = Request->Data.GetProcessListRequest.ProcessId; - Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) - || Offset & (sizeof(DWORD) - 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - for(current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if(++nItems <= Request->Data.GetProcessListRequest.nMaxIds) + Buffer = Request->Data.GetProcessListRequest.ProcessId; + Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) + || Offset & (sizeof(DWORD) - 1)) { - *Buffer++ = (DWORD)current->ProcessId; + return STATUS_ACCESS_VIOLATION; } - } - ConioUnlockConsole(Console); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } - Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; - return STATUS_SUCCESS; + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds) + { + *Buffer++ = (DWORD)current->ProcessId; + } + } + + ConioUnlockConsole(Console); + + Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; + return STATUS_SUCCESS; } CSR_API(CsrGenerateCtrlEvent) { - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DWORD Group; - NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DWORD Group; + NTSTATUS Status; - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Group = Request->Data.GenerateCtrlEvent.ProcessGroup; - Status = STATUS_INVALID_PARAMETER; - for (current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if (Group == 0 || current->ProcessGroup == Group) + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) { - ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); - Status = STATUS_SUCCESS; + return Status; } - } - ConioUnlockConsole(Console); + Group = Request->Data.GenerateCtrlEvent.ProcessGroup; + Status = STATUS_INVALID_PARAMETER; + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (Group == 0 || current->ProcessGroup == Group) + { + ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); + Status = STATUS_SUCCESS; + } + } - return Status; + ConioUnlockConsole(Console); + + return Status; } CSR_API(CsrSetScreenBufferSize) diff --git a/reactos/subsystems/win32/csrss/win32csr/desktopbg.c b/reactos/subsystems/win32/csrss/win32csr/desktopbg.c index 7221f323df9..1853ab6cc21 100644 --- a/reactos/subsystems/win32/csrss/win32csr/desktopbg.c +++ b/reactos/subsystems/win32/csrss/win32csr/desktopbg.c @@ -49,71 +49,71 @@ DtbgWindowProc(HWND Wnd, switch (Msg) { - case WM_ERASEBKGND: - PaintDesktop((HDC)wParam); - return 1; + case WM_ERASEBKGND: + PaintDesktop((HDC)wParam); + return 1; - case WM_PAINT: - if (BeginPaint(Wnd, &PS)) - EndPaint(Wnd, &PS); - return 0; + case WM_PAINT: + if (BeginPaint(Wnd, &PS)) + EndPaint(Wnd, &PS); + return 0; - case WM_SETCURSOR: - return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); + case WM_SETCURSOR: + return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); - case WM_NCCREATE: - return (LRESULT)TRUE; + case WM_NCCREATE: + return (LRESULT)TRUE; - case WM_CREATE: - case WM_CLOSE: - return 0; + case WM_CREATE: + case WM_CLOSE: + return 0; - case WM_NOTIFY: + case WM_NOTIFY: + { + PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; + + /* Use WM_NOTIFY for private messages since + * it can't be sent between processes! + */ + switch (nmh->hdr.code) { - PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; + case PM_SHOW_DESKTOP: + { + LRESULT Result; - /* Use WM_NOTIFY for private messages since - * it can't be sent between processes! - */ - switch (nmh->hdr.code) - { - case PM_SHOW_DESKTOP: - { - LRESULT Result; + Result = !SetWindowPos(Wnd, NULL, 0, 0, + nmh->ShowDesktop.Width, + nmh->ShowDesktop.Height, + SWP_NOACTIVATE | SWP_NOZORDER | + SWP_SHOWWINDOW); - Result = !SetWindowPos(Wnd, NULL, 0, 0, - nmh->ShowDesktop.Width, - nmh->ShowDesktop.Height, - SWP_NOACTIVATE | SWP_NOZORDER | - SWP_SHOWWINDOW); + UpdateWindow(Wnd); + VisibleDesktopWindow = Wnd; + return Result; + } - UpdateWindow(Wnd); - VisibleDesktopWindow = Wnd; - return Result; - } + case PM_HIDE_DESKTOP: + { + LRESULT Result; - case PM_HIDE_DESKTOP: - { - LRESULT Result; + Result = !SetWindowPos(Wnd, NULL, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | + SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); - Result = !SetWindowPos(Wnd, NULL, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOZORDER | - SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); - - UpdateWindow(Wnd); - VisibleDesktopWindow = NULL; - return Result; - } - - default: - DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", - nmh->hdr.code); - return 0; - } + UpdateWindow(Wnd); + VisibleDesktopWindow = NULL; + return Result; } default: - return DefWindowProcW(Wnd, Msg, wParam, lParam); + DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", + nmh->hdr.code); + return 0; + } + } + + default: + return DefWindowProcW(Wnd, Msg, wParam, lParam); } return 0; @@ -309,7 +309,7 @@ FASTCALL DtbgIsDesktopVisible(VOID) { if (VisibleDesktopWindow != NULL && - !IsWindowVisible(VisibleDesktopWindow)) + !IsWindowVisible(VisibleDesktopWindow)) { VisibleDesktopWindow = NULL; } diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 2e8947f014a..7d8b7e2aaf8 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -23,7 +23,7 @@ HINSTANCE Win32CsrDllHandle = NULL; static CSRSS_EXPORTED_FUNCS CsrExports; static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = - { +{ CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle), CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle), CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), @@ -83,37 +83,37 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize), CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo), { 0, 0, NULL } - }; +}; /* FUNCTIONS *****************************************************************/ BOOL WINAPI DllMain(HANDLE hDll, - DWORD dwReason, - LPVOID lpReserved) + DWORD dwReason, + LPVOID lpReserved) { - if (DLL_PROCESS_ATTACH == dwReason) + if (DLL_PROCESS_ATTACH == dwReason) { - Win32CsrDllHandle = hDll; - InitializeAppSwitchHook(); + Win32CsrDllHandle = hDll; + InitializeAppSwitchHook(); } - return TRUE; + return TRUE; } NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) { - return (CsrExports.CsrEnumProcessesProc)(EnumProc, Context); + return (CsrExports.CsrEnumProcessesProc)(EnumProc, Context); } static BOOL WINAPI Win32CsrInitComplete(void) { - PrivateCsrssInitialized(); + PrivateCsrssInitialized(); - return TRUE; + return TRUE; } BOOL WINAPI @@ -122,22 +122,22 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, PCSRSS_EXPORTED_FUNCS Exports, HANDLE CsrssApiHeap) { - NTSTATUS Status; - CsrExports = *Exports; - Win32CsrApiHeap = CsrssApiHeap; + NTSTATUS Status; + CsrExports = *Exports; + Win32CsrApiHeap = CsrssApiHeap; - Status = NtUserInitialize(0 ,NULL, NULL); + Status = NtUserInitialize(0, NULL, NULL); - PrivateCsrssManualGuiCheck(0); - CsrInitConsoleSupport(); + PrivateCsrssManualGuiCheck(0); + CsrInitConsoleSupport(); - *ApiDefinitions = Win32CsrApiDefinitions; - ServerProcs->InitCompleteProc = Win32CsrInitComplete; - ServerProcs->HardErrorProc = Win32CsrHardError; - ServerProcs->ProcessInheritProc = Win32CsrDuplicateHandleTable; - ServerProcs->ProcessDeletedProc = Win32CsrReleaseConsole; + *ApiDefinitions = Win32CsrApiDefinitions; + ServerProcs->InitCompleteProc = Win32CsrInitComplete; + ServerProcs->HardErrorProc = Win32CsrHardError; + ServerProcs->ProcessInheritProc = Win32CsrDuplicateHandleTable; + ServerProcs->ProcessDeletedProc = Win32CsrReleaseConsole; - return TRUE; + return TRUE; } /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/exitros.c b/reactos/subsystems/win32/csrss/win32csr/exitros.c index ca9fecbc188..984b44a86a3 100644 --- a/reactos/subsystems/win32/csrss/win32csr/exitros.c +++ b/reactos/subsystems/win32/csrss/win32csr/exitros.c @@ -18,61 +18,61 @@ static HANDLE LogonProcess = NULL; CSR_API(CsrRegisterLogonProcess) { - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (Request->Data.RegisterLogonProcessRequest.Register) + if (Request->Data.RegisterLogonProcessRequest.Register) { - if (0 != LogonProcess) + if (0 != LogonProcess) { - return STATUS_LOGON_SESSION_EXISTS; + return STATUS_LOGON_SESSION_EXISTS; } - LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId; + LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId; } - else + else { - if (Request->Header.ClientId.UniqueProcess != LogonProcess) + if (Request->Header.ClientId.UniqueProcess != LogonProcess) { - DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n", - LogonProcess, Request->Header.ClientId.UniqueProcess); - return STATUS_NOT_LOGON_PROCESS; + DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n", + LogonProcess, Request->Header.ClientId.UniqueProcess); + return STATUS_NOT_LOGON_PROCESS; } - LogonProcess = 0; + LogonProcess = 0; } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetLogonNotifyWindow) { - DWORD WindowCreator; + DWORD WindowCreator; - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - + sizeof(PORT_MESSAGE); - if (0 == GetWindowThreadProcessId(Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow, - &WindowCreator)) + if (0 == GetWindowThreadProcessId(Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow, + &WindowCreator)) { - DPRINT1("Can't get window creator\n"); - return STATUS_INVALID_HANDLE; + DPRINT1("Can't get window creator\n"); + return STATUS_INVALID_HANDLE; } - if (WindowCreator != (DWORD_PTR)LogonProcess) + if (WindowCreator != (DWORD_PTR)LogonProcess) { - DPRINT1("Trying to register window not created by winlogon as notify window\n"); - return STATUS_ACCESS_DENIED; + DPRINT1("Trying to register window not created by winlogon as notify window\n"); + return STATUS_ACCESS_DENIED; } - LogonNotifyWindow = Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow; + LogonNotifyWindow = Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } typedef struct tagSHUTDOWN_SETTINGS { - BOOL AutoEndTasks; - DWORD HungAppTimeout; - DWORD WaitToKillAppTimeout; + BOOL AutoEndTasks; + DWORD HungAppTimeout; + DWORD WaitToKillAppTimeout; } SHUTDOWN_SETTINGS, *PSHUTDOWN_SETTINGS; #define DEFAULT_AUTO_END_TASKS FALSE @@ -81,20 +81,20 @@ typedef struct tagSHUTDOWN_SETTINGS typedef struct tagNOTIFY_CONTEXT { - DWORD ProcessId; - UINT Msg; - WPARAM wParam; - LPARAM lParam; - HDESK Desktop; - DWORD StartTime; - DWORD QueryResult; - HWND Dlg; - DWORD EndNowResult; - BOOL ShowUI; - HANDLE UIThread; - HWND WndClient; - PSHUTDOWN_SETTINGS ShutdownSettings; - LPTHREAD_START_ROUTINE SendMessageProc; + DWORD ProcessId; + UINT Msg; + WPARAM wParam; + LPARAM lParam; + HDESK Desktop; + DWORD StartTime; + DWORD QueryResult; + HWND Dlg; + DWORD EndNowResult; + BOOL ShowUI; + HANDLE UIThread; + HWND WndClient; + PSHUTDOWN_SETTINGS ShutdownSettings; + LPTHREAD_START_ROUTINE SendMessageProc; } NOTIFY_CONTEXT, *PNOTIFY_CONTEXT; #define QUERY_RESULT_ABORT 0 @@ -106,30 +106,30 @@ typedef struct tagNOTIFY_CONTEXT static void FASTCALL UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext) { - DWORD Passed; + DWORD Passed; - Passed = GetTickCount() - NotifyContext->StartTime; - Passed -= NotifyContext->ShutdownSettings->HungAppTimeout; - if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed) + Passed = GetTickCount() - NotifyContext->StartTime; + Passed -= NotifyContext->ShutdownSettings->HungAppTimeout; + if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed) { - Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout; + Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout; } - SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0); + SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0); } static INT_PTR CALLBACK EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) { - INT_PTR Result; - PNOTIFY_CONTEXT NotifyContext; - HWND ProgressBar; - DWORD TitleLength; - int Len; - LPWSTR Title; + INT_PTR Result; + PNOTIFY_CONTEXT NotifyContext; + HWND ProgressBar; + DWORD TitleLength; + int Len; + LPWSTR Title; - switch(Msg) + switch(Msg) { - case WM_INITDIALOG: + case WM_INITDIALOG: NotifyContext = (PNOTIFY_CONTEXT) lParam; NotifyContext->EndNowResult = QUERY_RESULT_ABORT; SetWindowLongPtrW(Dlg, DWLP_USER, (LONG_PTR) lParam); @@ -138,13 +138,13 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) GetWindowTextLengthW(Dlg); Title = HeapAlloc(Win32CsrApiHeap, 0, (TitleLength + 1) * sizeof(WCHAR)); if (NULL != Title) - { + { Len = GetWindowTextW(Dlg, Title, TitleLength + 1); SendMessageW(NotifyContext->WndClient, WM_GETTEXT, TitleLength + 1 - Len, (LPARAM) (Title + Len)); SetWindowTextW(Dlg, Title); HeapFree(Win32CsrApiHeap, 0, Title); - } + } ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS); SendMessageW(ProgressBar, PBM_SETRANGE32, 0, NotifyContext->ShutdownSettings->WaitToKillAppTimeout / 2); @@ -153,33 +153,33 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) Result = FALSE; break; - case WM_TIMER: + case WM_TIMER: NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS); UpdateProgressBar(ProgressBar, NotifyContext); Result = TRUE; break; - case WM_COMMAND: + case WM_COMMAND: if (BN_CLICKED == HIWORD(wParam) && IDC_END_NOW == LOWORD(wParam)) - { + { NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); NotifyContext->EndNowResult = QUERY_RESULT_FORCE; SendMessageW(Dlg, WM_CLOSE, 0, 0); Result = TRUE; - } + } else - { + { Result = FALSE; - } + } break; - case WM_CLOSE: + case WM_CLOSE: DestroyWindow(Dlg); Result = TRUE; break; - case WM_DESTROY: + case WM_DESTROY: NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); NotifyContext->Dlg = NULL; KillTimer(Dlg, 0); @@ -187,12 +187,12 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) Result = TRUE; break; - default: + default: Result = FALSE; break; } - return Result; + return Result; } typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void); @@ -200,265 +200,265 @@ typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void); static void CallInitCommonControls() { - static BOOL Initialized = FALSE; - HMODULE Lib; - INITCOMMONCONTROLS_PROC InitProc; + static BOOL Initialized = FALSE; + HMODULE Lib; + INITCOMMONCONTROLS_PROC InitProc; - if (Initialized) + if (Initialized) { - return; + return; } - Lib = LoadLibraryW(L"COMCTL32.DLL"); - if (NULL == Lib) + Lib = LoadLibraryW(L"COMCTL32.DLL"); + if (NULL == Lib) { - return; + return; } - InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls"); - if (NULL == InitProc) + InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls"); + if (NULL == InitProc) { - return; + return; } - (*InitProc)(); + (*InitProc)(); - Initialized = TRUE; + Initialized = TRUE; } static DWORD WINAPI EndNowThreadProc(LPVOID Parameter) { - PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter; - MSG Msg; + PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter; + MSG Msg; - SetThreadDesktop(NotifyContext->Desktop); - SwitchDesktop(NotifyContext->Desktop); - CallInitCommonControls(); - NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"), - MAKEINTRESOURCE(IDD_END_NOW), NULL, - EndNowDlgProc, (LPARAM) NotifyContext); - if (NULL == NotifyContext->Dlg) + SetThreadDesktop(NotifyContext->Desktop); + SwitchDesktop(NotifyContext->Desktop); + CallInitCommonControls(); + NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"), + MAKEINTRESOURCE(IDD_END_NOW), NULL, + EndNowDlgProc, (LPARAM) NotifyContext); + if (NULL == NotifyContext->Dlg) { - return 0; + return 0; } - ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL); + ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL); - while (GetMessageW(&Msg, NULL, 0, 0)) + while (GetMessageW(&Msg, NULL, 0, 0)) { - if (! IsDialogMessage(NotifyContext->Dlg, &Msg)) + if (! IsDialogMessage(NotifyContext->Dlg, &Msg)) { - TranslateMessage(&Msg); - DispatchMessageW(&Msg); + TranslateMessage(&Msg); + DispatchMessageW(&Msg); } } - return Msg.wParam; + return Msg.wParam; } typedef struct tagMESSAGE_CONTEXT { - HWND Wnd; - UINT Msg; - WPARAM wParam; - LPARAM lParam; - DWORD Timeout; + HWND Wnd; + UINT Msg; + WPARAM wParam; + LPARAM lParam; + DWORD Timeout; } MESSAGE_CONTEXT, *PMESSAGE_CONTEXT; static DWORD WINAPI SendQueryEndSession(LPVOID Parameter) { - PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; - DWORD_PTR Result; + PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; + DWORD_PTR Result; - if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam, - Context->lParam, SMTO_NORMAL, Context->Timeout, - &Result)) + if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam, + Context->lParam, SMTO_NORMAL, Context->Timeout, + &Result)) { - return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT; + return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT; } - return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; + return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; } static DWORD WINAPI SendEndSession(LPVOID Parameter) { - PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; - DWORD_PTR Result; + PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; + DWORD_PTR Result; - if (Context->wParam) + if (Context->wParam) { - if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam, - Context->lParam, SMTO_NORMAL, Context->Timeout, - &Result)) + if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam, + Context->lParam, SMTO_NORMAL, Context->Timeout, + &Result)) { - return QUERY_RESULT_CONTINUE; + return QUERY_RESULT_CONTINUE; } - return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; + return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; } - else + else { - SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam, - Context->lParam); - return QUERY_RESULT_CONTINUE; + SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam, + Context->lParam); + return QUERY_RESULT_CONTINUE; } } static BOOL CALLBACK NotifyTopLevelEnum(HWND Wnd, LPARAM lParam) { - PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam; - MESSAGE_CONTEXT MessageContext; - DWORD Now, Passed; - DWORD Timeout, WaitStatus; - DWORD ProcessId; - HANDLE MessageThread; - HANDLE Threads[2]; + PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam; + MESSAGE_CONTEXT MessageContext; + DWORD Now, Passed; + DWORD Timeout, WaitStatus; + DWORD ProcessId; + HANDLE MessageThread; + HANDLE Threads[2]; - if (0 == GetWindowThreadProcessId(Wnd, &ProcessId)) + if (0 == GetWindowThreadProcessId(Wnd, &ProcessId)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - if (ProcessId == NotifyContext->ProcessId) + if (ProcessId == NotifyContext->ProcessId) { - Now = GetTickCount(); - if (0 == NotifyContext->StartTime) + Now = GetTickCount(); + if (0 == NotifyContext->StartTime) { - NotifyContext->StartTime = Now; + NotifyContext->StartTime = Now; } - /* Note: Passed is computed correctly even when GetTickCount() wraps due - to unsigned arithmetic */ - Passed = Now - NotifyContext->StartTime; - MessageContext.Wnd = Wnd; - MessageContext.Msg = NotifyContext->Msg; - MessageContext.wParam = NotifyContext->wParam; - MessageContext.lParam = NotifyContext->lParam; - MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; - if (! NotifyContext->ShutdownSettings->AutoEndTasks) + /* Note: Passed is computed correctly even when GetTickCount() wraps due + to unsigned arithmetic */ + Passed = Now - NotifyContext->StartTime; + MessageContext.Wnd = Wnd; + MessageContext.Msg = NotifyContext->Msg; + MessageContext.wParam = NotifyContext->wParam; + MessageContext.lParam = NotifyContext->lParam; + MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; + if (! NotifyContext->ShutdownSettings->AutoEndTasks) { - MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout; + MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout; } - if (Passed < MessageContext.Timeout) + if (Passed < MessageContext.Timeout) { - MessageContext.Timeout -= Passed; - MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc, - (LPVOID) &MessageContext, 0, NULL); - if (NULL == MessageThread) + MessageContext.Timeout -= Passed; + MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc, + (LPVOID) &MessageContext, 0, NULL); + if (NULL == MessageThread) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; - if (Passed < Timeout) + Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; + if (Passed < Timeout) { - Timeout -= Passed; - WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE); + Timeout -= Passed; + WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE); } - else + else { - WaitStatus = WAIT_TIMEOUT; + WaitStatus = WAIT_TIMEOUT; } - if (WAIT_TIMEOUT == WaitStatus) + if (WAIT_TIMEOUT == WaitStatus) { - NotifyContext->WndClient = Wnd; - if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI) + NotifyContext->WndClient = Wnd; + if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI) { - NotifyContext->UIThread = CreateThread(NULL, 0, - EndNowThreadProc, - (LPVOID) NotifyContext, - 0, NULL); + NotifyContext->UIThread = CreateThread(NULL, 0, + EndNowThreadProc, + (LPVOID) NotifyContext, + 0, NULL); } - Threads[0] = MessageThread; - Threads[1] = NotifyContext->UIThread; - WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ? - 1 : 2, - Threads, FALSE, INFINITE, - FALSE); - if (WAIT_OBJECT_0 == WaitStatus) + Threads[0] = MessageThread; + Threads[1] = NotifyContext->UIThread; + WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ? + 1 : 2, + Threads, FALSE, INFINITE, + FALSE); + if (WAIT_OBJECT_0 == WaitStatus) { - if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult)) + if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else if (WAIT_OBJECT_0 + 1 == WaitStatus) + else if (WAIT_OBJECT_0 + 1 == WaitStatus) { - if (! GetExitCodeThread(NotifyContext->UIThread, - &NotifyContext->QueryResult)) + if (! GetExitCodeThread(NotifyContext->UIThread, + &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } - if (WAIT_OBJECT_0 != WaitStatus) + if (WAIT_OBJECT_0 != WaitStatus) { - TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT); + TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT); } } - else if (WAIT_OBJECT_0 == WaitStatus) + else if (WAIT_OBJECT_0 == WaitStatus) { - if (! GetExitCodeThread(MessageThread, - &NotifyContext->QueryResult)) + if (! GetExitCodeThread(MessageThread, + &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } - CloseHandle(MessageThread); + CloseHandle(MessageThread); } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT; + NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT; } } - return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult; + return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult; } static BOOL CALLBACK NotifyDesktopEnum(LPWSTR DesktopName, LPARAM lParam) { - PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam; + PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam; - Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE, - DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP); - if (NULL == Context->Desktop) + Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE, + DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP); + if (NULL == Context->Desktop) { - DPRINT1("OpenDesktop failed with error %d\n", GetLastError()); - Context->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + DPRINT1("OpenDesktop failed with error %d\n", GetLastError()); + Context->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam); + EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam); - CloseDesktop(Context->Desktop); + CloseDesktop(Context->Desktop); - return QUERY_RESULT_CONTINUE == Context->QueryResult; + return QUERY_RESULT_CONTINUE == Context->QueryResult; } static BOOL FASTCALL NotifyTopLevelWindows(PNOTIFY_CONTEXT Context) { - HWINSTA WindowStation; + HWINSTA WindowStation; - WindowStation = GetProcessWindowStation(); - if (NULL == WindowStation) + WindowStation = GetProcessWindowStation(); + if (NULL == WindowStation) { - DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError()); - return TRUE; + DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError()); + return TRUE; } - EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context); + EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context); - return TRUE; + return TRUE; } static BOOL FASTCALL @@ -466,476 +466,476 @@ NotifyAndTerminateProcess(PCSRSS_PROCESS_DATA ProcessData, PSHUTDOWN_SETTINGS ShutdownSettings, UINT Flags) { - NOTIFY_CONTEXT Context; - HANDLE Process; - DWORD QueryResult = QUERY_RESULT_CONTINUE; + NOTIFY_CONTEXT Context; + HANDLE Process; + DWORD QueryResult = QUERY_RESULT_CONTINUE; - Context.QueryResult = QUERY_RESULT_CONTINUE; + Context.QueryResult = QUERY_RESULT_CONTINUE; - if (0 == (Flags & EWX_FORCE)) + if (0 == (Flags & EWX_FORCE)) { - if (NULL != ProcessData->Console) + if (NULL != ProcessData->Console) { - ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData, - ShutdownSettings->WaitToKillAppTimeout); + ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData, + ShutdownSettings->WaitToKillAppTimeout); } - else + else { - Context.ProcessId = (DWORD_PTR) ProcessData->ProcessId; - Context.wParam = 0; - Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? - ENDSESSION_LOGOFF : 0); - Context.StartTime = 0; - Context.UIThread = NULL; - Context.ShowUI = DtbgIsDesktopVisible(); - Context.Dlg = NULL; - Context.ShutdownSettings = ShutdownSettings; - Context.SendMessageProc = SendQueryEndSession; + Context.ProcessId = (DWORD_PTR) ProcessData->ProcessId; + Context.wParam = 0; + Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? + ENDSESSION_LOGOFF : 0); + Context.StartTime = 0; + Context.UIThread = NULL; + Context.ShowUI = DtbgIsDesktopVisible(); + Context.Dlg = NULL; + Context.ShutdownSettings = ShutdownSettings; + Context.SendMessageProc = SendQueryEndSession; - NotifyTopLevelWindows(&Context); + NotifyTopLevelWindows(&Context); - Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult); - Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? - ENDSESSION_LOGOFF : 0); - Context.SendMessageProc = SendEndSession; - Context.ShowUI = DtbgIsDesktopVisible() && - (QUERY_RESULT_ABORT != Context.QueryResult); - QueryResult = Context.QueryResult; - Context.QueryResult = QUERY_RESULT_CONTINUE; + Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult); + Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? + ENDSESSION_LOGOFF : 0); + Context.SendMessageProc = SendEndSession; + Context.ShowUI = DtbgIsDesktopVisible() && + (QUERY_RESULT_ABORT != Context.QueryResult); + QueryResult = Context.QueryResult; + Context.QueryResult = QUERY_RESULT_CONTINUE; - NotifyTopLevelWindows(&Context); + NotifyTopLevelWindows(&Context); - if (NULL != Context.UIThread) + if (NULL != Context.UIThread) { - if (NULL != Context.Dlg) + if (NULL != Context.Dlg) { - SendMessageW(Context.Dlg, WM_CLOSE, 0, 0); + SendMessageW(Context.Dlg, WM_CLOSE, 0, 0); } - else + else { - TerminateThread(Context.UIThread, QUERY_RESULT_ERROR); + TerminateThread(Context.UIThread, QUERY_RESULT_ERROR); } - CloseHandle(Context.UIThread); + CloseHandle(Context.UIThread); } } - if (QUERY_RESULT_ABORT == QueryResult) + if (QUERY_RESULT_ABORT == QueryResult) { - return FALSE; + return FALSE; } } - /* Terminate this process */ - Process = OpenProcess(PROCESS_TERMINATE, FALSE, - (DWORD_PTR) ProcessData->ProcessId); - if (NULL == Process) + /* Terminate this process */ + Process = OpenProcess(PROCESS_TERMINATE, FALSE, + (DWORD_PTR) ProcessData->ProcessId); + if (NULL == Process) { - DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, - GetLastError()); - return TRUE; + DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, + GetLastError()); + return TRUE; } - TerminateProcess(Process, 0); - CloseHandle(Process); + TerminateProcess(Process, 0); + CloseHandle(Process); - return TRUE; + return TRUE; } typedef struct tagPROCESS_ENUM_CONTEXT { - UINT ProcessCount; - PCSRSS_PROCESS_DATA *ProcessData; - TOKEN_ORIGIN TokenOrigin; - DWORD ShellProcess; - DWORD CsrssProcess; + UINT ProcessCount; + PCSRSS_PROCESS_DATA *ProcessData; + TOKEN_ORIGIN TokenOrigin; + DWORD ShellProcess; + DWORD CsrssProcess; } PROCESS_ENUM_CONTEXT, *PPROCESS_ENUM_CONTEXT; static NTSTATUS WINAPI ExitReactosProcessEnum(PCSRSS_PROCESS_DATA ProcessData, PVOID Data) { - HANDLE Process; - HANDLE Token; - TOKEN_ORIGIN Origin; - DWORD ReturnLength; - PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data; - PCSRSS_PROCESS_DATA *NewData; + HANDLE Process; + HANDLE Token; + TOKEN_ORIGIN Origin; + DWORD ReturnLength; + PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data; + PCSRSS_PROCESS_DATA *NewData; - /* Do not kill winlogon or csrss */ - if ((DWORD_PTR) ProcessData->ProcessId == Context->CsrssProcess || - ProcessData->ProcessId == LogonProcess) + /* Do not kill winlogon or csrss */ + if ((DWORD_PTR) ProcessData->ProcessId == Context->CsrssProcess || + ProcessData->ProcessId == LogonProcess) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - /* Get the login session of this process */ - Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, - (DWORD_PTR) ProcessData->ProcessId); - if (NULL == Process) + /* Get the login session of this process */ + Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, + (DWORD_PTR) ProcessData->ProcessId); + if (NULL == Process) { - DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, - GetLastError()); - return STATUS_UNSUCCESSFUL; + DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, + GetLastError()); + return STATUS_UNSUCCESSFUL; } - if (! OpenProcessToken(Process, TOKEN_QUERY, &Token)) + if (! OpenProcessToken(Process, TOKEN_QUERY, &Token)) { - DPRINT1("Unable to open token for process %d, error %d\n", - ProcessData->ProcessId, GetLastError()); - CloseHandle(Process); - return STATUS_UNSUCCESSFUL; + DPRINT1("Unable to open token for process %d, error %d\n", + ProcessData->ProcessId, GetLastError()); + CloseHandle(Process); + return STATUS_UNSUCCESSFUL; } - CloseHandle(Process); + CloseHandle(Process); - if (! GetTokenInformation(Token, TokenOrigin, &Origin, - sizeof(TOKEN_ORIGIN), &ReturnLength)) + if (! GetTokenInformation(Token, TokenOrigin, &Origin, + sizeof(TOKEN_ORIGIN), &ReturnLength)) { - DPRINT1("GetTokenInformation failed for process %d with error %d\n", - ProcessData->ProcessId, GetLastError()); - CloseHandle(Token); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed for process %d with error %d\n", + ProcessData->ProcessId, GetLastError()); + CloseHandle(Token); + return STATUS_UNSUCCESSFUL; } - CloseHandle(Token); + CloseHandle(Token); - /* This process will be killed if it's in the correct logon session */ - if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession), - &(Origin.OriginatingLogonSession))) + /* This process will be killed if it's in the correct logon session */ + if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession), + &(Origin.OriginatingLogonSession))) { - /* Kill the shell process last */ - if ((DWORD_PTR) ProcessData->ProcessId == Context->ShellProcess) + /* Kill the shell process last */ + if ((DWORD_PTR) ProcessData->ProcessId == Context->ShellProcess) { - ProcessData->ShutdownLevel = 0; + ProcessData->ShutdownLevel = 0; } - NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1) - * sizeof(PCSRSS_PROCESS_DATA)); - if (NULL == NewData) + NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1) + * sizeof(PCSRSS_PROCESS_DATA)); + if (NULL == NewData) { - return STATUS_NO_MEMORY; + return STATUS_NO_MEMORY; } - if (0 != Context->ProcessCount) + if (0 != Context->ProcessCount) { - memcpy(NewData, Context->ProcessData, - Context->ProcessCount * sizeof(PCSRSS_PROCESS_DATA)); - HeapFree(Win32CsrApiHeap, 0, Context->ProcessData); + memcpy(NewData, Context->ProcessData, + Context->ProcessCount * sizeof(PCSRSS_PROCESS_DATA)); + HeapFree(Win32CsrApiHeap, 0, Context->ProcessData); } - Context->ProcessData = NewData; - Context->ProcessData[Context->ProcessCount] = ProcessData; - Context->ProcessCount++; + Context->ProcessData = NewData; + Context->ProcessData[Context->ProcessCount] = ProcessData; + Context->ProcessCount++; } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } static int ProcessDataCompare(const void *Elem1, const void *Elem2) { - const PCSRSS_PROCESS_DATA *ProcessData1 = (PCSRSS_PROCESS_DATA *) Elem1; - const PCSRSS_PROCESS_DATA *ProcessData2 = (PCSRSS_PROCESS_DATA *) Elem2; + const PCSRSS_PROCESS_DATA *ProcessData1 = (PCSRSS_PROCESS_DATA *) Elem1; + const PCSRSS_PROCESS_DATA *ProcessData2 = (PCSRSS_PROCESS_DATA *) Elem2; - if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel) + if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel) { - return +1; + return +1; } - else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel) + else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel) { - return -1; + return -1; } - else if ((*ProcessData1)->ProcessId < (*ProcessData2)->ProcessId) + else if ((*ProcessData1)->ProcessId < (*ProcessData2)->ProcessId) { - return +1; + return +1; } - else if ((*ProcessData2)->ProcessId < (*ProcessData1)->ProcessId) + else if ((*ProcessData2)->ProcessId < (*ProcessData1)->ProcessId) { - return -1; + return -1; } - return 0; + return 0; } static DWORD FASTCALL GetShutdownSetting(HKEY DesktopKey, LPCWSTR ValueName, DWORD DefaultValue) { - BYTE ValueBuffer[16]; - LONG ErrCode; - DWORD Type; - DWORD ValueSize; - UNICODE_STRING StringValue; - ULONG Value; + BYTE ValueBuffer[16]; + LONG ErrCode; + DWORD Type; + DWORD ValueSize; + UNICODE_STRING StringValue; + ULONG Value; - ValueSize = sizeof(ValueBuffer); - ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer, - &ValueSize); - if (ERROR_SUCCESS != ErrCode) + ValueSize = sizeof(ValueBuffer); + ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer, + &ValueSize); + if (ERROR_SUCCESS != ErrCode) { - DPRINT("GetShutdownSetting for %S failed with error code %ld\n", - ValueName, ErrCode); - return DefaultValue; + DPRINT("GetShutdownSetting for %S failed with error code %ld\n", + ValueName, ErrCode); + return DefaultValue; } - if (REG_SZ == Type) + if (REG_SZ == Type) { - RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer); - if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value))) + RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer); + if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value))) { - DPRINT1("Unable to convert value %S for setting %S\n", - StringValue.Buffer, ValueName); - return DefaultValue; + DPRINT1("Unable to convert value %S for setting %S\n", + StringValue.Buffer, ValueName); + return DefaultValue; } - return (DWORD) Value; + return (DWORD) Value; } - else if (REG_DWORD == Type) + else if (REG_DWORD == Type) { - return *((DWORD *) ValueBuffer); + return *((DWORD *) ValueBuffer); } - DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName); - return DefaultValue; + DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName); + return DefaultValue; } static void FASTCALL LoadShutdownSettings(PSID Sid, PSHUTDOWN_SETTINGS ShutdownSettings) { - static WCHAR Subkey[] = L"\\Control Panel\\Desktop"; - LPWSTR StringSid; - WCHAR InitialKeyName[128]; - LPWSTR KeyName; - HKEY DesktopKey; - LONG ErrCode; + static WCHAR Subkey[] = L"\\Control Panel\\Desktop"; + LPWSTR StringSid; + WCHAR InitialKeyName[128]; + LPWSTR KeyName; + HKEY DesktopKey; + LONG ErrCode; - ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS; - ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT; - ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT; + ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS; + ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT; + ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT; - if (! ConvertSidToStringSidW(Sid, &StringSid)) + if (! ConvertSidToStringSidW(Sid, &StringSid)) { - DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n", - GetLastError()); - return; + DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n", + GetLastError()); + return; } - if (wcslen(StringSid) + wcslen(Subkey) + 1 <= - sizeof(InitialKeyName) / sizeof(WCHAR)) + if (wcslen(StringSid) + wcslen(Subkey) + 1 <= + sizeof(InitialKeyName) / sizeof(WCHAR)) { - KeyName = InitialKeyName; + KeyName = InitialKeyName; } - else + else { - KeyName = HeapAlloc(Win32CsrApiHeap, 0, - (wcslen(StringSid) + wcslen(Subkey) + 1) * - sizeof(WCHAR)); - if (NULL == KeyName) + KeyName = HeapAlloc(Win32CsrApiHeap, 0, + (wcslen(StringSid) + wcslen(Subkey) + 1) * + sizeof(WCHAR)); + if (NULL == KeyName) { - DPRINT1("Failed to allocate memory, using default shutdown settings\n"); - LocalFree(StringSid); - return; + DPRINT1("Failed to allocate memory, using default shutdown settings\n"); + LocalFree(StringSid); + return; } } - wcscat(wcscpy(KeyName, StringSid), Subkey); - LocalFree(StringSid); + wcscat(wcscpy(KeyName, StringSid), Subkey); + LocalFree(StringSid); - ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey); - if (KeyName != InitialKeyName) + ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey); + if (KeyName != InitialKeyName) { - HeapFree(Win32CsrApiHeap, 0, KeyName); + HeapFree(Win32CsrApiHeap, 0, KeyName); } - if (ERROR_SUCCESS != ErrCode) + if (ERROR_SUCCESS != ErrCode) { - DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode); - return; + DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode); + return; } - ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks", - (DWORD) DEFAULT_AUTO_END_TASKS); - ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey, - L"HungAppTimeout", - DEFAULT_HUNG_APP_TIMEOUT); - ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey, - L"WaitToKillAppTimeout", - DEFAULT_WAIT_TO_KILL_APP_TIMEOUT); + ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks", + (DWORD) DEFAULT_AUTO_END_TASKS); + ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey, + L"HungAppTimeout", + DEFAULT_HUNG_APP_TIMEOUT); + ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey, + L"WaitToKillAppTimeout", + DEFAULT_WAIT_TO_KILL_APP_TIMEOUT); - RegCloseKey(DesktopKey); + RegCloseKey(DesktopKey); } static NTSTATUS FASTCALL InternalExitReactos(DWORD ProcessId, DWORD ThreadId, UINT Flags) { - HANDLE CallerThread; - HANDLE CallerToken; - NTSTATUS Status; - PROCESS_ENUM_CONTEXT Context; - DWORD ReturnLength; - HWND ShellWnd; - UINT ProcessIndex; - char FixedUserInfo[64]; - TOKEN_USER *UserInfo; - SHUTDOWN_SETTINGS ShutdownSettings; + HANDLE CallerThread; + HANDLE CallerToken; + NTSTATUS Status; + PROCESS_ENUM_CONTEXT Context; + DWORD ReturnLength; + HWND ShellWnd; + UINT ProcessIndex; + char FixedUserInfo[64]; + TOKEN_USER *UserInfo; + SHUTDOWN_SETTINGS ShutdownSettings; - if (ProcessId != (DWORD_PTR) LogonProcess) + if (ProcessId != (DWORD_PTR) LogonProcess) { - DPRINT1("Internal ExitWindowsEx call not from winlogon\n"); - return STATUS_ACCESS_DENIED; + DPRINT1("Internal ExitWindowsEx call not from winlogon\n"); + return STATUS_ACCESS_DENIED; } - DPRINT1("FIXME: Need to close all user processes!\n"); - return STATUS_SUCCESS; + DPRINT1("FIXME: Need to close all user processes!\n"); + return STATUS_SUCCESS; - CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId); - if (NULL == CallerThread) + CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId); + if (NULL == CallerThread) { - DPRINT1("OpenThread failed with error %d\n", GetLastError()); - return STATUS_UNSUCCESSFUL; + DPRINT1("OpenThread failed with error %d\n", GetLastError()); + return STATUS_UNSUCCESSFUL; } - if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken)) + if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken)) { - DPRINT1("OpenThreadToken failed with error %d\n", GetLastError()); - CloseHandle(CallerThread); - return STATUS_UNSUCCESSFUL; + DPRINT1("OpenThreadToken failed with error %d\n", GetLastError()); + CloseHandle(CallerThread); + return STATUS_UNSUCCESSFUL; } - CloseHandle(CallerThread); + CloseHandle(CallerThread); - Context.ProcessCount = 0; - Context.ProcessData = NULL; - if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin, - sizeof(TOKEN_ORIGIN), &ReturnLength)) + Context.ProcessCount = 0; + Context.ProcessData = NULL; + if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin, + sizeof(TOKEN_ORIGIN), &ReturnLength)) { - DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } - if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo, - sizeof(FixedUserInfo), &ReturnLength)) + if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo, + sizeof(FixedUserInfo), &ReturnLength)) { - if (sizeof(FixedUserInfo) < ReturnLength) + if (sizeof(FixedUserInfo) < ReturnLength) { - UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength); - if (NULL == UserInfo) + UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength); + if (NULL == UserInfo) { - DPRINT1("Unable to allocate %u bytes for user info\n", - (unsigned) ReturnLength); - CloseHandle(CallerToken); - return STATUS_NO_MEMORY; + DPRINT1("Unable to allocate %u bytes for user info\n", + (unsigned) ReturnLength); + CloseHandle(CallerToken); + return STATUS_NO_MEMORY; } - if (! GetTokenInformation(CallerToken, TokenUser, UserInfo, - ReturnLength, &ReturnLength)) + if (! GetTokenInformation(CallerToken, TokenUser, UserInfo, + ReturnLength, &ReturnLength)) { - DPRINT1("GetTokenInformation failed with error %d\n", - GetLastError()); - HeapFree(Win32CsrApiHeap, 0, UserInfo); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", + GetLastError()); + HeapFree(Win32CsrApiHeap, 0, UserInfo); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } } - else + else { - DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } } - else + else { - UserInfo = (TOKEN_USER *) FixedUserInfo; + UserInfo = (TOKEN_USER *) FixedUserInfo; } - CloseHandle(CallerToken); - LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings); - if (UserInfo != (TOKEN_USER *) FixedUserInfo) + CloseHandle(CallerToken); + LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings); + if (UserInfo != (TOKEN_USER *) FixedUserInfo) { - HeapFree(Win32CsrApiHeap, 0, UserInfo); + HeapFree(Win32CsrApiHeap, 0, UserInfo); } - Context.CsrssProcess = GetCurrentProcessId(); - ShellWnd = GetShellWindow(); - if (NULL == ShellWnd) + Context.CsrssProcess = GetCurrentProcessId(); + ShellWnd = GetShellWindow(); + if (NULL == ShellWnd) { - DPRINT("No shell present\n"); - Context.ShellProcess = 0; + DPRINT("No shell present\n"); + Context.ShellProcess = 0; } - else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess)) + else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess)) { - DPRINT1("Can't get process id of shell window\n"); - Context.ShellProcess = 0; + DPRINT1("Can't get process id of shell window\n"); + Context.ShellProcess = 0; } - Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context); - if (! NT_SUCCESS(Status)) + Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context); + if (! NT_SUCCESS(Status)) { - DPRINT1("Failed to enumerate registered processes, status 0x%x\n", - Status); - if (NULL != Context.ProcessData) + DPRINT1("Failed to enumerate registered processes, status 0x%x\n", + Status); + if (NULL != Context.ProcessData) { - HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); + HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); } - return Status; + return Status; } - qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSRSS_PROCESS_DATA), - ProcessDataCompare); + qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSRSS_PROCESS_DATA), + ProcessDataCompare); - /* Terminate processes, stop if we find one kicking and screaming it doesn't - want to die */ - Status = STATUS_SUCCESS; - for (ProcessIndex = 0; - ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status); - ProcessIndex++) + /* Terminate processes, stop if we find one kicking and screaming it doesn't + want to die */ + Status = STATUS_SUCCESS; + for (ProcessIndex = 0; + ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status); + ProcessIndex++) { - if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex], - &ShutdownSettings, Flags)) + if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex], + &ShutdownSettings, Flags)) { - Status = STATUS_REQUEST_ABORTED; + Status = STATUS_REQUEST_ABORTED; } } - /* Cleanup */ - if (NULL != Context.ProcessData) + /* Cleanup */ + if (NULL != Context.ProcessData) { - HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); + HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); } - return Status; + return Status; } static NTSTATUS FASTCALL UserExitReactos(DWORD UserProcessId, UINT Flags) { - NTSTATUS Status; + NTSTATUS Status; - if (NULL == LogonNotifyWindow) + if (NULL == LogonNotifyWindow) { - DPRINT1("No LogonNotifyWindow registered\n"); - return STATUS_NOT_FOUND; + DPRINT1("No LogonNotifyWindow registered\n"); + return STATUS_NOT_FOUND; } - /* FIXME Inside 2000 says we should impersonate the caller here */ - Status = SendMessageW(LogonNotifyWindow, PM_WINLOGON_EXITWINDOWS, - (WPARAM) UserProcessId, - (LPARAM) Flags); - /* If the message isn't handled, the return value is 0, so 0 doesn't indicate - success. Success is indicated by a 1 return value, if anything besides 0 - or 1 it's a NTSTATUS value */ - if (1 == Status) + /* FIXME Inside 2000 says we should impersonate the caller here */ + Status = SendMessageW(LogonNotifyWindow, PM_WINLOGON_EXITWINDOWS, + (WPARAM) UserProcessId, + (LPARAM) Flags); + /* If the message isn't handled, the return value is 0, so 0 doesn't indicate + success. Success is indicated by a 1 return value, if anything besides 0 + or 1 it's a NTSTATUS value */ + if (1 == Status) { - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; } - else if (0 == Status) + else if (0 == Status) { - Status = STATUS_NOT_IMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; } - return Status; + return Status; } CSR_API(CsrExitReactos) { - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - + sizeof(PORT_MESSAGE); - if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG)) + if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG)) { - return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, - Request->Data.ExitReactosRequest.Flags); + return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, + Request->Data.ExitReactosRequest.Flags); } - else + else { - return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, - (DWORD_PTR) Request->Header.ClientId.UniqueThread, - Request->Data.ExitReactosRequest.Flags); + return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, + (DWORD_PTR) Request->Header.ClientId.UniqueThread, + Request->Data.ExitReactosRequest.Flags); } } diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 5398fd40a4e..e274872a6eb 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -19,33 +19,33 @@ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); typedef struct GUI_CONSOLE_DATA_TAG { - HFONT Font; - unsigned CharWidth; - unsigned CharHeight; - BOOL CursorBlinkOn; - BOOL ForceCursorOff; - CRITICAL_SECTION Lock; - HMODULE ConsoleLibrary; - HANDLE hGuiInitEvent; - WCHAR FontName[LF_FACESIZE]; - DWORD FontSize; - DWORD FontWeight; - DWORD HistoryNoDup; - DWORD FullScreen; - DWORD QuickEdit; - DWORD InsertMode; - DWORD NumberOfHistoryBuffers; - DWORD HistoryBufferSize; - DWORD WindowPosition; - DWORD UseRasterFonts; - COLORREF ScreenText; - COLORREF ScreenBackground; - COLORREF PopupBackground; - COLORREF PopupText; - COLORREF Colors[16]; - WCHAR szProcessName[MAX_PATH]; - BOOL WindowSizeLock; - POINT OldCursor; + HFONT Font; + unsigned CharWidth; + unsigned CharHeight; + BOOL CursorBlinkOn; + BOOL ForceCursorOff; + CRITICAL_SECTION Lock; + HMODULE ConsoleLibrary; + HANDLE hGuiInitEvent; + WCHAR FontName[LF_FACESIZE]; + DWORD FontSize; + DWORD FontWeight; + DWORD HistoryNoDup; + DWORD FullScreen; + DWORD QuickEdit; + DWORD InsertMode; + DWORD NumberOfHistoryBuffers; + DWORD HistoryBufferSize; + DWORD WindowPosition; + DWORD UseRasterFonts; + COLORREF ScreenText; + COLORREF ScreenBackground; + COLORREF PopupBackground; + COLORREF PopupText; + COLORREF Colors[16]; + WCHAR szProcessName[MAX_PATH]; + BOOL WindowSizeLock; + POINT OldCursor; } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; #ifndef WM_APP @@ -164,8 +164,8 @@ GuiConsoleAppendMenuItems(HMENU hMenu, 0, NULL); } - i++; - }while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); + i++; + } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } static VOID @@ -185,206 +185,206 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) static VOID GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) { - *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); - *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); + *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); + *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); } static BOOL GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) { - HANDLE hProcessToken = NULL; - HANDLE hProcess; + HANDLE hProcessToken = NULL; + HANDLE hProcess; - BYTE Buffer[256]; - DWORD Length = 0; - UNICODE_STRING SidName; - LONG res; - PTOKEN_USER TokUser; + BYTE Buffer[256]; + DWORD Length = 0; + UNICODE_STRING SidName; + LONG res; + PTOKEN_USER TokUser; - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); - if (!hProcess) + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); + if (!hProcess) { - DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); + return FALSE; } - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { - DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); - CloseHandle(hProcess); - return FALSE; + DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); + CloseHandle(hProcess); + return FALSE; } - if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) + if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) { - DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); - CloseHandle(hProcess); - CloseHandle(hProcessToken); - return FALSE; + DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); + CloseHandle(hProcess); + CloseHandle(hProcessToken); + return FALSE; } - TokUser = ((PTOKEN_USER)Buffer)->User.Sid; - if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) + TokUser = ((PTOKEN_USER)Buffer)->User.Sid; + if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) { - DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); + return FALSE; } - res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); - RtlFreeUnicodeString(&SidName); + res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); + RtlFreeUnicodeString(&SidName); - CloseHandle(hProcessToken); - if (hProcHandle) - *hProcHandle = hProcess; - else - CloseHandle(hProcess); + CloseHandle(hProcessToken); + if (hProcHandle) + *hProcHandle = hProcess; + else + CloseHandle(hProcess); - if (res != ERROR_SUCCESS) - return FALSE; - else - return TRUE; + if (res != ERROR_SUCCESS) + return FALSE; + else + return TRUE; } static BOOL GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) { - WCHAR szProcessName[MAX_PATH]; - WCHAR szBuffer[MAX_PATH]; - UINT fLength, wLength; - DWORD dwBitmask, dwLength; - WCHAR CurDrive[] = { 'A',':', 0 }; - HANDLE hProcess; - HKEY hKey; - WCHAR * ptr; + WCHAR szProcessName[MAX_PATH]; + WCHAR szBuffer[MAX_PATH]; + UINT fLength, wLength; + DWORD dwBitmask, dwLength; + WCHAR CurDrive[] = { 'A',':', 0 }; + HANDLE hProcess; + HKEY hKey; + WCHAR * ptr; - /* - * console properties are stored under - * HKCU\Console\* - * - * There are 3 ways to store console properties - * - * 1. use console title as subkey name - * i.e. cmd.exe - * - * 2. use application name as subkey name - * - * 3. use unexpanded path to console application. - * i.e. %SystemRoot%_system32_cmd.exe - */ + /* + * console properties are stored under + * HKCU\Console\* + * + * There are 3 ways to store console properties + * + * 1. use console title as subkey name + * i.e. cmd.exe + * + * 2. use application name as subkey name + * + * 3. use unexpanded path to console application. + * i.e. %SystemRoot%_system32_cmd.exe + */ - DPRINT("GuiConsoleOpenUserSettings entered\n"); + DPRINT("GuiConsoleOpenUserSettings entered\n"); - if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) + if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) { - DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); - return FALSE; + DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); + return FALSE; } - /* FIXME we do not getting the process name so no menu will be loading, why ?*/ - fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); - CloseHandle(hProcess); + /* FIXME we do not getting the process name so no menu will be loading, why ?*/ + fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); + CloseHandle(hProcess); - //DPRINT1("szProcessName3 : %S\n",szProcessName); + //DPRINT1("szProcessName3 : %S\n",szProcessName); - if (!fLength) + if (!fLength) { - DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); - return FALSE; + DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); + return FALSE; } - /* - * try the process name as path - */ + /* + * try the process name as path + */ - ptr = wcsrchr(szProcessName, L'\\'); - wcscpy(GuiData->szProcessName, ptr); + ptr = wcsrchr(szProcessName, L'\\'); + wcscpy(GuiData->szProcessName, ptr); - swprintf(szBuffer, L"Console%s",ptr); - DPRINT("#1 Path : %S\n", szBuffer); + swprintf(szBuffer, L"Console%s",ptr); + DPRINT("#1 Path : %S\n", szBuffer); - if (bCreate) + if (bCreate) { - if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) + if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - RegCloseKey(hKey); - return FALSE; - } - - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) - { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return FALSE; } - /* - * try the "Shortcut to processname" as path - * FIXME: detect wheter the process was started as a shortcut - */ - - swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); - DPRINT("#2 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - /* - * if the path contains \\Device\\HarddiskVolume1\... remove it - */ + /* + * try the "Shortcut to processname" as path + * FIXME: detect wheter the process was started as a shortcut + */ - if (szProcessName[0] == L'\\') + swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); + DPRINT("#2 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - dwBitmask = GetLogicalDrives(); - while(dwBitmask) + swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); + RegCloseKey(hKey); + return TRUE; + } + + /* + * if the path contains \\Device\\HarddiskVolume1\... remove it + */ + + if (szProcessName[0] == L'\\') + { + dwBitmask = GetLogicalDrives(); + while(dwBitmask) { - if (dwBitmask & 0x1) + if (dwBitmask & 0x1) { - dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); - if (dwLength) + dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); + if (dwLength) { - if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) + if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) { - wcscpy(szProcessName, CurDrive); - RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); - break; + wcscpy(szProcessName, CurDrive); + RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); + break; } } } - dwBitmask = (dwBitmask >> 1); - CurDrive[0]++; + dwBitmask = (dwBitmask >> 1); + CurDrive[0]++; } } - /* - * last attempt: check whether the file is under %SystemRoot% - * and use path like Console\%SystemRoot%_dir_dir2_file.exe - */ + /* + * last attempt: check whether the file is under %SystemRoot% + * and use path like Console\%SystemRoot%_dir_dir2_file.exe + */ - wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); - if (wLength) + wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); + if (wLength) { - if (!wcsncmp(szProcessName, szBuffer, wLength)) + if (!wcsncmp(szProcessName, szBuffer, wLength)) { - /* replace slashes by underscores */ - while((ptr = wcschr(szProcessName, L'\\'))) - ptr[0] = L'_'; + /* replace slashes by underscores */ + while((ptr = wcschr(szProcessName, L'\\'))) + ptr[0] = L'_'; - swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); - DPRINT("#3 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); + DPRINT("#3 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); - RegCloseKey(hKey); - return TRUE; + swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); + RegCloseKey(hKey); + return TRUE; } } } - RegCloseKey(hKey); - return FALSE; + RegCloseKey(hKey); + return FALSE; } static VOID @@ -394,238 +394,238 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) PCSRSS_PROCESS_DATA ProcessData; if (Console->ProcessList.Flink == &Console->ProcessList) - { + { DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); return; - } + } ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE)) - { + { return; - } - - if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) - { - RegDeleteKeyW(hKey, L"CursorSize"); - } - else - { - RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->NumberOfHistoryBuffers == 5) + if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) { - RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); - } - else - { - RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); - } - - if (GuiData->HistoryBufferSize == 50) - { - RegDeleteKeyW(hKey, L"HistoryBufferSize"); - } - else - { - RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); - } - - if (GuiData->FullScreen == FALSE) - { - RegDeleteKeyW(hKey, L"FullScreen"); - } - else - { - RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); - } - - if ( GuiData->QuickEdit == FALSE) - { - RegDeleteKeyW(hKey, L"QuickEdit"); + RegDeleteKeyW(hKey, L"CursorSize"); } else { - RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); + RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->InsertMode == TRUE) + if (GuiData->NumberOfHistoryBuffers == 5) { - RegDeleteKeyW(hKey, L"InsertMode"); + RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); } - else + else { - RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); } - if (GuiData->HistoryNoDup == FALSE) + if (GuiData->HistoryBufferSize == 50) { - RegDeleteKeyW(hKey, L"HistoryNoDup"); + RegDeleteKeyW(hKey, L"HistoryBufferSize"); } - else + else { - RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); } - if (GuiData->ScreenText == RGB(192, 192, 192)) + if (GuiData->FullScreen == FALSE) { - /* - * MS uses console attributes instead of real color - */ - RegDeleteKeyW(hKey, L"ScreenText"); + RegDeleteKeyW(hKey, L"FullScreen"); } - else + else { - RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); } - if (GuiData->ScreenBackground == RGB(0, 0, 0)) + if ( GuiData->QuickEdit == FALSE) { - RegDeleteKeyW(hKey, L"ScreenBackground"); + RegDeleteKeyW(hKey, L"QuickEdit"); } - else + else { - RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); } - RegCloseKey(hKey); + if (GuiData->InsertMode == TRUE) + { + RegDeleteKeyW(hKey, L"InsertMode"); + } + else + { + RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + } + + if (GuiData->HistoryNoDup == FALSE) + { + RegDeleteKeyW(hKey, L"HistoryNoDup"); + } + else + { + RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + } + + if (GuiData->ScreenText == RGB(192, 192, 192)) + { + /* + * MS uses console attributes instead of real color + */ + RegDeleteKeyW(hKey, L"ScreenText"); + } + else + { + RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + } + + if (GuiData->ScreenBackground == RGB(0, 0, 0)) + { + RegDeleteKeyW(hKey, L"ScreenBackground"); + } + else + { + RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + } + + RegCloseKey(hKey); } static void GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { - DWORD dwNumSubKeys = 0; - DWORD dwIndex; - DWORD dwValueName; - DWORD dwValue; - DWORD dwType; - WCHAR szValueName[MAX_PATH]; - WCHAR szValue[LF_FACESIZE] = L"\0"; - DWORD Value; + DWORD dwNumSubKeys = 0; + DWORD dwIndex; + DWORD dwValueName; + DWORD dwValue; + DWORD dwType; + WCHAR szValueName[MAX_PATH]; + WCHAR szValue[LF_FACESIZE] = L"\0"; + DWORD Value; - if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { - DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); - return; + DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); + return; } - DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); + DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); - for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) + for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) { - dwValue = sizeof(Value); - dwValueName = MAX_PATH; + dwValue = sizeof(Value); + dwValueName = MAX_PATH; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) { - if (dwType == REG_SZ) + if (dwType == REG_SZ) { - /* - * retry in case of string value - */ - dwValue = sizeof(szValue); - dwValueName = LF_FACESIZE; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) + /* + * retry in case of string value + */ + dwValue = sizeof(szValue); + dwValueName = LF_FACESIZE; + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) + break; + } + else break; - } - else - break; } - if (!wcscmp(szValueName, L"CursorSize")) + if (!wcscmp(szValueName, L"CursorSize")) { - if (Value == 0x32) + if (Value == 0x32) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } - else if (Value == 0x64) + else if (Value == 0x64) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } } - else if (!wcscmp(szValueName, L"ScreenText")) + else if (!wcscmp(szValueName, L"ScreenText")) { - GuiData->ScreenText = Value; + GuiData->ScreenText = Value; } - else if (!wcscmp(szValueName, L"ScreenBackground")) + else if (!wcscmp(szValueName, L"ScreenBackground")) { - GuiData->ScreenBackground = Value; + GuiData->ScreenBackground = Value; } - else if (!wcscmp(szValueName, L"FaceName")) + else if (!wcscmp(szValueName, L"FaceName")) { - wcscpy(GuiData->FontName, szValue); + wcscpy(GuiData->FontName, szValue); } - else if (!wcscmp(szValueName, L"FontSize")) + else if (!wcscmp(szValueName, L"FontSize")) { - GuiData->FontSize = Value; + GuiData->FontSize = Value; } - else if (!wcscmp(szValueName, L"FontWeight")) + else if (!wcscmp(szValueName, L"FontWeight")) { - GuiData->FontWeight = Value; + GuiData->FontWeight = Value; } - else if (!wcscmp(szValueName, L"HistoryNoDup")) + else if (!wcscmp(szValueName, L"HistoryNoDup")) { - GuiData->HistoryNoDup = Value; + GuiData->HistoryNoDup = Value; } - else if (!wcscmp(szValueName, L"WindowSize")) + else if (!wcscmp(szValueName, L"WindowSize")) { - Console->Size.X = LOWORD(Value); - Console->Size.Y = HIWORD(Value); + Console->Size.X = LOWORD(Value); + Console->Size.Y = HIWORD(Value); } - else if (!wcscmp(szValueName, L"ScreenBufferSize")) + else if (!wcscmp(szValueName, L"ScreenBufferSize")) { if(Buffer) - { + { Buffer->MaxX = LOWORD(Value); Buffer->MaxY = HIWORD(Value); - } + } } - else if (!wcscmp(szValueName, L"FullScreen")) + else if (!wcscmp(szValueName, L"FullScreen")) { - GuiData->FullScreen = Value; + GuiData->FullScreen = Value; } - else if (!wcscmp(szValueName, L"QuickEdit")) + else if (!wcscmp(szValueName, L"QuickEdit")) { - GuiData->QuickEdit = Value; + GuiData->QuickEdit = Value; } - else if (!wcscmp(szValueName, L"InsertMode")) + else if (!wcscmp(szValueName, L"InsertMode")) { - GuiData->InsertMode = Value; + GuiData->InsertMode = Value; } - } + } } static VOID GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { - /* - * init guidata with default properties - */ + /* + * init guidata with default properties + */ - wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); - GuiData->FontSize = 0x0008000C; // font is 8x12 - GuiData->FontWeight = FW_NORMAL; - GuiData->HistoryNoDup = FALSE; - GuiData->FullScreen = FALSE; - GuiData->QuickEdit = FALSE; - GuiData->InsertMode = TRUE; - GuiData->HistoryBufferSize = 50; - GuiData->NumberOfHistoryBuffers = 5; - GuiData->ScreenText = RGB(192, 192, 192); - GuiData->ScreenBackground = RGB(0, 0, 0); - GuiData->PopupText = RGB(128, 0, 128); - GuiData->PopupBackground = RGB(255, 255, 255); - GuiData->WindowPosition = UINT_MAX; - GuiData->UseRasterFonts = TRUE; - memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); + wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); + GuiData->FontSize = 0x0008000C; // font is 8x12 + GuiData->FontWeight = FW_NORMAL; + GuiData->HistoryNoDup = FALSE; + GuiData->FullScreen = FALSE; + GuiData->QuickEdit = FALSE; + GuiData->InsertMode = TRUE; + GuiData->HistoryBufferSize = 50; + GuiData->NumberOfHistoryBuffers = 5; + GuiData->ScreenText = RGB(192, 192, 192); + GuiData->ScreenBackground = RGB(0, 0, 0); + GuiData->PopupText = RGB(128, 0, 128); + GuiData->PopupBackground = RGB(255, 255, 255); + GuiData->WindowPosition = UINT_MAX; + GuiData->UseRasterFonts = TRUE; + memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); - Console->Size.X = 80; - Console->Size.Y = 25; + Console->Size.X = 80; + Console->Size.Y = 25; - if (Buffer) + if (Buffer) { - Buffer->MaxX = 80; - Buffer->MaxY = 300; - Buffer->CursorInfo.bVisible = TRUE; - Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + Buffer->MaxX = 80; + Buffer->MaxY = 300; + Buffer->CursorInfo.bVisible = TRUE; + Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; } } @@ -633,157 +633,157 @@ VOID FASTCALL GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd) { - SCROLLINFO sInfo; - PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + SCROLLINFO sInfo; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; - DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - sInfo.nMin = 0; - if (Console->ActiveBuffer->MaxY > Console->Size.Y) - { - sInfo.nMax = Console->ActiveBuffer->MaxY - 1; - sInfo.nPage = Console->Size.Y; - sInfo.nPos = Console->ActiveBuffer->ShowY; - SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); - Width += GetSystemMetrics(SM_CXVSCROLL); - ShowScrollBar(hwnd, SB_VERT, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_VERT, FALSE); - } + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + sInfo.nMin = 0; + if (Console->ActiveBuffer->MaxY > Console->Size.Y) + { + sInfo.nMax = Console->ActiveBuffer->MaxY - 1; + sInfo.nPage = Console->Size.Y; + sInfo.nPos = Console->ActiveBuffer->ShowY; + SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); + Width += GetSystemMetrics(SM_CXVSCROLL); + ShowScrollBar(hwnd, SB_VERT, TRUE); + } + else + { + ShowScrollBar(hwnd, SB_VERT, FALSE); + } - if (Console->ActiveBuffer->MaxX > Console->Size.X) - { - sInfo.nMax = Console->ActiveBuffer->MaxX - 1; - sInfo.nPage = Console->Size.X; - sInfo.nPos = Console->ActiveBuffer->ShowX; - SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); - Height += GetSystemMetrics(SM_CYHSCROLL); - ShowScrollBar(hwnd, SB_HORZ, TRUE); + if (Console->ActiveBuffer->MaxX > Console->Size.X) + { + sInfo.nMax = Console->ActiveBuffer->MaxX - 1; + sInfo.nPage = Console->Size.X; + sInfo.nPos = Console->ActiveBuffer->ShowX; + SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); + Height += GetSystemMetrics(SM_CYHSCROLL); + ShowScrollBar(hwnd, SB_HORZ, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_HORZ, FALSE); - } + } + else + { + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } - SetWindowPos(hwnd, NULL, 0, 0, Width, Height, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + SetWindowPos(hwnd, NULL, 0, 0, Width, Height, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); } static BOOL GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; - HDC Dc; - HFONT OldFont; - TEXTMETRICW Metrics; - SIZE CharSize; - PCSRSS_PROCESS_DATA ProcessData; - HKEY hKey; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; + HDC Dc; + HFONT OldFont; + TEXTMETRICW Metrics; + SIZE CharSize; + PCSRSS_PROCESS_DATA ProcessData; + HKEY hKey; - Console->hWindow = hWnd; + Console->hWindow = hWnd; - if (NULL == GuiData) + if (NULL == GuiData) { - DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); - return FALSE; + DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); + return FALSE; } - GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); - if (Console->ProcessList.Flink != &Console->ProcessList) + GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); + if (Console->ProcessList.Flink != &Console->ProcessList) { - ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); - if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) + ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); + if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) { - GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); - RegCloseKey(hKey); + GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); + RegCloseKey(hKey); } } - InitializeCriticalSection(&GuiData->Lock); + InitializeCriticalSection(&GuiData->Lock); - GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), - 0, //HIWORD(GuiData->FontSize), - 0, - TA_BASELINE, - GuiData->FontWeight, - FALSE, - FALSE, - FALSE, - OEM_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, - GuiData->FontName); - if (NULL == GuiData->Font) + GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), + 0, //HIWORD(GuiData->FontSize), + 0, + TA_BASELINE, + GuiData->FontWeight, + FALSE, + FALSE, + FALSE, + OEM_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, + GuiData->FontName); + if (NULL == GuiData->Font) { - DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - Dc = GetDC(hWnd); - if (NULL == Dc) + Dc = GetDC(hWnd); + if (NULL == Dc) { - DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - OldFont = SelectObject(Dc, GuiData->Font); - if (NULL == OldFont) + OldFont = SelectObject(Dc, GuiData->Font); + if (NULL == OldFont) { - DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - if (! GetTextMetricsW(Dc, &Metrics)) + if (! GetTextMetricsW(Dc, &Metrics)) { - DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); - SelectObject(Dc, OldFont); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); + SelectObject(Dc, OldFont); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - GuiData->CharWidth = Metrics.tmMaxCharWidth; - GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; + GuiData->CharWidth = Metrics.tmMaxCharWidth; + GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; - /* Measure real char width more precisely if possible. */ - if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) - GuiData->CharWidth = CharSize.cx; + /* Measure real char width more precisely if possible. */ + if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) + GuiData->CharWidth = CharSize.cx; - SelectObject(Dc, OldFont); + SelectObject(Dc, OldFont); - ReleaseDC(hWnd, Dc); - GuiData->CursorBlinkOn = TRUE; - GuiData->ForceCursorOff = FALSE; + ReleaseDC(hWnd, Dc); + GuiData->CursorBlinkOn = TRUE; + GuiData->ForceCursorOff = FALSE; - DPRINT("Console %p GuiData %p\n", Console, GuiData); - Console->PrivateData = GuiData; - SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); + DPRINT("Console %p GuiData %p\n", Console, GuiData); + Console->PrivateData = GuiData; + SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); - SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); - GuiConsoleCreateSysMenu(Console); + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); + GuiConsoleCreateSysMenu(Console); - GuiData->WindowSizeLock = TRUE; - GuiConsoleInitScrollbar(Console, hWnd); - GuiData->WindowSizeLock = FALSE; + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, hWnd); + GuiData->WindowSizeLock = FALSE; - SetEvent(GuiData->hGuiInitEvent); + SetEvent(GuiData->hGuiInitEvent); - return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); + return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); } static VOID @@ -800,62 +800,62 @@ SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) static VOID GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) { - RECT oldRect, newRect; - HWND hWnd = Console->hWindow; + RECT oldRect, newRect; + HWND hWnd = Console->hWindow; - SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); + SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); - if(coord != NULL) - { - SMALL_RECT rc; - /* exchange left/top with right/bottom if required */ - rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); - rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); - rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); - rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); - - SmallRectToRect(Console, &newRect, &rc); - - if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) + if(coord != NULL) { - if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) - { - HRGN rgn1, rgn2; + SMALL_RECT rc; + /* exchange left/top with right/bottom if required */ + rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); + rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); - /* calculate the region that needs to be updated */ - if((rgn1 = CreateRectRgnIndirect(&oldRect))) + SmallRectToRect(Console, &newRect, &rc); + + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - if((rgn2 = CreateRectRgnIndirect(&newRect))) - { - if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) { - InvalidateRgn(hWnd, rgn1, FALSE); - } + HRGN rgn1, rgn2; - DeleteObject(rgn2); - } - DeleteObject(rgn1); + /* calculate the region that needs to be updated */ + if((rgn1 = CreateRectRgnIndirect(&oldRect))) + { + if((rgn2 = CreateRectRgnIndirect(&newRect))) + { + if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + { + InvalidateRgn(hWnd, rgn1, FALSE); + } + + DeleteObject(rgn2); + } + DeleteObject(rgn1); + } + } } - } + else + { + InvalidateRect(hWnd, &newRect, FALSE); + } + Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; + Console->Selection.srSelection = rc; + ConioPause(Console, PAUSED_FROM_SELECTION); } else { - InvalidateRect(hWnd, &newRect, FALSE); + /* clear the selection */ + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) + { + InvalidateRect(hWnd, &oldRect, FALSE); + } + Console->Selection.dwFlags = CONSOLE_NO_SELECTION; + ConioUnpause(Console, PAUSED_FROM_SELECTION); } - Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; - Console->Selection.srSelection = rc; - ConioPause(Console, PAUSED_FROM_SELECTION); - } - else - { - /* clear the selection */ - if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) - { - InvalidateRect(hWnd, &oldRect, FALSE); - } - Console->Selection.dwFlags = CONSOLE_NO_SELECTION; - ConioUnpause(Console, PAUSED_FROM_SELECTION); - } } @@ -939,12 +939,12 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, } if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn && - !GuiData->ForceCursorOff) + !GuiData->ForceCursorOff) { CursorX = Buff->CurrentX; CursorY = Buff->CurrentY; if (LeftChar <= CursorX && CursorX <= RightChar && - TopLine <= CursorY && CursorY <= BottomLine) + TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100; if (CursorHeight < 1) @@ -992,14 +992,14 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC = BeginPaint(hWnd, &ps); if (hDC != NULL && - ps.rcPaint.left < ps.rcPaint.right && - ps.rcPaint.top < ps.rcPaint.bottom) + ps.rcPaint.left < ps.rcPaint.right && + ps.rcPaint.top < ps.rcPaint.bottom) { GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console != NULL && GuiData != NULL && - Console->ActiveBuffer != NULL) + Console->ActiveBuffer != NULL) { if (Console->ActiveBuffer->Buffer != NULL) { @@ -1040,23 +1040,23 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) static VOID GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - MSG Message; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + MSG Message; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - Message.hwnd = hWnd; - Message.message = msg; - Message.wParam = wParam; - Message.lParam = lParam; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + Message.hwnd = hWnd; + Message.message = msg; + Message.wParam = wParam; + Message.lParam = lParam; - if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) - { - /* clear the selection */ - GuiConsoleUpdateSelection(Console, NULL); - } + if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) + { + /* clear the selection */ + GuiConsoleUpdateSelection(Console, NULL); + } - ConioProcessKey(&Message, Console, FALSE); + ConioProcessKey(&Message, Console, FALSE); } static VOID WINAPI @@ -1078,48 +1078,48 @@ static VOID WINAPI GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - LONG CursorEndX, CursorEndY; - RECT ScrollRect; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + LONG CursorEndX, CursorEndY; + RECT ScrollRect; - if (NULL == Console->hWindow || NULL == GuiData) + if (NULL == Console->hWindow || NULL == GuiData) { - return; + return; } - if (0 != ScrolledLines) + if (0 != ScrolledLines) { - ScrollRect.left = 0; - ScrollRect.top = 0; - ScrollRect.right = Console->Size.X * GuiData->CharWidth; - ScrollRect.bottom = Region->Top * GuiData->CharHeight; + ScrollRect.left = 0; + ScrollRect.top = 0; + ScrollRect.right = Console->Size.X * GuiData->CharWidth; + ScrollRect.bottom = Region->Top * GuiData->CharHeight; - ScrollWindowEx(Console->hWindow, - 0, - -(ScrolledLines * GuiData->CharHeight), - &ScrollRect, - NULL, - NULL, - NULL, - SW_INVALIDATE); + ScrollWindowEx(Console->hWindow, + 0, + -(ScrolledLines * GuiData->CharHeight), + &ScrollRect, + NULL, + NULL, + NULL, + SW_INVALIDATE); } - GuiDrawRegion(Console, Region); + GuiDrawRegion(Console, Region); - if (CursorStartX < Region->Left || Region->Right < CursorStartX - || CursorStartY < Region->Top || Region->Bottom < CursorStartY) + if (CursorStartX < Region->Left || Region->Right < CursorStartX + || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { - GuiInvalidateCell(Console, CursorStartX, CursorStartY); + GuiInvalidateCell(Console, CursorStartX, CursorStartY); } - CursorEndX = Buff->CurrentX; - CursorEndY = Buff->CurrentY; - if ((CursorEndX < Region->Left || Region->Right < CursorEndX - || CursorEndY < Region->Top || Region->Bottom < CursorEndY) - && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) + CursorEndX = Buff->CurrentX; + CursorEndY = Buff->CurrentY; + if ((CursorEndX < Region->Left || Region->Right < CursorEndX + || CursorEndY < Region->Top || Region->Bottom < CursorEndY) + && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { - GuiInvalidateCell(Console, CursorEndX, CursorEndY); + GuiInvalidateCell(Console, CursorEndX, CursorEndY); } // Set up the update timer (very short interval) - this is a "hack" for getting the OS to @@ -1131,26 +1131,26 @@ GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LO static BOOL WINAPI GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - /* Redraw char at old position (removes cursor) */ - GuiInvalidateCell(Console, OldCursorX, OldCursorY); - /* Redraw char at new position (shows cursor) */ - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + /* Redraw char at old position (removes cursor) */ + GuiInvalidateCell(Console, OldCursorX, OldCursorY); + /* Redraw char at new position (shows cursor) */ + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI @@ -1170,135 +1170,135 @@ GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) static VOID GuiConsoleHandleTimer(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - PCSRSS_SCREEN_BUFFER Buff; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PCSRSS_SCREEN_BUFFER Buff; - SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - Buff = Console->ActiveBuffer; - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); - GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; + Buff = Console->ActiveBuffer; + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; - if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) - { - SCROLLINFO xScroll; - int OldScrollX = -1, OldScrollY = -1; - int NewScrollX = -1, NewScrollY = -1; + if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) + { + SCROLLINFO xScroll; + int OldScrollX = -1, OldScrollY = -1; + int NewScrollX = -1, NewScrollY = -1; - xScroll.cbSize = sizeof(SCROLLINFO); - xScroll.fMask = SIF_POS; - // Capture the original position of the scroll bars and save them. - if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; - if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; + xScroll.cbSize = sizeof(SCROLLINFO); + xScroll.fMask = SIF_POS; + // Capture the original position of the scroll bars and save them. + if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; + if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; - // If we successfully got the info for the horizontal scrollbar - if(OldScrollX >= 0) - { - if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) - { - // Handle the horizontal scroll bar - if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; - else NewScrollX = 0; - } - else - { - NewScrollX = OldScrollX; - } - } - // If we successfully got the info for the vertical scrollbar - if(OldScrollY >= 0) - { - if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) + // If we successfully got the info for the horizontal scrollbar + if(OldScrollX >= 0) { - // Handle the vertical scroll bar - if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; - else NewScrollY = 0; + if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) + { + // Handle the horizontal scroll bar + if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; + else NewScrollX = 0; + } + else + { + NewScrollX = OldScrollX; + } } - else + // If we successfully got the info for the vertical scrollbar + if(OldScrollY >= 0) { - NewScrollY = OldScrollY; + if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) + { + // Handle the vertical scroll bar + if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; + else NewScrollY = 0; + } + else + { + NewScrollY = OldScrollY; + } } - } - // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area - // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar - // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) - // and their associated scrollbar is left alone. - if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) - { - Buff->ShowX = NewScrollX; - Buff->ShowY = NewScrollY; - ScrollWindowEx(hWnd, - (OldScrollX - NewScrollX) * GuiData->CharWidth, - (OldScrollY - NewScrollY) * GuiData->CharHeight, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); - if(NewScrollX >= 0) + // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area + // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar + // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) + // and their associated scrollbar is left alone. + if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) { - xScroll.nPos = NewScrollX; - SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); + Buff->ShowX = NewScrollX; + Buff->ShowY = NewScrollY; + ScrollWindowEx(hWnd, + (OldScrollX - NewScrollX) * GuiData->CharWidth, + (OldScrollY - NewScrollY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + if(NewScrollX >= 0) + { + xScroll.nPos = NewScrollX; + SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); + } + if(NewScrollY >= 0) + { + xScroll.nPos = NewScrollY; + SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); + } + UpdateWindow(hWnd); + GuiData->OldCursor.x = Buff->CurrentX; + GuiData->OldCursor.y = Buff->CurrentY; } - if(NewScrollY >= 0) - { - xScroll.nPos = NewScrollY; - SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); - } - UpdateWindow(hWnd); - GuiData->OldCursor.x = Buff->CurrentX; - GuiData->OldCursor.y = Buff->CurrentY; - } - } + } } static VOID GuiConsoleHandleClose(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - PLIST_ENTRY current_entry; - PCSRSS_PROCESS_DATA current; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PLIST_ENTRY current_entry; + PCSRSS_PROCESS_DATA current; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - EnterCriticalSection(&Console->Lock); + EnterCriticalSection(&Console->Lock); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; - /* FIXME: Windows will wait up to 5 seconds for the thread to exit. - * We shouldn't wait here, though, since the console lock is entered. - * A copy of the thread list probably needs to be made. */ - ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); + /* FIXME: Windows will wait up to 5 seconds for the thread to exit. + * We shouldn't wait here, though, since the console lock is entered. + * A copy of the thread list probably needs to be made. */ + ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); } - LeaveCriticalSection(&Console->Lock); + LeaveCriticalSection(&Console->Lock); } static VOID GuiConsoleHandleNcDestroy(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - KillTimer(hWnd, 1); - Console->PrivateData = NULL; - DeleteCriticalSection(&GuiData->Lock); - GetSystemMenu(hWnd, TRUE); - if (GuiData->ConsoleLibrary) - FreeLibrary(GuiData->ConsoleLibrary); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + KillTimer(hWnd, 1); + Console->PrivateData = NULL; + DeleteCriticalSection(&GuiData->Lock); + GetSystemMenu(hWnd, TRUE); + if (GuiData->ConsoleLibrary) + FreeLibrary(GuiData->ConsoleLibrary); - HeapFree(Win32CsrApiHeap, 0, GuiData); + HeapFree(Win32CsrApiHeap, 0, GuiData); } static COORD @@ -1321,78 +1321,78 @@ PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) static VOID GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); + Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); - SetCapture(hWnd); + SetCapture(hWnd); - Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; + Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); + GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); } static VOID GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - COORD c; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; - if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - c = PointToCoord(Console, lParam); + c = PointToCoord(Console, lParam); - Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; + Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; - GuiConsoleUpdateSelection(Console, &c); + GuiConsoleUpdateSelection(Console, &c); - ReleaseCapture(); + ReleaseCapture(); } static VOID GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - COORD c; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; - if (!(wParam & MK_LBUTTON)) return; + if (!(wParam & MK_LBUTTON)) return; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; - if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ + c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ - GuiConsoleUpdateSelection(Console, &c); + GuiConsoleUpdateSelection(Console, &c); } static VOID GuiConsoleRightMouseDown(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) - { - /* FIXME - paste text from clipboard */ - } - else - { - /* FIXME - copy selection to clipboard */ + if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) + { + /* FIXME - paste text from clipboard */ + } + else + { + /* FIXME - copy selection to clipboard */ - GuiConsoleUpdateSelection(Console, NULL); - } + GuiConsoleUpdateSelection(Console, NULL); + } } @@ -1400,74 +1400,74 @@ GuiConsoleRightMouseDown(HWND hWnd) static VOID GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) { - PCSRSS_CONSOLE Console; - APPLET_PROC CPLFunc; - TCHAR szBuffer[MAX_PATH]; - ConsoleInfo SharedInfo; + PCSRSS_CONSOLE Console; + APPLET_PROC CPLFunc; + TCHAR szBuffer[MAX_PATH]; + ConsoleInfo SharedInfo; - DPRINT("GuiConsoleShowConsoleProperties entered\n"); + DPRINT("GuiConsoleShowConsoleProperties entered\n"); - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (GuiData == NULL) + if (GuiData == NULL) { - DPRINT("GuiConsoleGetDataPointers failed\n"); - return; + DPRINT("GuiConsoleGetDataPointers failed\n"); + return; } - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - GetWindowsDirectory(szBuffer,MAX_PATH); - _tcscat(szBuffer, _T("\\system32\\console.dll")); - GuiData->ConsoleLibrary = LoadLibrary(szBuffer); + GetWindowsDirectory(szBuffer,MAX_PATH); + _tcscat(szBuffer, _T("\\system32\\console.dll")); + GuiData->ConsoleLibrary = LoadLibrary(szBuffer); - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - DPRINT1("failed to load console.dll"); - return; + DPRINT1("failed to load console.dll"); + return; } } - CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); - if (!CPLFunc) + CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); + if (!CPLFunc) { - DPRINT("Error: Console.dll misses CPlApplet export\n"); - return; + DPRINT("Error: Console.dll misses CPlApplet export\n"); + return; } - /* setup struct */ - SharedInfo.InsertMode = GuiData->InsertMode; - SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; - SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers; - SharedInfo.ScreenText = GuiData->ScreenText; - SharedInfo.ScreenBackground = GuiData->ScreenBackground; - SharedInfo.PopupText = GuiData->PopupText; - SharedInfo.PopupBackground = GuiData->PopupBackground; - SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); - SharedInfo.WindowPosition = GuiData->WindowPosition; - SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); - SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; - SharedInfo.FontSize = (DWORD)GuiData->FontSize; - SharedInfo.FontWeight = GuiData->FontWeight; - SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; - SharedInfo.HistoryNoDup = GuiData->HistoryNoDup; - SharedInfo.FullScreen = GuiData->FullScreen; - SharedInfo.QuickEdit = GuiData->QuickEdit; - memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); + /* setup struct */ + SharedInfo.InsertMode = GuiData->InsertMode; + SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; + SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers; + SharedInfo.ScreenText = GuiData->ScreenText; + SharedInfo.ScreenBackground = GuiData->ScreenBackground; + SharedInfo.PopupText = GuiData->PopupText; + SharedInfo.PopupBackground = GuiData->PopupBackground; + SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); + SharedInfo.WindowPosition = GuiData->WindowPosition; + SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); + SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; + SharedInfo.FontSize = (DWORD)GuiData->FontSize; + SharedInfo.FontWeight = GuiData->FontWeight; + SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; + SharedInfo.HistoryNoDup = GuiData->HistoryNoDup; + SharedInfo.FullScreen = GuiData->FullScreen; + SharedInfo.QuickEdit = GuiData->QuickEdit; + memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); - if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) + if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) { - DPRINT("Error: failed to initialize console.dll\n"); - return; + DPRINT("Error: failed to initialize console.dll\n"); + return; } - if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) + if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) { - DPRINT("Error: console.dll returned unexpected CPL count\n"); - return; + DPRINT("Error: console.dll returned unexpected CPL count\n"); + return; } - CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); + CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } static LRESULT GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData) @@ -1476,25 +1476,25 @@ GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CON switch(wParam) { - case ID_SYSTEM_EDIT_MARK: - case ID_SYSTEM_EDIT_COPY: - case ID_SYSTEM_EDIT_PASTE: - case ID_SYSTEM_EDIT_SELECTALL: - case ID_SYSTEM_EDIT_SCROLL: - case ID_SYSTEM_EDIT_FIND: - break; + case ID_SYSTEM_EDIT_MARK: + case ID_SYSTEM_EDIT_COPY: + case ID_SYSTEM_EDIT_PASTE: + case ID_SYSTEM_EDIT_SELECTALL: + case ID_SYSTEM_EDIT_SCROLL: + case ID_SYSTEM_EDIT_FIND: + break; - case ID_SYSTEM_DEFAULTS: - GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); - break; + case ID_SYSTEM_DEFAULTS: + GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); + break; - case ID_SYSTEM_PROPERTIES: - GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); - break; + case ID_SYSTEM_PROPERTIES: + GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); + break; - default: - Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); - break; + default: + Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); + break; } return Ret; } @@ -1502,105 +1502,105 @@ GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CON static VOID GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if((Console == NULL)|| (GuiData == NULL)) return; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL)|| (GuiData == NULL)) return; - DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - minMaxInfo->ptMinTrackSize.x = windx; - minMaxInfo->ptMinTrackSize.y = windy; + minMaxInfo->ptMinTrackSize.x = windx; + minMaxInfo->ptMinTrackSize.y = windy; - windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar - minMaxInfo->ptMaxTrackSize.x = windx; - minMaxInfo->ptMaxTrackSize.y = windy; + minMaxInfo->ptMaxTrackSize.x = windx; + minMaxInfo->ptMaxTrackSize.y = windy; } static VOID GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if((Console == NULL) || (GuiData == NULL)) return; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL) || (GuiData == NULL)) return; - if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) - { - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) + { + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - GuiData->WindowSizeLock = TRUE; + GuiData->WindowSizeLock = TRUE; - DWORD windx = LOWORD(lParam); - DWORD windy = HIWORD(lParam); + DWORD windx = LOWORD(lParam); + DWORD windy = HIWORD(lParam); - // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) - if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) + if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar - DWORD charx = windx / GuiData->CharWidth; - DWORD chary = windy / GuiData->CharHeight; + DWORD charx = windx / GuiData->CharWidth; + DWORD chary = windy / GuiData->CharHeight; - // Character alignment (round size up or down) - if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; - if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; - // Compensate for added scroll bars in new window - if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar - if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar + // Compensate for added scroll bars in new window + if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar + if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar - charx = windx / GuiData->CharWidth; - chary = windy / GuiData->CharHeight; + charx = windx / GuiData->CharWidth; + chary = windy / GuiData->CharHeight; - // Character alignment (round size up or down) - if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; - if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; - // Resize window - if((charx != Console->Size.X) || (chary != Console->Size.Y)) - { - Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; - Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; - } + // Resize window + if((charx != Console->Size.X) || (chary != Console->Size.Y)) + { + Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; + Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; + } - GuiConsoleInitScrollbar(Console, hWnd); + GuiConsoleInitScrollbar(Console, hWnd); - // Adjust the start of the visible area if we are attempting to show nonexistent areas - if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; - if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; - InvalidateRect(hWnd, NULL, TRUE); + // Adjust the start of the visible area if we are attempting to show nonexistent areas + if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; + if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; + InvalidateRect(hWnd, NULL, TRUE); - GuiData->WindowSizeLock = FALSE; - } + GuiData->WindowSizeLock = FALSE; + } } VOID FASTCALL GuiConsoleHandleScrollbarMenu() { - HMENU hMenu; + HMENU hMenu; - hMenu = CreatePopupMenu(); - if (hMenu == NULL) + hMenu = CreatePopupMenu(); + if (hMenu == NULL) { - DPRINT("CreatePopupMenu failed\n"); - return; + DPRINT("CreatePopupMenu failed\n"); + return; } - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); } @@ -1700,258 +1700,258 @@ GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD static VOID GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) { - DWORD windx, windy; - PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; - COORD BufSize; - BOOL SizeChanged = FALSE; + DWORD windx, windy; + PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; + COORD BufSize; + BOOL SizeChanged = FALSE; - EnterCriticalSection(&Console->Lock); + EnterCriticalSection(&Console->Lock); - /* apply text / background color */ - GuiData->ScreenText = pConInfo->ScreenText; - GuiData->ScreenBackground = pConInfo->ScreenBackground; + /* apply text / background color */ + GuiData->ScreenText = pConInfo->ScreenText; + GuiData->ScreenBackground = pConInfo->ScreenBackground; - /* apply cursor size */ - ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); + /* apply cursor size */ + ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); - windx = LOWORD(pConInfo->WindowSize); - windy = HIWORD(pConInfo->WindowSize); + windx = LOWORD(pConInfo->WindowSize); + windy = HIWORD(pConInfo->WindowSize); - if (windx != Console->Size.X || windy != Console->Size.Y) - { - /* resize window */ - Console->Size.X = windx; - Console->Size.Y = windy; - SizeChanged = TRUE; - } + if (windx != Console->Size.X || windy != Console->Size.Y) + { + /* resize window */ + Console->Size.X = windx; + Console->Size.Y = windy; + SizeChanged = TRUE; + } - BufSize.X = LOWORD(pConInfo->ScreenBuffer); - BufSize.Y = HIWORD(pConInfo->ScreenBuffer); - if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) - { - if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) - SizeChanged = TRUE; - } + BufSize.X = LOWORD(pConInfo->ScreenBuffer); + BufSize.Y = HIWORD(pConInfo->ScreenBuffer); + if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) + { + if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) + SizeChanged = TRUE; + } - if (SizeChanged) - { - GuiData->WindowSizeLock = TRUE; - GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); - GuiData->WindowSizeLock = FALSE; - } + if (SizeChanged) + { + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); + GuiData->WindowSizeLock = FALSE; + } - LeaveCriticalSection(&Console->Lock); - InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); + LeaveCriticalSection(&Console->Lock); + InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); } static LRESULT GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PGUI_CONSOLE_DATA GuiData; - SCROLLINFO sInfo; - int fnBar; - int old_pos, Maximum; - PUSHORT pShowXY; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PGUI_CONSOLE_DATA GuiData; + SCROLLINFO sInfo; + int fnBar; + int old_pos, Maximum; + PUSHORT pShowXY; - GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) - return FALSE; - Buff = Console->ActiveBuffer; + GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) + return FALSE; + Buff = Console->ActiveBuffer; - if (uMsg == WM_HSCROLL) - { - fnBar = SB_HORZ; - Maximum = Buff->MaxX - Console->Size.X; - pShowXY = &Buff->ShowX; - } - else - { - fnBar = SB_VERT; - Maximum = Buff->MaxY - Console->Size.Y; - pShowXY = &Buff->ShowY; - } + if (uMsg == WM_HSCROLL) + { + fnBar = SB_HORZ; + Maximum = Buff->MaxX - Console->Size.X; + pShowXY = &Buff->ShowX; + } + else + { + fnBar = SB_VERT; + Maximum = Buff->MaxY - Console->Size.Y; + pShowXY = &Buff->ShowY; + } - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; - if (!GetScrollInfo(hwnd, fnBar, &sInfo)) - { - return FALSE; - } + if (!GetScrollInfo(hwnd, fnBar, &sInfo)) + { + return FALSE; + } - old_pos = sInfo.nPos; + old_pos = sInfo.nPos; - switch(LOWORD(wParam)) - { - case SB_LINELEFT: - sInfo.nPos -= 1; - break; + switch(LOWORD(wParam)) + { + case SB_LINELEFT: + sInfo.nPos -= 1; + break; - case SB_LINERIGHT: - sInfo.nPos += 1; - break; + case SB_LINERIGHT: + sInfo.nPos += 1; + break; - case SB_PAGELEFT: - sInfo.nPos -= sInfo.nPage; - break; + case SB_PAGELEFT: + sInfo.nPos -= sInfo.nPage; + break; - case SB_PAGERIGHT: - sInfo.nPos += sInfo.nPage; - break; + case SB_PAGERIGHT: + sInfo.nPos += sInfo.nPage; + break; - case SB_THUMBTRACK: - sInfo.nPos = sInfo.nTrackPos; - ConioPause(Console, PAUSED_FROM_SCROLLBAR); - break; + case SB_THUMBTRACK: + sInfo.nPos = sInfo.nTrackPos; + ConioPause(Console, PAUSED_FROM_SCROLLBAR); + break; - case SB_THUMBPOSITION: - ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); - break; + case SB_THUMBPOSITION: + ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); + break; - case SB_TOP: - sInfo.nPos = sInfo.nMin; - break; + case SB_TOP: + sInfo.nPos = sInfo.nMin; + break; - case SB_BOTTOM: - sInfo.nPos = sInfo.nMax; - break; + case SB_BOTTOM: + sInfo.nPos = sInfo.nMax; + break; - default: - break; - } + default: + break; + } - sInfo.nPos = max(sInfo.nPos, 0); - sInfo.nPos = min(sInfo.nPos, Maximum); + sInfo.nPos = max(sInfo.nPos, 0); + sInfo.nPos = min(sInfo.nPos, Maximum); - if (old_pos != sInfo.nPos) - { - USHORT OldX = Buff->ShowX; - USHORT OldY = Buff->ShowY; - *pShowXY = sInfo.nPos; + if (old_pos != sInfo.nPos) + { + USHORT OldX = Buff->ShowX; + USHORT OldY = Buff->ShowY; + *pShowXY = sInfo.nPos; - ScrollWindowEx(hwnd, - (OldX - Buff->ShowX) * GuiData->CharWidth, - (OldY - Buff->ShowY) * GuiData->CharHeight, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); + ScrollWindowEx(hwnd, + (OldX - Buff->ShowX) * GuiData->CharWidth, + (OldY - Buff->ShowY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); - sInfo.fMask = SIF_POS; - SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); + sInfo.fMask = SIF_POS; + SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); - UpdateWindow(hwnd); - } - return 0; + UpdateWindow(hwnd); + } + return 0; } static LRESULT CALLBACK GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT Result = 0; - PGUI_CONSOLE_DATA GuiData = NULL; - PCSRSS_CONSOLE Console = NULL; + LRESULT Result = 0; + PGUI_CONSOLE_DATA GuiData = NULL; + PCSRSS_CONSOLE Console = NULL; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - switch(msg) + switch(msg) { - case WM_NCCREATE: + case WM_NCCREATE: Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam); break; - case WM_PAINT: + case WM_PAINT: GuiConsoleHandlePaint(hWnd, (HDC)wParam); break; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_CHAR: GuiConsoleHandleKey(hWnd, msg, wParam, lParam); break; - case WM_TIMER: + case WM_TIMER: GuiConsoleHandleTimer(hWnd); break; - case WM_CLOSE: + case WM_CLOSE: GuiConsoleHandleClose(hWnd); break; - case WM_NCDESTROY: + case WM_NCDESTROY: GuiConsoleHandleNcDestroy(hWnd); break; - case WM_LBUTTONDOWN: - GuiConsoleLeftMouseDown(hWnd, lParam); + case WM_LBUTTONDOWN: + GuiConsoleLeftMouseDown(hWnd, lParam); break; - case WM_LBUTTONUP: - GuiConsoleLeftMouseUp(hWnd, lParam); + case WM_LBUTTONUP: + GuiConsoleLeftMouseUp(hWnd, lParam); break; - case WM_RBUTTONDOWN: - GuiConsoleRightMouseDown(hWnd); + case WM_RBUTTONDOWN: + GuiConsoleRightMouseDown(hWnd); break; - case WM_MOUSEMOVE: - GuiConsoleMouseMove(hWnd, wParam, lParam); + case WM_MOUSEMOVE: + GuiConsoleMouseMove(hWnd, wParam, lParam); break; - case WM_SYSCOMMAND: - Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); - break; - case WM_HSCROLL: - case WM_VSCROLL: - Result = GuiConsoleHandleScroll(hWnd, msg, wParam); - break; - case WM_GETMINMAXINFO: - GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); - break; - case WM_SIZE: - GuiConsoleResize(hWnd, wParam, lParam); - break; - case PM_APPLY_CONSOLE_INFO: - GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); - if (lParam) - { - GuiConsoleWriteUserSettings(Console, GuiData); - } - break; - default: + case WM_SYSCOMMAND: + Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); + break; + case WM_HSCROLL: + case WM_VSCROLL: + Result = GuiConsoleHandleScroll(hWnd, msg, wParam); + break; + case WM_GETMINMAXINFO: + GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); + break; + case WM_SIZE: + GuiConsoleResize(hWnd, wParam, lParam); + break; + case PM_APPLY_CONSOLE_INFO: + GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); + if (lParam) + { + GuiConsoleWriteUserSettings(Console, GuiData); + } + break; + default: Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; } - return Result; + return Result; } static LRESULT CALLBACK GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - HWND NewWindow; - LONG WindowCount; - MSG Msg; - PWCHAR Buffer, Title; - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; + HWND NewWindow; + LONG WindowCount; + MSG Msg; + PWCHAR Buffer, Title; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; - switch(msg) + switch(msg) { - case WM_CREATE: + case WM_CREATE: SetWindowLongW(hWnd, GWL_USERDATA, 0); return 0; - case PM_CREATE_CONSOLE: + case PM_CREATE_CONSOLE: Buffer = HeapAlloc(Win32CsrApiHeap, 0, Console->Title.Length + sizeof(WCHAR)); if (NULL != Buffer) - { + { memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; Title = Buffer; - } + } else - { + { Title = L""; - } + } NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, L"ConsoleWindowClass", Title, @@ -1965,41 +1965,41 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) (HINSTANCE) GetModuleHandleW(NULL), (PVOID) Console); if (NULL != Buffer) - { + { HeapFree(Win32CsrApiHeap, 0, Buffer); - } + } if (NULL != NewWindow) - { + { SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); if (wParam) { ShowWindow(NewWindow, SW_SHOW); } - } + } return (LRESULT) NewWindow; - case PM_DESTROY_CONSOLE: + case PM_DESTROY_CONSOLE: /* Window creation is done using a PostMessage(), so it's possible that the * window that we want to destroy doesn't exist yet. So first empty the message * queue */ while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) - { + { TranslateMessage(&Msg); DispatchMessageW(&Msg); - } + } DestroyWindow(Console->hWindow); Console->hWindow = NULL; WindowCount = GetWindowLongW(hWnd, GWL_USERDATA); WindowCount--; SetWindowLongW(hWnd, GWL_USERDATA, WindowCount); if (0 == WindowCount) - { + { NotifyWnd = NULL; DestroyWindow(hWnd); PrivateCsrssManualGuiCheck(-1); PostQuitMessage(0); - } + } return 0; - default: + default: return DefWindowProcW(hWnd, msg, wParam, lParam); } } @@ -2007,209 +2007,209 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) static DWORD WINAPI GuiConsoleGuiThread(PVOID Data) { - MSG msg; - PHANDLE GraphicsStartupEvent = (PHANDLE) Data; + MSG msg; + PHANDLE GraphicsStartupEvent = (PHANDLE) Data; - NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", - L"", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - NULL, - NULL, - (HINSTANCE) GetModuleHandleW(NULL), - NULL); - if (NULL == NotifyWnd) + NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", + L"", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + (HINSTANCE) GetModuleHandleW(NULL), + NULL); + if (NULL == NotifyWnd) { - PrivateCsrssManualGuiCheck(-1); - SetEvent(*GraphicsStartupEvent); - return 1; + PrivateCsrssManualGuiCheck(-1); + SetEvent(*GraphicsStartupEvent); + return 1; } - SetEvent(*GraphicsStartupEvent); + SetEvent(*GraphicsStartupEvent); - while(GetMessageW(&msg, NULL, 0, 0)) + while(GetMessageW(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); + TranslateMessage(&msg); + DispatchMessageW(&msg); } - return 1; + return 1; } static BOOL GuiInit(VOID) { - WNDCLASSEXW wc; + WNDCLASSEXW wc; - if (NULL == NotifyWnd) + if (NULL == NotifyWnd) { - PrivateCsrssManualGuiCheck(+1); + PrivateCsrssManualGuiCheck(+1); } - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"Win32CsrCreateNotify"; - wc.lpfnWndProc = GuiConsoleNotifyWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = NULL; - if (RegisterClassExW(&wc) == 0) + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"Win32CsrCreateNotify"; + wc.lpfnWndProc = GuiConsoleNotifyWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = NULL; + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register notify wndproc\n"); - return FALSE; + DPRINT1("Failed to register notify wndproc\n"); + return FALSE; } - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"ConsoleWindowClass"; - wc.lpfnWndProc = GuiConsoleWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); - wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); - wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), - LR_SHARED); - if (RegisterClassExW(&wc) == 0) + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"ConsoleWindowClass"; + wc.lpfnWndProc = GuiConsoleWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); + wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); + wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), + LR_SHARED); + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register console wndproc\n"); - return FALSE; + DPRINT1("Failed to register console wndproc\n"); + return FALSE; } - return TRUE; + return TRUE; } static VOID WINAPI GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = DEFAULT_ATTRIB; + Buffer->DefaultAttrib = DEFAULT_ATTRIB; } static BOOL WINAPI GuiChangeTitle(PCSRSS_CONSOLE Console) { - PWCHAR Buffer, Title; + PWCHAR Buffer, Title; - Buffer = HeapAlloc(Win32CsrApiHeap, 0, - Console->Title.Length + sizeof(WCHAR)); - if (NULL != Buffer) + Buffer = HeapAlloc(Win32CsrApiHeap, 0, + Console->Title.Length + sizeof(WCHAR)); + if (NULL != Buffer) { - memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); - Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; - Title = Buffer; + memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); + Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; + Title = Buffer; } - else + else { - Title = L""; + Title = L""; } - SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); + SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); - if (NULL != Buffer) + if (NULL != Buffer) { - HeapFree(Win32CsrApiHeap, 0, Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon) { - SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); - SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); - return TRUE; + return TRUE; } static VOID WINAPI GuiCleanupConsole(PCSRSS_CONSOLE Console) { - SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); + SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); } static CSRSS_CONSOLE_VTBL GuiVtbl = { - GuiInitScreenBuffer, - GuiWriteStream, - GuiDrawRegion, - GuiSetCursorInfo, - GuiSetScreenInfo, - GuiUpdateScreenInfo, - GuiChangeTitle, - GuiCleanupConsole, - GuiChangeIcon, - GuiResizeBuffer, + GuiInitScreenBuffer, + GuiWriteStream, + GuiDrawRegion, + GuiSetCursorInfo, + GuiSetScreenInfo, + GuiUpdateScreenInfo, + GuiChangeTitle, + GuiCleanupConsole, + GuiChangeIcon, + GuiResizeBuffer, }; NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { - HANDLE GraphicsStartupEvent; - HANDLE ThreadHandle; - PGUI_CONSOLE_DATA GuiData; + HANDLE GraphicsStartupEvent; + HANDLE ThreadHandle; + PGUI_CONSOLE_DATA GuiData; - if (! ConsInitialized) + if (! ConsInitialized) { - ConsInitialized = TRUE; - if (! GuiInit()) + ConsInitialized = TRUE; + if (! GuiInit()) { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; } } - Console->Vtbl = &GuiVtbl; - if (NULL == NotifyWnd) + Console->Vtbl = &GuiVtbl; + if (NULL == NotifyWnd) { - GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - if (NULL == GraphicsStartupEvent) + GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (NULL == GraphicsStartupEvent) { - return STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; } - ThreadHandle = CreateThread(NULL, - 0, - GuiConsoleGuiThread, - (PVOID) &GraphicsStartupEvent, - 0, - NULL); - if (NULL == ThreadHandle) + ThreadHandle = CreateThread(NULL, + 0, + GuiConsoleGuiThread, + (PVOID) &GraphicsStartupEvent, + 0, + NULL); + if (NULL == ThreadHandle) { - NtClose(GraphicsStartupEvent); - DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); - return STATUS_UNSUCCESSFUL; + NtClose(GraphicsStartupEvent); + DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); + return STATUS_UNSUCCESSFUL; } - SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); - CloseHandle(ThreadHandle); + SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); + CloseHandle(ThreadHandle); - WaitForSingleObject(GraphicsStartupEvent, INFINITE); - CloseHandle(GraphicsStartupEvent); + WaitForSingleObject(GraphicsStartupEvent, INFINITE); + CloseHandle(GraphicsStartupEvent); - if (NULL == NotifyWnd) + if (NULL == NotifyWnd) { - DPRINT1("Win32Csr: Failed to create notification window.\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("Win32Csr: Failed to create notification window.\n"); + return STATUS_UNSUCCESSFUL; } } GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA)); if (!GuiData) - { + { DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n"); return STATUS_UNSUCCESSFUL; - } + } Console->PrivateData = (PVOID) GuiData; /* @@ -2229,7 +2229,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) CloseHandle(GuiData->hGuiInitEvent); GuiData->hGuiInitEvent = NULL; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index 87f5c6348a4..ce8db451681 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -101,7 +101,7 @@ Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, { ULONG_PTR h = (ULONG_PTR)Handle >> 2; - DPRINT("CsrGetObject, Object: %x, %x, %x\n", + DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); RtlEnterCriticalSection(&ProcessData->HandleTableLock); @@ -271,7 +271,7 @@ CSR_API(CsrGetHandle) PCSRSS_CONSOLE Console = ProcessData->Console; Object_t *Object; - + EnterCriticalSection(&Console->Lock); if (Request->Type == GET_OUTPUT_HANDLE) Object = &Console->ActiveBuffer->Header; @@ -366,7 +366,7 @@ CSR_API(CsrDuplicateHandle) return STATUS_INVALID_PARAMETER; } } - + Request->Status = Win32CsrInsertObject(ProcessData, &Request->Data.DuplicateHandleRequest.Handle, Entry->Object, diff --git a/reactos/subsystems/win32/csrss/win32csr/harderror.c b/reactos/subsystems/win32/csrss/win32csr/harderror.c index 4b46e340842..0e10aad8a9d 100644 --- a/reactos/subsystems/win32/csrss/win32csr/harderror.c +++ b/reactos/subsystems/win32/csrss/win32csr/harderror.c @@ -84,8 +84,8 @@ CsrpGetClientFileName( ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength; ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - ClientFileNameU->MaximumLength); + HEAP_ZERO_MEMORY, + ClientFileNameU->MaximumLength); Status = NtReadVirtualMemory(hProcess, ModuleData.BaseDllName.Buffer, @@ -123,9 +123,9 @@ CsrpCaptureStringParameters( UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask; /* Read all strings from client space */ - for (nParam = 0; - nParam < HardErrorMessage->NumberOfParameters; - nParam++, UnicodeStringParameterMask >>= 1) + for (nParam = 0; + nParam < HardErrorMessage->NumberOfParameters; + nParam++, UnicodeStringParameterMask >>= 1) { Parameters[nParam] = 0; @@ -194,9 +194,9 @@ CsrpFreeStringParameters( UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask; /* Loop all parameters */ - for (nParam = 0; - nParam < HardErrorMessage->NumberOfParameters; - nParam++, UnicodeStringParameterMask >>= 1) + for (nParam = 0; + nParam < HardErrorMessage->NumberOfParameters; + nParam++, UnicodeStringParameterMask >>= 1) { /* Check if the current parameter is a string */ if (UnicodeStringParameterMask & 0x01) @@ -292,8 +292,8 @@ CsrpFormatMessages( /* Allocate a buffer for the caption */ CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - CaptionStringU->MaximumLength); + HEAP_ZERO_MEMORY, + CaptionStringU->MaximumLength); /* Append the file name, seperator and the caption text */ CaptionStringU->Length = 0; @@ -383,13 +383,13 @@ CsrpFormatMessages( { /* Print the string into the buffer */ StringCbPrintfW(TextStringU->Buffer, - TextStringU->MaximumLength, - FormatString, - Parameters[0], - Parameters[1], - Parameters[2], - Parameters[3], - Parameters[4]); + TextStringU->MaximumLength, + FormatString, + Parameters[0], + Parameters[1], + Parameters[2], + Parameters[3], + Parameters[4]); Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -424,30 +424,30 @@ CsrpMessageBox( /* Set the message box type */ switch (ValidResponseOptions) { - case OptionAbortRetryIgnore: - Type = MB_ABORTRETRYIGNORE; - break; - case OptionOk: - Type = MB_OK; - break; - case OptionOkCancel: - Type = MB_OKCANCEL; - break; - case OptionRetryCancel: - Type = MB_RETRYCANCEL; - break; - case OptionYesNo: - Type = MB_YESNO; - break; - case OptionYesNoCancel: - Type = MB_YESNOCANCEL; - break; - case OptionShutdownSystem: - Type = MB_RETRYCANCEL; // FIXME??? - break; + case OptionAbortRetryIgnore: + Type = MB_ABORTRETRYIGNORE; + break; + case OptionOk: + Type = MB_OK; + break; + case OptionOkCancel: + Type = MB_OKCANCEL; + break; + case OptionRetryCancel: + Type = MB_RETRYCANCEL; + break; + case OptionYesNo: + Type = MB_YESNO; + break; + case OptionYesNoCancel: + Type = MB_YESNOCANCEL; + break; + case OptionShutdownSystem: + Type = MB_RETRYCANCEL; // FIXME??? + break; /* Anything else is invalid */ - default: - return ResponseNotHandled; + default: + return ResponseNotHandled; } /* Set severity */ @@ -457,7 +457,7 @@ CsrpMessageBox( Type |= MB_SYSTEMMODAL | MB_SETFOREGROUND; - DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n", + DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n", Text, Caption, Severity, Type); /* Display a message box */ @@ -466,15 +466,15 @@ CsrpMessageBox( /* Return response value */ switch (MessageBoxResponse) { - case IDOK: return ResponseOk; - case IDCANCEL: return ResponseCancel; - case IDYES: return ResponseYes; - case IDNO: return ResponseNo; - case IDABORT: return ResponseAbort; - case IDIGNORE: return ResponseIgnore; - case IDRETRY: return ResponseRetry; - case IDTRYAGAIN: return ResponseTryAgain; - case IDCONTINUE: return ResponseContinue; + case IDOK: return ResponseOk; + case IDCANCEL: return ResponseCancel; + case IDYES: return ResponseYes; + case IDNO: return ResponseNo; + case IDABORT: return ResponseAbort; + case IDIGNORE: return ResponseIgnore; + case IDRETRY: return ResponseRetry; + case IDTRYAGAIN: return ResponseTryAgain; + case IDCONTINUE: return ResponseContinue; } return ResponseNotHandled; @@ -537,7 +537,7 @@ Win32CsrHardError( if (!NT_SUCCESS(Status)) { - return FALSE; + return FALSE; } /* Display the message box */ diff --git a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c index c9071686e13..f078fe1e2a6 100644 --- a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c @@ -20,15 +20,15 @@ static BOOL ConsInitialized = FALSE; static LRESULT CALLBACK TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_ACTIVATE) + if (msg == WM_ACTIVATE) { - if (LOWORD(wParam) != WA_INACTIVE) + if (LOWORD(wParam) != WA_INACTIVE) { - SetFocus(hWnd); - ConioDrawConsole(ActiveConsole); + SetFocus(hWnd); + ConioDrawConsole(ActiveConsole); } } - return DefWindowProcW(hWnd, msg, wParam, lParam); + return DefWindowProcW(hWnd, msg, wParam, lParam); } static BOOL FASTCALL @@ -63,19 +63,19 @@ cleanup: static BOOL FASTCALL TuiInit(DWORD OemCP) { - CONSOLE_SCREEN_BUFFER_INFO ScrInfo; - DWORD BytesReturned; - WNDCLASSEXW wc; - USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + CONSOLE_SCREEN_BUFFER_INFO ScrInfo; + DWORD BytesReturned; + WNDCLASSEXW wc; + USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - TuiStartService(L"Blue"); + TuiStartService(L"Blue"); - ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, - OPEN_EXISTING, 0, NULL); - if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) + ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, + OPEN_EXISTING, 0, NULL); + if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) { - DPRINT1("Failed to open BlueScreen.\n"); - return FALSE; + DPRINT1("Failed to open BlueScreen.\n"); + return FALSE; } if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT, @@ -93,163 +93,163 @@ TuiInit(DWORD OemCP) DPRINT1("Failed to set text attribute\n"); } - ActiveConsole = NULL; - InitializeCriticalSection(&ActiveConsoleLock); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, - NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) + ActiveConsole = NULL; + InitializeCriticalSection(&ActiveConsoleLock); + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, + NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) { - DPRINT1("Failed to get console info\n"); - return FALSE; + DPRINT1("Failed to get console info\n"); + return FALSE; } - PhysicalConsoleSize = ScrInfo.dwSize; + PhysicalConsoleSize = ScrInfo.dwSize; - RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"TuiConsoleWindowClass"; - wc.lpfnWndProc = TuiConsoleWndProc; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - if (RegisterClassExW(&wc) == 0) + RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"TuiConsoleWindowClass"; + wc.lpfnWndProc = TuiConsoleWndProc; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register console wndproc\n"); - return FALSE; + DPRINT1("Failed to register console wndproc\n"); + return FALSE; } - return TRUE; + return TRUE; } static VOID WINAPI TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; } static void FASTCALL TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region) { - UINT SrcDelta, DestDelta; - LONG i; - PBYTE Src, SrcEnd; + UINT SrcDelta, DestDelta; + LONG i; + PBYTE Src, SrcEnd; - Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); - SrcDelta = Buff->MaxX * 2; - SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; - DestDelta = ConioRectWidth(Region) * 2; - for (i = Region->Top; i <= Region->Bottom; i++) + Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); + SrcDelta = Buff->MaxX * 2; + SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; + DestDelta = ConioRectWidth(Region) * 2; + for (i = Region->Top; i <= Region->Bottom; i++) { - memcpy(Dest, Src, DestDelta); - Src += SrcDelta; - if (SrcEnd <= Src) + memcpy(Dest, Src, DestDelta); + Src += SrcDelta; + if (SrcEnd <= Src) { - Src -= Buff->MaxY * Buff->MaxX * 2; + Src -= Buff->MaxY * Buff->MaxX * 2; } - Dest += DestDelta; + Dest += DestDelta; } } static VOID WINAPI TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) { - DWORD BytesReturned; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - PCONSOLE_DRAW ConsoleDraw; - UINT ConsoleDrawSize; + DWORD BytesReturned; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCONSOLE_DRAW ConsoleDraw; + UINT ConsoleDrawSize; - if (ActiveConsole != Console) + if (ActiveConsole != Console) { - return; + return; } - ConsoleDrawSize = sizeof(CONSOLE_DRAW) + - (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; - ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize); - if (NULL == ConsoleDraw) + ConsoleDrawSize = sizeof(CONSOLE_DRAW) + + (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; + ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize); + if (NULL == ConsoleDraw) { - DPRINT1("HeapAlloc failed\n"); - return; + DPRINT1("HeapAlloc failed\n"); + return; } - ConsoleDraw->X = Region->Left; - ConsoleDraw->Y = Region->Top; - ConsoleDraw->SizeX = ConioRectWidth(Region); - ConsoleDraw->SizeY = ConioRectHeight(Region); - ConsoleDraw->CursorX = Buff->CurrentX; - ConsoleDraw->CursorY = Buff->CurrentY; + ConsoleDraw->X = Region->Left; + ConsoleDraw->Y = Region->Top; + ConsoleDraw->SizeX = ConioRectWidth(Region); + ConsoleDraw->SizeY = ConioRectHeight(Region); + ConsoleDraw->CursorX = Buff->CurrentX; + ConsoleDraw->CursorY = Buff->CurrentY; - TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); + TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, - NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, + NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) { - DPRINT1("Failed to draw console\n"); - HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); - return; + DPRINT1("Failed to draw console\n"); + HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); + return; } - HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); + HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); } static VOID WINAPI TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - DWORD BytesWritten; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + DWORD BytesWritten; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return; + return; } - if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) + if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) { - DPRINT1("Error writing to BlueScreen\n"); + DPRINT1("Error writing to BlueScreen\n"); } } static BOOL WINAPI TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - DWORD BytesReturned; + DWORD BytesReturned; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return TRUE; + return TRUE; } - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, - &Buff->CursorInfo, sizeof(Buff->CursorInfo), NULL, 0, - &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, + &Buff->CursorInfo, sizeof(Buff->CursorInfo), NULL, 0, + &BytesReturned, NULL)) { - DPRINT1( "Failed to set cursor info\n" ); - return FALSE; + DPRINT1( "Failed to set cursor info\n" ); + return FALSE; } - return TRUE; + return TRUE; } static BOOL WINAPI TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - CONSOLE_SCREEN_BUFFER_INFO Info; - DWORD BytesReturned; + CONSOLE_SCREEN_BUFFER_INFO Info; + DWORD BytesReturned; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return TRUE; + return TRUE; } - Info.dwCursorPosition.X = Buff->CurrentX; - Info.dwCursorPosition.Y = Buff->CurrentY; - Info.wAttributes = Buff->DefaultAttrib; + Info.dwCursorPosition.X = Buff->CurrentX; + Info.dwCursorPosition.Y = Buff->CurrentY; + Info.wAttributes = Buff->DefaultAttrib; - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, - &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, - &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, + &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, + &BytesReturned, NULL)) { - DPRINT1( "Failed to set cursor position\n" ); - return FALSE; + DPRINT1( "Failed to set cursor position\n" ); + return FALSE; } - return TRUE; + return TRUE; } static BOOL WINAPI @@ -261,32 +261,32 @@ TuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) static BOOL WINAPI TuiChangeTitle(PCSRSS_CONSOLE Console) { - return TRUE; + return TRUE; } static VOID WINAPI TuiCleanupConsole(PCSRSS_CONSOLE Console) { - DestroyWindow(Console->hWindow); + DestroyWindow(Console->hWindow); - EnterCriticalSection(&ActiveConsoleLock); + EnterCriticalSection(&ActiveConsoleLock); - /* Switch to next console */ - if (ActiveConsole == Console) + /* Switch to next console */ + if (ActiveConsole == Console) { - ActiveConsole = Console->Next != Console ? Console->Next : NULL; + ActiveConsole = Console->Next != Console ? Console->Next : NULL; } - if (Console->Next != Console) + if (Console->Next != Console) { - Console->Prev->Next = Console->Next; - Console->Next->Prev = Console->Prev; + Console->Prev->Next = Console->Next; + Console->Next->Prev = Console->Prev; } - LeaveCriticalSection(&ActiveConsoleLock); + LeaveCriticalSection(&ActiveConsoleLock); - if (NULL != ActiveConsole) + if (NULL != ActiveConsole) { - ConioDrawConsole(ActiveConsole); + ConioDrawConsole(ActiveConsole); } } @@ -306,179 +306,179 @@ TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD DWORD WINAPI TuiConsoleThread (PVOID Data) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data; - HWND NewWindow; - MSG msg; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data; + HWND NewWindow; + MSG msg; - NewWindow = CreateWindowW(L"TuiConsoleWindowClass", - Console->Title.Buffer, - 0, - -32000, -32000, 0, 0, - NULL, NULL, - (HINSTANCE) GetModuleHandleW(NULL), - (PVOID) Console); - Console->hWindow = NewWindow; - if (NULL == NewWindow) + NewWindow = CreateWindowW(L"TuiConsoleWindowClass", + Console->Title.Buffer, + 0, + -32000, -32000, 0, 0, + NULL, NULL, + (HINSTANCE) GetModuleHandleW(NULL), + (PVOID) Console); + Console->hWindow = NewWindow; + if (NULL == NewWindow) { - DPRINT1("CSR: Unable to create console window\n"); - return 1; + DPRINT1("CSR: Unable to create console window\n"); + return 1; } - SetForegroundWindow(Console->hWindow); + SetForegroundWindow(Console->hWindow); - while (TRUE) + while (TRUE) { - GetMessageW(&msg, 0, 0, 0); - DispatchMessage(&msg); - TranslateMessage(&msg); + GetMessageW(&msg, 0, 0, 0); + DispatchMessage(&msg); + TranslateMessage(&msg); - if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || - msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || - msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) + if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || + msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || + msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) { - ConioProcessKey(&msg, Console, TRUE); + ConioProcessKey(&msg, Console, TRUE); } } - return 0; + return 0; } static CSRSS_CONSOLE_VTBL TuiVtbl = { - TuiInitScreenBuffer, - TuiWriteStream, - TuiDrawRegion, - TuiSetCursorInfo, - TuiSetScreenInfo, - TuiUpdateScreenInfo, - TuiChangeTitle, - TuiCleanupConsole, - TuiChangeIcon, - TuiResizeBuffer, + TuiInitScreenBuffer, + TuiWriteStream, + TuiDrawRegion, + TuiSetCursorInfo, + TuiSetScreenInfo, + TuiUpdateScreenInfo, + TuiChangeTitle, + TuiCleanupConsole, + TuiChangeIcon, + TuiResizeBuffer, }; NTSTATUS FASTCALL TuiInitConsole(PCSRSS_CONSOLE Console) { - HANDLE ThreadHandle; + HANDLE ThreadHandle; - if (! ConsInitialized) + if (! ConsInitialized) { - ConsInitialized = TRUE; - if (! TuiInit(Console->CodePage)) + ConsInitialized = TRUE; + if (! TuiInit(Console->CodePage)) { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; } } - Console->Vtbl = &TuiVtbl; - Console->hWindow = NULL; - Console->Size = PhysicalConsoleSize; - Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; - Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; + Console->Vtbl = &TuiVtbl; + Console->hWindow = NULL; + Console->Size = PhysicalConsoleSize; + Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; + Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; - ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread, - Console, 0, NULL); - if (NULL == ThreadHandle) + ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread, + Console, 0, NULL); + if (NULL == ThreadHandle) { - DPRINT1("CSR: Unable to create console thread\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("CSR: Unable to create console thread\n"); + return STATUS_UNSUCCESSFUL; } - CloseHandle(ThreadHandle); + CloseHandle(ThreadHandle); - EnterCriticalSection(&ActiveConsoleLock); - if (NULL != ActiveConsole) + EnterCriticalSection(&ActiveConsoleLock); + if (NULL != ActiveConsole) { - Console->Prev = ActiveConsole; - Console->Next = ActiveConsole->Next; - ActiveConsole->Next->Prev = Console; - ActiveConsole->Next = Console; + Console->Prev = ActiveConsole; + Console->Next = ActiveConsole->Next; + ActiveConsole->Next->Prev = Console; + ActiveConsole->Next = Console; } - else + else { - Console->Prev = Console; - Console->Next = Console; + Console->Prev = Console; + Console->Next = Console; } - ActiveConsole = Console; - LeaveCriticalSection(&ActiveConsoleLock); + ActiveConsole = Console; + LeaveCriticalSection(&ActiveConsoleLock); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } PCSRSS_CONSOLE FASTCALL TuiGetFocusConsole(VOID) { - return ActiveConsole; + return ActiveConsole; } BOOL FASTCALL TuiSwapConsole(int Next) { - static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */ - DWORD BytesReturned; - ANSI_STRING Title; - void * Buffer; - COORD *pos; + static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */ + DWORD BytesReturned; + ANSI_STRING Title; + void * Buffer; + COORD *pos; - if (0 != Next) + if (0 != Next) { - /* alt-tab, swap consoles */ - /* move SwapConsole to next console, and print its title */ - EnterCriticalSection(&ActiveConsoleLock); - if (! SwapConsole) + /* alt-tab, swap consoles */ + /* move SwapConsole to next console, and print its title */ + EnterCriticalSection(&ActiveConsoleLock); + if (! SwapConsole) { - SwapConsole = ActiveConsole; + SwapConsole = ActiveConsole; } - SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev); - Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title); - Title.Length = 0; - Buffer = HeapAlloc(Win32CsrApiHeap, - 0, - sizeof(COORD) + Title.MaximumLength); - pos = (COORD *)Buffer; - Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD )); + SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev); + Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title); + Title.Length = 0; + Buffer = HeapAlloc(Win32CsrApiHeap, + 0, + sizeof(COORD) + Title.MaximumLength); + pos = (COORD *)Buffer; + Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD )); - RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE); - pos->Y = PhysicalConsoleSize.Y / 2; - pos->X = (PhysicalConsoleSize.X - Title.Length) / 2; - /* redraw the console to clear off old title */ - ConioDrawConsole(ActiveConsole); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - NULL, 0, Buffer, sizeof(COORD) + Title.Length, - &BytesReturned, NULL)) + RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE); + pos->Y = PhysicalConsoleSize.Y / 2; + pos->X = (PhysicalConsoleSize.X - Title.Length) / 2; + /* redraw the console to clear off old title */ + ConioDrawConsole(ActiveConsole); + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, + NULL, 0, Buffer, sizeof(COORD) + Title.Length, + &BytesReturned, NULL)) { - DPRINT1( "Error writing to console\n" ); + DPRINT1( "Error writing to console\n" ); } - HeapFree(Win32CsrApiHeap, 0, Buffer); - LeaveCriticalSection(&ActiveConsoleLock); + HeapFree(Win32CsrApiHeap, 0, Buffer); + LeaveCriticalSection(&ActiveConsoleLock); - return TRUE; + return TRUE; } - else if (NULL != SwapConsole) + else if (NULL != SwapConsole) { - EnterCriticalSection(&ActiveConsoleLock); - if (SwapConsole != ActiveConsole) + EnterCriticalSection(&ActiveConsoleLock); + if (SwapConsole != ActiveConsole) { - /* first remove swapconsole from the list */ - SwapConsole->Prev->Next = SwapConsole->Next; - SwapConsole->Next->Prev = SwapConsole->Prev; - /* now insert before activeconsole */ - SwapConsole->Next = ActiveConsole; - SwapConsole->Prev = ActiveConsole->Prev; - ActiveConsole->Prev->Next = SwapConsole; - ActiveConsole->Prev = SwapConsole; + /* first remove swapconsole from the list */ + SwapConsole->Prev->Next = SwapConsole->Next; + SwapConsole->Next->Prev = SwapConsole->Prev; + /* now insert before activeconsole */ + SwapConsole->Next = ActiveConsole; + SwapConsole->Prev = ActiveConsole->Prev; + ActiveConsole->Prev->Next = SwapConsole; + ActiveConsole->Prev = SwapConsole; } - ActiveConsole = SwapConsole; - SwapConsole = NULL; - ConioDrawConsole(ActiveConsole); - LeaveCriticalSection(&ActiveConsoleLock); - return TRUE; + ActiveConsole = SwapConsole; + SwapConsole = NULL; + ConioDrawConsole(ActiveConsole); + LeaveCriticalSection(&ActiveConsoleLock); + return TRUE; } - else + else { - return FALSE; + return FALSE; } } From 63313191f023925b6e797bfc4cdd10fbfdf94a72 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 20:19:21 +0000 Subject: [PATCH 128/292] Various application fixes by Jan Roeloffzen, bug #5182, part 1 Notepad: remove unused variable, tabs -> spaces Regedit: remove unused variable Calc: dword->bool, remove unused variables, tabs -> spaces svn path=/trunk/; revision=47458 --- reactos/base/applications/calc/utl.c | 6 ++- reactos/base/applications/calc/winmain.c | 54 +++++++++++----------- reactos/base/applications/notepad/dialog.c | 29 ++++++------ reactos/base/applications/regedit/edit.c | 7 ++- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/reactos/base/applications/calc/utl.c b/reactos/base/applications/calc/utl.c index 599115e9883..9ec8bebcc8f 100644 --- a/reactos/base/applications/calc/utl.c +++ b/reactos/base/applications/calc/utl.c @@ -2,7 +2,6 @@ void prepare_rpn_result_2(calc_number_t *rpn, TCHAR *buffer, int size, int base) { - TCHAR *ptr, *dst; calc_number_t tmp; int width; @@ -21,9 +20,12 @@ void prepare_rpn_result_2(calc_number_t *rpn, TCHAR *buffer, int size, int base) /* calculate the width of integer number */ width = (rpn->f==0) ? 1 : (int)log10(fabs(rpn->f))+1; if (calc.sci_out == TRUE || width > MAX_LD_WIDTH || width < -MAX_LD_WIDTH) - ptr = buffer + _stprintf(buffer, TEXT("%#e"), rpn->f); + _stprintf(buffer, TEXT("%#e"), rpn->f); else { + TCHAR *ptr, *dst; + ptr = buffer + _stprintf(buffer, TEXT("%#*.*f"), width, ((MAX_LD_WIDTH-width-1)>=0) ? MAX_LD_WIDTH-width-1 : 0, rpn->f); + /* format sring ensures there is a '.': */ dst = _tcschr(buffer, TEXT('.')); while (--ptr > dst) if (*ptr != TEXT('0')) diff --git a/reactos/base/applications/calc/winmain.c b/reactos/base/applications/calc/winmain.c index 40a34682b62..6279d3d5091 100644 --- a/reactos/base/applications/calc/winmain.c +++ b/reactos/base/applications/calc/winmain.c @@ -861,18 +861,18 @@ static INT_PTR CALLBACK DlgStatProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) n = SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_GETCURSEL, 0, 0); if (n == (DWORD)-1) return TRUE; - PostMessage(GetParent(hWnd), WM_LOAD_STAT, (WPARAM)n, 0); + PostMessage(GetParent(hWnd), WM_LOAD_STAT, (WPARAM)n, 0); return TRUE; case IDC_BUTTON_CD: n = SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_GETCURSEL, 0, 0); if (n == (DWORD)-1) return TRUE; - SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_DELETESTRING, (WPARAM)n, 0); + SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_DELETESTRING, (WPARAM)n, 0); update_n_stats_items(hWnd, buffer); delete_stat_item(n); return TRUE; case IDC_BUTTON_CAD: - SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_RESETCONTENT, 0, 0); clean_stat_list(); update_n_stats_items(hWnd, buffer); return TRUE; @@ -910,20 +910,20 @@ static WPARAM idm_2_idc(int idm) static void CopyMemToClipboard(void *ptr) { if(OpenClipboard(NULL)) { - HGLOBAL clipbuffer; - TCHAR *buffer; + HGLOBAL clipbuffer; + TCHAR *buffer; - EmptyClipboard(); - clipbuffer = GlobalAlloc(GMEM_DDESHARE, (_tcslen(ptr)+1)*sizeof(TCHAR)); - buffer = (TCHAR *)GlobalLock(clipbuffer); - _tcscpy(buffer, ptr); - GlobalUnlock(clipbuffer); + EmptyClipboard(); + clipbuffer = GlobalAlloc(GMEM_DDESHARE, (_tcslen(ptr)+1)*sizeof(TCHAR)); + buffer = (TCHAR *)GlobalLock(clipbuffer); + _tcscpy(buffer, ptr); + GlobalUnlock(clipbuffer); #ifdef UNICODE - SetClipboardData(CF_UNICODETEXT,clipbuffer); + SetClipboardData(CF_UNICODETEXT,clipbuffer); #else - SetClipboardData(CF_TEXT,clipbuffer); + SetClipboardData(CF_TEXT,clipbuffer); #endif - CloseClipboard(); + CloseClipboard(); } } @@ -942,16 +942,16 @@ static char *ReadClipboard(void) char *buffer = NULL; if (OpenClipboard(NULL)) { - HANDLE hData = GetClipboardData(CF_TEXT); + HANDLE hData = GetClipboardData(CF_TEXT); char *fromClipboard; if (hData != NULL) { fromClipboard = (char *)GlobalLock(hData); if (strlen(fromClipboard)) - buffer = _strupr(_strdup(fromClipboard)); - GlobalUnlock( hData ); + buffer = _strupr(_strdup(fromClipboard)); + GlobalUnlock( hData ); } - CloseClipboard(); + CloseClipboard(); } return buffer; } @@ -1110,20 +1110,20 @@ static void handle_context_menu(HWND hWnd, WPARAM wp, LPARAM lp) { TCHAR text[64]; HMENU hMenu = CreatePopupMenu(); - DWORD idm; + BOOL idm; LoadString(calc.hInstance, IDS_QUICKHELP, text, SIZEOF(text)); AppendMenu(hMenu, MF_STRING | MF_ENABLED, IDM_HELP_HELP, text); - idm = (DWORD)TrackPopupMenu(hMenu, - TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, - LOWORD(lp), - HIWORD(lp), - 0, - hWnd, - NULL); + idm = TrackPopupMenu( hMenu, + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, + LOWORD(lp), + HIWORD(lp), + 0, + hWnd, + NULL); DestroyMenu(hMenu); #ifndef DISABLE_HTMLHELP_SUPPORT - if (idm != 0) { + if (idm) { HH_POPUP popup; memset(&popup, 0, sizeof(popup)); @@ -1139,6 +1139,8 @@ static void handle_context_menu(HWND hWnd, WPARAM wp, LPARAM lp) popup.idString = GetWindowLongPtr((HWND)wp, GWL_ID); HtmlHelp((HWND)wp, HTMLHELP_PATH("/popups.txt"), HH_DISPLAY_TEXT_POPUP, (DWORD_PTR)&popup); } +#else + (void)idm; #endif } diff --git a/reactos/base/applications/notepad/dialog.c b/reactos/base/applications/notepad/dialog.c index 937dd5807de..d8c6adc04e6 100644 --- a/reactos/base/applications/notepad/dialog.c +++ b/reactos/base/applications/notepad/dialog.c @@ -400,7 +400,6 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar { TCHAR szText[128]; HWND hCombo; - OFNOTIFY *pNotify; UNREFERENCED_PARAMETER(wParam); @@ -440,15 +439,13 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar case WM_NOTIFY: if (((NMHDR *) lParam)->code == CDN_FILEOK) { - pNotify = (OFNOTIFY *) lParam; - hCombo = GetDlgItem(hDlg, ID_ENCODING); - if (hCombo) - Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); + if (hCombo) + Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); hCombo = GetDlgItem(hDlg, ID_EOLN); - if (hCombo) - Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); + if (hCombo) + Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); } break; } @@ -808,11 +805,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA TCHAR szText[32]; switch(uMsg) { - case WM_INITDIALOG: + case WM_INITDIALOG: hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER); - _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam); + _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam); SetWindowText(hTextBox, szText); - break; + break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { @@ -823,11 +820,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA EndDialog(hwndDialog, _ttoi(szText)); bResult = TRUE; } - else if (LOWORD(wParam) == IDCANCEL) - { + else if (LOWORD(wParam) == IDCANCEL) + { EndDialog(hwndDialog, 0); bResult = TRUE; - } + } } break; } @@ -862,7 +859,7 @@ VOID DIALOG_GoTo(VOID) Globals.hMainWnd, DIALOG_GoTo_DialogProc, nLine); if (nLine >= 1) - { + { for (i = 0; pszText[i] && (nLine > 1) && (i < nLength - 1); i++) { if (pszText[i] == '\n') @@ -870,8 +867,8 @@ VOID DIALOG_GoTo(VOID) } SendMessage(Globals.hEdit, EM_SETSEL, i, i); SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0); - } - HeapFree(GetProcessHeap(), 0, pszText); + } + HeapFree(GetProcessHeap(), 0, pszText); } VOID DIALOG_StatusBarUpdateCaretPos(VOID) diff --git a/reactos/base/applications/regedit/edit.c b/reactos/base/applications/regedit/edit.c index ca4d5b3ac8f..6ed32b974bb 100644 --- a/reactos/base/applications/regedit/edit.c +++ b/reactos/base/applications/regedit/edit.c @@ -276,7 +276,6 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP { WNDPROC oldproc; HWND hwndValue; - int len; TCHAR ValueString[32]; LPTSTR Remainder; DWORD Base; @@ -319,7 +318,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP dwordEditMode = EDIT_MODE_HEX; if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (GetWindowText(hwndValue, ValueString, 32)) { @@ -339,7 +338,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP dwordEditMode = EDIT_MODE_DEC; if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (GetWindowText(hwndValue, ValueString, 32)) { @@ -356,7 +355,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP case IDOK: if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (!GetWindowText(hwndValue, ValueString, 32)) { From 81d25d5267744aa9632052ba4724df569b2f9029 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 20:25:46 +0000 Subject: [PATCH 129/292] Various application fixes by Jan Roeloffzen, bug #5182, part 2 fontview: remove unused variable kbswitch: remove unused variables magnify: remove unused variable mplay32: DWORD -> MCIERROR, tabs -> spaces eventvwr: remove unused variable svn path=/trunk/; revision=47459 --- reactos/base/applications/fontview/fontview.c | 3 --- reactos/base/applications/kbswitch/kbswitch.c | 5 ++--- reactos/base/applications/magnify/magnifier.c | 3 +-- reactos/base/applications/mplay32/mplay32.c | 14 +++++++------- .../base/applications/mscutils/eventvwr/eventvwr.c | 4 ---- 5 files changed, 10 insertions(+), 19 deletions(-) diff --git a/reactos/base/applications/fontview/fontview.c b/reactos/base/applications/fontview/fontview.c index 82fa44aff6a..72b183212ba 100644 --- a/reactos/base/applications/fontview/fontview.c +++ b/reactos/base/applications/fontview/fontview.c @@ -60,13 +60,10 @@ FormatString( static void ErrorMsgBox(HWND hParent, DWORD dwCaptionID, DWORD dwMessageId, ...) { - HMODULE hModule; HLOCAL hMemCaption = NULL; HLOCAL hMemText = NULL; va_list args; - hModule = GetModuleHandle(NULL); - va_start(args, dwMessageId); FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, (LPWSTR)&hMemText, 0, &args); diff --git a/reactos/base/applications/kbswitch/kbswitch.c b/reactos/base/applications/kbswitch/kbswitch.c index 5c94c25f79a..03f196f7771 100644 --- a/reactos/base/applications/kbswitch/kbswitch.c +++ b/reactos/base/applications/kbswitch/kbswitch.c @@ -33,7 +33,6 @@ CreateTrayIcon(LPTSTR szLCID) HDC hdc, hdcsrc; HBITMAP hBitmap, hBmpNew, hBmpOld; RECT rect; - DWORD bkColor, bkText; HFONT hFontOld, hFont = NULL; ICONINFO IconInfo; HICON hIcon = NULL; @@ -63,8 +62,8 @@ CreateTrayIcon(LPTSTR szLCID) rect.bottom = 16; rect.top = 0; - bkColor = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); - bkText = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); ExtTextOut(hdc, rect.left, rect.top, ETO_OPAQUE, &rect, _T(""), 0, NULL); diff --git a/reactos/base/applications/magnify/magnifier.c b/reactos/base/applications/magnify/magnifier.c index 43816d6b5aa..4c2b4f623e9 100644 --- a/reactos/base/applications/magnify/magnifier.c +++ b/reactos/base/applications/magnify/magnifier.c @@ -295,7 +295,7 @@ void Draw(HDC aDc) // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - int wmId, wmEvent; + int wmId; switch (message) { @@ -354,7 +354,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_COMMAND: wmId = LOWORD(wParam); - wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { diff --git a/reactos/base/applications/mplay32/mplay32.c b/reactos/base/applications/mplay32/mplay32.c index 9b1b564908a..f4bd117a65f 100644 --- a/reactos/base/applications/mplay32/mplay32.c +++ b/reactos/base/applications/mplay32/mplay32.c @@ -407,7 +407,7 @@ PlayFile(HWND hwnd, LPTSTR lpFileName) MCI_PLAY_PARMS mciPlay; TCHAR szLocalFileName[MAX_PATH]; UINT FileType; - DWORD dwError; + MCIERROR mciError; if (lpFileName == NULL) { @@ -449,14 +449,14 @@ PlayFile(HWND hwnd, LPTSTR lpFileName) SetTimer(hwnd, IDT_PLAYTIMER, 100, (TIMERPROC) PlayTimerProc); - dwError = mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_SEEK_TO_START, 0); + mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_SEEK_TO_START, 0); mciPlay.dwCallback = (DWORD_PTR)hwnd; mciPlay.dwFrom = 0; mciPlay.dwTo = MaxFilePos; - dwError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)&mciPlay); - if (dwError != 0) + mciError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)&mciPlay); + if (mciError != 0) { MessageBox(hwnd, _T("Can't play!"), NULL, MB_OK); } @@ -641,12 +641,12 @@ MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) break; case IDM_ABOUT: - { + { HICON mplayIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN)); ShellAbout(hwnd, szAppTitle, 0, mplayIcon); - DeleteObject(mplayIcon); + DeleteObject(mplayIcon); break; - } + } case IDM_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0); return 0; diff --git a/reactos/base/applications/mscutils/eventvwr/eventvwr.c b/reactos/base/applications/mscutils/eventvwr/eventvwr.c index dbe44a8b913..011c0ec5da6 100644 --- a/reactos/base/applications/mscutils/eventvwr/eventvwr.c +++ b/reactos/base/applications/mscutils/eventvwr/eventvwr.c @@ -506,7 +506,6 @@ QueryEventMessages(LPWSTR lpMachineName, DWORD dwRead, dwNeeded, dwThisRecord, dwTotalRecords = 0, dwCurrentRecord = 1, dwRecordsToRead = 0, dwFlags; LPWSTR lpSourceName; LPWSTR lpComputerName; - LPWSTR lpEventStr; LPWSTR lpData; BOOL bResult = TRUE; /* Read succeeded. */ @@ -609,9 +608,6 @@ QueryEventMessages(LPWSTR lpMachineName, // This ist the data section of the current event lpData = (LPWSTR)((LPBYTE)pevlr + pevlr->DataOffset); - // This is the text of the current event - lpEventStr = (LPWSTR)((LPBYTE)pevlr + pevlr->StringOffset); - // Compute the event type EventTimeToSystemTime(pevlr->TimeWritten, &time); From ad964bddb130eb3b07b5658bf9524052ef523a07 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 20:31:58 +0000 Subject: [PATCH 130/292] Various application fixes by Jan Roeloffzen, bug #5182, part 3 arp: Remove unused variables ftp: tabs->spaces, remove unused variables nslookup: Remove unused variables svn path=/trunk/; revision=47460 --- reactos/base/applications/network/arp/arp.c | 25 +-- reactos/base/applications/network/ftp/fake.c | 152 +++++++++--------- reactos/base/applications/network/ftp/ftp.c | 11 +- .../applications/network/nslookup/nslookup.c | 16 +- 4 files changed, 92 insertions(+), 112 deletions(-) diff --git a/reactos/base/applications/network/arp/arp.c b/reactos/base/applications/network/arp/arp.c index 539d6cf98d7..3014b5823e0 100644 --- a/reactos/base/applications/network/arp/arp.c +++ b/reactos/base/applications/network/arp/arp.c @@ -170,9 +170,7 @@ INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -201,9 +199,7 @@ INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpAddrTable, sizeof(*pIpAddrTable)); - iRet = GetIpAddrTable(pIpAddrTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if ((iRet = GetIpAddrTable(pIpAddrTable, &Size, TRUE)) != NO_ERROR) { _tprintf(_T("GetIpAddrTable failed: %d\n"), iRet); DoFormatMessage(); @@ -272,7 +268,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) PMIB_IPNETTABLE pIpNetTable = NULL; DWORD dwIpAddr = 0; ULONG Size = 0; - INT iRet, i, val, c; + INT i, val, c; /* error checking */ @@ -320,9 +316,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -382,7 +376,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) /* Add the ARP entry */ - if ((iRet = SetIpNetEntry(pAddHost)) != NO_ERROR) + if (SetIpNetEntry(pAddHost) != NO_ERROR) { DoFormatMessage(); goto cleanup; @@ -415,7 +409,6 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) PMIB_IPNETTABLE pIpNetTable = NULL; ULONG Size = 0; DWORD dwIpAddr = 0; - INT iRet; BOOL bFlushTable = FALSE; /* error checking */ @@ -449,9 +442,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -485,7 +476,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) if (bFlushTable == TRUE) { /* delete arp cache */ - if ((iRet = FlushIpNetTable(pDelHost->dwIndex)) != NO_ERROR) + if (FlushIpNetTable(pDelHost->dwIndex) != NO_ERROR) { DoFormatMessage(); goto cleanup; @@ -501,7 +492,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) pDelHost->dwAddr = dwIpAddr; /* Add the ARP entry */ - if ((iRet = DeleteIpNetEntry(pDelHost)) != NO_ERROR) + if (DeleteIpNetEntry(pDelHost) != NO_ERROR) { DoFormatMessage(); goto cleanup; diff --git a/reactos/base/applications/network/ftp/fake.c b/reactos/base/applications/network/ftp/fake.c index f8d0c8cdadf..a00f30560be 100644 --- a/reactos/base/applications/network/ftp/fake.c +++ b/reactos/base/applications/network/ftp/fake.c @@ -29,10 +29,10 @@ int checkRecv(SOCKET s) void blkfree(char **av0) { - register char **av = av0; + register char **av = av0; - while (*av) - free(*av++); + while (*av) + free(*av++); } char **glob(register char *v) @@ -52,16 +52,16 @@ int herror(char *string) #if 0 int gettimeofday(struct timeval *timenow, - struct timezone *zone) + struct timezone *zone) { - time_t t; + time_t t; - t = clock(); + t = clock(); - timenow->tv_usec = t; - timenow->tv_sec = t / CLK_TCK; + timenow->tv_usec = t; + timenow->tv_sec = t / CLK_TCK; - return 0; + return 0; } int fgetcSocket(int s) @@ -100,13 +100,13 @@ int fgetcSocket(int s) total = recv(s, buffer, sizeof(buffer), 0); if (total == SOCKET_ERROR) - { - total = 0; - return ERROR; - } + { + total = 0; + return ERROR; + } if (total == 0) - return EOF; + return EOF; } return buffer[index++]; } @@ -142,29 +142,29 @@ int fputcSocket(int s, char putChar) buffer[1] = '\0'; if(SOCKET_ERROR==send(s, buffer, 1, 0)) { - int iret=WSAGetLastError (); - fprintf(stdout,"fputcSocket: %d\n",iret); - return 0; + int iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; } else { - return putChar; + return putChar; } } int fputSocket(int s, char *buffer, int len) { - int iret; - while(len) { - if(SOCKET_ERROR==(iret=send(s, buffer, len, 0))) - { - iret=WSAGetLastError (); - fprintf(stdout,"fputcSocket: %d\n",iret); - return 0; - } - else { - return len-=iret; - } - } - return 0; + int iret; + while(len) { + if(SOCKET_ERROR==(iret=send(s, buffer, len, 0))) + { + iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; + } + else { + return len-=iret; + } + } + return 0; } char *fgetsSocket(int s, char *string) @@ -180,31 +180,31 @@ char *fgetsSocket(int s, char *string) if (count == SOCKET_ERROR) { - printf("Error in fgetssocket"); - return NULL; + printf("Error in fgetssocket"); + return NULL; } if (count == 1) { - string[i] = buffer[0]; + string[i] = buffer[0]; - if (i == MAX_ASCII - 3) - { - count = 0; - string[++i] = '\n'; - string[++i] = '\0'; - } + if (i == MAX_ASCII - 3) + { + count = 0; + string[++i] = '\n'; + string[++i] = '\0'; + } } else { - if (i == 0) - return NULL; - else - { - string[i] = '\n'; - string[i + 1] = '\0'; // This is risky - return string; - } + if (i == 0) + return NULL; + else + { + string[i] = '\n'; + string[i + 1] = '\0'; // This is risky + return string; + } } @@ -250,44 +250,44 @@ char *getpass (const char * prompt) int rc; if (istty) - { - if (GetConsoleMode (in, &old_flags)) - SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); - else - istty = 0; - } + { + if (GetConsoleMode (in, &old_flags)) + SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); + else + istty = 0; + } /* Need to read line one byte at time to avoid blocking, if not a tty, so always do it this way. */ count = 0; while (1) - { - DWORD dummy; - char one_char; + { + DWORD dummy; + char one_char; - rc = ReadFile (in, &one_char, 1, &dummy, NULL); - if (rc == 0) - break; - if (one_char == '\r') - { - /* CR is always followed by LF if reading from tty. */ - if (istty) - continue; - else - break; - } - if (one_char == '\n') - break; - /* Silently truncate password string if overly long. */ - if (count < sizeof (input) - 1) - input[count++] = one_char; - } + rc = ReadFile (in, &one_char, 1, &dummy, NULL); + if (rc == 0) + break; + if (one_char == '\r') + { + /* CR is always followed by LF if reading from tty. */ + if (istty) + continue; + else + break; + } + if (one_char == '\n') + break; + /* Silently truncate password string if overly long. */ + if (count < sizeof (input) - 1) + input[count++] = one_char; + } input[count] = '\0'; WriteFile (err, "\r\n", 2, &count, NULL); if (istty) - SetConsoleMode (in, old_flags); + SetConsoleMode (in, old_flags); if (rc) - return input; + return input; } return NULL; diff --git a/reactos/base/applications/network/ftp/ftp.c b/reactos/base/applications/network/ftp/ftp.c index 2b09522fb51..5fdc81ce9fa 100644 --- a/reactos/base/applications/network/ftp/ftp.c +++ b/reactos/base/applications/network/ftp/ftp.c @@ -345,7 +345,7 @@ getreply(expecteof) cp = reply_string; while ((c = fgetcSocket(cin)) != '\n') { if (c == IAC) { /* handle telnet commands */ - switch (c = fgetcSocket(cin)) { + switch (fgetcSocket(cin)) { case WILL: case WONT: c = fgetcSocket(cin); @@ -745,7 +745,7 @@ void recvrequest(const char *cmd, const char *local, const char *remote, const c long bytes = 0, hashbytes = HASHBYTES; // struct fd_set mask; - register int c, d; + register int c; struct timeval start, stop; // struct stat st; @@ -781,6 +781,7 @@ null();// (void) signal(SIGINT, oldintr); null();// oldintr = signal(SIGINT, abortrecv); if (strcmp(local, "-") && *local != '|') { #ifndef _WIN32 + register int d; // This whole thing is a problem... access Won't work on non-existent files if (access(local, 2) < 0) { char *dir = rindex(local, '/'); @@ -919,7 +920,7 @@ null();// oldintp = signal(SIGPIPE, SIG_IGN); (*closefunc)(fout); return; } - errno = d = 0; + errno = 0; // while ((c = recv(din, buf, bufsize, 1)) > 0) { // if ((d = write(fileno(fout), buf, c)) != c) // if ((d = write(fileno(fout), buf, c)) != c) @@ -1106,10 +1107,10 @@ null();// (void) signal(SIGINT,oldintr); lostpeer(); } if (din && FD_ISSET(din, &mask)) { - while ((c = recv(din, buf, bufsize, 0)) > 0) + while (recv(din, buf, bufsize, 0) > 0) ; } - if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */ + if (getreply(0) == ERROR && code == 552) { /* needed for nic style abort */ if (data >= 0) { (void) close(data); data = -1; diff --git a/reactos/base/applications/network/nslookup/nslookup.c b/reactos/base/applications/network/nslookup/nslookup.c index 993ab04a650..3e7ce484fd9 100644 --- a/reactos/base/applications/network/nslookup/nslookup.c +++ b/reactos/base/applications/network/nslookup/nslookup.c @@ -90,11 +90,7 @@ BOOL PerformInternalLookup( PCHAR pAddr, PCHAR pResult ) BOOL bOk = FALSE; /* Makes things easier when parsing the response packet. */ - UCHAR Header1, Header2; USHORT NumQuestions; - USHORT NumAnswers; - USHORT NumAuthority; - USHORT NumAdditional; USHORT Type; if( (strlen( pAddr ) + 1) > 255 ) return FALSE; @@ -198,12 +194,7 @@ BOOL PerformInternalLookup( PCHAR pAddr, PCHAR pResult ) if( !bOk ) goto cleanup; /* Start parsing the received packet. */ - Header1 = RecBuffer[2]; - Header2 = RecBuffer[3]; NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] ); - NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] ); - NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] ); - NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] ); k = 12; @@ -257,11 +248,10 @@ void PerformLookup( PCHAR pAddr ) BOOL bOk = FALSE; /* Makes things easier when parsing the response packet. */ - UCHAR Header1, Header2; + UCHAR Header2; USHORT NumQuestions; USHORT NumAnswers; USHORT NumAuthority; - USHORT NumAdditional; USHORT Type; if( (strlen( pAddr ) + 1) > 255 ) return; @@ -368,19 +358,17 @@ void PerformLookup( PCHAR pAddr ) ((PSHORT)&Buffer[i])[0] = htons( ClassNametoClassID( State.Class ) ); /* Ship off the request to the DNS server. */ - bOk = SendRequest( Buffer, + bOk = SendRequest( Buffer, BufferLength, RecBuffer, &RecBufferLength ); if( !bOk ) goto cleanup; /* Start parsing the received packet. */ - Header1 = RecBuffer[2]; Header2 = RecBuffer[3]; NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] ); NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] ); NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] ); - NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] ); Type = 0; /* Check the RCODE for failure. */ From 8117e461310ce4731c9652523fa37bb46bccc33c Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 20:36:20 +0000 Subject: [PATCH 131/292] Various application fixes by Jan Roeloffzen, bug #5182, part 4/4 dxdiag: tabs -> spaces, UINT -> UINT_PTR, remove unused assignments, simplify code, fix compiler warnings svn path=/trunk/; revision=47461 --- reactos/base/applications/dxdiag/ddtest.c | 5 +++-- reactos/base/applications/dxdiag/input.c | 6 +++--- reactos/base/applications/dxdiag/network.c | 18 ++++++++---------- reactos/base/applications/dxdiag/sound.c | 1 + 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/reactos/base/applications/dxdiag/ddtest.c b/reactos/base/applications/dxdiag/ddtest.c index 47f41a54ec0..734f166d9e5 100644 --- a/reactos/base/applications/dxdiag/ddtest.c +++ b/reactos/base/applications/dxdiag/ddtest.c @@ -151,7 +151,7 @@ BOOL DDPrimarySurfaceTest(HWND hWnd){ { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_TIMER && TimerID == msg.wParam) + if (msg.message == WM_TIMER && TimerID == msg.wParam) break; TranslateMessage(&msg); DispatchMessage(&msg); @@ -200,7 +200,7 @@ VOID DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface) BOOL DDOffscreenBufferTest(HWND hWnd, BOOL Fullscreen){ - UINT TimerID, TimerIDUpdate; + UINT_PTR TimerID, TimerIDUpdate; LPDIRECTDRAW lpDD; LPDIRECTDRAWSURFACE lpDDPrimarySurface; LPDIRECTDRAWSURFACE lpDDBackBuffer; @@ -288,6 +288,7 @@ BOOL DDOffscreenBufferTest(HWND hWnd, BOOL Fullscreen){ /* set our timers, TimerID - for test timeout, TimerIDUpdate - for frame updating */ TimerID = SetTimer(hWnd, -1, (UINT)TEST_DURATION, NULL); TimerIDUpdate = SetTimer(hWnd, 2, (UINT)10, NULL); + (void)TimerIDUpdate; while (TRUE) { diff --git a/reactos/base/applications/dxdiag/input.c b/reactos/base/applications/dxdiag/input.c index 08bb2b718b8..03d238a57ce 100644 --- a/reactos/base/applications/dxdiag/input.c +++ b/reactos/base/applications/dxdiag/input.c @@ -129,13 +129,13 @@ BOOL CALLBACK DirectInputEnumDevCb( ZeroMemory(&GuidPath, sizeof(DIPROPGUIDANDPATH)); GuidPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); GuidPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); - GuidPath.diph.dwHow = DIPH_DEVICE; + GuidPath.diph.dwHow = DIPH_DEVICE; hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GUIDANDPATH, (LPDIPROPHEADER)&GuidPath); ZeroMemory(&TypeName, sizeof(TypeName)); TypeName.diph.dwSize = sizeof(TypeName); TypeName.diph.dwHeaderSize = sizeof(DIPROPHEADER); - TypeName.diph.dwHow = DIPH_DEVICE; + TypeName.diph.dwHow = DIPH_DEVICE; hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GETPORTDISPLAYNAME, (LPDIPROPHEADER)&TypeName); @@ -191,7 +191,7 @@ InitializeDirectInputDialog(HWND hwndDlg) Context.pObj = pObj; Context.hwndDlg = hwndDlg; InitListViewColumns(&Context); - hResult = pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES); + pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES); pObj->lpVtbl->Release(pObj); } diff --git a/reactos/base/applications/dxdiag/network.c b/reactos/base/applications/dxdiag/network.c index 5154c4eef87..3a4b7c666f2 100644 --- a/reactos/base/applications/dxdiag/network.c +++ b/reactos/base/applications/dxdiag/network.c @@ -178,10 +178,10 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv { DWORD dwIndex = 0; LONG result; - WCHAR szName[50]; + WCHAR szName[50]; WCHAR szGUID[40]; WCHAR szTemp[63]; - WCHAR szResult[MAX_PATH+20] = {0}; + WCHAR szResult[MAX_PATH+20] = {0}; DWORD RegProviders = 0; DWORD ProviderIndex; DWORD dwName; @@ -203,13 +203,12 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv szResult[0] = L'\0'; LoadStringW(hInst, PreDefProviders[dwIndex].ResourceID, szResult, sizeof(szResult)/sizeof(WCHAR)); szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0'; - lResult = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item); + Item.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item); + Item.iSubItem = 1; szResult[0] = L'\0'; LoadStringW(hInst, IDS_REG_FAIL, szResult, sizeof(szResult)/sizeof(WCHAR)); szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0'; - Item.iItem = lResult; - Item.iSubItem = 1; - lResult = SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item); + SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item); } dwIndex = 0; @@ -228,8 +227,7 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv if (ProviderIndex == UINT_MAX) { /* a custom service provider was found */ - lResult = ListView_GetItemCount(hDlgCtrl); - Item.iItem = lResult; + Item.iItem = ListView_GetItemCount(hDlgCtrl); /* FIXME * on Windows Vista we need to use RegLoadMUIString which is not available for older systems @@ -291,7 +289,7 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv } } dwIndex++; - }while(result != ERROR_NO_MORE_ITEMS); + }while(result != ERROR_NO_MORE_ITEMS); /* check if all providers have been registered */ // if (RegProviders == 15) @@ -330,7 +328,7 @@ InitializeDirectPlayDialog(HWND hwndDlg) return; /* enumerate providers */ - result = EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP); + EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP); RegCloseKey(hKey); } diff --git a/reactos/base/applications/dxdiag/sound.c b/reactos/base/applications/dxdiag/sound.c index 6db11c66540..4a84c9c6342 100644 --- a/reactos/base/applications/dxdiag/sound.c +++ b/reactos/base/applications/dxdiag/sound.c @@ -275,6 +275,7 @@ void InitializeDirectSoundPage(PDXDIAG_CONTEXT pContext) /* release the DSound object */ // pObj->lpVtbl->Release(pObj); + (void)hResult; } From 8da06df0105f6f3c4c1f3df1e1bd1f36f04032c2 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 20:57:02 +0000 Subject: [PATCH 132/292] [PSEH] Use dummy pseh for clang svn path=/trunk/; revision=47462 --- reactos/include/reactos/libs/pseh/pseh2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/reactos/libs/pseh/pseh2.h b/reactos/include/reactos/libs/pseh/pseh2.h index ce1326e9ae0..6c473a4c43d 100644 --- a/reactos/include/reactos/libs/pseh/pseh2.h +++ b/reactos/include/reactos/libs/pseh/pseh2.h @@ -26,7 +26,7 @@ #ifndef KJK_PSEH2_H_ #define KJK_PSEH2_H_ -#if !defined (__arm__) +#if !defined (__arm__) && !defined(__clang__) #if defined(__GNUC__) struct _EXCEPTION_RECORD; @@ -395,7 +395,7 @@ __SEH_END_SCOPE_CHAIN; #define _SEH2_END } #define _SEH2_GetExceptionInformation() -#define _SEH2_GetExceptionCode() STATUS_SUCCESS +#define _SEH2_GetExceptionCode() 0 #define _SEH2_AbnormalTermination() #define _SEH2_YIELD(STMT_) STMT_ From 06a6306fa8ee7f83ef154e2bde5beeb90873059e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 21:01:52 +0000 Subject: [PATCH 133/292] [WINETESTS] Disable unused value warnings svn path=/trunk/; revision=47463 --- rostests/winetests/directory.rbuild | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rostests/winetests/directory.rbuild b/rostests/winetests/directory.rbuild index 5e7a7698b93..a35ec8e331c 100644 --- a/rostests/winetests/directory.rbuild +++ b/rostests/winetests/directory.rbuild @@ -1,6 +1,9 @@ + + -Wno-unused-value + From 744022564b991783e291968889c5c4208e11f028 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 30 May 2010 21:19:26 +0000 Subject: [PATCH 134/292] [KERNEL32] Return nothing from InternalCopyDeviceFindDataA/W functions svn path=/trunk/; revision=47464 --- reactos/dll/win32/kernel32/file/find.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/kernel32/file/find.c b/reactos/dll/win32/kernel32/file/find.c index ef2346a598c..df245232e0e 100644 --- a/reactos/dll/win32/kernel32/file/find.c +++ b/reactos/dll/win32/kernel32/file/find.c @@ -54,7 +54,7 @@ typedef struct _KERNEL32_FIND_DATA_HEADER /* FUNCTIONS ****************************************************************/ -static HANDLE +static VOID InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData, LPCWSTR lpFileName, ULONG DeviceNameInfo) @@ -71,11 +71,9 @@ InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData, RtlCopyMemory(lpFindFileData->cFileName, DeviceName.Buffer, DeviceName.Length); - - return FIND_DEVICE_HANDLE; } -static HANDLE +static VOID InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData, PUNICODE_STRING FileName, ULONG DeviceNameInfo) @@ -101,8 +99,6 @@ InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData, RtlCopyMemory(lpFindFileData->cFileName, BufferA.Buffer, BufferA.Length); - - return FIND_DEVICE_HANDLE; } static VOID From 08d4b579ab2fc462ade781744e9f6e39e98b80dc Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 21:32:28 +0000 Subject: [PATCH 135/292] [lib/3rdparty] Disable unused value warning here, too svn path=/trunk/; revision=47465 --- reactos/lib/3rdparty/3rdparty.rbuild | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/lib/3rdparty/3rdparty.rbuild b/reactos/lib/3rdparty/3rdparty.rbuild index 7f0c2006e45..92ecd8abc7c 100644 --- a/reactos/lib/3rdparty/3rdparty.rbuild +++ b/reactos/lib/3rdparty/3rdparty.rbuild @@ -1,6 +1,9 @@ + + -Wno-unused-value + From 1c2429510e97f6ef79d5145072d25c71c3c5e0eb Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 22:02:42 +0000 Subject: [PATCH 136/292] [NTIFS] Use a preprocessor definition for FSRTL_COMMON_FCB_HEADER instead of using an ms extension, that wouldn't work for ISO C svn path=/trunk/; revision=47466 --- reactos/include/ddk/ntifs.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 15bace86764..f1df074e4f4 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -6148,26 +6148,29 @@ typedef enum _FAST_IO_POSSIBLE { FastIoIsQuestionable } FAST_IO_POSSIBLE; -typedef struct _FSRTL_COMMON_FCB_HEADER { - CSHORT NodeTypeCode; - CSHORT NodeByteSize; - UCHAR Flags; - UCHAR IsFastIoPossible; - UCHAR Flags2; - UCHAR Reserved:4; - UCHAR Version:4; - PERESOURCE Resource; - PERESOURCE PagingIoResource; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER FileSize; +#define FSRTL_COMMON_FCB_HEADER_LAYOUT \ + CSHORT NodeTypeCode; \ + CSHORT NodeByteSize; \ + UCHAR Flags; \ + UCHAR IsFastIoPossible; \ + UCHAR Flags2; \ + UCHAR Reserved:4; \ + UCHAR Version:4; \ + PERESOURCE Resource; \ + PERESOURCE PagingIoResource; \ + LARGE_INTEGER AllocationSize; \ + LARGE_INTEGER FileSize; \ LARGE_INTEGER ValidDataLength; + +typedef struct _FSRTL_COMMON_FCB_HEADER { + FSRTL_COMMON_FCB_HEADER_LAYOUT } FSRTL_COMMON_FCB_HEADER, *PFSRTL_COMMON_FCB_HEADER; #ifdef __cplusplus typedef struct _FSRTL_ADVANCED_FCB_HEADER:FSRTL_COMMON_FCB_HEADER { #else /* __cplusplus */ typedef struct _FSRTL_ADVANCED_FCB_HEADER { - FSRTL_COMMON_FCB_HEADER DUMMYSTRUCTNAME; + FSRTL_COMMON_FCB_HEADER_LAYOUT #endif /* __cplusplus */ PFAST_MUTEX FastMutex; LIST_ENTRY FilterContexts; From 5de258d708e6b241c17ad1fe0f9d4dc400e7adb1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 30 May 2010 22:18:50 +0000 Subject: [PATCH 137/292] [NPFS] - Fix race conditions in read IRP cancellation that resulting in random crashes and hangs - Fixes MULTIPLE_IRP_COMPLETE_REQUESTS bug checks and failed cancellations resulting in hangs during ntdll:file test svn path=/trunk/; revision=47470 --- reactos/drivers/filesystems/npfs/rw.c | 74 ++++++++++++++++++++------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index f3f02bdd315..c9d7cfc64e6 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -51,7 +51,9 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject, PNPFS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; PNPFS_CCB Ccb; - BOOLEAN Complete = FALSE; + PLIST_ENTRY ListEntry; + PNPFS_THREAD_CONTEXT ThreadContext; + ULONG i; DPRINT("NpfsReadWriteCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); @@ -67,28 +69,50 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject, switch(IoStack->MajorFunction) { case IRP_MJ_READ: - if (Ccb->ReadRequestListHead.Flink != &Context->ListEntry) + ListEntry = DeviceExt->ThreadListHead.Flink; + while (ListEntry != &DeviceExt->ThreadListHead) { - /* we are not the first in the list, remove an complete us */ - RemoveEntryList(&Context->ListEntry); - Complete = TRUE; - } - else - { - KeSetEvent(&Ccb->ReadEvent, IO_NO_INCREMENT, FALSE); + ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry); + /* Real events start at index 1 */ + for (i = 1; i < ThreadContext->Count; i++) + { + if (ThreadContext->WaitIrpArray[i] == Irp) + { + ASSERT(ThreadContext->WaitObjectArray[i] == Context->WaitEvent); + + ThreadContext->WaitIrpArray[i] = NULL; + + RemoveEntryList(&Context->ListEntry); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE); + + ExReleaseFastMutex(&Ccb->DataListLock); + KeUnlockMutex(&DeviceExt->PipeListLock); + + return; + } + } + ListEntry = ListEntry->Flink; } + + RemoveEntryList(&Context->ListEntry); + + ExReleaseFastMutex(&Ccb->DataListLock); + KeUnlockMutex(&DeviceExt->PipeListLock); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); break; default: ASSERT(FALSE); } - ExReleaseFastMutex(&Ccb->DataListLock); - KeUnlockMutex(&DeviceExt->PipeListLock); - if (Complete) - { - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } } static VOID NTAPI @@ -96,7 +120,7 @@ NpfsWaiterThread(PVOID InitContext) { PNPFS_THREAD_CONTEXT ThreadContext = (PNPFS_THREAD_CONTEXT) InitContext; ULONG CurrentCount; - ULONG Count = 0; + ULONG Count = 0, i; PIRP Irp = NULL; PIRP NextIrp; NTSTATUS Status; @@ -191,8 +215,20 @@ NpfsWaiterThread(PVOID InitContext) } else { - /* someone has add a new wait request */ + /* someone has add a new wait request or cancelled an old one */ Irp = NULL; + + /* Look for cancelled requests */ + for (i = 1; i < ThreadContext->Count; i++) + { + if (ThreadContext->WaitIrpArray[i] == NULL) + { + ThreadContext->Count--; + ThreadContext->DeviceExt->EmptyWaiterCount++; + ThreadContext->WaitObjectArray[i] = ThreadContext->WaitObjectArray[ThreadContext->Count]; + ThreadContext->WaitIrpArray[i] = ThreadContext->WaitIrpArray[ThreadContext->Count]; + } + } } if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS) { From 2991d5eb42e36cef50e56502dd7bed9cea14d13e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 30 May 2010 22:28:00 +0000 Subject: [PATCH 138/292] [CRT] - Don't define __int64 for clang (patch by Amine Khaldi) - Fix file and purpose in the header svn path=/trunk/; revision=47471 --- reactos/lib/sdk/crt/string/strset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/lib/sdk/crt/string/strset.c b/reactos/lib/sdk/crt/string/strset.c index e6c422d4f9c..29a72121197 100644 --- a/reactos/lib/sdk/crt/string/strset.c +++ b/reactos/lib/sdk/crt/string/strset.c @@ -1,14 +1,14 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crt/?????? - * PURPOSE: Unknown + * FILE: lib/crt/strset.c + * PURPOSE: Implementation of _strnset and _strset * PROGRAMER: Unknown * UPDATE HISTORY: * 25/11/05: Added license header */ -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__clang__) #define __int64 long long #endif From 1db109e182b9e3d46b42ca371f7e0366bd7aa20e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 01:49:22 +0000 Subject: [PATCH 139/292] [time.h] Add missing asctime_s and localtime_s, don't include time_s.h anymore svn path=/trunk/; revision=47478 --- reactos/include/crt/time.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/include/crt/time.h b/reactos/include/crt/time.h index 75da425e3a1..5cf88adf7c9 100644 --- a/reactos/include/crt/time.h +++ b/reactos/include/crt/time.h @@ -114,6 +114,7 @@ extern "C" { _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(struct tm *_Tm); _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec); + _CRTIMP errno_t __cdecl asctime_s(char *_Buf,size_t _SizeInWords,const struct tm *_Tm); _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); @@ -184,6 +185,7 @@ __CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _diff __CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime32(_Time); } __CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime32(_Time); } __CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime32(_Time); } +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); } __CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime32(_Tm); } __CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); } __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time32(_Time); } @@ -193,6 +195,7 @@ __CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _diff __CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime64(_Time); } __CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime64(_Time); } __CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime64(_Time); } +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); } __CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime64(_Tm); } __CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); } __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } @@ -214,7 +217,5 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } #pragma pack(pop) -#include - #endif /* End _TIME_H_ */ From f0c2cec9d5154940606b2c3fc02d1d61cf003e2c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 01:50:09 +0000 Subject: [PATCH 140/292] [CRT] - add clang compatible asm version of ldexp and make the code more readable - constify strndup parameter to match standard - fix broken pointer comparison in signal() svn path=/trunk/; revision=47479 --- reactos/lib/sdk/crt/math/i386/ldexp.c | 32 +++++++++++++++++---------- reactos/lib/sdk/crt/misc/getargs.c | 2 +- reactos/lib/sdk/crt/signal/signal.c | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/reactos/lib/sdk/crt/math/i386/ldexp.c b/reactos/lib/sdk/crt/math/i386/ldexp.c index b240275ef95..327e72a27b8 100644 --- a/reactos/lib/sdk/crt/math/i386/ldexp.c +++ b/reactos/lib/sdk/crt/math/i386/ldexp.c @@ -21,24 +21,32 @@ #include -double ldexp (double __x, int __y); - -double ldexp (double __x, int __y) +double ldexp (double value, int exp) { - register double __val; + register double result; #ifdef __GNUC__ - __asm __volatile__ - ("fscale" - : "=t" (__val) : "0" (__x), "u" ((double) __y)); +#if defined(__clang__) + asm ("fild %[exp]\n" + "fscale\n" + "fstp %%st(1)\n" + : [result] "=t" (result) + : [value] "0" (value), [exp] "m" (exp)); #else - register double __dy = (double)__y; + asm ("fscale" + : "=t" (result) + : "0" (value), "u" ((double)exp) + : "1"); +#endif +#else /* !__GNUC__ */ + register double __dy = (double)exp; __asm { fld __dy - fld __x + fld value fscale - fstp __val + fstp result } -#endif /*__GNUC__*/ - return __val; +#endif /* !__GNUC__ */ + return result; } + diff --git a/reactos/lib/sdk/crt/misc/getargs.c b/reactos/lib/sdk/crt/misc/getargs.c index 1bdb409ab46..18672e6bd44 100644 --- a/reactos/lib/sdk/crt/misc/getargs.c +++ b/reactos/lib/sdk/crt/misc/getargs.c @@ -22,7 +22,7 @@ int __argc = 0; extern wchar_t **__winitenv; -char* strndup(char* name, size_t len) +char* strndup(char const* name, size_t len) { char *s = malloc(len + 1); if (s != NULL) diff --git a/reactos/lib/sdk/crt/signal/signal.c b/reactos/lib/sdk/crt/signal/signal.c index 6cfe3f64b5a..5dd6381c53d 100644 --- a/reactos/lib/sdk/crt/signal/signal.c +++ b/reactos/lib/sdk/crt/signal/signal.c @@ -42,7 +42,7 @@ __p_sig_fn_t signal(int sig, __p_sig_fn_t func) } // check with IsBadCodePtr - if ( func < (__p_sig_fn_t)4096 && func != SIG_DFL && func != SIG_IGN) + if ( (uintptr_t)func < 4096 && func != SIG_DFL && func != SIG_IGN) { __set_errno(EINVAL); return SIG_ERR; From 62327e715f7cd587fd350bc1f05e2fd7cb8c50b8 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 02:15:15 +0000 Subject: [PATCH 141/292] [DDK/XDK] - Use PCI_COMMON_HEADER_LAYOUT for C, too, place it where it belongs svn path=/trunk/; revision=47480 --- reactos/include/ddk/wdm.h | 155 ++++++++++++++++------------------ reactos/include/xdk/iotypes.h | 155 ++++++++++++++++------------------ 2 files changed, 148 insertions(+), 162 deletions(-) diff --git a/reactos/include/ddk/wdm.h b/reactos/include/ddk/wdm.h index af239bbb4c3..aaa474bd057 100644 --- a/reactos/include/ddk/wdm.h +++ b/reactos/include/ddk/wdm.h @@ -4172,80 +4172,6 @@ typedef struct _SHARE_ACCESS { ULONG SharedDelete; } SHARE_ACCESS, *PSHARE_ACCESS; -/* While MS WDK uses inheritance in C++, we cannot do this with gcc, as - inheritance, even from a struct renders the type non-POD. So we use - this hack */ -#define PCI_COMMON_HEADER_LAYOUT \ - USHORT VendorID; \ - USHORT DeviceID; \ - USHORT Command; \ - USHORT Status; \ - UCHAR RevisionID; \ - UCHAR ProgIf; \ - UCHAR SubClass; \ - UCHAR BaseClass; \ - UCHAR CacheLineSize; \ - UCHAR LatencyTimer; \ - UCHAR HeaderType; \ - UCHAR BIST; \ - union { \ - struct _PCI_HEADER_TYPE_0 { \ - ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ - ULONG CIS; \ - USHORT SubVendorID; \ - USHORT SubSystemID; \ - ULONG ROMBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG Reserved2; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - UCHAR MinimumGrant; \ - UCHAR MaximumLatency; \ - } type0; \ - struct _PCI_HEADER_TYPE_1 { \ - ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - UCHAR IOBase; \ - UCHAR IOLimit; \ - USHORT SecondaryStatus; \ - USHORT MemoryBase; \ - USHORT MemoryLimit; \ - USHORT PrefetchBase; \ - USHORT PrefetchLimit; \ - ULONG PrefetchBaseUpper32; \ - ULONG PrefetchLimitUpper32; \ - USHORT IOBaseUpper16; \ - USHORT IOLimitUpper16; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG ROMBaseAddress; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type1; \ - struct _PCI_HEADER_TYPE_2 { \ - ULONG SocketRegistersBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved; \ - USHORT SecondaryStatus; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - struct { \ - ULONG Base; \ - ULONG Limit; \ - } Range[PCI_TYPE2_ADDRESSES-1]; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type2; \ - } u; - typedef enum _CREATE_FILE_TYPE { CreateFileTypeNone, CreateFileTypeNamedPipe, @@ -6665,21 +6591,88 @@ typedef struct _PCI_SLOT_NUMBER { #define PCI_TYPE1_ADDRESSES 2 #define PCI_TYPE2_ADDRESSES 5 +/* While MS WDK uses inheritance in C++, we cannot do this with gcc, as + inheritance, even from a struct renders the type non-POD. So we use + this hack */ +#define PCI_COMMON_HEADER_LAYOUT \ + USHORT VendorID; \ + USHORT DeviceID; \ + USHORT Command; \ + USHORT Status; \ + UCHAR RevisionID; \ + UCHAR ProgIf; \ + UCHAR SubClass; \ + UCHAR BaseClass; \ + UCHAR CacheLineSize; \ + UCHAR LatencyTimer; \ + UCHAR HeaderType; \ + UCHAR BIST; \ + union { \ + struct _PCI_HEADER_TYPE_0 { \ + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ + ULONG CIS; \ + USHORT SubVendorID; \ + USHORT SubSystemID; \ + ULONG ROMBaseAddress; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved1[3]; \ + ULONG Reserved2; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + UCHAR MinimumGrant; \ + UCHAR MaximumLatency; \ + } type0; \ + struct _PCI_HEADER_TYPE_1 { \ + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ + UCHAR PrimaryBus; \ + UCHAR SecondaryBus; \ + UCHAR SubordinateBus; \ + UCHAR SecondaryLatency; \ + UCHAR IOBase; \ + UCHAR IOLimit; \ + USHORT SecondaryStatus; \ + USHORT MemoryBase; \ + USHORT MemoryLimit; \ + USHORT PrefetchBase; \ + USHORT PrefetchLimit; \ + ULONG PrefetchBaseUpper32; \ + ULONG PrefetchLimitUpper32; \ + USHORT IOBaseUpper16; \ + USHORT IOLimitUpper16; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved1[3]; \ + ULONG ROMBaseAddress; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + USHORT BridgeControl; \ + } type1; \ + struct _PCI_HEADER_TYPE_2 { \ + ULONG SocketRegistersBaseAddress; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved; \ + USHORT SecondaryStatus; \ + UCHAR PrimaryBus; \ + UCHAR SecondaryBus; \ + UCHAR SubordinateBus; \ + UCHAR SecondaryLatency; \ + struct { \ + ULONG Base; \ + ULONG Limit; \ + } Range[PCI_TYPE2_ADDRESSES-1]; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + USHORT BridgeControl; \ + } type2; \ + } u; + typedef struct _PCI_COMMON_HEADER { PCI_COMMON_HEADER_LAYOUT } PCI_COMMON_HEADER, *PPCI_COMMON_HEADER; -#ifdef __cplusplus typedef struct _PCI_COMMON_CONFIG { PCI_COMMON_HEADER_LAYOUT UCHAR DeviceSpecific[192]; } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; -#else -typedef struct _PCI_COMMON_CONFIG { - PCI_COMMON_HEADER DUMMYSTRUCTNAME; - UCHAR DeviceSpecific[192]; -} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; -#endif #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET(PCI_COMMON_CONFIG, DeviceSpecific)) diff --git a/reactos/include/xdk/iotypes.h b/reactos/include/xdk/iotypes.h index aac22cb3668..19af071d420 100644 --- a/reactos/include/xdk/iotypes.h +++ b/reactos/include/xdk/iotypes.h @@ -495,80 +495,6 @@ typedef struct _SHARE_ACCESS { ULONG SharedDelete; } SHARE_ACCESS, *PSHARE_ACCESS; -/* While MS WDK uses inheritance in C++, we cannot do this with gcc, as - inheritance, even from a struct renders the type non-POD. So we use - this hack */ -#define PCI_COMMON_HEADER_LAYOUT \ - USHORT VendorID; \ - USHORT DeviceID; \ - USHORT Command; \ - USHORT Status; \ - UCHAR RevisionID; \ - UCHAR ProgIf; \ - UCHAR SubClass; \ - UCHAR BaseClass; \ - UCHAR CacheLineSize; \ - UCHAR LatencyTimer; \ - UCHAR HeaderType; \ - UCHAR BIST; \ - union { \ - struct _PCI_HEADER_TYPE_0 { \ - ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ - ULONG CIS; \ - USHORT SubVendorID; \ - USHORT SubSystemID; \ - ULONG ROMBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG Reserved2; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - UCHAR MinimumGrant; \ - UCHAR MaximumLatency; \ - } type0; \ - struct _PCI_HEADER_TYPE_1 { \ - ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - UCHAR IOBase; \ - UCHAR IOLimit; \ - USHORT SecondaryStatus; \ - USHORT MemoryBase; \ - USHORT MemoryLimit; \ - USHORT PrefetchBase; \ - USHORT PrefetchLimit; \ - ULONG PrefetchBaseUpper32; \ - ULONG PrefetchLimitUpper32; \ - USHORT IOBaseUpper16; \ - USHORT IOLimitUpper16; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG ROMBaseAddress; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type1; \ - struct _PCI_HEADER_TYPE_2 { \ - ULONG SocketRegistersBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved; \ - USHORT SecondaryStatus; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - struct { \ - ULONG Base; \ - ULONG Limit; \ - } Range[PCI_TYPE2_ADDRESSES-1]; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type2; \ - } u; - typedef enum _CREATE_FILE_TYPE { CreateFileTypeNone, CreateFileTypeNamedPipe, @@ -2988,21 +2914,88 @@ typedef struct _PCI_SLOT_NUMBER { #define PCI_TYPE1_ADDRESSES 2 #define PCI_TYPE2_ADDRESSES 5 +/* While MS WDK uses inheritance in C++, we cannot do this with gcc, as + inheritance, even from a struct renders the type non-POD. So we use + this hack */ +#define PCI_COMMON_HEADER_LAYOUT \ + USHORT VendorID; \ + USHORT DeviceID; \ + USHORT Command; \ + USHORT Status; \ + UCHAR RevisionID; \ + UCHAR ProgIf; \ + UCHAR SubClass; \ + UCHAR BaseClass; \ + UCHAR CacheLineSize; \ + UCHAR LatencyTimer; \ + UCHAR HeaderType; \ + UCHAR BIST; \ + union { \ + struct _PCI_HEADER_TYPE_0 { \ + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ + ULONG CIS; \ + USHORT SubVendorID; \ + USHORT SubSystemID; \ + ULONG ROMBaseAddress; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved1[3]; \ + ULONG Reserved2; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + UCHAR MinimumGrant; \ + UCHAR MaximumLatency; \ + } type0; \ + struct _PCI_HEADER_TYPE_1 { \ + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ + UCHAR PrimaryBus; \ + UCHAR SecondaryBus; \ + UCHAR SubordinateBus; \ + UCHAR SecondaryLatency; \ + UCHAR IOBase; \ + UCHAR IOLimit; \ + USHORT SecondaryStatus; \ + USHORT MemoryBase; \ + USHORT MemoryLimit; \ + USHORT PrefetchBase; \ + USHORT PrefetchLimit; \ + ULONG PrefetchBaseUpper32; \ + ULONG PrefetchLimitUpper32; \ + USHORT IOBaseUpper16; \ + USHORT IOLimitUpper16; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved1[3]; \ + ULONG ROMBaseAddress; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + USHORT BridgeControl; \ + } type1; \ + struct _PCI_HEADER_TYPE_2 { \ + ULONG SocketRegistersBaseAddress; \ + UCHAR CapabilitiesPtr; \ + UCHAR Reserved; \ + USHORT SecondaryStatus; \ + UCHAR PrimaryBus; \ + UCHAR SecondaryBus; \ + UCHAR SubordinateBus; \ + UCHAR SecondaryLatency; \ + struct { \ + ULONG Base; \ + ULONG Limit; \ + } Range[PCI_TYPE2_ADDRESSES-1]; \ + UCHAR InterruptLine; \ + UCHAR InterruptPin; \ + USHORT BridgeControl; \ + } type2; \ + } u; + typedef struct _PCI_COMMON_HEADER { PCI_COMMON_HEADER_LAYOUT } PCI_COMMON_HEADER, *PPCI_COMMON_HEADER; -#ifdef __cplusplus typedef struct _PCI_COMMON_CONFIG { PCI_COMMON_HEADER_LAYOUT UCHAR DeviceSpecific[192]; } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; -#else -typedef struct _PCI_COMMON_CONFIG { - PCI_COMMON_HEADER DUMMYSTRUCTNAME; - UCHAR DeviceSpecific[192]; -} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; -#endif #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET(PCI_COMMON_CONFIG, DeviceSpecific)) From 8deca41d3fecc9558a90850f19e2771e6e74d751 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 02:23:30 +0000 Subject: [PATCH 142/292] Fix build (don't redefine structures) svn path=/trunk/; revision=47481 --- reactos/include/ddk/wdm.h | 117 ++++++++++++++++++---------------- reactos/include/xdk/iotypes.h | 117 ++++++++++++++++++---------------- 2 files changed, 124 insertions(+), 110 deletions(-) diff --git a/reactos/include/ddk/wdm.h b/reactos/include/ddk/wdm.h index aaa474bd057..563801bfece 100644 --- a/reactos/include/ddk/wdm.h +++ b/reactos/include/ddk/wdm.h @@ -6594,6 +6594,65 @@ typedef struct _PCI_SLOT_NUMBER { /* While MS WDK uses inheritance in C++, we cannot do this with gcc, as inheritance, even from a struct renders the type non-POD. So we use this hack */ + + struct _PCI_HEADER_TYPE_0 { + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; + ULONG CIS; + USHORT SubVendorID; + USHORT SubSystemID; + ULONG ROMBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG Reserved2; + UCHAR InterruptLine; + UCHAR InterruptPin; + UCHAR MinimumGrant; + UCHAR MaximumLatency; + }; + + struct _PCI_HEADER_TYPE_1 { + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + UCHAR IOBase; + UCHAR IOLimit; + USHORT SecondaryStatus; + USHORT MemoryBase; + USHORT MemoryLimit; + USHORT PrefetchBase; + USHORT PrefetchLimit; + ULONG PrefetchBaseUpper32; + ULONG PrefetchLimitUpper32; + USHORT IOBaseUpper16; + USHORT IOLimitUpper16; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG ROMBaseAddress; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + }; + + struct _PCI_HEADER_TYPE_2 { + ULONG SocketRegistersBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved; + USHORT SecondaryStatus; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + struct { + ULONG Base; + ULONG Limit; + } Range[PCI_TYPE2_ADDRESSES-1]; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + }; + #define PCI_COMMON_HEADER_LAYOUT \ USHORT VendorID; \ USHORT DeviceID; \ @@ -6608,61 +6667,9 @@ typedef struct _PCI_SLOT_NUMBER { UCHAR HeaderType; \ UCHAR BIST; \ union { \ - struct _PCI_HEADER_TYPE_0 { \ - ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ - ULONG CIS; \ - USHORT SubVendorID; \ - USHORT SubSystemID; \ - ULONG ROMBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG Reserved2; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - UCHAR MinimumGrant; \ - UCHAR MaximumLatency; \ - } type0; \ - struct _PCI_HEADER_TYPE_1 { \ - ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - UCHAR IOBase; \ - UCHAR IOLimit; \ - USHORT SecondaryStatus; \ - USHORT MemoryBase; \ - USHORT MemoryLimit; \ - USHORT PrefetchBase; \ - USHORT PrefetchLimit; \ - ULONG PrefetchBaseUpper32; \ - ULONG PrefetchLimitUpper32; \ - USHORT IOBaseUpper16; \ - USHORT IOLimitUpper16; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG ROMBaseAddress; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type1; \ - struct _PCI_HEADER_TYPE_2 { \ - ULONG SocketRegistersBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved; \ - USHORT SecondaryStatus; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - struct { \ - ULONG Base; \ - ULONG Limit; \ - } Range[PCI_TYPE2_ADDRESSES-1]; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type2; \ + struct _PCI_HEADER_TYPE_0 type0; \ + struct _PCI_HEADER_TYPE_1 type1; \ + struct _PCI_HEADER_TYPE_2 type2; \ } u; typedef struct _PCI_COMMON_HEADER { diff --git a/reactos/include/xdk/iotypes.h b/reactos/include/xdk/iotypes.h index 19af071d420..6ac3d6ec77c 100644 --- a/reactos/include/xdk/iotypes.h +++ b/reactos/include/xdk/iotypes.h @@ -2917,6 +2917,65 @@ typedef struct _PCI_SLOT_NUMBER { /* While MS WDK uses inheritance in C++, we cannot do this with gcc, as inheritance, even from a struct renders the type non-POD. So we use this hack */ + + struct _PCI_HEADER_TYPE_0 { + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; + ULONG CIS; + USHORT SubVendorID; + USHORT SubSystemID; + ULONG ROMBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG Reserved2; + UCHAR InterruptLine; + UCHAR InterruptPin; + UCHAR MinimumGrant; + UCHAR MaximumLatency; + }; + + struct _PCI_HEADER_TYPE_1 { + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + UCHAR IOBase; + UCHAR IOLimit; + USHORT SecondaryStatus; + USHORT MemoryBase; + USHORT MemoryLimit; + USHORT PrefetchBase; + USHORT PrefetchLimit; + ULONG PrefetchBaseUpper32; + ULONG PrefetchLimitUpper32; + USHORT IOBaseUpper16; + USHORT IOLimitUpper16; + UCHAR CapabilitiesPtr; + UCHAR Reserved1[3]; + ULONG ROMBaseAddress; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + }; + + struct _PCI_HEADER_TYPE_2 { + ULONG SocketRegistersBaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved; + USHORT SecondaryStatus; + UCHAR PrimaryBus; + UCHAR SecondaryBus; + UCHAR SubordinateBus; + UCHAR SecondaryLatency; + struct { + ULONG Base; + ULONG Limit; + } Range[PCI_TYPE2_ADDRESSES-1]; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + }; + #define PCI_COMMON_HEADER_LAYOUT \ USHORT VendorID; \ USHORT DeviceID; \ @@ -2931,61 +2990,9 @@ typedef struct _PCI_SLOT_NUMBER { UCHAR HeaderType; \ UCHAR BIST; \ union { \ - struct _PCI_HEADER_TYPE_0 { \ - ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; \ - ULONG CIS; \ - USHORT SubVendorID; \ - USHORT SubSystemID; \ - ULONG ROMBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG Reserved2; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - UCHAR MinimumGrant; \ - UCHAR MaximumLatency; \ - } type0; \ - struct _PCI_HEADER_TYPE_1 { \ - ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - UCHAR IOBase; \ - UCHAR IOLimit; \ - USHORT SecondaryStatus; \ - USHORT MemoryBase; \ - USHORT MemoryLimit; \ - USHORT PrefetchBase; \ - USHORT PrefetchLimit; \ - ULONG PrefetchBaseUpper32; \ - ULONG PrefetchLimitUpper32; \ - USHORT IOBaseUpper16; \ - USHORT IOLimitUpper16; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved1[3]; \ - ULONG ROMBaseAddress; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type1; \ - struct _PCI_HEADER_TYPE_2 { \ - ULONG SocketRegistersBaseAddress; \ - UCHAR CapabilitiesPtr; \ - UCHAR Reserved; \ - USHORT SecondaryStatus; \ - UCHAR PrimaryBus; \ - UCHAR SecondaryBus; \ - UCHAR SubordinateBus; \ - UCHAR SecondaryLatency; \ - struct { \ - ULONG Base; \ - ULONG Limit; \ - } Range[PCI_TYPE2_ADDRESSES-1]; \ - UCHAR InterruptLine; \ - UCHAR InterruptPin; \ - USHORT BridgeControl; \ - } type2; \ + struct _PCI_HEADER_TYPE_0 type0; \ + struct _PCI_HEADER_TYPE_1 type1; \ + struct _PCI_HEADER_TYPE_2 type2; \ } u; typedef struct _PCI_COMMON_HEADER { From 8cab5daeec2c4e93a6e74b5d4f38cb6bfee7461b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 02:29:36 +0000 Subject: [PATCH 143/292] [IPHLPAPI] - remove unused variable svn path=/trunk/; revision=47482 --- reactos/dll/win32/iphlpapi/iphlpapi_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_main.c b/reactos/dll/win32/iphlpapi/iphlpapi_main.c index 3fd68560c17..8508d2d416a 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_main.c +++ b/reactos/dll/win32/iphlpapi/iphlpapi_main.c @@ -63,7 +63,6 @@ typedef struct _NAME_SERVER_LIST_CONTEXT { BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - DWORD Version; switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); From b6e791249281396379413f8e13a99cca2769b82b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 03:32:51 +0000 Subject: [PATCH 144/292] remove WTIME_S_DEFINED guard and move the functions from wchar_s to wchar.h (like in MS headers) svn path=/trunk/; revision=47483 --- reactos/include/crt/sec_api/wchar_s.h | 10 ---------- reactos/include/crt/wchar.h | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/reactos/include/crt/sec_api/wchar_s.h b/reactos/include/crt/sec_api/wchar_s.h index 94251aa8b64..8a3ea3739d5 100644 --- a/reactos/include/crt/sec_api/wchar_s.h +++ b/reactos/include/crt/sec_api/wchar_s.h @@ -96,16 +96,6 @@ extern "C" { _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); #endif -#ifndef _WTIME_S_DEFINED -#define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); -#if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); -#endif - #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL #ifdef _USE_32BIT_TIME_T diff --git a/reactos/include/crt/wchar.h b/reactos/include/crt/wchar.h index f70dfbbc6a2..364b1697534 100644 --- a/reactos/include/crt/wchar.h +++ b/reactos/include/crt/wchar.h @@ -751,19 +751,27 @@ _CRTIMP int __cdecl iswblank(wint_t _C); _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); + + _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); + _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); + #if _INTEGRAL_MAX_BITS >= 64 _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time); + _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); #endif #if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) #define _INC_WTIME_INL #ifdef _USE_32BIT_TIME_T __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); } -#else +#else /* !_USE_32BIT_TIME_T */ __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); } -#endif -#endif -#endif +#endif /* !_USE_32BIT_TIME_T */ +#endif /* !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) */ + +#endif /* _WTIME_DEFINED */ typedef int mbstate_t; typedef wchar_t _Wint_t; From d3d2badface649cd1009bdf9ca6f369be0d50700 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 04:13:40 +0000 Subject: [PATCH 145/292] - add explicit braces to avoid ambiguous 'else' - fix deprecated conversion from string constant to 'char*' svn path=/trunk/; revision=47484 --- reactos/dll/win32/browseui/internettoolbar.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/browseui/internettoolbar.cpp b/reactos/dll/win32/browseui/internettoolbar.cpp index c4f6bd004af..bfad8a5bd9c 100644 --- a/reactos/dll/win32/browseui/internettoolbar.cpp +++ b/reactos/dll/win32/browseui/internettoolbar.cpp @@ -414,10 +414,16 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WP { SMINFO *infoPtr = (SMINFO *)lParam; if ((infoPtr->dwMask & SMIM_FLAGS) != 0) + { if (psmd->uId == FCIDM_MENU_FAVORITES) + { infoPtr->dwFlags |= SMIF_DROPCASCADE; - else{ - infoPtr->dwFlags |= SMIF_TRACKPOPUP;} + } + else + { + infoPtr->dwFlags |= SMIF_TRACKPOPUP; + } + } if ((infoPtr->dwMask & SMIM_ICON) != 0) infoPtr->iIcon = -1; } @@ -1213,7 +1219,7 @@ LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO CComPtr objectWithSite; CComPtr contextMenu; CMINVOKECOMMANDINFO commandInfo; - char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}"; + const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}"; HRESULT hResult; // TODO: Query shell if this command is enabled first From 46e34b56400aecddebb0b380ecc6442782d1e939 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Mon, 31 May 2010 06:28:55 +0000 Subject: [PATCH 146/292] [WIN32CSR] Split up excessively large and disorganized conio.c into 3 separate files: one for input-related functions, one for output-related functions, and one for general/miscellaneous functions. svn path=/trunk/; revision=47485 --- .../win32/csrss/win32csr/coninput.c | 805 +++++ .../subsystems/win32/csrss/win32csr/conio.c | 3133 ----------------- .../subsystems/win32/csrss/win32csr/conio.h | 124 +- .../win32/csrss/win32csr/conoutput.c | 1505 ++++++++ .../subsystems/win32/csrss/win32csr/console.c | 851 +++++ .../win32/csrss/win32csr/win32csr.rbuild | 4 +- 6 files changed, 3228 insertions(+), 3194 deletions(-) create mode 100644 reactos/subsystems/win32/csrss/win32csr/coninput.c delete mode 100644 reactos/subsystems/win32/csrss/win32csr/conio.c create mode 100644 reactos/subsystems/win32/csrss/win32csr/conoutput.c create mode 100644 reactos/subsystems/win32/csrss/win32csr/console.c diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c new file mode 100644 index 00000000000..8b3c8849950 --- /dev/null +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -0,0 +1,805 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* GLOBALS *******************************************************************/ + +#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) + +/* FUNCTIONS *****************************************************************/ + +CSR_API(CsrReadConsole) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput *Input; + PUCHAR Buffer; + PWCHAR UnicodeBuffer; + ULONG i; + ULONG nNumberOfCharsToRead, CharSize; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrReadConsole\n"); + + CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ + nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buffer = Request->Data.ReadConsoleRequest.Buffer; + UnicodeBuffer = (PWCHAR)Buffer; + Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, + &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; + for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to valid ascii chars, on key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown + && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') + { + /* + * backspace handling - if we are in charge of echoing it then we handle it here + * otherwise we treat it like a normal char. + */ + if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 + != (Console->Mode & ENABLE_ECHO_INPUT)) + { + /* echo if it has not already been done, and either we or the client has chars to be deleted */ + if (! Input->Echoed + && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) + { + ConioWriteConsole(Console, Console->ActiveBuffer, + &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + } + if (0 != i) + { + i -= 2; /* if we already have something to return, just back it up by 2 */ + } + else + { + /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ + Console->WaitingChars--; + ConioUnlockConsole(Console); + HeapFree(Win32CsrApiHeap, 0, Input); + Request->Data.ReadConsoleRequest.NrCharactersRead = 0; + return STATUS_NOTIFY_CLEANUP; + + } + Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; + Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ + } + /* do not copy backspace to buffer */ + else + { + if(Request->Data.ReadConsoleRequest.Unicode) + ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); + else + Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; + } + /* echo to screen if enabled and we did not already echo the char */ + if (0 != (Console->Mode & ENABLE_ECHO_INPUT) + && ! Input->Echoed + && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + { + ConioWriteConsole(Console, Console->ActiveBuffer, + &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + } + } + else + { + i--; + } + Console->WaitingChars--; + HeapFree(Win32CsrApiHeap, 0, Input); + } + Request->Data.ReadConsoleRequest.NrCharactersRead = i; + if (0 == i) + { + Status = STATUS_PENDING; /* we didn't read anything */ + } + else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) + { + if (0 == Console->WaitingLines || + (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) + { + Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ + } + else + { + Console->WaitingLines--; + Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ + } + } + else + { + Status = STATUS_SUCCESS; /* not line buffered, did read something */ + } + + if (Status == STATUS_PENDING) + { + Console->EchoCount = nNumberOfCharsToRead - i; + } + else + { + Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ + } + + ConioUnlockConsole(Console); + + if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + } + + return Status; +} + +static VOID FASTCALL +ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) +{ + if (InputEvent->EventType == KEY_EVENT) + { + WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; + InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; + ConsoleInputUnicodeCharToAnsiChar(Console, + &InputEvent->Event.KeyEvent.uChar.AsciiChar, + &UnicodeChar); + } +} + +static VOID FASTCALL +ConioProcessChar(PCSRSS_CONSOLE Console, + ConsoleInput *KeyEventRecord) +{ + BOOL updown; + ConsoleInput *TempInput; + + if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && + KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + { + WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; + if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) + { + DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; + if (Console->Mode & ENABLE_LINE_INPUT && + (vk == VK_PAUSE || (vk == 'S' && + (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && + !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) + { + ConioPause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; + } + } + else + { + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + { + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + return; + } + } + } + + if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) + { + switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + { + case '\r': + /* first add the \r */ + KeyEventRecord->InputEvent.EventType = KEY_EVENT; + updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; + KeyEventRecord->Echoed = FALSE; + KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r'; + InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); + Console->WaitingChars++; + KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (NULL == KeyEventRecord) + { + DPRINT1("Failed to allocate KeyEventRecord\n"); + return; + } + KeyEventRecord->InputEvent.EventType = KEY_EVENT; + KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; + KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; + KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; + KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n'; + KeyEventRecord->Fake = TRUE; + break; + } + } + /* add event to the queue */ + InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); + Console->WaitingChars++; + /* if line input mode is enabled, only wake the client on enter key down */ + if (0 == (Console->Mode & ENABLE_LINE_INPUT) + || Console->EarlyReturn + || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) + { + if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + { + Console->WaitingLines++; + } + } + KeyEventRecord->Echoed = FALSE; + if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) + && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + { + /* walk the input queue looking for a char to backspace */ + for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; + TempInput != (ConsoleInput *) &Console->InputEvents + && (KEY_EVENT == TempInput->InputEvent.EventType + || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown + || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); + TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) + { + /* NOP */; + } + /* if we found one, delete it, otherwise, wake the client */ + if (TempInput != (ConsoleInput *) &Console->InputEvents) + { + /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ + RemoveEntryList(&TempInput->ListEntry); + if (TempInput->Echoed) + { + ConioWriteConsole(Console, Console->ActiveBuffer, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, + 1, TRUE); + } + HeapFree(Win32CsrApiHeap, 0, TempInput); + RemoveEntryList(&KeyEventRecord->ListEntry); + HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); + Console->WaitingChars -= 2; + return; + } + } + else + { + /* echo chars if we are supposed to and client is waiting for some */ + if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount + && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown + && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + { + /* mark the char as already echoed */ + ConioWriteConsole(Console, Console->ActiveBuffer, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, + 1, TRUE); + Console->EchoCount--; + KeyEventRecord->Echoed = TRUE; + } + } + + /* Console->WaitingChars++; */ + SetEvent(Console->ActiveEvent); +} + +static DWORD FASTCALL +ConioGetShiftState(PBYTE KeyState) +{ + DWORD ssOut = 0; + + if (KeyState[VK_CAPITAL] & 1) + ssOut |= CAPSLOCK_ON; + + if (KeyState[VK_NUMLOCK] & 1) + ssOut |= NUMLOCK_ON; + + if (KeyState[VK_SCROLL] & 1) + ssOut |= SCROLLLOCK_ON; + + if (KeyState[VK_SHIFT] & 0x80) + ssOut |= SHIFT_PRESSED; + + if (KeyState[VK_LCONTROL] & 0x80) + ssOut |= LEFT_CTRL_PRESSED; + if (KeyState[VK_RCONTROL] & 0x80) + ssOut |= RIGHT_CTRL_PRESSED; + + if (KeyState[VK_LMENU] & 0x80) + ssOut |= LEFT_ALT_PRESSED; + if (KeyState[VK_RMENU] & 0x80) + ssOut |= RIGHT_ALT_PRESSED; + + return ssOut; +} + +VOID WINAPI +ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) +{ + static BYTE KeyState[256] = { 0 }; + /* MSDN mentions that you should use the last virtual key code received + * when putting a virtual key identity to a WM_CHAR message since multiple + * or translated keys may be involved. */ + static UINT LastVirtualKey = 0; + DWORD ShiftState; + ConsoleInput *ConInRec; + UINT RepeatCount; + CHAR AsciiChar; + WCHAR UnicodeChar; + UINT VirtualKeyCode; + UINT VirtualScanCode; + BOOL Down = FALSE; + INPUT_RECORD er; + ULONG ResultSize = 0; + + RepeatCount = 1; + VirtualScanCode = (msg->lParam >> 16) & 0xff; + Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || + msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; + + GetKeyboardState(KeyState); + ShiftState = ConioGetShiftState(KeyState); + + if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) + { + VirtualKeyCode = LastVirtualKey; + UnicodeChar = msg->wParam; + } + else + { + WCHAR Chars[2]; + INT RetChars = 0; + + VirtualKeyCode = msg->wParam; + RetChars = ToUnicodeEx(VirtualKeyCode, + VirtualScanCode, + KeyState, + Chars, + 2, + 0, + 0); + UnicodeChar = (1 == RetChars ? Chars[0] : 0); + } + + if (0 == ResultSize) + { + AsciiChar = 0; + } + + er.EventType = KEY_EVENT; + er.Event.KeyEvent.bKeyDown = Down; + er.Event.KeyEvent.wRepeatCount = RepeatCount; + er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; + er.Event.KeyEvent.dwControlKeyState = ShiftState; + er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; + er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; + + if (TextMode) + { + if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && VK_TAB == VirtualKeyCode) + { + if (Down) + { + TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); + } + + return; + } + else if (VK_MENU == VirtualKeyCode && ! Down) + { + if (TuiSwapConsole(0)) + { + return; + } + } + } + + if (NULL == Console) + { + DPRINT1("No Active Console!\n"); + return; + } + + ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + + if (NULL == ConInRec) + { + return; + } + + ConInRec->InputEvent = er; + ConInRec->Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + ConInRec->Echoed = FALSE; + if (ConInRec->NotChar) + LastVirtualKey = msg->wParam; + + DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", + Down ? "down" : "up ", + (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? + "char" : "key ", + ConInRec->Fake ? "fake" : "real", + ConInRec->NotChar ? "notc" : "char", + VirtualScanCode, + VirtualKeyCode, + (AsciiChar >= ' ') ? AsciiChar : '.', + ShiftState); + + if (ConInRec->Fake && ConInRec->NotChar) + { + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; + } + + /* process Ctrl-C and Ctrl-Break */ + if (Console->Mode & ENABLE_PROCESSED_INPUT && + er.Event.KeyEvent.bKeyDown && + ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || + (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && + (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) + { + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DPRINT1("Console_Api Ctrl-C\n"); + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; + ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); + } + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; + } + + if (0 != (er.Event.KeyEvent.dwControlKeyState + & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode + || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) + { + if (er.Event.KeyEvent.bKeyDown) + { + /* scroll up or down */ + if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) + { + /* only scroll up if there is room to scroll up into */ + if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + + Console->ActiveBuffer->MaxY - 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY++; + } + } + else + { + /* only scroll down if there is room to scroll down into */ + if (Console->ActiveBuffer->CurrentY != 0) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY--; + } + } + ConioDrawConsole(Console); + } + HeapFree(Win32CsrApiHeap, 0, ConInRec); + return; + } + /* FIXME - convert to ascii */ + ConioProcessChar(Console, ConInRec); +} + +CSR_API(CsrReadInputEvent) +{ + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + BOOLEAN Done = FALSE; + ConsoleInput *Input; + + DPRINT("CsrReadInputEvent\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; + + Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + /* only get input if there is any */ + CurrentEntry = Console->InputEvents.Flink; + while (CurrentEntry != &Console->InputEvents) + { + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + CurrentEntry = CurrentEntry->Flink; + + if (Done && !Input->Fake) + { + Request->Data.ReadInputRequest.MoreEvents = TRUE; + break; + } + + RemoveEntryList(&Input->ListEntry); + + if (!Done && !Input->Fake) + { + Request->Data.ReadInputRequest.Input = Input->InputEvent; + if (Request->Data.ReadInputRequest.Unicode == FALSE) + { + ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); + } + Done = TRUE; + } + + if (Input->InputEvent.EventType == KEY_EVENT) + { + if (0 != (Console->Mode & ENABLE_LINE_INPUT) + && Input->InputEvent.Event.KeyEvent.bKeyDown + && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + { + Console->WaitingLines--; + } + Console->WaitingChars--; + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + + if (Done) + { + Status = STATUS_SUCCESS; + Console->EarlyReturn = FALSE; + } + else + { + Status = STATUS_PENDING; + Console->EarlyReturn = TRUE; /* mark for early return */ + } + + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrFlushInputBuffer) +{ + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + ConsoleInput* Input; + NTSTATUS Status; + + DPRINT("CsrFlushInputBuffer\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockConsole(ProcessData, + Request->Data.FlushInputBufferRequest.ConsoleInput, + &Console, + GENERIC_WRITE); + if(! NT_SUCCESS(Status)) + { + return Status; + } + + /* Discard all entries in the input event queue */ + while (!IsListEmpty(&Console->InputEvents)) + { + CurrentEntry = RemoveHeadList(&Console->InputEvents); + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + /* Destroy the event */ + HeapFree(Win32CsrApiHeap, 0, Input); + } + ResetEvent(Console->ActiveEvent); + Console->WaitingChars=0; + + ConioUnlockConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrGetNumberOfConsoleInputEvents) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PLIST_ENTRY CurrentItem; + DWORD NumEvents; + ConsoleInput *Input; + + DPRINT("CsrGetNumberOfConsoleInputEvents\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + CurrentItem = Console->InputEvents.Flink; + NumEvents = 0; + + /* If there are any events ... */ + while (CurrentItem != &Console->InputEvents) + { + Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); + CurrentItem = CurrentItem->Flink; + if (!Input->Fake) + { + NumEvents++; + } + } + + ConioUnlockConsole(Console); + + Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; + + return STATUS_SUCCESS; +} + +CSR_API(CsrPeekConsoleInput) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Size; + DWORD Length; + PLIST_ENTRY CurrentItem; + PINPUT_RECORD InputRecord; + ConsoleInput* Item; + UINT NumItems; + + DPRINT("CsrPeekConsoleInput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if(! NT_SUCCESS(Status)) + { + return Status; + } + + InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; + Length = Request->Data.PeekConsoleInputRequest.Length; + Size = Length * sizeof(INPUT_RECORD); + + if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; + } + + NumItems = 0; + + if (! IsListEmpty(&Console->InputEvents)) + { + CurrentItem = Console->InputEvents.Flink; + + while (CurrentItem != &Console->InputEvents && NumItems < Length) + { + Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); + + if (Item->Fake) + { + CurrentItem = CurrentItem->Flink; + continue; + } + + ++NumItems; + *InputRecord = Item->InputEvent; + + if (Request->Data.ReadInputRequest.Unicode == FALSE) + { + ConioInputEventToAnsi(Console, InputRecord); + } + + InputRecord++; + CurrentItem = CurrentItem->Flink; + } + } + + ConioUnlockConsole(Console); + + Request->Data.PeekConsoleInputRequest.Length = NumItems; + + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleInput) +{ + PINPUT_RECORD InputRecord; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + DWORD Length; + DWORD Size; + DWORD i; + ConsoleInput* Record; + + DPRINT("CsrWriteConsoleInput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; + Length = Request->Data.WriteConsoleInputRequest.Length; + Size = Length * sizeof(INPUT_RECORD); + + if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; + } + + for (i = 0; i < Length; i++) + { + Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (NULL == Record) + { + ConioUnlockConsole(Console); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Record->Echoed = FALSE; + Record->Fake = FALSE; + //Record->InputEvent = *InputRecord++; + memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); + if (KEY_EVENT == Record->InputEvent.EventType) + { + /* FIXME - convert from unicode to ascii!! */ + ConioProcessChar(Console, Record); + } + } + + ConioUnlockConsole(Console); + + Request->Data.WriteConsoleInputRequest.Length = i; + + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c deleted file mode 100644 index f3a15157db0..00000000000 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ /dev/null @@ -1,3133 +0,0 @@ -/* - * reactos/subsys/csrss/win32csr/conio.c - * - * Console I/O functions - * - * ReactOS Operating System - */ - -/* INCLUDES ******************************************************************/ - -#define NDEBUG -#include "w32csr.h" -#include - -/* GLOBALS *******************************************************************/ - -#define ConioInitRect(Rect, top, left, bottom, right) \ - ((Rect)->Top) = top; \ - ((Rect)->Left) = left; \ - ((Rect)->Bottom) = bottom; \ - ((Rect)->Right) = right - -#define ConioIsRectEmpty(Rect) \ - (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) - -#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) - -#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) - - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS FASTCALL -ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) -{ - PCSRSS_CONSOLE ProcessConsole; - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - ProcessConsole = ProcessData->Console; - - if (!ProcessConsole) - { - *Console = NULL; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - - InterlockedIncrement(&ProcessConsole->ReferenceCount); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - EnterCriticalSection(&(ProcessConsole->Lock)); - *Console = ProcessConsole; - - return STATUS_SUCCESS; -} - -VOID FASTCALL -ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout) -{ - HANDLE Thread; - - DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); - - if (ProcessData->CtrlDispatcher) - { - - Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, - (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, - UlongToPtr(Event), 0, NULL); - if (NULL == Thread) - { - DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); - return; - } - WaitForSingleObject(Thread, Timeout); - CloseHandle(Thread); - } -} - -VOID FASTCALL -ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData) -{ - ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); -} - -PBYTE FASTCALL -ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y) -{ - return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; -} - -static VOID FASTCALL -ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff) -{ - PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); - UINT Pos; - - for (Pos = 0; Pos < Buff->MaxX; Pos++) - { - /* Fill the cell */ - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - } -} - -static NTSTATUS FASTCALL -CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, - PCSRSS_SCREEN_BUFFER Buffer) -{ - DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); - - Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; - Buffer->Header.Console = Console; - Buffer->Header.HandleCount = 0; - Buffer->ShowX = 0; - Buffer->ShowY = 0; - Buffer->VirtualY = 0; - Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); - if (NULL == Buffer->Buffer) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - ConioInitScreenBuffer(Console, Buffer); - /* initialize buffer to be empty with default attributes */ - for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) - { - ClearLineBuffer(Buffer); - } - Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; - Buffer->CurrentX = 0; - Buffer->CurrentY = 0; - - InsertHeadList(&Console->BufferList, &Buffer->ListEntry); - return STATUS_SUCCESS; -} - -static NTSTATUS WINAPI -CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) -{ - NTSTATUS Status; - SECURITY_ATTRIBUTES SecurityAttributes; - PCSRSS_SCREEN_BUFFER NewBuffer; - BOOL GuiMode; - - Console->Title.MaximumLength = Console->Title.Length = 0; - Console->Title.Buffer = NULL; - - //FIXME - RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); - - Console->ReferenceCount = 0; - Console->WaitingChars = 0; - Console->WaitingLines = 0; - Console->EchoCount = 0; - Console->Header.Type = CONIO_CONSOLE_MAGIC; - Console->Header.Console = Console; - Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - Console->EarlyReturn = FALSE; - InitializeListHead(&Console->BufferList); - Console->ActiveBuffer = NULL; - InitializeListHead(&Console->InputEvents); - Console->CodePage = GetOEMCP(); - Console->OutputCodePage = GetOEMCP(); - - SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - SecurityAttributes.lpSecurityDescriptor = NULL; - SecurityAttributes.bInheritHandle = TRUE; - - Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); - if (NULL == Console->ActiveEvent) - { - RtlFreeUnicodeString(&Console->Title); - return STATUS_UNSUCCESSFUL; - } - Console->PrivateData = NULL; - InitializeCriticalSection(&Console->Lock); - - GuiMode = DtbgIsDesktopVisible(); - - /* allocate console screen buffer */ - NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - if (NULL == NewBuffer) - { - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - return STATUS_INSUFFICIENT_RESOURCES; - } - /* init screen buffer with defaults */ - NewBuffer->CursorInfo.bVisible = TRUE; - NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - /* make console active, and insert into console list */ - Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; - - if (! GuiMode) - { - Status = TuiInitConsole(Console); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); - GuiMode = TRUE; - } - } - if (GuiMode) - { - Status = GuiInitConsole(Console, Visible); - if (! NT_SUCCESS(Status)) - { - HeapFree(Win32CsrApiHeap,0, NewBuffer); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - DPRINT1("GuiInitConsole: failed\n"); - return Status; - } - } - - Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); - if (! NT_SUCCESS(Status)) - { - ConioCleanupConsole(Console); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->ActiveEvent); - HeapFree(Win32CsrApiHeap, 0, NewBuffer); - DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); - return Status; - } - - /* copy buffer contents to screen */ - ConioDrawConsole(Console); - - return STATUS_SUCCESS; -} - - -CSR_API(CsrAllocConsole) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN NewConsole = FALSE; - - DPRINT("CsrAllocConsole\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (ProcessData->Console) - { - DPRINT1("Process already has a console\n"); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_PARAMETER; - } - - /* If we don't need a console, then get out of here */ - if (!Request->Data.AllocConsoleRequest.ConsoleNeeded) - { - DPRINT("No console needed\n"); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_SUCCESS; - } - - /* If we already have one, then don't create a new one... */ - if (!Request->Data.AllocConsoleRequest.Console || - Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) - { - /* Allocate a console structure */ - NewConsole = TRUE; - Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE)); - if (NULL == Console) - { - DPRINT1("Not enough memory for console\n"); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_NO_MEMORY; - } - /* initialize list head */ - InitializeListHead(&Console->ProcessList); - /* insert process data required for GUI initialization */ - InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); - /* Initialize the Console */ - Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Console init failed\n"); - HeapFree(Win32CsrApiHeap, 0, Console); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; - } - } - else - { - /* Reuse our current console */ - Console = Request->Data.AllocConsoleRequest.Console; - } - - /* Set the Process Console */ - ProcessData->Console = Console; - - /* Return it to the caller */ - Request->Data.AllocConsoleRequest.Console = Console; - - /* Add a reference count because the process is tied to the console */ - _InterlockedIncrement(&Console->ReferenceCount); - - if (NewConsole || !ProcessData->bInheritHandles) - { - /* Insert the Objects */ - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.AllocConsoleRequest.InputHandle, - &Console->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE, - FILE_SHARE_READ | FILE_SHARE_WRITE); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to insert object\n"); - ConioDeleteConsole((Object_t *) Console); - ProcessData->Console = 0; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; - } - - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.AllocConsoleRequest.OutputHandle, - &Console->ActiveBuffer->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE, - FILE_SHARE_READ | FILE_SHARE_WRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to insert object\n"); - ConioDeleteConsole((Object_t *) Console); - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.InputHandle); - ProcessData->Console = 0; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; - } - } - - /* Duplicate the Event */ - if (!DuplicateHandle(GetCurrentProcess(), - ProcessData->Console->ActiveEvent, - ProcessData->Process, - &ProcessData->ConsoleEvent, - EVENT_ALL_ACCESS, - FALSE, - 0)) - { - DPRINT1("DuplicateHandle() failed: %d\n", GetLastError); - ConioDeleteConsole((Object_t *) Console); - if (NewConsole || !ProcessData->bInheritHandles) - { - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.OutputHandle); - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.InputHandle); - } - ProcessData->Console = 0; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; - } - - /* Set the Ctrl Dispatcher */ - ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher; - DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); - - if (!NewConsole) - { - /* Insert into the list if it has not been added */ - InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); - } - - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_SUCCESS; -} - -CSR_API(CsrFreeConsole) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - return Win32CsrReleaseConsole(ProcessData); -} - -static VOID FASTCALL -ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines) -{ - /* If we hit bottom, slide the viewable screen */ - if (++Buff->CurrentY == Buff->MaxY) - { - Buff->CurrentY--; - if (++Buff->VirtualY == Buff->MaxY) - { - Buff->VirtualY = 0; - } - (*ScrolledLines)++; - ClearLineBuffer(Buff); - if (UpdateRect->Top != 0) - { - UpdateRect->Top--; - } - } - UpdateRect->Left = 0; - UpdateRect->Right = Buff->MaxX - 1; - UpdateRect->Bottom = Buff->CurrentY; -} - -static NTSTATUS FASTCALL -ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, - CHAR *Buffer, DWORD Length, BOOL Attrib) -{ - UINT i; - PBYTE Ptr; - SMALL_RECT UpdateRect; - LONG CursorStartX, CursorStartY; - UINT ScrolledLines; - - CursorStartX = Buff->CurrentX; - CursorStartY = Buff->CurrentY; - UpdateRect.Left = Buff->MaxX; - UpdateRect.Top = Buff->CurrentY; - UpdateRect.Right = -1; - UpdateRect.Bottom = Buff->CurrentY; - ScrolledLines = 0; - - for (i = 0; i < Length; i++) - { - if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) - { - /* --- LF --- */ - if (Buffer[i] == '\n') - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - continue; - } - /* --- BS --- */ - else if (Buffer[i] == '\b') - { - /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CurrentX || 0 != Buff->CurrentY) - { - if (0 == Buff->CurrentX) - { - /* slide virtual position up */ - Buff->CurrentX = Buff->MaxX - 1; - Buff->CurrentY--; - UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); - } - else - { - Buff->CurrentX--; - } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = ' '; - Ptr[1] = Buff->DefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); - } - continue; - } - /* --- CR --- */ - else if (Buffer[i] == '\r') - { - Buff->CurrentX = 0; - UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); - continue; - } - /* --- TAB --- */ - else if (Buffer[i] == '\t') - { - UINT EndX; - - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - EndX = (Buff->CurrentX + 8) & ~7; - if (EndX > Buff->MaxX) - { - EndX = Buff->MaxX; - } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - while (Buff->CurrentX < EndX) - { - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - Buff->CurrentX++; - } - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); - if (Buff->CurrentX == Buff->MaxX) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CurrentX--; - } - } - continue; - } - } - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = Buffer[i]; - if (Attrib) - { - Ptr[1] = Buff->DefaultAttrib; - } - Buff->CurrentX++; - if (Buff->CurrentX == Buff->MaxX) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CurrentX = CursorStartX; - } - } - } - - if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) - { - ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, - Buffer, Length); - } - - return STATUS_SUCCESS; -} - -CSR_API(CsrReadConsole) -{ - PLIST_ENTRY CurrentEntry; - ConsoleInput *Input; - PUCHAR Buffer; - PWCHAR UnicodeBuffer; - ULONG i; - ULONG nNumberOfCharsToRead, CharSize; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrReadConsole\n"); - - CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ - nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Buffer = Request->Data.ReadConsoleRequest.Buffer; - UnicodeBuffer = (PWCHAR)Buffer; - Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, - &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; - for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) - { - /* remove input event from queue */ - CurrentEntry = RemoveHeadList(&Console->InputEvents); - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') - { - /* - * backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 - != (Console->Mode & ENABLE_ECHO_INPUT)) - { - /* echo if it has not already been done, and either we or the client has chars to be deleted */ - if (! Input->Echoed - && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); - } - if (0 != i) - { - i -= 2; /* if we already have something to return, just back it up by 2 */ - } - else - { - /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ - Console->WaitingChars--; - ConioUnlockConsole(Console); - HeapFree(Win32CsrApiHeap, 0, Input); - Request->Data.ReadConsoleRequest.NrCharactersRead = 0; - return STATUS_NOTIFY_CLEANUP; - - } - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; - Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ - } - /* do not copy backspace to buffer */ - else - { - if(Request->Data.ReadConsoleRequest.Unicode) - ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); - else - Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; - } - /* echo to screen if enabled and we did not already echo the char */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) - && ! Input->Echoed - && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); - } - } - else - { - i--; - } - Console->WaitingChars--; - HeapFree(Win32CsrApiHeap, 0, Input); - } - Request->Data.ReadConsoleRequest.NrCharactersRead = i; - if (0 == i) - { - Status = STATUS_PENDING; /* we didn't read anything */ - } - else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) - { - if (0 == Console->WaitingLines || - (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) - { - Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ - } - else - { - Console->WaitingLines--; - Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ - } - } - else - { - Status = STATUS_SUCCESS; /* not line buffered, did read something */ - } - - if (Status == STATUS_PENDING) - { - Console->EchoCount = nNumberOfCharsToRead - i; - } - else - { - Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ - } - - ConioUnlockConsole(Console); - - if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - } - - return Status; -} - -__inline BOOLEAN ConioGetIntersection( - SMALL_RECT *Intersection, - SMALL_RECT *Rect1, - SMALL_RECT *Rect2) -{ - if (ConioIsRectEmpty(Rect1) || - (ConioIsRectEmpty(Rect2)) || - (Rect1->Top > Rect2->Bottom) || - (Rect1->Left > Rect2->Right) || - (Rect1->Bottom < Rect2->Top) || - (Rect1->Right < Rect2->Left)) - { - /* The rectangles do not intersect */ - ConioInitRect(Intersection, 0, -1, 0, -1); - return FALSE; - } - - ConioInitRect(Intersection, - max(Rect1->Top, Rect2->Top), - max(Rect1->Left, Rect2->Left), - min(Rect1->Bottom, Rect2->Bottom), - min(Rect1->Right, Rect2->Right)); - - return TRUE; -} - -__inline BOOLEAN ConioGetUnion( - SMALL_RECT *Union, - SMALL_RECT *Rect1, - SMALL_RECT *Rect2) -{ - if (ConioIsRectEmpty(Rect1)) - { - if (ConioIsRectEmpty(Rect2)) - { - ConioInitRect(Union, 0, -1, 0, -1); - return FALSE; - } - else - { - *Union = *Rect2; - } - } - else if (ConioIsRectEmpty(Rect2)) - { - *Union = *Rect1; - } - else - { - ConioInitRect(Union, - min(Rect1->Top, Rect2->Top), - min(Rect1->Left, Rect2->Left), - max(Rect1->Bottom, Rect2->Bottom), - max(Rect1->Right, Rect2->Right)); - } - - return TRUE; -} - -/* Move from one rectangle to another. We must be careful about the order that - * this is done, to avoid overwriting parts of the source before they are moved. */ -static VOID FASTCALL -ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, - SMALL_RECT *SrcRegion, - SMALL_RECT *DstRegion, - SMALL_RECT *ClipRegion, - WORD Fill) -{ - int Width = ConioRectWidth(SrcRegion); - int Height = ConioRectHeight(SrcRegion); - int SX, SY; - int DX, DY; - int XDelta, YDelta; - int i, j; - - SY = SrcRegion->Top; - DY = DstRegion->Top; - YDelta = 1; - if (SY < DY) - { - /* Moving down: work from bottom up */ - SY = SrcRegion->Bottom; - DY = DstRegion->Bottom; - YDelta = -1; - } - for (i = 0; i < Height; i++) - { - PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); - PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); - - SX = SrcRegion->Left; - DX = DstRegion->Left; - XDelta = 1; - if (SX < DX) - { - /* Moving right: work from right to left */ - SX = SrcRegion->Right; - DX = DstRegion->Right; - XDelta = -1; - } - for (j = 0; j < Width; j++) - { - WORD Cell = SRow[SX]; - if (SX >= ClipRegion->Left && SX <= ClipRegion->Right - && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) - { - SRow[SX] = Fill; - } - if (DX >= ClipRegion->Left && DX <= ClipRegion->Right - && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) - { - DRow[DX] = Cell; - } - SX += XDelta; - DX += XDelta; - } - SY += YDelta; - DY += YDelta; - } -} - -static VOID FASTCALL -ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) -{ - if (InputEvent->EventType == KEY_EVENT) - { - WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; - InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; - ConsoleInputUnicodeCharToAnsiChar(Console, - &InputEvent->Event.KeyEvent.uChar.AsciiChar, - &UnicodeChar); - } -} - -CSR_API(CsrWriteConsole) -{ - NTSTATUS Status; - PCHAR Buffer; - PCSRSS_SCREEN_BUFFER Buff; - PCSRSS_CONSOLE Console; - DWORD Written = 0; - ULONG Length; - ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - DPRINT("CsrWriteConsole\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) - + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - if (Console->UnpauseEvent) - { - Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, - ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, - SYNCHRONIZE, 0, 0); - ConioUnlockScreenBuffer(Buff); - return NT_SUCCESS(Status) ? STATUS_PENDING : Status; - } - - if(Request->Data.WriteConsoleRequest.Unicode) - { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - NULL, 0, NULL, NULL); - Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (Buffer) - { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - Buffer, Length, NULL, NULL); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - else - { - Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; - } - - if (Buffer) - { - if (NT_SUCCESS(Status)) - { - Status = ConioWriteConsole(Console, Buff, Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); - if (NT_SUCCESS(Status)) - { - Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; - } - } - if (Request->Data.WriteConsoleRequest.Unicode) - { - RtlFreeHeap(GetProcessHeap(), 0, Buffer); - } - } - ConioUnlockScreenBuffer(Buff); - - Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; - - return Status; -} - -VOID WINAPI -ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) -{ - PCSRSS_CONSOLE Console = Buffer->Header.Console; - - RemoveEntryList(&Buffer->ListEntry); - if (Buffer == Console->ActiveBuffer) - { - /* Deleted active buffer; switch to most recently created */ - Console->ActiveBuffer = NULL; - if (!IsListEmpty(&Console->BufferList)) - { - Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry); - ConioDrawConsole(Console); - } - } - - HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); - HeapFree(Win32CsrApiHeap, 0, Buffer); -} - -VOID FASTCALL -ConioDrawConsole(PCSRSS_CONSOLE Console) -{ - SMALL_RECT Region; - - ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); - - ConioDrawRegion(Console, &Region); -} - - -VOID WINAPI -ConioDeleteConsole(Object_t *Object) -{ - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; - ConsoleInput *Event; - - DPRINT("ConioDeleteConsole\n"); - - /* Drain input event queue */ - while (Console->InputEvents.Flink != &Console->InputEvents) - { - Event = (ConsoleInput *) Console->InputEvents.Flink; - Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; - Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; - HeapFree(Win32CsrApiHeap, 0, Event); - } - - ConioCleanupConsole(Console); - ConioDeleteScreenBuffer(Console->ActiveBuffer); - if (!IsListEmpty(&Console->BufferList)) - { - DPRINT1("BUG: screen buffer list not empty\n"); - } - - CloseHandle(Console->ActiveEvent); - if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); - DeleteCriticalSection(&Console->Lock); - RtlFreeUnicodeString(&Console->Title); - IntDeleteAllAliases(Console->Aliases); - HeapFree(Win32CsrApiHeap, 0, Console); -} - -VOID WINAPI -CsrInitConsoleSupport(VOID) -{ - DPRINT("CSR: CsrInitConsoleSupport()\n"); - - /* Should call LoadKeyboardLayout */ -} - -VOID FASTCALL -ConioPause(PCSRSS_CONSOLE Console, UINT Flags) -{ - Console->PauseFlags |= Flags; - if (!Console->UnpauseEvent) - Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); -} - -VOID FASTCALL -ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags) -{ - Console->PauseFlags &= ~Flags; - if (Console->PauseFlags == 0 && Console->UnpauseEvent) - { - SetEvent(Console->UnpauseEvent); - CloseHandle(Console->UnpauseEvent); - Console->UnpauseEvent = NULL; - } -} - -static VOID FASTCALL -ConioProcessChar(PCSRSS_CONSOLE Console, - ConsoleInput *KeyEventRecord) -{ - BOOL updown; - ConsoleInput *TempInput; - - if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; - if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) - { - DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; - if (Console->Mode & ENABLE_LINE_INPUT && - (vk == VK_PAUSE || (vk == 'S' && - (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && - !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) - { - ConioPause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; - } - } - else - { - if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && - vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) - { - ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; - } - } - } - - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) - { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - case '\r': - /* first add the \r */ - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; - KeyEventRecord->Echoed = FALSE; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r'; - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == KeyEventRecord) - { - DPRINT1("Failed to allocate KeyEventRecord\n"); - return; - } - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n'; - KeyEventRecord->Fake = TRUE; - break; - } - } - /* add event to the queue */ - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - /* if line input mode is enabled, only wake the client on enter key down */ - if (0 == (Console->Mode & ENABLE_LINE_INPUT) - || Console->EarlyReturn - || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) - { - if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - Console->WaitingLines++; - } - } - KeyEventRecord->Echoed = FALSE; - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - /* walk the input queue looking for a char to backspace */ - for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; - TempInput != (ConsoleInput *) &Console->InputEvents - && (KEY_EVENT == TempInput->InputEvent.EventType - || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); - TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) - { - /* NOP */; - } - /* if we found one, delete it, otherwise, wake the client */ - if (TempInput != (ConsoleInput *) &Console->InputEvents) - { - /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ - RemoveEntryList(&TempInput->ListEntry); - if (TempInput->Echoed) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); - } - HeapFree(Win32CsrApiHeap, 0, TempInput); - RemoveEntryList(&KeyEventRecord->ListEntry); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - Console->WaitingChars -= 2; - return; - } - } - else - { - /* echo chars if we are supposed to and client is waiting for some */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - /* mark the char as already echoed */ - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); - Console->EchoCount--; - KeyEventRecord->Echoed = TRUE; - } - } - - /* Console->WaitingChars++; */ - SetEvent(Console->ActiveEvent); -} - -static DWORD FASTCALL -ConioGetShiftState(PBYTE KeyState) -{ - DWORD ssOut = 0; - - if (KeyState[VK_CAPITAL] & 1) - ssOut |= CAPSLOCK_ON; - - if (KeyState[VK_NUMLOCK] & 1) - ssOut |= NUMLOCK_ON; - - if (KeyState[VK_SCROLL] & 1) - ssOut |= SCROLLLOCK_ON; - - if (KeyState[VK_SHIFT] & 0x80) - ssOut |= SHIFT_PRESSED; - - if (KeyState[VK_LCONTROL] & 0x80) - ssOut |= LEFT_CTRL_PRESSED; - if (KeyState[VK_RCONTROL] & 0x80) - ssOut |= RIGHT_CTRL_PRESSED; - - if (KeyState[VK_LMENU] & 0x80) - ssOut |= LEFT_ALT_PRESSED; - if (KeyState[VK_RMENU] & 0x80) - ssOut |= RIGHT_ALT_PRESSED; - - return ssOut; -} - -VOID WINAPI -ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) -{ - static BYTE KeyState[256] = { 0 }; - /* MSDN mentions that you should use the last virtual key code received - * when putting a virtual key identity to a WM_CHAR message since multiple - * or translated keys may be involved. */ - static UINT LastVirtualKey = 0; - DWORD ShiftState; - ConsoleInput *ConInRec; - UINT RepeatCount; - CHAR AsciiChar; - WCHAR UnicodeChar; - UINT VirtualKeyCode; - UINT VirtualScanCode; - BOOL Down = FALSE; - INPUT_RECORD er; - ULONG ResultSize = 0; - - RepeatCount = 1; - VirtualScanCode = (msg->lParam >> 16) & 0xff; - Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || - msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; - - GetKeyboardState(KeyState); - ShiftState = ConioGetShiftState(KeyState); - - if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) - { - VirtualKeyCode = LastVirtualKey; - UnicodeChar = msg->wParam; - } - else - { - WCHAR Chars[2]; - INT RetChars = 0; - - VirtualKeyCode = msg->wParam; - RetChars = ToUnicodeEx(VirtualKeyCode, - VirtualScanCode, - KeyState, - Chars, - 2, - 0, - 0); - UnicodeChar = (1 == RetChars ? Chars[0] : 0); - } - - if (0 == ResultSize) - { - AsciiChar = 0; - } - - er.EventType = KEY_EVENT; - er.Event.KeyEvent.bKeyDown = Down; - er.Event.KeyEvent.wRepeatCount = RepeatCount; - er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; - er.Event.KeyEvent.dwControlKeyState = ShiftState; - er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; - er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - - if (TextMode) - { - if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && VK_TAB == VirtualKeyCode) - { - if (Down) - { - TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); - } - - return; - } - else if (VK_MENU == VirtualKeyCode && ! Down) - { - if (TuiSwapConsole(0)) - { - return; - } - } - } - - if (NULL == Console) - { - DPRINT1("No Active Console!\n"); - return; - } - - ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - - if (NULL == ConInRec) - { - return; - } - - ConInRec->InputEvent = er; - ConInRec->Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - ConInRec->Echoed = FALSE; - if (ConInRec->NotChar) - LastVirtualKey = msg->wParam; - - DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", - Down ? "down" : "up ", - (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? - "char" : "key ", - ConInRec->Fake ? "fake" : "real", - ConInRec->NotChar ? "notc" : "char", - VirtualScanCode, - VirtualKeyCode, - (AsciiChar >= ' ') ? AsciiChar : '.', - ShiftState); - - if (ConInRec->Fake && ConInRec->NotChar) - { - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - - /* process Ctrl-C and Ctrl-Break */ - if (Console->Mode & ENABLE_PROCESSED_INPUT && - er.Event.KeyEvent.bKeyDown && - ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || - (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && - (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) - { - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DPRINT1("Console_Api Ctrl-C\n"); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; - ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); - } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - - if (0 != (er.Event.KeyEvent.dwControlKeyState - & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode - || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) - { - if (er.Event.KeyEvent.bKeyDown) - { - /* scroll up or down */ - if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) - { - /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->MaxY - 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY++; - } - } - else - { - /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CurrentY != 0) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY--; - } - } - ConioDrawConsole(Console); - } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - /* FIXME - convert to ascii */ - ConioProcessChar(Console, ConInRec); -} - -CSR_API(CsrGetScreenBufferInfo) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PCONSOLE_SCREEN_BUFFER_INFO pInfo; - - DPRINT("CsrGetScreenBufferInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - pInfo = &Request->Data.ScreenBufferInfoRequest.Info; - pInfo->dwSize.X = Buff->MaxX; - pInfo->dwSize.Y = Buff->MaxY; - pInfo->dwCursorPosition.X = Buff->CurrentX; - pInfo->dwCursorPosition.Y = Buff->CurrentY; - pInfo->wAttributes = Buff->DefaultAttrib; - pInfo->srWindow.Left = Buff->ShowX; - pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; - pInfo->srWindow.Top = Buff->ShowY; - pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; - pInfo->dwMaximumWindowSize.X = Buff->MaxX; - pInfo->dwMaximumWindowSize.Y = Buff->MaxY; - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetCursor) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - LONG OldCursorX, OldCursorY; - LONG NewCursorX, NewCursorY; - - DPRINT("CsrSetCursor\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - NewCursorX = Request->Data.SetCursorRequest.Position.X; - NewCursorY = Request->Data.SetCursorRequest.Position.Y; - if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || - NewCursorY < 0 || NewCursorY >= Buff->MaxY) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_INVALID_PARAMETER; - } - OldCursorX = Buff->CurrentX; - OldCursorY = Buff->CurrentY; - Buff->CurrentX = NewCursorX; - Buff->CurrentY = NewCursorY; - if (Buff == Console->ActiveBuffer) - { - if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -static VOID FASTCALL -ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length) -{ - if (Buff->MaxX <= Start->X + Length) - { - UpdateRect->Left = 0; - } - else - { - UpdateRect->Left = Start->X; - } - if (Buff->MaxX <= Start->X + Length) - { - UpdateRect->Right = Buff->MaxX - 1; - } - else - { - UpdateRect->Right = Start->X + Length - 1; - } - UpdateRect->Top = Start->Y; - UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; - if (Buff->MaxY <= UpdateRect->Bottom) - { - UpdateRect->Bottom = Buff->MaxY - 1; - } -} - -CSR_API(CsrWriteConsoleOutputChar) -{ - NTSTATUS Status; - PCHAR String, tmpString = NULL; - PBYTE Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, CharSize, Written = 0; - SMALL_RECT UpdateRect; - - DPRINT("CsrWriteConsoleOutputChar\n"); - - CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (NT_SUCCESS(Status)) - { - Console = Buff->Header.Console; - if(Request->Data.WriteConsoleOutputCharRequest.Unicode) - { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - NULL, 0, NULL, NULL); - tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (String) - { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - String, Length, NULL, NULL); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - else - { - String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; - } - - if (String) - { - if (NT_SUCCESS(Status)) - { - X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputCharRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - while (Length--) - { - *Buffer = *String++; - Written++; - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer; - } - X = 0; - } - } - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, - Request->Data.WriteConsoleOutputCharRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; - Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - - } - if (Request->Data.WriteConsoleRequest.Unicode) - { - RtlFreeHeap(GetProcessHeap(), 0, tmpString); - } - } - ConioUnlockScreenBuffer(Buff); - } - Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; - return Status; -} - -CSR_API(CsrFillOutputChar) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, Written = 0; - CHAR Char; - PBYTE Buffer; - SMALL_RECT UpdateRect; - - DPRINT("CsrFillOutputChar\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - X = Request->Data.FillOutputRequest.Position.X; - Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - if(Request->Data.FillOutputRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); - else - Char = Request->Data.FillOutputRequest.Char.AsciiChar; - Length = Request->Data.FillOutputRequest.Length; - while (Length--) - { - *Buffer = Char; - Buffer += 2; - Written++; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, - Request->Data.FillOutputRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConioUnlockScreenBuffer(Buff); - Length = Request->Data.FillOutputRequest.Length; - Request->Data.FillOutputRequest.NrCharactersWritten = Length; - return STATUS_SUCCESS; -} - -CSR_API(CsrReadInputEvent) -{ - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - BOOLEAN Done = FALSE; - ConsoleInput *Input; - - DPRINT("CsrReadInputEvent\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; - - Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - /* only get input if there is any */ - CurrentEntry = Console->InputEvents.Flink; - while (CurrentEntry != &Console->InputEvents) - { - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - CurrentEntry = CurrentEntry->Flink; - - if (Done && !Input->Fake) - { - Request->Data.ReadInputRequest.MoreEvents = TRUE; - break; - } - - RemoveEntryList(&Input->ListEntry); - - if (!Done && !Input->Fake) - { - Request->Data.ReadInputRequest.Input = Input->InputEvent; - if (Request->Data.ReadInputRequest.Unicode == FALSE) - { - ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); - } - Done = TRUE; - } - - if (Input->InputEvent.EventType == KEY_EVENT) - { - if (0 != (Console->Mode & ENABLE_LINE_INPUT) - && Input->InputEvent.Event.KeyEvent.bKeyDown - && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - Console->WaitingLines--; - } - Console->WaitingChars--; - } - HeapFree(Win32CsrApiHeap, 0, Input); - } - - if (Done) - { - Status = STATUS_SUCCESS; - Console->EarlyReturn = FALSE; - } - else - { - Status = STATUS_PENDING; - Console->EarlyReturn = TRUE; /* mark for early return */ - } - - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrWriteConsoleOutputAttrib) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - PWORD Attribute; - int X, Y, Length; - NTSTATUS Status; - SMALL_RECT UpdateRect; - - DPRINT("CsrWriteConsoleOutputAttrib\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputAttribRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; - Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; - while (Length--) - { - *Buffer = (UCHAR)(*Attribute++); - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer + 1; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, - Request->Data.WriteConsoleOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrFillOutputAttrib) -{ - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - NTSTATUS Status; - int X, Y, Length; - UCHAR Attr; - SMALL_RECT UpdateRect; - PCSRSS_CONSOLE Console; - - DPRINT("CsrFillOutputAttrib\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - X = Request->Data.FillOutputAttribRequest.Coord.X; - Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.FillOutputAttribRequest.Length; - Attr = Request->Data.FillOutputAttribRequest.Attribute; - Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; - while (Length--) - { - *Buffer = Attr; - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer + 1; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, - Request->Data.FillOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - - -CSR_API(CsrGetCursorInfo) -{ - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; - - DPRINT("CsrGetCursorInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; - Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetCursorInfo) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - BOOL Visible; - NTSTATUS Status; - - DPRINT("CsrSetCursorInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - Size = Request->Data.SetCursorInfoRequest.Info.dwSize; - Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; - if (Size < 1) - { - Size = 1; - } - if (100 < Size) - { - Size = 100; - } - - if (Size != Buff->CursorInfo.dwSize - || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) - { - Buff->CursorInfo.dwSize = Size; - Buff->CursorInfo.bVisible = Visible; - - if (! ConioSetCursorInfo(Console, Buff)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetTextAttrib) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetTextAttrib\n"); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; - if (Buff == Console->ActiveBuffer) - { - if (! ConioUpdateScreenInfo(Console, Buff)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleMode) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetConsoleMode\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrLockObject(ProcessData, - Request->Data.SetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_WRITE, 0); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Buff = (PCSRSS_SCREEN_BUFFER)Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) - { - Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; - } - else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) - { - Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; - } - else - { - Status = STATUS_INVALID_HANDLE; - } - - Win32CsrUnlockObject((Object_t *)Console); - - return Status; -} - -CSR_API(CsrGetConsoleMode) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ - - DPRINT("CsrGetConsoleMode\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_READ, 0); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = STATUS_SUCCESS; - Buff = (PCSRSS_SCREEN_BUFFER) Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) - { - Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; - } - else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) - { - Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; - } - else - { - Status = STATUS_INVALID_HANDLE; - } - - Win32CsrUnlockObject((Object_t *)Console); - return Status; -} - -CSR_API(CsrCreateScreenBuffer) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; - - DPRINT("CsrCreateScreenBuffer\n"); - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - - if (Buff != NULL) - { - if (Console->ActiveBuffer) - { - Buff->MaxX = Console->ActiveBuffer->MaxX; - Buff->MaxY = Console->ActiveBuffer->MaxY; - Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; - Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; - } - else - { - Buff->CursorInfo.bVisible = TRUE; - Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - } - - if (Buff->MaxX == 0) - { - Buff->MaxX = 80; - } - - if (Buff->MaxY == 0) - { - Buff->MaxY = 25; - } - - Status = CsrInitConsoleScreenBuffer(Console, Buff); - if (NT_SUCCESS(Status)) - { - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.CreateScreenBufferRequest.OutputHandle, - &Buff->Header, - Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable, - Request->Data.CreateScreenBufferRequest.ShareMode); - } - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - - ConioUnlockConsole(Console); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; -} - -CSR_API(CsrSetScreenBuffer) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetScreenBuffer\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - if (Buff == Console->ActiveBuffer) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - - /* If old buffer has no handles, it's now unreferenced */ - if (Console->ActiveBuffer->Header.HandleCount == 0) - { - ConioDeleteScreenBuffer(Console->ActiveBuffer); - } - /* tie console to new buffer */ - Console->ActiveBuffer = Buff; - /* Redraw the console */ - ConioDrawConsole(Console); - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetTitle) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PWCHAR Buffer; - - DPRINT("CsrSetTitle\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) - + Request->Data.SetTitleRequest.Length) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if(NT_SUCCESS(Status)) - { - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); - if (Buffer) - { - /* copy title to console */ - RtlFreeUnicodeString(&Console->Title); - Console->Title.Buffer = Buffer; - Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; - memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); - if (! ConioChangeTitle(Console)) - { - Status = STATUS_UNSUCCESSFUL; - } - else - { - Status = STATUS_SUCCESS; - } - } - else - { - Status = STATUS_NO_MEMORY; - } - ConioUnlockConsole(Console); - } - - return Status; -} - -CSR_API(CsrGetTitle) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Length; - - DPRINT("CsrGetTitle\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Can't get console\n"); - return Status; - } - - /* Copy title of the console to the user title buffer */ - RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); - Request->Data.GetTitleRequest.Length = Console->Title.Length; - memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, - Console->Title.Length); - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; - - ConioUnlockConsole(Console); - - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } - return STATUS_SUCCESS; -} - -CSR_API(CsrWriteConsoleOutput) -{ - SHORT i, X, Y, SizeX, SizeY; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - SMALL_RECT ScreenBuffer; - CHAR_INFO* CurCharInfo; - SMALL_RECT WriteRegion; - CHAR_INFO* CharInfo; - COORD BufferCoord; - COORD BufferSize; - NTSTATUS Status; - PBYTE Ptr; - DWORD PSize; - - DPRINT("CsrWriteConsoleOutput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; - PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); - BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; - CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || - (((ULONG_PTR)CharInfo + PSize) > - ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_ACCESS_VIOLATION; - } - WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; - - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); - WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - WriteRegion.Right = WriteRegion.Left + SizeX - 1; - - /* Make sure WriteRegion is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) - { - ConioUnlockScreenBuffer(Buff); - - /* It is okay to have a WriteRegion completely outside the screen buffer. - No data is written then. */ - return STATUS_SUCCESS; - } - - for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) - { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); - for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) - { - CHAR AsciiChar; - if (Request->Data.WriteConsoleOutputRequest.Unicode) - { - ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); - } - else - { - AsciiChar = CurCharInfo->Char.AsciiChar; - } - *Ptr++ = AsciiChar; - *Ptr++ = CurCharInfo->Attributes; - CurCharInfo++; - } - } - - ConioDrawRegion(Console, &WriteRegion); - - ConioUnlockScreenBuffer(Buff); - - Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; - - return STATUS_SUCCESS; -} - -CSR_API(CsrFlushInputBuffer) -{ - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - ConsoleInput* Input; - NTSTATUS Status; - - DPRINT("CsrFlushInputBuffer\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, - Request->Data.FlushInputBufferRequest.ConsoleInput, - &Console, - GENERIC_WRITE); - if(! NT_SUCCESS(Status)) - { - return Status; - } - - /* Discard all entries in the input event queue */ - while (!IsListEmpty(&Console->InputEvents)) - { - CurrentEntry = RemoveHeadList(&Console->InputEvents); - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - /* Destroy the event */ - HeapFree(Win32CsrApiHeap, 0, Input); - } - ResetEvent(Console->ActiveEvent); - Console->WaitingChars=0; - - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrScrollConsoleScreenBuffer) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - SMALL_RECT ScreenBuffer; - SMALL_RECT SrcRegion; - SMALL_RECT DstRegion; - SMALL_RECT UpdateRegion; - SMALL_RECT ScrollRectangle; - SMALL_RECT ClipRectangle; - NTSTATUS Status; - HANDLE ConsoleHandle; - BOOLEAN UseClipRectangle; - COORD DestinationOrigin; - CHAR_INFO Fill; - CHAR FillChar; - - DPRINT("CsrScrollConsoleScreenBuffer\n"); - - ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; - UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; - DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; - Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; - - /* Make sure source rectangle is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - - /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.Left < 0) - { - DestinationOrigin.X -= ScrollRectangle.Left; - } - if (ScrollRectangle.Top < 0) - { - DestinationOrigin.Y -= ScrollRectangle.Top; - } - - if (UseClipRectangle) - { - ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; - if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - } - else - { - ClipRectangle = ScreenBuffer; - } - - ConioInitRect(&DstRegion, - DestinationOrigin.Y, - DestinationOrigin.X, - DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, - DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); - - if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); - else - FillChar = Fill.Char.AsciiChar; - - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); - - if (Buff == Console->ActiveBuffer) - { - ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); - if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) - { - /* Draw update region */ - ConioDrawRegion(Console, &UpdateRegion); - } - } - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrReadConsoleOutputChar) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PCHAR ReadBuffer; - DWORD i; - ULONG CharSize; - CHAR Char; - - DPRINT("CsrReadConsoleOutputChar\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; - - CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - - for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) - { - Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; - - if(Request->Data.ReadConsoleOutputCharRequest.Unicode) - { - ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); - ReadBuffer += sizeof(WCHAR); - } - else - *(ReadBuffer++) = Char; - - Xpos++; - - if (Xpos == Buff->MaxX) - { - Xpos = 0; - Ypos++; - - if (Ypos == Buff->MaxY) - { - Ypos = 0; - } - } - } - - *ReadBuffer = 0; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - - Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; - if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - } - - return STATUS_SUCCESS; -} - - -CSR_API(CsrReadConsoleOutputAttrib) -{ - NTSTATUS Status; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PWORD ReadBuffer; - DWORD i; - DWORD CurrentLength; - - DPRINT("CsrReadConsoleOutputAttrib\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - - for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) - { - *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; - - ReadBuffer++; - Xpos++; - - if (Xpos == Buff->MaxX) - { - Xpos = 0; - Ypos++; - - if (Ypos == Buff->MaxY) - { - Ypos = 0; - } - } - } - - *ReadBuffer = 0; - - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - - CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); - if (CurrentLength > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = CurrentLength; - Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); - } - - return STATUS_SUCCESS; -} - - -CSR_API(CsrGetNumberOfConsoleInputEvents) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PLIST_ENTRY CurrentItem; - DWORD NumEvents; - ConsoleInput *Input; - - DPRINT("CsrGetNumberOfConsoleInputEvents\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - CurrentItem = Console->InputEvents.Flink; - NumEvents = 0; - - /* If there are any events ... */ - while (CurrentItem != &Console->InputEvents) - { - Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - CurrentItem = CurrentItem->Flink; - if (!Input->Fake) - { - NumEvents++; - } - } - - ConioUnlockConsole(Console); - - Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrPeekConsoleInput) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Size; - DWORD Length; - PLIST_ENTRY CurrentItem; - PINPUT_RECORD InputRecord; - ConsoleInput* Item; - UINT NumItems; - - DPRINT("CsrPeekConsoleInput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if(! NT_SUCCESS(Status)) - { - return Status; - } - - InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; - Length = Request->Data.PeekConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; - } - - NumItems = 0; - - if (! IsListEmpty(&Console->InputEvents)) - { - CurrentItem = Console->InputEvents.Flink; - - while (CurrentItem != &Console->InputEvents && NumItems < Length) - { - Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - - if (Item->Fake) - { - CurrentItem = CurrentItem->Flink; - continue; - } - - ++NumItems; - *InputRecord = Item->InputEvent; - - if (Request->Data.ReadInputRequest.Unicode == FALSE) - { - ConioInputEventToAnsi(Console, InputRecord); - } - - InputRecord++; - CurrentItem = CurrentItem->Flink; - } - } - - ConioUnlockConsole(Console); - - Request->Data.PeekConsoleInputRequest.Length = NumItems; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrReadConsoleOutput) -{ - PCHAR_INFO CharInfo; - PCHAR_INFO CurCharInfo; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - DWORD Length; - DWORD SizeX, SizeY; - NTSTATUS Status; - COORD BufferSize; - COORD BufferCoord; - SMALL_RECT ReadRegion; - SMALL_RECT ScreenRect; - DWORD i; - PBYTE Ptr; - LONG X, Y; - UINT CodePage; - - DPRINT("CsrReadConsoleOutput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; - ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; - BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; - BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; - Length = BufferSize.X * BufferSize.Y; - Size = Length * sizeof(CHAR_INFO); - - /* FIXME: Is this correct? */ - CodePage = ProcessData->Console->OutputCodePage; - - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_ACCESS_VIOLATION; - } - - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); - ReadRegion.Bottom = ReadRegion.Top + SizeY; - ReadRegion.Right = ReadRegion.Left + SizeX; - - ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); - if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - - for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) - { - CurCharInfo = CharInfo + (i * BufferSize.X); - - Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); - for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) - { - if (Request->Data.ReadConsoleOutputRequest.Unicode) - { - MultiByteToWideChar(CodePage, 0, - (PCHAR)Ptr++, 1, - &CurCharInfo->Char.UnicodeChar, 1); - } - else - { - CurCharInfo->Char.AsciiChar = *Ptr++; - } - CurCharInfo->Attributes = *Ptr++; - ++CurCharInfo; - } - } - - ConioUnlockScreenBuffer(Buff); - - Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrWriteConsoleInput) -{ - PINPUT_RECORD InputRecord; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - DWORD Length; - DWORD Size; - DWORD i; - ConsoleInput* Record; - - DPRINT("CsrWriteConsoleInput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; - Length = Request->Data.WriteConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; - } - - for (i = 0; i < Length; i++) - { - Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == Record) - { - ConioUnlockConsole(Console); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Record->Echoed = FALSE; - Record->Fake = FALSE; - //Record->InputEvent = *InputRecord++; - memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); - if (KEY_EVENT == Record->InputEvent.EventType) - { - /* FIXME - convert from unicode to ascii!! */ - ConioProcessChar(Console, Record); - } - } - - ConioUnlockConsole(Console); - - Request->Data.WriteConsoleInputRequest.Length = i; - - return STATUS_SUCCESS; -} - -/********************************************************************** - * HardwareStateProperty - * - * DESCRIPTION - * Set/Get the value of the HardwareState and switch - * between direct video buffer ouput and GDI windowed - * output. - * ARGUMENTS - * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE - * object. We use the same object to Request. - * NOTE - * ConsoleHwState has the correct size to be compatible - * with NT's, but values are not. - */ -static NTSTATUS FASTCALL -SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) -{ - DPRINT1("Console Hardware State: %d\n", ConsoleHwState); - - if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) - ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) - { - if (Console->HardwareState != ConsoleHwState) - { - /* TODO: implement switching from full screen to windowed mode */ - /* TODO: or back; now simply store the hardware state */ - Console->HardwareState = ConsoleHwState; - } - - return STATUS_SUCCESS; - } - - return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ -} - -CSR_API(CsrHardwareStateProperty) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrHardwareStateProperty\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, - Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, - &Console, - GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); - return Status; - } - - switch (Request->Data.ConsoleHardwareStateRequest.SetGet) - { - case CONSOLE_HARDWARE_STATE_GET: - Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState; - break; - - case CONSOLE_HARDWARE_STATE_SET: - DPRINT("Setting console hardware state.\n"); - Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State); - break; - - default: - Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */ - break; - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrGetConsoleWindow) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleWindow\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleIcon) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleIcon\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) - ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrGetConsoleCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) - { - Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; -} - -CSR_API(CsrGetConsoleOutputCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleOutputCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleOutputCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleOutputCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) - { - Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; -} - -CSR_API(CsrGetProcessList) -{ - PDWORD Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - ULONG nItems = 0; - NTSTATUS Status; - ULONG_PTR Offset; - - DPRINT("CsrGetProcessList\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Buffer = Request->Data.GetProcessListRequest.ProcessId; - Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) - || Offset & (sizeof(DWORD) - 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - for (current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds) - { - *Buffer++ = (DWORD)current->ProcessId; - } - } - - ConioUnlockConsole(Console); - - Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; - return STATUS_SUCCESS; -} - -CSR_API(CsrGenerateCtrlEvent) -{ - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DWORD Group; - NTSTATUS Status; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Group = Request->Data.GenerateCtrlEvent.ProcessGroup; - Status = STATUS_INVALID_PARAMETER; - for (current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if (Group == 0 || current->ProcessGroup == Group) - { - ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); - Status = STATUS_SUCCESS; - } - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrSetScreenBufferSize) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); - if (!NT_SUCCESS(Status)) - { - return Status; - } - Console = Buff->Header.Console; - - Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); - ConioUnlockScreenBuffer(Buff); - - return Status; -} - -CSR_API(CsrGetConsoleSelectionInfo) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO)); - if (Console->Selection.dwFlags != 0) - Request->Data.GetConsoleSelectionInfo.Info = Console->Selection; - ConioUnlockConsole(Console); - } - return Status; -} - -/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 9b0c6905ce8..2befcaf0b2d 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -118,62 +118,6 @@ typedef struct ConsoleInput_t #define PAUSED_FROM_SCROLLBAR 0x2 #define PAUSED_FROM_SELECTION 0x4 -NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); -VOID WINAPI ConioDeleteConsole(Object_t *Object); -VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); -VOID WINAPI CsrInitConsoleSupport(VOID); -VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags); -VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags); -void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); -PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); -VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); -VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData); -VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, - DWORD Timeout); - -/* api/conio.c */ -CSR_API(CsrWriteConsole); -CSR_API(CsrAllocConsole); -CSR_API(CsrFreeConsole); -CSR_API(CsrReadConsole); -CSR_API(CsrConnectProcess); -CSR_API(CsrGetScreenBufferInfo); -CSR_API(CsrSetCursor); -CSR_API(CsrFillOutputChar); -CSR_API(CsrReadInputEvent); -CSR_API(CsrWriteConsoleOutputChar); -CSR_API(CsrWriteConsoleOutputAttrib); -CSR_API(CsrFillOutputAttrib); -CSR_API(CsrGetCursorInfo); -CSR_API(CsrSetCursorInfo); -CSR_API(CsrSetTextAttrib); -CSR_API(CsrSetConsoleMode); -CSR_API(CsrGetConsoleMode); -CSR_API(CsrCreateScreenBuffer); -CSR_API(CsrSetScreenBuffer); -CSR_API(CsrSetTitle); -CSR_API(CsrGetTitle); -CSR_API(CsrWriteConsoleOutput); -CSR_API(CsrFlushInputBuffer); -CSR_API(CsrScrollConsoleScreenBuffer); -CSR_API(CsrReadConsoleOutputChar); -CSR_API(CsrReadConsoleOutputAttrib); -CSR_API(CsrGetNumberOfConsoleInputEvents); -CSR_API(CsrPeekConsoleInput); -CSR_API(CsrReadConsoleOutput); -CSR_API(CsrWriteConsoleInput); -CSR_API(CsrHardwareStateProperty); -CSR_API(CsrGetConsoleWindow); -CSR_API(CsrSetConsoleIcon); -CSR_API(CsrGetConsoleCodePage); -CSR_API(CsrSetConsoleCodePage); -CSR_API(CsrGetConsoleOutputCodePage); -CSR_API(CsrSetConsoleOutputCodePage); -CSR_API(CsrGetProcessList); -CSR_API(CsrGenerateCtrlEvent); -CSR_API(CsrSetScreenBufferSize); -CSR_API(CsrGetConsoleSelectionInfo); - #define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff)) #define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region)) #define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \ @@ -189,19 +133,79 @@ CSR_API(CsrGetConsoleSelectionInfo); #define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon(Console, hWindowIcon) #define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size) -#define ConioRectHeight(Rect) \ - (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) -#define ConioRectWidth(Rect) \ - (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) +/* console.c */ +NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); +VOID WINAPI ConioDeleteConsole(Object_t *Object); +VOID WINAPI CsrInitConsoleSupport(VOID); +VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags); +VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags); +VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData); +VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, + DWORD Timeout); +CSR_API(CsrAllocConsole); +CSR_API(CsrFreeConsole); +CSR_API(CsrSetConsoleMode); +CSR_API(CsrGetConsoleMode); +CSR_API(CsrSetTitle); +CSR_API(CsrGetTitle); +CSR_API(CsrHardwareStateProperty); +CSR_API(CsrGetConsoleWindow); +CSR_API(CsrSetConsoleIcon); +CSR_API(CsrGetConsoleCodePage); +CSR_API(CsrSetConsoleCodePage); +CSR_API(CsrGetConsoleOutputCodePage); +CSR_API(CsrSetConsoleOutputCodePage); +CSR_API(CsrGetProcessList); +CSR_API(CsrGenerateCtrlEvent); +CSR_API(CsrGetConsoleSelectionInfo); +/* coninput.c */ #define ConioLockConsole(ProcessData, Handle, Ptr, Access) \ Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC) #define ConioUnlockConsole(Console) \ Win32CsrUnlockObject((Object_t *) Console) +void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); +CSR_API(CsrReadConsole); +CSR_API(CsrReadInputEvent); +CSR_API(CsrFlushInputBuffer); +CSR_API(CsrGetNumberOfConsoleInputEvents); +CSR_API(CsrPeekConsoleInput); +CSR_API(CsrWriteConsoleInput); + +/* conoutput.c */ +#define ConioRectHeight(Rect) \ + (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) +#define ConioRectWidth(Rect) \ + (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) #define ConioLockScreenBuffer(ProcessData, Handle, Ptr, Access) \ Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_SCREEN_BUFFER_MAGIC) #define ConioUnlockScreenBuffer(Buff) \ Win32CsrUnlockObject((Object_t *) Buff) +PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); +VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); +NTSTATUS FASTCALL ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, + CHAR *Buffer, DWORD Length, BOOL Attrib); +NTSTATUS FASTCALL CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer); +VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); + +CSR_API(CsrWriteConsole); +CSR_API(CsrGetScreenBufferInfo); +CSR_API(CsrSetCursor); +CSR_API(CsrWriteConsoleOutputChar); +CSR_API(CsrFillOutputChar); +CSR_API(CsrWriteConsoleOutputAttrib); +CSR_API(CsrFillOutputAttrib); +CSR_API(CsrGetCursorInfo); +CSR_API(CsrSetCursorInfo); +CSR_API(CsrSetTextAttrib); +CSR_API(CsrCreateScreenBuffer); +CSR_API(CsrSetScreenBuffer); +CSR_API(CsrWriteConsoleOutput); +CSR_API(CsrScrollConsoleScreenBuffer); +CSR_API(CsrReadConsoleOutputChar); +CSR_API(CsrReadConsoleOutputAttrib); +CSR_API(CsrReadConsoleOutput); +CSR_API(CsrSetScreenBufferSize); /* alias.c */ VOID IntDeleteAllAliases(struct tagALIAS_HEADER *RootHeader); diff --git a/reactos/subsystems/win32/csrss/win32csr/conoutput.c b/reactos/subsystems/win32/csrss/win32csr/conoutput.c new file mode 100644 index 00000000000..b401ca23abd --- /dev/null +++ b/reactos/subsystems/win32/csrss/win32csr/conoutput.c @@ -0,0 +1,1505 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* GLOBALS *******************************************************************/ + +#define ConioInitRect(Rect, top, left, bottom, right) \ + ((Rect)->Top) = top; \ + ((Rect)->Left) = left; \ + ((Rect)->Bottom) = bottom; \ + ((Rect)->Right) = right + +#define ConioIsRectEmpty(Rect) \ + (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) + +#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) + +/* FUNCTIONS *****************************************************************/ + +PBYTE FASTCALL +ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y) +{ + return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; +} + +static VOID FASTCALL +ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff) +{ + PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); + UINT Pos; + + for (Pos = 0; Pos < Buff->MaxX; Pos++) + { + /* Fill the cell */ + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; + } +} + +NTSTATUS FASTCALL +CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, + PCSRSS_SCREEN_BUFFER Buffer) +{ + DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); + + Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; + Buffer->Header.Console = Console; + Buffer->Header.HandleCount = 0; + Buffer->ShowX = 0; + Buffer->ShowY = 0; + Buffer->VirtualY = 0; + Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); + if (NULL == Buffer->Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + ConioInitScreenBuffer(Console, Buffer); + /* initialize buffer to be empty with default attributes */ + for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) + { + ClearLineBuffer(Buffer); + } + Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + Buffer->CurrentX = 0; + Buffer->CurrentY = 0; + + InsertHeadList(&Console->BufferList, &Buffer->ListEntry); + return STATUS_SUCCESS; +} + +static VOID FASTCALL +ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines) +{ + /* If we hit bottom, slide the viewable screen */ + if (++Buff->CurrentY == Buff->MaxY) + { + Buff->CurrentY--; + if (++Buff->VirtualY == Buff->MaxY) + { + Buff->VirtualY = 0; + } + (*ScrolledLines)++; + ClearLineBuffer(Buff); + if (UpdateRect->Top != 0) + { + UpdateRect->Top--; + } + } + UpdateRect->Left = 0; + UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Bottom = Buff->CurrentY; +} + +NTSTATUS FASTCALL +ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, + CHAR *Buffer, DWORD Length, BOOL Attrib) +{ + UINT i; + PBYTE Ptr; + SMALL_RECT UpdateRect; + LONG CursorStartX, CursorStartY; + UINT ScrolledLines; + + CursorStartX = Buff->CurrentX; + CursorStartY = Buff->CurrentY; + UpdateRect.Left = Buff->MaxX; + UpdateRect.Top = Buff->CurrentY; + UpdateRect.Right = -1; + UpdateRect.Bottom = Buff->CurrentY; + ScrolledLines = 0; + + for (i = 0; i < Length; i++) + { + if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) + { + /* --- LF --- */ + if (Buffer[i] == '\n') + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + continue; + } + /* --- BS --- */ + else if (Buffer[i] == '\b') + { + /* Only handle BS if we're not on the first pos of the first line */ + if (0 != Buff->CurrentX || 0 != Buff->CurrentY) + { + if (0 == Buff->CurrentX) + { + /* slide virtual position up */ + Buff->CurrentX = Buff->MaxX - 1; + Buff->CurrentY--; + UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); + } + else + { + Buff->CurrentX--; + } + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = ' '; + Ptr[1] = Buff->DefaultAttrib; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + } + continue; + } + /* --- CR --- */ + else if (Buffer[i] == '\r') + { + Buff->CurrentX = 0; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + continue; + } + /* --- TAB --- */ + else if (Buffer[i] == '\t') + { + UINT EndX; + + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + EndX = (Buff->CurrentX + 8) & ~7; + if (EndX > Buff->MaxX) + { + EndX = Buff->MaxX; + } + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + while (Buff->CurrentX < EndX) + { + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; + Buff->CurrentX++; + } + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); + if (Buff->CurrentX == Buff->MaxX) + { + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + } + else + { + Buff->CurrentX--; + } + } + continue; + } + } + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = Buffer[i]; + if (Attrib) + { + Ptr[1] = Buff->DefaultAttrib; + } + Buff->CurrentX++; + if (Buff->CurrentX == Buff->MaxX) + { + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + } + else + { + Buff->CurrentX = CursorStartX; + } + } + } + + if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) + { + ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, + Buffer, Length); + } + + return STATUS_SUCCESS; +} + +__inline BOOLEAN ConioGetIntersection( + SMALL_RECT *Intersection, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) +{ + if (ConioIsRectEmpty(Rect1) || + (ConioIsRectEmpty(Rect2)) || + (Rect1->Top > Rect2->Bottom) || + (Rect1->Left > Rect2->Right) || + (Rect1->Bottom < Rect2->Top) || + (Rect1->Right < Rect2->Left)) + { + /* The rectangles do not intersect */ + ConioInitRect(Intersection, 0, -1, 0, -1); + return FALSE; + } + + ConioInitRect(Intersection, + max(Rect1->Top, Rect2->Top), + max(Rect1->Left, Rect2->Left), + min(Rect1->Bottom, Rect2->Bottom), + min(Rect1->Right, Rect2->Right)); + + return TRUE; +} + +__inline BOOLEAN ConioGetUnion( + SMALL_RECT *Union, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) +{ + if (ConioIsRectEmpty(Rect1)) + { + if (ConioIsRectEmpty(Rect2)) + { + ConioInitRect(Union, 0, -1, 0, -1); + return FALSE; + } + else + { + *Union = *Rect2; + } + } + else if (ConioIsRectEmpty(Rect2)) + { + *Union = *Rect1; + } + else + { + ConioInitRect(Union, + min(Rect1->Top, Rect2->Top), + min(Rect1->Left, Rect2->Left), + max(Rect1->Bottom, Rect2->Bottom), + max(Rect1->Right, Rect2->Right)); + } + + return TRUE; +} + +/* Move from one rectangle to another. We must be careful about the order that + * this is done, to avoid overwriting parts of the source before they are moved. */ +static VOID FASTCALL +ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, + SMALL_RECT *SrcRegion, + SMALL_RECT *DstRegion, + SMALL_RECT *ClipRegion, + WORD Fill) +{ + int Width = ConioRectWidth(SrcRegion); + int Height = ConioRectHeight(SrcRegion); + int SX, SY; + int DX, DY; + int XDelta, YDelta; + int i, j; + + SY = SrcRegion->Top; + DY = DstRegion->Top; + YDelta = 1; + if (SY < DY) + { + /* Moving down: work from bottom up */ + SY = SrcRegion->Bottom; + DY = DstRegion->Bottom; + YDelta = -1; + } + for (i = 0; i < Height; i++) + { + PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); + PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); + + SX = SrcRegion->Left; + DX = DstRegion->Left; + XDelta = 1; + if (SX < DX) + { + /* Moving right: work from right to left */ + SX = SrcRegion->Right; + DX = DstRegion->Right; + XDelta = -1; + } + for (j = 0; j < Width; j++) + { + WORD Cell = SRow[SX]; + if (SX >= ClipRegion->Left && SX <= ClipRegion->Right + && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) + { + SRow[SX] = Fill; + } + if (DX >= ClipRegion->Left && DX <= ClipRegion->Right + && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) + { + DRow[DX] = Cell; + } + SX += XDelta; + DX += XDelta; + } + SY += YDelta; + DY += YDelta; + } +} + +CSR_API(CsrWriteConsole) +{ + NTSTATUS Status; + PCHAR Buffer; + PCSRSS_SCREEN_BUFFER Buff; + PCSRSS_CONSOLE Console; + DWORD Written = 0; + ULONG Length; + ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + DPRINT("CsrWriteConsole\n"); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + if (Console->UnpauseEvent) + { + Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, + ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, + SYNCHRONIZE, 0, 0); + ConioUnlockScreenBuffer(Buff); + return NT_SUCCESS(Status) ? STATUS_PENDING : Status; + } + + if(Request->Data.WriteConsoleRequest.Unicode) + { + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + NULL, 0, NULL, NULL); + Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (Buffer) + { + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + Buffer, Length, NULL, NULL); + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; + } + + if (Buffer) + { + if (NT_SUCCESS(Status)) + { + Status = ConioWriteConsole(Console, Buff, Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); + if (NT_SUCCESS(Status)) + { + Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; + } + } + if (Request->Data.WriteConsoleRequest.Unicode) + { + RtlFreeHeap(GetProcessHeap(), 0, Buffer); + } + } + ConioUnlockScreenBuffer(Buff); + + Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; + + return Status; +} + +VOID WINAPI +ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) +{ + PCSRSS_CONSOLE Console = Buffer->Header.Console; + + RemoveEntryList(&Buffer->ListEntry); + if (Buffer == Console->ActiveBuffer) + { + /* Deleted active buffer; switch to most recently created */ + Console->ActiveBuffer = NULL; + if (!IsListEmpty(&Console->BufferList)) + { + Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry); + ConioDrawConsole(Console); + } + } + + HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); +} + +VOID FASTCALL +ConioDrawConsole(PCSRSS_CONSOLE Console) +{ + SMALL_RECT Region; + + ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); + + ConioDrawRegion(Console, &Region); +} + +CSR_API(CsrGetScreenBufferInfo) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PCONSOLE_SCREEN_BUFFER_INFO pInfo; + + DPRINT("CsrGetScreenBufferInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + pInfo = &Request->Data.ScreenBufferInfoRequest.Info; + pInfo->dwSize.X = Buff->MaxX; + pInfo->dwSize.Y = Buff->MaxY; + pInfo->dwCursorPosition.X = Buff->CurrentX; + pInfo->dwCursorPosition.Y = Buff->CurrentY; + pInfo->wAttributes = Buff->DefaultAttrib; + pInfo->srWindow.Left = Buff->ShowX; + pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; + pInfo->srWindow.Top = Buff->ShowY; + pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; + pInfo->dwMaximumWindowSize.X = Buff->MaxX; + pInfo->dwMaximumWindowSize.Y = Buff->MaxY; + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetCursor) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + LONG OldCursorX, OldCursorY; + LONG NewCursorX, NewCursorY; + + DPRINT("CsrSetCursor\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + NewCursorX = Request->Data.SetCursorRequest.Position.X; + NewCursorY = Request->Data.SetCursorRequest.Position.Y; + if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || + NewCursorY < 0 || NewCursorY >= Buff->MaxY) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_INVALID_PARAMETER; + } + OldCursorX = Buff->CurrentX; + OldCursorY = Buff->CurrentY; + Buff->CurrentX = NewCursorX; + Buff->CurrentY = NewCursorY; + if (Buff == Console->ActiveBuffer) + { + if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +static VOID FASTCALL +ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length) +{ + if (Buff->MaxX <= Start->X + Length) + { + UpdateRect->Left = 0; + } + else + { + UpdateRect->Left = Start->X; + } + if (Buff->MaxX <= Start->X + Length) + { + UpdateRect->Right = Buff->MaxX - 1; + } + else + { + UpdateRect->Right = Start->X + Length - 1; + } + UpdateRect->Top = Start->Y; + UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; + if (Buff->MaxY <= UpdateRect->Bottom) + { + UpdateRect->Bottom = Buff->MaxY - 1; + } +} + +CSR_API(CsrWriteConsoleOutputChar) +{ + NTSTATUS Status; + PCHAR String, tmpString = NULL; + PBYTE Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, CharSize, Written = 0; + SMALL_RECT UpdateRect; + + DPRINT("CsrWriteConsoleOutputChar\n"); + + CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (NT_SUCCESS(Status)) + { + Console = Buff->Header.Console; + if(Request->Data.WriteConsoleOutputCharRequest.Unicode) + { + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + NULL, 0, NULL, NULL); + tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (String) + { + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + String, Length, NULL, NULL); + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; + } + + if (String) + { + if (NT_SUCCESS(Status)) + { + X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputCharRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + while (Length--) + { + *Buffer = *String++; + Written++; + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; + } + } + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, + Request->Data.WriteConsoleOutputCharRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; + Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + + } + if (Request->Data.WriteConsoleRequest.Unicode) + { + RtlFreeHeap(GetProcessHeap(), 0, tmpString); + } + } + ConioUnlockScreenBuffer(Buff); + } + Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; + return Status; +} + +CSR_API(CsrFillOutputChar) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, Written = 0; + CHAR Char; + PBYTE Buffer; + SMALL_RECT UpdateRect; + + DPRINT("CsrFillOutputChar\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.FillOutputRequest.Position.X; + Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + if(Request->Data.FillOutputRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); + else + Char = Request->Data.FillOutputRequest.Char.AsciiChar; + Length = Request->Data.FillOutputRequest.Length; + while (Length--) + { + *Buffer = Char; + Buffer += 2; + Written++; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, + Request->Data.FillOutputRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + ConioUnlockScreenBuffer(Buff); + Length = Request->Data.FillOutputRequest.Length; + Request->Data.FillOutputRequest.NrCharactersWritten = Length; + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleOutputAttrib) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + PWORD Attribute; + int X, Y, Length; + NTSTATUS Status; + SMALL_RECT UpdateRect; + + DPRINT("CsrWriteConsoleOutputAttrib\n"); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputAttribRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; + Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; + while (Length--) + { + *Buffer = (UCHAR)(*Attribute++); + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, + Request->Data.WriteConsoleOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrFillOutputAttrib) +{ + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + NTSTATUS Status; + int X, Y, Length; + UCHAR Attr; + SMALL_RECT UpdateRect; + PCSRSS_CONSOLE Console; + + DPRINT("CsrFillOutputAttrib\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.FillOutputAttribRequest.Coord.X; + Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.FillOutputAttribRequest.Length; + Attr = Request->Data.FillOutputAttribRequest.Attribute; + Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; + while (Length--) + { + *Buffer = Attr; + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, + Request->Data.FillOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrGetCursorInfo) +{ + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + + DPRINT("CsrGetCursorInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; + Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetCursorInfo) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Size; + BOOL Visible; + NTSTATUS Status; + + DPRINT("CsrSetCursorInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Size = Request->Data.SetCursorInfoRequest.Info.dwSize; + Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; + if (Size < 1) + { + Size = 1; + } + if (100 < Size) + { + Size = 100; + } + + if (Size != Buff->CursorInfo.dwSize + || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) + { + Buff->CursorInfo.dwSize = Size; + Buff->CursorInfo.bVisible = Visible; + + if (! ConioSetCursorInfo(Console, Buff)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetTextAttrib) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetTextAttrib\n"); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; + if (Buff == Console->ActiveBuffer) + { + if (! ConioUpdateScreenInfo(Console, Buff)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrCreateScreenBuffer) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + + DPRINT("CsrCreateScreenBuffer\n"); + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + + if (Buff != NULL) + { + if (Console->ActiveBuffer) + { + Buff->MaxX = Console->ActiveBuffer->MaxX; + Buff->MaxY = Console->ActiveBuffer->MaxY; + Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; + Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; + } + else + { + Buff->CursorInfo.bVisible = TRUE; + Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + } + + if (Buff->MaxX == 0) + { + Buff->MaxX = 80; + } + + if (Buff->MaxY == 0) + { + Buff->MaxY = 25; + } + + Status = CsrInitConsoleScreenBuffer(Console, Buff); + if (NT_SUCCESS(Status)) + { + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.CreateScreenBufferRequest.OutputHandle, + &Buff->Header, + Request->Data.CreateScreenBufferRequest.Access, + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); + } + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + + ConioUnlockConsole(Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; +} + +CSR_API(CsrSetScreenBuffer) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetScreenBuffer\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + if (Buff == Console->ActiveBuffer) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + /* If old buffer has no handles, it's now unreferenced */ + if (Console->ActiveBuffer->Header.HandleCount == 0) + { + ConioDeleteScreenBuffer(Console->ActiveBuffer); + } + /* tie console to new buffer */ + Console->ActiveBuffer = Buff; + /* Redraw the console */ + ConioDrawConsole(Console); + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleOutput) +{ + SHORT i, X, Y, SizeX, SizeY; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + CHAR_INFO* CurCharInfo; + SMALL_RECT WriteRegion; + CHAR_INFO* CharInfo; + COORD BufferCoord; + COORD BufferSize; + NTSTATUS Status; + PBYTE Ptr; + DWORD PSize; + + DPRINT("CsrWriteConsoleOutput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; + PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); + BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; + CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; + if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || + (((ULONG_PTR)CharInfo + PSize) > + ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; + } + WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; + + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); + WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + WriteRegion.Right = WriteRegion.Left + SizeX - 1; + + /* Make sure WriteRegion is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) + { + ConioUnlockScreenBuffer(Buff); + + /* It is okay to have a WriteRegion completely outside the screen buffer. + No data is written then. */ + return STATUS_SUCCESS; + } + + for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) + { + CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; + Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); + for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) + { + CHAR AsciiChar; + if (Request->Data.WriteConsoleOutputRequest.Unicode) + { + ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); + } + else + { + AsciiChar = CurCharInfo->Char.AsciiChar; + } + *Ptr++ = AsciiChar; + *Ptr++ = CurCharInfo->Attributes; + CurCharInfo++; + } + } + + ConioDrawRegion(Console, &WriteRegion); + + ConioUnlockScreenBuffer(Buff); + + Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; + + return STATUS_SUCCESS; +} + +CSR_API(CsrScrollConsoleScreenBuffer) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + SMALL_RECT SrcRegion; + SMALL_RECT DstRegion; + SMALL_RECT UpdateRegion; + SMALL_RECT ScrollRectangle; + SMALL_RECT ClipRectangle; + NTSTATUS Status; + HANDLE ConsoleHandle; + BOOLEAN UseClipRectangle; + COORD DestinationOrigin; + CHAR_INFO Fill; + CHAR FillChar; + + DPRINT("CsrScrollConsoleScreenBuffer\n"); + + ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; + UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; + DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; + Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; + + /* Make sure source rectangle is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + /* If the source was clipped on the left or top, adjust the destination accordingly */ + if (ScrollRectangle.Left < 0) + { + DestinationOrigin.X -= ScrollRectangle.Left; + } + if (ScrollRectangle.Top < 0) + { + DestinationOrigin.Y -= ScrollRectangle.Top; + } + + if (UseClipRectangle) + { + ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; + if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + } + else + { + ClipRectangle = ScreenBuffer; + } + + ConioInitRect(&DstRegion, + DestinationOrigin.Y, + DestinationOrigin.X, + DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, + DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); + + if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); + else + FillChar = Fill.Char.AsciiChar; + + ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); + + if (Buff == Console->ActiveBuffer) + { + ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); + if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) + { + /* Draw update region */ + ConioDrawRegion(Console, &UpdateRegion); + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrReadConsoleOutputChar) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PCHAR ReadBuffer; + DWORD i; + ULONG CharSize; + CHAR Char; + + DPRINT("CsrReadConsoleOutputChar\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; + + CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + + for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) + { + Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; + + if(Request->Data.ReadConsoleOutputCharRequest.Unicode) + { + ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); + ReadBuffer += sizeof(WCHAR); + } + else + *(ReadBuffer++) = Char; + + Xpos++; + + if (Xpos == Buff->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->MaxY) + { + Ypos = 0; + } + } + } + + *ReadBuffer = 0; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; + if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + } + + return STATUS_SUCCESS; +} + + +CSR_API(CsrReadConsoleOutputAttrib) +{ + NTSTATUS Status; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PWORD ReadBuffer; + DWORD i; + DWORD CurrentLength; + + DPRINT("CsrReadConsoleOutputAttrib\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + + for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) + { + *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; + + ReadBuffer++; + Xpos++; + + if (Xpos == Buff->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->MaxY) + { + Ypos = 0; + } + } + } + + *ReadBuffer = 0; + + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); + if (CurrentLength > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = CurrentLength; + Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); + } + + return STATUS_SUCCESS; +} + +CSR_API(CsrReadConsoleOutput) +{ + PCHAR_INFO CharInfo; + PCHAR_INFO CurCharInfo; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Size; + DWORD Length; + DWORD SizeX, SizeY; + NTSTATUS Status; + COORD BufferSize; + COORD BufferCoord; + SMALL_RECT ReadRegion; + SMALL_RECT ScreenRect; + DWORD i; + PBYTE Ptr; + LONG X, Y; + UINT CodePage; + + DPRINT("CsrReadConsoleOutput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; + ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; + BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; + BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; + Length = BufferSize.X * BufferSize.Y; + Size = Length * sizeof(CHAR_INFO); + + /* FIXME: Is this correct? */ + CodePage = ProcessData->Console->OutputCodePage; + + if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) + || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; + } + + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); + ReadRegion.Bottom = ReadRegion.Top + SizeY; + ReadRegion.Right = ReadRegion.Left + SizeX; + + ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); + if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) + { + CurCharInfo = CharInfo + (i * BufferSize.X); + + Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); + for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) + { + if (Request->Data.ReadConsoleOutputRequest.Unicode) + { + MultiByteToWideChar(CodePage, 0, + (PCHAR)Ptr++, 1, + &CurCharInfo->Char.UnicodeChar, 1); + } + else + { + CurCharInfo->Char.AsciiChar = *Ptr++; + } + CurCharInfo->Attributes = *Ptr++; + ++CurCharInfo; + } + } + + ConioUnlockScreenBuffer(Buff); + + Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetScreenBufferSize) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); + ConioUnlockScreenBuffer(Buff); + + return Status; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/console.c b/reactos/subsystems/win32/csrss/win32csr/console.c new file mode 100644 index 00000000000..8b6d4d7e6f4 --- /dev/null +++ b/reactos/subsystems/win32/csrss/win32csr/console.c @@ -0,0 +1,851 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS FASTCALL +ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) +{ + PCSRSS_CONSOLE ProcessConsole; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + ProcessConsole = ProcessData->Console; + + if (!ProcessConsole) + { + *Console = NULL; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + + InterlockedIncrement(&ProcessConsole->ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + EnterCriticalSection(&(ProcessConsole->Lock)); + *Console = ProcessConsole; + + return STATUS_SUCCESS; +} + +VOID FASTCALL +ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout) +{ + HANDLE Thread; + + DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); + + if (ProcessData->CtrlDispatcher) + { + + Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, + (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, + UlongToPtr(Event), 0, NULL); + if (NULL == Thread) + { + DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); + return; + } + WaitForSingleObject(Thread, Timeout); + CloseHandle(Thread); + } +} + +VOID FASTCALL +ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData) +{ + ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); +} + +static NTSTATUS WINAPI +CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) +{ + NTSTATUS Status; + SECURITY_ATTRIBUTES SecurityAttributes; + PCSRSS_SCREEN_BUFFER NewBuffer; + BOOL GuiMode; + + Console->Title.MaximumLength = Console->Title.Length = 0; + Console->Title.Buffer = NULL; + + //FIXME + RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); + + Console->ReferenceCount = 0; + Console->WaitingChars = 0; + Console->WaitingLines = 0; + Console->EchoCount = 0; + Console->Header.Type = CONIO_CONSOLE_MAGIC; + Console->Header.Console = Console; + Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; + Console->EarlyReturn = FALSE; + InitializeListHead(&Console->BufferList); + Console->ActiveBuffer = NULL; + InitializeListHead(&Console->InputEvents); + Console->CodePage = GetOEMCP(); + Console->OutputCodePage = GetOEMCP(); + + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = TRUE; + + Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); + if (NULL == Console->ActiveEvent) + { + RtlFreeUnicodeString(&Console->Title); + return STATUS_UNSUCCESSFUL; + } + Console->PrivateData = NULL; + InitializeCriticalSection(&Console->Lock); + + GuiMode = DtbgIsDesktopVisible(); + + /* allocate console screen buffer */ + NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + if (NULL == NewBuffer) + { + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + return STATUS_INSUFFICIENT_RESOURCES; + } + /* init screen buffer with defaults */ + NewBuffer->CursorInfo.bVisible = TRUE; + NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + /* make console active, and insert into console list */ + Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; + + if (! GuiMode) + { + Status = TuiInitConsole(Console); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); + GuiMode = TRUE; + } + } + if (GuiMode) + { + Status = GuiInitConsole(Console, Visible); + if (! NT_SUCCESS(Status)) + { + HeapFree(Win32CsrApiHeap,0, NewBuffer); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + DPRINT1("GuiInitConsole: failed\n"); + return Status; + } + } + + Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); + if (! NT_SUCCESS(Status)) + { + ConioCleanupConsole(Console); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + HeapFree(Win32CsrApiHeap, 0, NewBuffer); + DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); + return Status; + } + + /* copy buffer contents to screen */ + ConioDrawConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrAllocConsole) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN NewConsole = FALSE; + + DPRINT("CsrAllocConsole\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (ProcessData->Console) + { + DPRINT1("Process already has a console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_PARAMETER; + } + + /* If we don't need a console, then get out of here */ + if (!Request->Data.AllocConsoleRequest.ConsoleNeeded) + { + DPRINT("No console needed\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; + } + + /* If we already have one, then don't create a new one... */ + if (!Request->Data.AllocConsoleRequest.Console || + Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) + { + /* Allocate a console structure */ + NewConsole = TRUE; + Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE)); + if (NULL == Console) + { + DPRINT1("Not enough memory for console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_NO_MEMORY; + } + /* initialize list head */ + InitializeListHead(&Console->ProcessList); + /* insert process data required for GUI initialization */ + InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); + /* Initialize the Console */ + Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Console init failed\n"); + HeapFree(Win32CsrApiHeap, 0, Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + } + else + { + /* Reuse our current console */ + Console = Request->Data.AllocConsoleRequest.Console; + } + + /* Set the Process Console */ + ProcessData->Console = Console; + + /* Return it to the caller */ + Request->Data.AllocConsoleRequest.Console = Console; + + /* Add a reference count because the process is tied to the console */ + _InterlockedIncrement(&Console->ReferenceCount); + + if (NewConsole || !ProcessData->bInheritHandles) + { + /* Insert the Objects */ + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.AllocConsoleRequest.InputHandle, + &Console->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to insert object\n"); + ConioDeleteConsole((Object_t *) Console); + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.AllocConsoleRequest.OutputHandle, + &Console->ActiveBuffer->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to insert object\n"); + ConioDeleteConsole((Object_t *) Console); + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.InputHandle); + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + } + + /* Duplicate the Event */ + if (!DuplicateHandle(GetCurrentProcess(), + ProcessData->Console->ActiveEvent, + ProcessData->Process, + &ProcessData->ConsoleEvent, + EVENT_ALL_ACCESS, + FALSE, + 0)) + { + DPRINT1("DuplicateHandle() failed: %d\n", GetLastError); + ConioDeleteConsole((Object_t *) Console); + if (NewConsole || !ProcessData->bInheritHandles) + { + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.OutputHandle); + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.InputHandle); + } + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + + /* Set the Ctrl Dispatcher */ + ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher; + DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); + + if (!NewConsole) + { + /* Insert into the list if it has not been added */ + InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); + } + + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; +} + +CSR_API(CsrFreeConsole) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + return Win32CsrReleaseConsole(ProcessData); +} + +VOID WINAPI +ConioDeleteConsole(Object_t *Object) +{ + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; + ConsoleInput *Event; + + DPRINT("ConioDeleteConsole\n"); + + /* Drain input event queue */ + while (Console->InputEvents.Flink != &Console->InputEvents) + { + Event = (ConsoleInput *) Console->InputEvents.Flink; + Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; + Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; + HeapFree(Win32CsrApiHeap, 0, Event); + } + + ConioCleanupConsole(Console); + ConioDeleteScreenBuffer(Console->ActiveBuffer); + if (!IsListEmpty(&Console->BufferList)) + { + DPRINT1("BUG: screen buffer list not empty\n"); + } + + CloseHandle(Console->ActiveEvent); + if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); + DeleteCriticalSection(&Console->Lock); + RtlFreeUnicodeString(&Console->Title); + IntDeleteAllAliases(Console->Aliases); + HeapFree(Win32CsrApiHeap, 0, Console); +} + +VOID WINAPI +CsrInitConsoleSupport(VOID) +{ + DPRINT("CSR: CsrInitConsoleSupport()\n"); + + /* Should call LoadKeyboardLayout */ +} + +VOID FASTCALL +ConioPause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags |= Flags; + if (!Console->UnpauseEvent) + Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +VOID FASTCALL +ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags &= ~Flags; + if (Console->PauseFlags == 0 && Console->UnpauseEvent) + { + SetEvent(Console->UnpauseEvent); + CloseHandle(Console->UnpauseEvent); + Console->UnpauseEvent = NULL; + } +} + +CSR_API(CsrSetConsoleMode) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetConsoleMode\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, + Request->Data.SetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_WRITE, 0); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Buff = (PCSRSS_SCREEN_BUFFER)Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + { + Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; + } + else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) + { + Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + Win32CsrUnlockObject((Object_t *)Console); + + return Status; +} + +CSR_API(CsrGetConsoleMode) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ + + DPRINT("CsrGetConsoleMode\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_READ, 0); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Status = STATUS_SUCCESS; + Buff = (PCSRSS_SCREEN_BUFFER) Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + { + Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; + } + else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) + { + Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + Win32CsrUnlockObject((Object_t *)Console); + return Status; +} + +CSR_API(CsrSetTitle) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PWCHAR Buffer; + + DPRINT("CsrSetTitle\n"); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + + Request->Data.SetTitleRequest.Length) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if(NT_SUCCESS(Status)) + { + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); + if (Buffer) + { + /* copy title to console */ + RtlFreeUnicodeString(&Console->Title); + Console->Title.Buffer = Buffer; + Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; + memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); + if (! ConioChangeTitle(Console)) + { + Status = STATUS_UNSUCCESSFUL; + } + else + { + Status = STATUS_SUCCESS; + } + } + else + { + Status = STATUS_NO_MEMORY; + } + ConioUnlockConsole(Console); + } + + return Status; +} + +CSR_API(CsrGetTitle) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Length; + + DPRINT("CsrGetTitle\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Can't get console\n"); + return Status; + } + + /* Copy title of the console to the user title buffer */ + RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); + Request->Data.GetTitleRequest.Length = Console->Title.Length; + memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, + Console->Title.Length); + Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; + + ConioUnlockConsole(Console); + + if (Length > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = Length; + Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); + } + return STATUS_SUCCESS; +} + +/********************************************************************** + * HardwareStateProperty + * + * DESCRIPTION + * Set/Get the value of the HardwareState and switch + * between direct video buffer ouput and GDI windowed + * output. + * ARGUMENTS + * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE + * object. We use the same object to Request. + * NOTE + * ConsoleHwState has the correct size to be compatible + * with NT's, but values are not. + */ +static NTSTATUS FASTCALL +SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) +{ + DPRINT1("Console Hardware State: %d\n", ConsoleHwState); + + if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) + ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) + { + if (Console->HardwareState != ConsoleHwState) + { + /* TODO: implement switching from full screen to windowed mode */ + /* TODO: or back; now simply store the hardware state */ + Console->HardwareState = ConsoleHwState; + } + + return STATUS_SUCCESS; + } + + return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ +} + +CSR_API(CsrHardwareStateProperty) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrHardwareStateProperty\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, + Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, + &Console, + GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); + return Status; + } + + switch (Request->Data.ConsoleHardwareStateRequest.SetGet) + { + case CONSOLE_HARDWARE_STATE_GET: + Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState; + break; + + case CONSOLE_HARDWARE_STATE_SET: + DPRINT("Setting console hardware state.\n"); + Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State); + break; + + default: + Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */ + break; + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleWindow) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleWindow\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; + ConioUnlockConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleIcon) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleIcon\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) + { + Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; + } + + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; +} + +CSR_API(CsrGetConsoleOutputCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleOutputCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleOutputCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleOutputCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) + { + Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; + } + + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; +} + +CSR_API(CsrGetProcessList) +{ + PDWORD Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + ULONG nItems = 0; + NTSTATUS Status; + ULONG_PTR Offset; + + DPRINT("CsrGetProcessList\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buffer = Request->Data.GetProcessListRequest.ProcessId; + Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) + || Offset & (sizeof(DWORD) - 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds) + { + *Buffer++ = (DWORD)current->ProcessId; + } + } + + ConioUnlockConsole(Console); + + Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; + return STATUS_SUCCESS; +} + +CSR_API(CsrGenerateCtrlEvent) +{ + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DWORD Group; + NTSTATUS Status; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Group = Request->Data.GenerateCtrlEvent.ProcessGroup; + Status = STATUS_INVALID_PARAMETER; + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (Group == 0 || current->ProcessGroup == Group) + { + ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); + Status = STATUS_SUCCESS; + } + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleSelectionInfo) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO)); + if (Console->Selection.dwFlags != 0) + Request->Data.GetConsoleSelectionInfo.Info = Console->Selection; + ConioUnlockConsole(Console); + } + return Status; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 392dccbf50d..728bd6adea4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -17,7 +17,9 @@ pseh w32csr.h alias.c - conio.c + coninput.c + conoutput.c + console.c desktopbg.c dllmain.c exitros.c From 11f78560e8d14d3b1158d3ee2dee5a2814423676 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 31 May 2010 12:36:40 +0000 Subject: [PATCH 147/292] [win32k] - When processing and deleting timers use a seperate timer lock instead of using the global user lock. svn path=/trunk/; revision=47486 --- .../subsystems/win32/win32k/ntuser/timer.c | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index 4ab3916c8a6..ea3b509da5d 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -31,6 +31,7 @@ static RTL_BITMAP WindowLessTimersBitMap; static PVOID WindowLessTimersBitMapBuffer; static ULONG HintIndex = 0; +ERESOURCE TimerLock; #define IntLockWindowlessTimerBitmap() \ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex) @@ -38,6 +39,19 @@ static ULONG HintIndex = 0; #define IntUnlockWindowlessTimerBitmap() \ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex) +#define TimerEnterExclusive() \ +{ \ + KeEnterCriticalRegion(); \ + ExAcquireResourceExclusiveLite(&TimerLock, TRUE); \ +} + +#define TimerLeave() \ +{ \ + ExReleaseResourceLite(&TimerLock); \ + KeLeaveCriticalRegion(); \ +} + + /* FUNCTIONS *****************************************************************/ static PTIMER @@ -49,6 +63,7 @@ CreateTimer(VOID) if (!FirstpTmr) { + ExInitializeResourceLite(&TimerLock); FirstpTmr = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); if (FirstpTmr) { @@ -96,7 +111,7 @@ FindTimer(PWINDOW_OBJECT Window, { PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr, RetTmr = NULL; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if (!pTmr) break; @@ -116,7 +131,7 @@ FindTimer(PWINDOW_OBJECT Window, pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return RetTmr; } @@ -127,7 +142,7 @@ FindSystemTimer(PMSG pMsg) { PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if (!pTmr) break; @@ -139,7 +154,7 @@ FindSystemTimer(PMSG pMsg) pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return pTmr; } @@ -156,7 +171,7 @@ ValidateTimerCallback(PTHREADINFO pti, if (!pTmr) return FALSE; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if ( (lParam == (LPARAM)pTmr->pfn) && @@ -167,7 +182,7 @@ ValidateTimerCallback(PTHREADINFO pti, pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); if (!pTmr) return FALSE; @@ -320,7 +335,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; - UserEnterExclusive(); + TimerEnterExclusive(); do { @@ -343,7 +358,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - UserLeave(); + TimerLeave(); return Hit; } @@ -360,7 +375,7 @@ ProcessTimers(VOID) if (!pTmr) return; - UserEnterExclusive(); + TimerEnterExclusive(); KeQueryTickCount(&TickCount); Time = MsqCalculateMessageTime(&TickCount); @@ -423,7 +438,7 @@ ProcessTimers(VOID) TimeLast = Time; - UserLeave(); + TimerLeave(); DPRINT("TimerCount = %d\n", TimerCount); } @@ -533,7 +548,7 @@ DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) if ((FirstpTmr == NULL) || (Window == NULL)) return FALSE; - UserEnterExclusive(); + TimerEnterExclusive(); do { @@ -545,7 +560,7 @@ DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - UserLeave(); + TimerLeave(); return TimersRemoved; } @@ -560,7 +575,7 @@ DestroyTimersForThread(PTHREADINFO pti) if (FirstpTmr == NULL) return FALSE; - UserEnterExclusive(); + TimerEnterExclusive(); do { @@ -572,7 +587,7 @@ DestroyTimersForThread(PTHREADINFO pti) pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - UserLeave(); + TimerLeave(); return TimersRemoved; } @@ -683,16 +698,19 @@ NtUserSetTimer TIMERPROC lpTimerFunc ) { + PWINDOW_OBJECT Window; DECLARE_RETURN(UINT_PTR); DPRINT("Enter NtUserSetTimer\n"); UserEnterExclusive(); + Window = UserGetWindowObject(hWnd); + UserLeave(); - RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_TIFROMWND)); + RETURN(IntSetTimer(Window, nIDEvent, uElapse, lpTimerFunc, TMRF_TIFROMWND)); CLEANUP: DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_); - UserLeave(); + END_CLEANUP; } @@ -710,14 +728,13 @@ NtUserKillTimer DPRINT("Enter NtUserKillTimer\n"); UserEnterExclusive(); - Window = UserGetWindowObject(hWnd); + UserLeave(); RETURN(IntKillTimer(Window, uIDEvent, FALSE)); CLEANUP: DPRINT("Leave NtUserKillTimer, ret=%i\n", _ret_); - UserLeave(); END_CLEANUP; } @@ -734,14 +751,12 @@ NtUserSetSystemTimer( DECLARE_RETURN(UINT_PTR); DPRINT("Enter NtUserSetSystemTimer\n"); - UserEnterExclusive(); // This is wrong, lpTimerFunc is NULL! RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM)); CLEANUP: DPRINT("Leave NtUserSetSystemTimer, ret=%i\n", _ret_); - UserLeave(); END_CLEANUP; } From 98ca38a88cbfcce0919a27511da9715c17c49a02 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Mon, 31 May 2010 12:52:16 +0000 Subject: [PATCH 148/292] [NTOS] Re-enable the APC debug check in the system call exit code that somehow got removed in 46247. [NTOS] Use an inline for emitting the iret instruction in C code for portability. [NTOS] Simplify the MSC assembly in KiSwitchToBootStack. svn path=/trunk/; revision=47487 --- reactos/ntoskrnl/include/internal/i386/ke.h | 27 +++++++++++++++++++-- reactos/ntoskrnl/include/internal/trap_x.h | 15 ++++++------ reactos/ntoskrnl/ke/i386/traphdlr.c | 2 +- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 701688ead1f..dda0cf88eb8 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -774,8 +774,7 @@ KiSwitchToBootStack(IN ULONG_PTR InitialStack) VOID NTAPI KiSystemStartupBootStack(VOID); __asm { - mov ecx, InitialStack - mov esp, ecx + mov esp, InitialStack sub esp, (NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH) push (CR0_EM | CR0_TS | CR0_MP) jmp KiSystemStartupBootStack @@ -785,6 +784,30 @@ KiSwitchToBootStack(IN ULONG_PTR InitialStack) #endif } +// +// Emits the iret instruction for C code +// +DECLSPEC_NORETURN +VOID +FORCEINLINE +KiIret(VOID) +{ +#if defined(__GNUC__) + __asm__ __volatile__ + ( + "iret\n" + ); +#elif defined(_MSC_VER) + __asm + { + iret + } +#else +#error Unsupported compiler +#endif + UNREACHABLE; +} + // // Normally this is done by the HAL, but on x86 as an optimization, the kernel // initiates the end by calling back into the HAL and exiting the trap here. diff --git a/reactos/ntoskrnl/include/internal/trap_x.h b/reactos/ntoskrnl/include/internal/trap_x.h index 3da69917d70..0d61dd6f78b 100644 --- a/reactos/ntoskrnl/include/internal/trap_x.h +++ b/reactos/ntoskrnl/include/internal/trap_x.h @@ -8,7 +8,7 @@ #pragma once -//#define TRAP_DEBUG 1 +#define TRAP_DEBUG 0 // // Unreachable code hint for GCC 4.5.x, older GCC versions, and MSVC @@ -81,7 +81,7 @@ KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame) DbgPrint("V86Gs: %x\n", TrapFrame->V86Gs); } -#ifdef TRAP_DEBUG +#if TRAP_DEBUG VOID FORCEINLINE KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame) @@ -168,7 +168,7 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall, 0, 0); } -#if 0 + /* Make sure we're not attached and that APCs are not disabled */ if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) || (KeGetCurrentThread()->CombinedApcDisable != 0)) @@ -180,7 +180,6 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall, KeGetCurrentThread()->CombinedApcDisable, 0); } -#endif } } #else @@ -200,9 +199,11 @@ DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame); typedef +DECLSPEC_NORETURN VOID -(FASTCALL -*PFAST_SYSTEM_CALL_EXIT)(IN PKTRAP_FRAME TrapFrame); +(FASTCALL *PFAST_SYSTEM_CALL_EXIT)( + IN PKTRAP_FRAME TrapFrame +); extern PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler; @@ -222,7 +223,7 @@ KiExitV86Trap(IN PKTRAP_FRAME TrapFrame) while (TRUE) { /* Return if this isn't V86 mode anymore */ - if (!(TrapFrame->EFlags & EFLAGS_V86_MASK)) KiEoiHelper(TrapFrame);; + if (!(TrapFrame->EFlags & EFLAGS_V86_MASK)) KiEoiHelper(TrapFrame); /* Turn off the alerted state for kernel mode */ Thread->Alerted[KernelMode] = FALSE; diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 8c535103123..7e960432bd2 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -547,7 +547,7 @@ KiTrap02(VOID) // // Handled, return from interrupt // - __asm__ __volatile__ ("iret\n"); + KiIret(); } // From 5168fe0e809e763537d9e0c9492e79f3493f4af5 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 13:45:29 +0000 Subject: [PATCH 149/292] [MSCONFIG] Add header guards. They are not neccessary in this case, but better to have them, especially since it uses a compilation unit. svn path=/trunk/; revision=47488 --- reactos/base/applications/msconfig/freeldrpage.h | 5 +++++ reactos/base/applications/msconfig/generalpage.h | 5 +++++ reactos/base/applications/msconfig/srvpage.h | 5 +++++ reactos/base/applications/msconfig/startuppage.h | 5 +++++ reactos/base/applications/msconfig/systempage.h | 5 +++++ reactos/base/applications/msconfig/toolspage.h | 4 ++++ 6 files changed, 29 insertions(+) diff --git a/reactos/base/applications/msconfig/freeldrpage.h b/reactos/base/applications/msconfig/freeldrpage.h index 6e0331b2a4f..23b046b1849 100644 --- a/reactos/base/applications/msconfig/freeldrpage.h +++ b/reactos/base/applications/msconfig/freeldrpage.h @@ -1,3 +1,8 @@ +#ifndef _FREELDRPAGE_H_ +#define _FREELDRPAGE_H_ + extern HWND hFreeLdrPage; INT_PTR CALLBACK FreeLdrPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/reactos/base/applications/msconfig/generalpage.h b/reactos/base/applications/msconfig/generalpage.h index 408c4049dc1..19551866bc4 100644 --- a/reactos/base/applications/msconfig/generalpage.h +++ b/reactos/base/applications/msconfig/generalpage.h @@ -1,3 +1,8 @@ +#ifndef _GENERALPAGE_H_ +#define _GENERALPAGE_H_ + extern HWND hGeneralPage; INT_PTR CALLBACK GeneralPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/reactos/base/applications/msconfig/srvpage.h b/reactos/base/applications/msconfig/srvpage.h index 89c8f3e6112..db51a1b2258 100644 --- a/reactos/base/applications/msconfig/srvpage.h +++ b/reactos/base/applications/msconfig/srvpage.h @@ -1,4 +1,9 @@ +#ifndef _SVRPAGE_H_ +#define _SVRPAGE_H_ + extern HWND hServicesPage; extern HWND hServicesListCtrl; INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/reactos/base/applications/msconfig/startuppage.h b/reactos/base/applications/msconfig/startuppage.h index 9ac644081f0..a016fb320fb 100644 --- a/reactos/base/applications/msconfig/startuppage.h +++ b/reactos/base/applications/msconfig/startuppage.h @@ -1,4 +1,9 @@ +#ifndef _STARTUPPAGE_H_ +#define _STARTUPPAGE_H_ + extern HWND hStartupPage; extern HWND hStartupPageListCtrl; INT_PTR CALLBACK StartupPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/reactos/base/applications/msconfig/systempage.h b/reactos/base/applications/msconfig/systempage.h index d928c77389c..1aa9dcafe8b 100644 --- a/reactos/base/applications/msconfig/systempage.h +++ b/reactos/base/applications/msconfig/systempage.h @@ -1,3 +1,8 @@ +#ifndef _SYSTEMPAGE_H_ +#define _SYSTEMPAGE_H_ + extern HWND hSystemPage; INT_PTR CALLBACK SystemPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/reactos/base/applications/msconfig/toolspage.h b/reactos/base/applications/msconfig/toolspage.h index daa938fec80..4ec159358bf 100644 --- a/reactos/base/applications/msconfig/toolspage.h +++ b/reactos/base/applications/msconfig/toolspage.h @@ -1,5 +1,9 @@ +#ifndef _TOOLSPAGE_H_ +#define _TOOLSPAGE_H_ + extern HWND hToolsPage; extern HWND hToolsListCtrl; INT_PTR CALLBACK ToolsPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +#endif From e5b901a419c333c5eb8126e2c530bb0261c17431 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 13:54:38 +0000 Subject: [PATCH 150/292] [ACPI] - Add some missing NTAPI - Fix AcpiInterfaceConnectVector and AcpiInterfaceDisconnectVector parameters (ACPI_INTERFACE_STANDARD version 1 not version 2) - Patch by Amine Khaldi svn path=/trunk/; revision=47489 --- reactos/drivers/bus/acpi/busmgr/bus.c | 1 + reactos/drivers/bus/acpi/include/acpisys.h | 1 + reactos/drivers/bus/acpi/interface.c | 12 +++++++++--- reactos/drivers/bus/acpi/pnp.c | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/reactos/drivers/bus/acpi/busmgr/bus.c b/reactos/drivers/bus/acpi/busmgr/bus.c index ae04c2cb31b..9860055873a 100644 --- a/reactos/drivers/bus/acpi/busmgr/bus.c +++ b/reactos/drivers/bus/acpi/busmgr/bus.c @@ -457,6 +457,7 @@ acpi_bus_get_perf_flags ( -------------------------------------------------------------------------- */ void +NTAPI acpi_bus_generate_event_dpc(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, diff --git a/reactos/drivers/bus/acpi/include/acpisys.h b/reactos/drivers/bus/acpi/include/acpisys.h index adf2a0c592a..eb171f15546 100644 --- a/reactos/drivers/bus/acpi/include/acpisys.h +++ b/reactos/drivers/bus/acpi/include/acpisys.h @@ -130,6 +130,7 @@ Bus_PnP ( ); NTSTATUS +NTAPI Bus_CompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, diff --git a/reactos/drivers/bus/acpi/interface.c b/reactos/drivers/bus/acpi/interface.c index 59717056484..4e54115c0b4 100644 --- a/reactos/drivers/bus/acpi/interface.c +++ b/reactos/drivers/bus/acpi/interface.c @@ -25,13 +25,14 @@ AcpiInterfaceDereference(PVOID Context) } NTSTATUS +NTAPI AcpiInterfaceConnectVector(PDEVICE_OBJECT Context, ULONG GpeNumber, KINTERRUPT_MODE Mode, BOOLEAN Shareable, PGPE_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, - PVOID *ObjectContext) + PVOID ObjectContext) { UNIMPLEMENTED @@ -39,8 +40,8 @@ AcpiInterfaceConnectVector(PDEVICE_OBJECT Context, } NTSTATUS -AcpiInterfaceDisconnectVector(PDEVICE_OBJECT Context, - PVOID ObjectContext) +NTAPI +AcpiInterfaceDisconnectVector(PVOID ObjectContext) { UNIMPLEMENTED @@ -48,6 +49,7 @@ AcpiInterfaceDisconnectVector(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceEnableEvent(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -57,6 +59,7 @@ AcpiInterfaceEnableEvent(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceDisableEvent(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -66,6 +69,7 @@ AcpiInterfaceDisableEvent(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceClearStatus(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -75,6 +79,7 @@ AcpiInterfaceClearStatus(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceNotificationsRegister(PDEVICE_OBJECT Context, PDEVICE_NOTIFY_CALLBACK NotificationHandler, PVOID NotificationContext) @@ -85,6 +90,7 @@ AcpiInterfaceNotificationsRegister(PDEVICE_OBJECT Context, } VOID +NTAPI AcpiInterfaceNotificationsUnregister(PDEVICE_OBJECT Context, PDEVICE_NOTIFY_CALLBACK NotificationHandler) { diff --git a/reactos/drivers/bus/acpi/pnp.c b/reactos/drivers/bus/acpi/pnp.c index c82a3905023..9259fb9d2a5 100644 --- a/reactos/drivers/bus/acpi/pnp.c +++ b/reactos/drivers/bus/acpi/pnp.c @@ -363,6 +363,7 @@ Bus_SendIrpSynchronously ( } NTSTATUS +NTAPI Bus_CompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, From e9f941b00b4e2fdd8e27a4bafdad35515aad6045 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 13:56:29 +0000 Subject: [PATCH 151/292] [FORMAT] Fix "potentially insecure" usage of non-string-literals in printf. svn path=/trunk/; revision=47490 --- reactos/base/system/format/format.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/base/system/format/format.c b/reactos/base/system/format/format.c index ba9f42b3a05..4eae18bb614 100755 --- a/reactos/base/system/format/format.c +++ b/reactos/base/system/format/format.c @@ -185,7 +185,7 @@ FormatExCallback ( if( *status == FALSE ) { LoadString( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); Error = TRUE; } break; @@ -204,7 +204,7 @@ FormatExCallback ( case STRUCTUREPROGRESS: case CLUSTERSIZETOOSMALL: LoadString( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); return FALSE; } return TRUE; @@ -320,7 +320,7 @@ _tmain(int argc, TCHAR *argv[]) // if( !LoadFMIFSEntryPoints()) { LoadString( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); return -1; } @@ -422,7 +422,7 @@ _tmain(int argc, TCHAR *argv[]) break; } LoadString( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } } @@ -471,7 +471,7 @@ _tmain(int argc, TCHAR *argv[]) ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); } LoadString( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } // @@ -489,7 +489,7 @@ _tmain(int argc, TCHAR *argv[]) #endif if( Error ) return -1; LoadString( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); // // Enable compression if desired @@ -504,7 +504,7 @@ _tmain(int argc, TCHAR *argv[]) #endif LoadString( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } } @@ -514,7 +514,7 @@ _tmain(int argc, TCHAR *argv[]) if( !GotALabel ) { LoadString( GetModuleHandle(NULL), STRING_ENTER_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); _fgetts( input, sizeof(LabelString)/2, stdin ); input[ _tcslen(input)-1] = 0; From 633c71de4e54c6b7eab06c793eeaa6d9c668582f Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 13:57:33 +0000 Subject: [PATCH 152/292] [BATTC] - define _BATTERYCLASS_ to not get dllimport specifiers svn path=/trunk/; revision=47491 --- reactos/drivers/battery/battc/battc.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/drivers/battery/battc/battc.rbuild b/reactos/drivers/battery/battc/battc.rbuild index c0261344994..5847dd401b0 100644 --- a/reactos/drivers/battery/battc/battc.rbuild +++ b/reactos/drivers/battery/battc/battc.rbuild @@ -5,6 +5,7 @@ hal . + battc.c battc.rc From 336bd01387b06a279c4d356cc024840f9c394247 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 14:00:50 +0000 Subject: [PATCH 153/292] [LIBJPEG] Instead of disabling a warning when using "main" as something else then the main function, define it to mainptr (it's used as a pointer variable) globally, this approach is portable. svn path=/trunk/; revision=47492 --- reactos/dll/3rdparty/libjpeg/libjpeg.rbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/3rdparty/libjpeg/libjpeg.rbuild b/reactos/dll/3rdparty/libjpeg/libjpeg.rbuild index 990e595377f..9749f7ab35e 100644 --- a/reactos/dll/3rdparty/libjpeg/libjpeg.rbuild +++ b/reactos/dll/3rdparty/libjpeg/libjpeg.rbuild @@ -1,11 +1,11 @@ - -Wno-main + mainptr . jcapimin.c jcapistd.c From aa42ebb18f6607d89b6d47eff8b6fa5238768dea Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 14:04:24 +0000 Subject: [PATCH 154/292] [OSKITTCP] Improve the reactos-hack, by changing the ";" after an "if (...)" to "(void)0;" to tell the compiler that we intentionally do nothing in the if body. svn path=/trunk/; revision=47493 --- reactos/lib/drivers/oskittcp/oskittcp/rtsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/drivers/oskittcp/oskittcp/rtsock.c b/reactos/lib/drivers/oskittcp/oskittcp/rtsock.c index 5654b7b41f6..b7caadc5eab 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/rtsock.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/rtsock.c @@ -277,7 +277,7 @@ route_output(m, so) #ifndef __REACTOS__ ifp = ifa->ifa_ifp; #else - ; + (void)0; #endif if (ifa) { register struct ifaddr *oifa = rt->rt_ifa; From f9639de5902801051a0f1ddc9772db23e13cc6f2 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 14:11:10 +0000 Subject: [PATCH 155/292] [MMENT4] Remove a ";" after an if (), that makes no sense and caused GetNt4SoundDeviceCapabilities to always return without doing anything. svn path=/trunk/; revision=47494 --- reactos/lib/drivers/sound/mment4/control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/drivers/sound/mment4/control.c b/reactos/lib/drivers/sound/mment4/control.c index 87a9a4f9d50..7d8b437014c 100644 --- a/reactos/lib/drivers/sound/mment4/control.c +++ b/reactos/lib/drivers/sound/mment4/control.c @@ -101,7 +101,7 @@ GetNt4SoundDeviceCapabilities( Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); - if ( ! MMSUCCESS(Result) ); + if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); /* Choose the appropriate IOCTL */ From 76a1e465eac262dad4201260e3e971286252f014 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 14:58:43 +0000 Subject: [PATCH 156/292] [CMIDRIVER] - Fix a number of warnings, no actual code change - Patch by Love Nystrom, improvements by me See issue #5336 for more details. svn path=/trunk/; revision=47496 --- .../wdm/audio/drivers/CMIDriver/adapter.cpp | 29 +++++--- .../wdm/audio/drivers/CMIDriver/common.cpp | 12 ++-- .../wdm/audio/drivers/CMIDriver/mintopo.cpp | 15 +++-- .../audio/drivers/CMIDriver/mintopotables.hpp | 63 ++++++++++-------- .../wdm/audio/drivers/CMIDriver/minwave.cpp | 31 +++++---- .../audio/drivers/CMIDriver/minwavetables.hpp | 66 +++++++++---------- 6 files changed, 124 insertions(+), 92 deletions(-) diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp index edf88bf746e..a3d884dc912 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp @@ -29,7 +29,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "adapter.hpp" -//#pragma code_seg("PAGE") +#ifdef _MSC_VER +//#pragma code_seg("PAGE") // GCC ignores pragma code_seg +#endif const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; @@ -267,7 +269,9 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour PUNKNOWN unknownTopology = NULL; // install the topology miniport. - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Topology", CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyCMI, pCMIAdapter, NULL, GUID_NULL, &unknownTopology); + ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Topology", + CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyCMI, + pCMIAdapter, NULL, GUID_NULL, &unknownTopology ); if (!NT_SUCCESS (ntStatus)) { DBGPRINT(("Topology miniport installation failed")); return ntStatus; @@ -277,7 +281,7 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour // install the UART miniport - execution order important ntStatus = STATUS_UNSUCCESSFUL; MPUBase = 0; - for (int i=0;iNumberOfPorts();i++) { + for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) { if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 2) { MPUBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart; } @@ -285,7 +289,10 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour if (MPUBase != 0) { ntStatus = pCMIAdapter->activateMPU(MPUBase); if (NT_SUCCESS(ntStatus)) { - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Uart", CLSID_PortDMus, CLSID_MiniportDriverDMusUART, NULL, pCMIAdapter->getInterruptSync(), UartResourceList, IID_IPortDMus, NULL); + ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Uart", + CLSID_PortDMus, CLSID_MiniportDriverDMusUART, NULL, + pCMIAdapter->getInterruptSync(), UartResourceList, + IID_IPortDMus, NULL ); } } if (!NT_SUCCESS(ntStatus)) { @@ -300,9 +307,13 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour // install the wave miniport - the order matters here #ifdef WAVERT - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Wave", CLSID_PortWaveRT, CLSID_PortWaveRT, CreateMiniportWaveCMI, pCMIAdapter, ResourceList, IID_IPortWaveRT, &unknownWave); + ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", + CLSID_PortWaveRT, CLSID_PortWaveRT, CreateMiniportWaveCMI, + pCMIAdapter, ResourceList, IID_IPortWaveRT, &unknownWave ); #else - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Wave", CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCMI, pCMIAdapter, ResourceList, IID_IPortWaveCyclic, &unknownWave); + ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", + CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCMI, + pCMIAdapter, ResourceList, IID_IPortWaveCyclic, &unknownWave ); #endif if (!NT_SUCCESS(ntStatus)) { DBGPRINT(("Wave miniport installation failed")); @@ -449,8 +460,10 @@ AdapterDispatchPnp( resourceList->List[0].Count = 0; // copy the resources which have already been assigned - for (int i=0;iList[0].Count;i++) { - if (CopyResourceDescriptor(&list->List[0].Descriptors[i], &resourceList->List[0].Descriptors[resourceList->List[0].Count])) { + for ( UINT i=0; i < list->List[0].Count; i++ ) { + if (CopyResourceDescriptor( &list->List[0].Descriptors[i], + &resourceList->List[0].Descriptors[resourceList->List[0].Count] )) + { resourceList->List[0].Count++; } } diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp index 260f51d62e2..dc2b62ac55e 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp @@ -27,7 +27,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common.hpp" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif NTSTATUS NewCMIAdapter( @@ -63,7 +65,7 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::init(PRESOURCELIST ResourceList, PDEVICE_OB DeviceObject = aDeviceObject; cm.IOBase = 0; - for (int i=0;iNumberOfPorts();i++) { + for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) { if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 0x100) { cm.IOBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart; } @@ -357,7 +359,7 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::loadSBMixerFromMemory() //PAGED_CODE(); DBGPRINT(("CCMIAdapter[%p]::loadSBMixerFromMemory()", this)); #endif - for (int i = 0; i<(sizeof(sbIndex)/sizeof(sbIndex[0]));i++) { + for ( UINT i = 0; i < (sizeof(sbIndex)/sizeof(sbIndex[0])); i++ ) { writeUInt8(REG_SBINDEX, sbIndex[i]); writeUInt8(REG_SBDATA, mixerCache[i]); } @@ -368,7 +370,9 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::loadSBMixerFromMemory() /* ** non-paged code below */ -#pragma code_seg() +#ifdef _MSC_VER +#pragma code_seg() /* warning - ignored by GCC compiler */ +#endif STDMETHODIMP_(UInt8) CCMIAdapter::readUInt8(UInt8 reg) { diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp index 23584dd1dcd..283dc2b071f 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp @@ -31,7 +31,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define NTSTRSAFE_LIB //for Windows 2000 compatibility #include "ntstrsafe.h" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}}; @@ -173,7 +175,7 @@ STDMETHODIMP CCMITopology::loadMixerSettingsFromRegistry() PropertyRequest.ValueSize = sizeof(DWORD); PropertyRequest.PropertyItem = &PropertyItem; - for (int i=0;i < SIZEOF_ARRAY(TopologyNodes); i++) { + for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) { PropertyRequest.Node = i; Channel = CHAN_LEFT; @@ -310,7 +312,7 @@ STDMETHODIMP CCMITopology::storeMixerSettingsToRegistry() PropertyRequest.ValueSize = sizeof(DWORD); PropertyRequest.PropertyItem = &PropertyItem; - for (int i=0;i < SIZEOF_ARRAY(TopologyNodes); i++) { + for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) { PropertyRequest.Node = i; if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_VOLUME)) { PropertyRequest.Node = i; @@ -473,7 +475,8 @@ NTSTATUS NTAPI PropertyHandler_OnOff(PPCPROPERTY_REQUEST PropertyRequest) CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget); NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; - UInt8 data, mask, reg; + //UInt8 data, mask, reg; + UInt8 mask, reg; LONG channel; if (PropertyRequest->Node == ULONG(-1)) { @@ -1042,7 +1045,7 @@ static NTSTATUS BasicSupportHandler(PPCPROPERTY_REQUEST PropertyRequest) PKSPROPERTY_STEPPING_LONG Range = PKSPROPERTY_STEPPING_LONG(Members + 1); - for (int i=0;iNode) { Range->Bounds.SignedMaximum = (VolTable[i].max << 16); Range->Bounds.SignedMinimum = (VolTable[i].min << 16); @@ -1110,7 +1113,7 @@ NTSTATUS NTAPI PropertyHandler_Level(PPCPROPERTY_REQUEST PropertyRequest) PLONG Level = (PLONG)PropertyRequest->Value; - for (int i=0;iNode) { if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) { diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp index dce93b1cf44..182b4e6d97f 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp @@ -35,7 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF\ DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF) DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF); -#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED( KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF ) +/* Warning - Recursive #define for KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF */ #endif #endif @@ -47,15 +48,17 @@ NTSTATUS NTAPI PropertyHandler_Private(PPCPROPERTY_REQUEST PropertyRequest); static KSDATARANGE PinDataRangesBridge[] = { - { - sizeof(KSDATARANGE), - 0, - 0, - 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { + { + sizeof(KSDATARANGE), + 0, + 0, + 0, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + } + } }; static PKSDATARANGE PinDataRangePointersBridge[] = @@ -65,14 +68,16 @@ static PKSDATARANGE PinDataRangePointersBridge[] = static KSDATARANGE WavePinDataRangesAC3Bridge[] = { - { - sizeof(KSDATARANGE), - 0, - 0, - 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) + { + { + sizeof(KSDATARANGE), + 0, + 0, + 0, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + } } }; @@ -98,7 +103,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -117,7 +122,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_SPDIF_INTERFACE, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -136,7 +141,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_MICROPHONE, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -155,7 +160,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_CD_PLAYER, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -174,7 +179,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_LINE_CONNECTOR, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -193,7 +198,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_ANALOG_CONNECTOR, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -212,7 +217,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_ANALOG_CONNECTOR, // Category &CMINAME_DAC, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -231,7 +236,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_SPEAKER, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -250,7 +255,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -269,7 +274,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -288,7 +293,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication NULL, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } } }; diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp index 4a0477133d5..5152d863e57 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp @@ -29,7 +29,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "minwavetables.hpp" #include "ntddk.h" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif HRESULT NTAPI CreateMiniportWaveCMI(PUNKNOWN *Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { @@ -233,7 +235,8 @@ NTSTATUS CMiniportWaveCMI::loadChannelConfigFromRegistry() PREGISTRYKEY DriverKey; PREGISTRYKEY SettingsKey; UNICODE_STRING KeyName; - DWORD Value, ResultLength; + //DWORD Value, ResultLength; + DWORD ResultLength; PVOID KeyInfo; DBGPRINT(("CMiniportWaveCMI::loadChannelConfigFromRegistry()")); @@ -418,12 +421,12 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO DBGPRINT(("---channels: %d, resolution: %d, sample rate: %d, pin: %d, formatMask: %x", waveFormat->nChannels, waveFormat->wBitsPerSample, waveFormat->nSamplesPerSec, PinID, cm->formatMask)); //WaveFormatEx - if ( ( format->FormatSize >= sizeof(KSDATAFORMAT_WAVEFORMATEX)) + if ( ( (size_t) format->FormatSize >= sizeof(KSDATAFORMAT_WAVEFORMATEX)) && IsEqualGUIDAligned(format->MajorFormat,KSDATAFORMAT_TYPE_AUDIO) && IsEqualGUIDAligned(format->Specifier,KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ) { switch (EXTRACT_WAVEFORMATEX_ID(&format->SubFormat)) { case WAVE_FORMAT_PCM: - if ((PinID != PIN_WAVE_RENDER_SINK) && (PinID != PIN_WAVE_CAPTURE_SOURCE) && (PinID != -1)) { + if ((PinID != PIN_WAVE_RENDER_SINK) && (PinID != PIN_WAVE_CAPTURE_SOURCE) && ((int)PinID != -1)) { if ((PinID == PIN_WAVE_AC3_RENDER_SINK) && !IoIsWdmVersionAvailable(6,0)) { return STATUS_INVALID_PARAMETER; } @@ -438,10 +441,10 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO return isFormatAllowed(waveFormat->nSamplesPerSec, FALSE, FALSE); } if ( (waveFormat->wBitsPerSample == 16) - && ((waveFormat->nChannels >= 4) && (waveFormat->nChannels <= cm->maxChannels)) + && ((waveFormat->nChannels >= 4) && (waveFormat->nChannels <= (WORD) cm->maxChannels)) && ((waveFormat->nSamplesPerSec == 44100) || (waveFormat->nSamplesPerSec == 48000)) ) { #if OUT_CHANNEL == 1 - if ((PinID == PIN_WAVE_RENDER_SINK) || (PinID == -1)) { + if ((PinID == PIN_WAVE_RENDER_SINK) || ((int)PinID == -1)) { return isFormatAllowed(waveFormat->nSamplesPerSec, TRUE, FALSE); } #else @@ -450,7 +453,7 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO } break; case WAVE_FORMAT_DOLBY_AC3_SPDIF: - if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && (PinID != -1)) { + if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && ((int)PinID != -1)) { return STATUS_INVALID_PARAMETER; } if ( ((waveFormat->wBitsPerSample >= MIN_BITS_PER_SAMPLE_AC3) && (waveFormat->wBitsPerSample <= MAX_BITS_PER_SAMPLE_AC3)) @@ -907,7 +910,7 @@ NTSTATUS CMiniportWaveStreamCMI::prepareStream() DBGPRINT(("---streamIndex: %d, channelNumber: %d", streamIndex, channelNumber)); NTSTATUS ntStatus; - UInt8 reg; + //UInt8 reg; UInt32 val; if (state == KSSTATE_RUN) { @@ -990,7 +993,7 @@ NTSTATUS CMiniportWaveStreamCMI::setDACChannels() NTSTATUS ntStatus = STATUS_SUCCESS; if (currentChannelCount > 2) { - if (Miniport->cm->maxChannels < currentChannelCount) { + if ((WORD) Miniport->cm->maxChannels < currentChannelCount ) { return STATUS_INVALID_DEVICE_REQUEST; } if ((currentResolution != 16) || (currentChannelCount < 2)) { @@ -1052,7 +1055,7 @@ NTSTATUS CMiniportWaveStreamCMI::setupSPDIFPlayback(bool enableSPDIF) //PAGED_CODE(); DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupSPDIFPlayback(%d)", this, enableSPDIF)); - NTSTATUS ntStatus; + //NTSTATUS ntStatus; KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, false, NULL); @@ -1434,7 +1437,9 @@ STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::GetClockRegister(PKSRTAUDIO_HWRE /* ** non-paged code below */ -#pragma code_seg() +#ifdef _MSC_VER +#pragma code_seg() /* warning - ignored by GCC compiler */ +#endif STDMETHODIMP CMiniportWaveStreamCMI::SetState(KSSTATE NewState) { @@ -1461,7 +1466,9 @@ STDMETHODIMP CMiniportWaveStreamCMI::SetState(KSSTATE NewState) // STOP -> ACQUIRE -> PAUSE -> PLAY -> PAUSE -> ACQUIRE -> STOP if (state != NewState) { - switch (NewState) { + switch ((UINT) NewState) { + // LN: The cast on NewState is to satisfy the compiler about + // KSSTATE_STOP_AC3, which is not in the original enum KSSTATE. case KSSTATE_ACQUIRE: DBGPRINT(("---KSSTATE_ACQUIRE: previous state: %d", state)); if (state == KSSTATE_PAUSE) { diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp index 0c0326ca21c..8f44c5a977d 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp @@ -31,23 +31,23 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF\ DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF) DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF); -#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +/* Warning - Recursive #define for KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF */ NTSTATUS NTAPI PropertyHandler_ChannelConfig(PPCPROPERTY_REQUEST PropertyRequest); - static KSDATARANGE_AUDIO WavePinDataRangesPCMStream[] = { { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) } + }}, MAX_CHANNELS_PCM, MIN_BITS_PER_SAMPLE_PCM, MAX_BITS_PER_SAMPLE_PCM, @@ -59,15 +59,15 @@ static KSDATARANGE_AUDIO WavePinDataRangesPCMStream[] = static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = { { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) } + }}, MAX_CHANNELS_AC3, MIN_BITS_PER_SAMPLE_AC3, MAX_BITS_PER_SAMPLE_AC3, @@ -75,15 +75,15 @@ static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = MAX_SAMPLE_RATE_AC3 }, { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND) } + }}, MAX_CHANNELS_AC3, MIN_BITS_PER_SAMPLE_AC3, MAX_BITS_PER_SAMPLE_AC3, @@ -107,28 +107,28 @@ static PKSDATARANGE WavePinDataRangePointersAC3Stream[] = static KSDATARANGE WavePinDataRangesPCMBridge[] = { - { + {{ sizeof(KSDATARANGE), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + }} }; static KSDATARANGE WavePinDataRangesAC3Bridge[] = { - { + {{ sizeof(KSDATARANGE), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + }} }; static PKSDATARANGE WavePinDataRangePointersPCMBridge[] = @@ -160,7 +160,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, &KSAUDFNAME_RECORDING_CONTROL, - 0 + { 0 } } }, @@ -181,7 +181,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSCATEGORY_AUDIO, NULL, - 0 + { 0 } } }, @@ -202,7 +202,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, &KSAUDFNAME_VOLUME_CONTROL, - 0 + { 0 } } }, @@ -223,7 +223,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSNODETYPE_SPEAKER, NULL, - 0 + { 0 } } }, @@ -244,7 +244,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, NULL, - 0 + { 0 } } }, @@ -266,7 +266,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSNODETYPE_SPDIF_INTERFACE, NULL, - 0 + { 0 } } } }; From fa63efd41112e91a9a9be35abaf487d8cc27dbd9 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 15:07:19 +0000 Subject: [PATCH 157/292] [ntstrsafe.h] - Fix a number of parameter types (LPSTR/LPCSTR instead of PCHAR, PCCHAR) This is not the same, PCCHAR is a char * not a const char * svn path=/trunk/; revision=47497 --- reactos/include/ddk/ntstrsafe.h | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/reactos/include/ddk/ntstrsafe.h b/reactos/include/ddk/ntstrsafe.h index d5a02cb1bf7..447a3a5265c 100644 --- a/reactos/include/ddk/ntstrsafe.h +++ b/reactos/include/ddk/ntstrsafe.h @@ -36,7 +36,7 @@ typedef unsigned long DWORD; __inline NTSTATUS NTAPI -RtlStringLengthWorkerA(IN PCHAR String, +RtlStringLengthWorkerA(IN LPCSTR String, IN SIZE_T MaxLength, OUT PSIZE_T ReturnLength OPTIONAL) { @@ -69,7 +69,7 @@ RtlStringLengthWorkerA(IN PCHAR String, __inline NTSTATUS NTAPI -RtlStringValidateDestA(IN PCHAR Destination, +RtlStringValidateDestA(IN LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength) @@ -98,7 +98,7 @@ RtlStringValidateDestA(IN PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringExValidateDestA(IN OUT PCHAR *Destination, +RtlStringExValidateDestA(IN OUT LPSTR *Destination, IN OUT PSIZE_T DestinationLength, OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength, @@ -114,7 +114,7 @@ RtlStringExValidateDestA(IN OUT PCHAR *Destination, __inline NTSTATUS NTAPI -RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL, +RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, IN OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength, IN DWORD Flags) @@ -133,10 +133,10 @@ RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL, __inline NTSTATUS NTAPI -RtlStringVPrintfWorkerA(OUT PCHAR Destination, +RtlStringVPrintfWorkerA(OUT LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T NewLength OPTIONAL, - IN PCCHAR Format, + IN LPCSTR Format, IN va_list argList) { NTSTATUS Status = STATUS_SUCCESS; @@ -174,10 +174,10 @@ RtlStringVPrintfWorkerA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCopyWorkerA(OUT PCHAR Destination, +RtlStringCopyWorkerA(OUT LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T NewLength OPTIONAL, - IN PCCHAR Source, + IN LPCSTR Source, IN SIZE_T CopyLength) { NTSTATUS Status = STATUS_SUCCESS; @@ -211,9 +211,9 @@ RtlStringCopyWorkerA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCchCopyA(IN PCHAR Destination, +RtlStringCchCopyA(IN LPSTR Destination, IN SIZE_T cchDest, - IN PCCHAR pszSrc) + IN LPCSTR pszSrc) { ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); return STATUS_NOT_IMPLEMENTED; @@ -222,9 +222,9 @@ RtlStringCchCopyA(IN PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbPrintfA(OUT PCHAR Destination, +RtlStringCbPrintfA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCHAR Format, + IN LPCSTR Format, ...) { NTSTATUS Status; @@ -252,12 +252,12 @@ RtlStringCbPrintfA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbPrintfExA(OUT PCHAR Destination, +RtlStringCbPrintfExA(OUT LPSTR Destination, IN SIZE_T Length, - OUT PCHAR *DestinationEnd OPTIONAL, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags, - IN PCCHAR Format, + IN LPCSTR Format, ...) { NTSTATUS Status; @@ -333,10 +333,10 @@ RtlStringCbPrintfExA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbCopyExA(OUT PCHAR Destination, +RtlStringCbCopyExA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source, - OUT PCHAR *DestinationEnd OPTIONAL, + IN LPCSTR Source, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags) { @@ -423,10 +423,10 @@ RtlStringCbPrintfW( __inline NTSTATUS NTAPI -RtlStringCbCatExA(IN OUT PCHAR Destination, +RtlStringCbCatExA(IN OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source, - OUT PCHAR *DestinationEnd OPTIONAL, + IN LPCSTR Source, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags) { @@ -497,9 +497,9 @@ RtlStringCbCatExA(IN OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbCopyA(OUT PCHAR Destination, +RtlStringCbCopyA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source) + IN LPCSTR Source) { NTSTATUS Status; SIZE_T CharLength = Length / sizeof(CHAR); From c6de0424478b147056d1524e928fc063fe9766aa Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 15:10:25 +0000 Subject: [PATCH 158/292] [PSDK] Fix braces around initializers for GUIDs Patch by Love Nystrom See issue #5336 for more details. svn path=/trunk/; revision=47498 --- reactos/include/dxsdk/ksguid.h | 2 +- reactos/include/psdk/ks.h | 54 ++++++++++---------- reactos/include/psdk/ksmedia.h | 90 +++++++++++++++++----------------- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/reactos/include/dxsdk/ksguid.h b/reactos/include/dxsdk/ksguid.h index 84b1e59487c..51b1bb38a36 100644 --- a/reactos/include/dxsdk/ksguid.h +++ b/reactos/include/dxsdk/ksguid.h @@ -6,7 +6,7 @@ #endif #if !defined( DEFINE_WAVEFORMATEX_GUID ) - #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } #endif #if defined( DEFINE_GUIDEX ) diff --git a/reactos/include/psdk/ks.h b/reactos/include/psdk/ks.h index 2290d7cf4e2..62357d623a1 100644 --- a/reactos/include/psdk/ks.h +++ b/reactos/include/psdk/ks.h @@ -166,77 +166,77 @@ DEFINE_GUIDSTRUCT("d833f8f8-7894-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_P */ #define STATIC_KSCATEGORY_BRIDGE \ - 0x085AFF00L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x085AFF00L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("085AFF00-62CE-11CF-A5D6-28DB04C10000", KSCATEGORY_BRIDGE); #define KSCATEGORY_BRIDGE DEFINE_GUIDNAMED(KSCATEGORY_BRIDGE) #define STATIC_KSCATEGORY_CAPTURE \ - 0x65E8773DL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("65E8773D-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_CAPTURE); #define KSCATEGORY_CAPTURE DEFINE_GUIDNAMED(KSCATEGORY_CAPTURE) #define STATIC_KSCATEGORY_RENDER \ - 0x65E8773EL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("65E8773E-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_RENDER); #define KSCATEGORY_RENDER DEFINE_GUIDNAMED(KSCATEGORY_RENDER) #define STATIC_KSCATEGORY_MIXER \ - 0xAD809C00L, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0xAD809C00L, 0x7B88, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("AD809C00-7B88-11D0-A5D6-28DB04C10000", KSCATEGORY_MIXER); #define KSCATEGORY_MIXER DEFINE_GUIDNAMED(KSCATEGORY_MIXER) #define STATIC_KSCATEGORY_SPLITTER \ - 0x0A4252A0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x0A4252A0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("0A4252A0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_SPLITTER); #define KSCATEGORY_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_SPLITTER) #define STATIC_KSCATEGORY_DATACOMPRESSOR \ - 0x1E84C900L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x1E84C900L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("1E84C900-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATACOMPRESSOR); #define KSCATEGORY_DATACOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATACOMPRESSOR) #define STATIC_KSCATEGORY_DATADECOMPRESSOR \ - 0x2721AE20L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x2721AE20L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("2721AE20-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATADECOMPRESSOR); #define KSCATEGORY_DATADECOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATADECOMPRESSOR) #define STATIC_KSCATEGORY_DATATRANSFORM \ - 0x2EB07EA0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x2EB07EA0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("2EB07EA0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATATRANSFORM); #define KSCATEGORY_DATATRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_DATATRANSFORM) #define STATIC_KSCATEGORY_COMMUNICATIONSTRANSFORM \ - 0xCF1DDA2CL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2CL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2C-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_COMMUNICATIONSTRANSFORM); #define KSCATEGORY_COMMUNICATIONSTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_COMMUNICATIONSTRANSFORM) #define STATIC_KSCATEGORY_INTERFACETRANSFORM \ - 0xCF1DDA2DL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2DL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2D-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_INTERFACETRANSFORM); #define KSCATEGORY_INTERFACETRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_INTERFACETRANSFORM) #define STATIC_KSCATEGORY_MEDIUMTRANSFORM \ - 0xCF1DDA2EL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2EL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2E-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_MEDIUMTRANSFORM); #define KSCATEGORY_MEDIUMTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_MEDIUMTRANSFORM) #define STATIC_KSCATEGORY_FILESYSTEM \ - 0x760FED5EL, 0x9357, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x760FED5EL, 0x9357, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("760FED5E-9357-11D0-A3CC-00A0C9223196", KSCATEGORY_FILESYSTEM); #define KSCATEGORY_FILESYSTEM DEFINE_GUIDNAMED(KSCATEGORY_FILESYSTEM) #define STATIC_KSCATEGORY_CLOCK \ - 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x53172480L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSCATEGORY_CLOCK); #define KSCATEGORY_CLOCK DEFINE_GUIDNAMED(KSCATEGORY_CLOCK) #define STATIC_KSCATEGORY_PROXY \ - 0x97EBAACAL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x97EBAACAL, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY); #define KSCATEGORY_PROXY DEFINE_GUIDNAMED(KSCATEGORY_PROXY) #define STATIC_KSCATEGORY_QUALITY \ - 0x97EBAACBL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x97EBAACBL, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY); #define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY) @@ -308,7 +308,7 @@ typedef enum } KSINTERFACE_STANDARD; #define STATIC_KSINTERFACESETID_FileIo \ - 0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x8C6F932CL, 0xE771, 0x11D0, {0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo); #define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo) @@ -337,7 +337,7 @@ DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard */ #define STATIC_KSPROPSETID_Clock \ - 0xDF12A4C0L, 0xAC17, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("DF12A4C0-AC17-11CF-A5D6-28DB04C10000", KSPROPSETID_Clock); #define KSPROPSETID_Clock DEFINE_GUIDNAMED(KSPROPSETID_Clock) @@ -355,7 +355,7 @@ typedef enum } KSPROPERTY_CLOCK; #define STATIC_KSEVENTSETID_Clock \ - 0x364D8E20L, 0x62C7, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x364D8E20L, 0x62C7, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("364D8E20-62C7-11CF-A5D6-28DB04C10000", KSEVENTSETID_Clock); #define KSEVENTSETID_Clock DEFINE_GUIDNAMED(KSEVENTSETID_Clock) @@ -491,7 +491,7 @@ typedef enum */ #define KSPROPSETID_GM \ - 0xAF627536L, 0xE719, 0x11D2, 0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D + 0xAF627536L, 0xE719, 0x11D2, {0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D} typedef enum { @@ -508,7 +508,7 @@ typedef enum */ #define STATIC_KSPROPSETID_MediaSeeking\ - 0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xEE904F0CL, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking); #define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking) @@ -652,12 +652,12 @@ typedef struct { */ #define STATIC_KSPROPSETID_Pin\ - 0x8C134960L, 0x51AD, 0x11CF, 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00 + 0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin); #define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin) #define STATIC_KSNAME_Pin\ - 0x146F1A80L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x146F1A80L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("146F1A80-4791-11D0-A5D6-28DB04C10000", KSNAME_Pin); #define KSNAME_Pin DEFINE_GUIDNAMED(KSNAME_Pin) @@ -725,7 +725,7 @@ typedef enum */ #define STATIC_KSPROPSETID_Stream\ - 0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream); #define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream) @@ -844,7 +844,7 @@ typedef enum */ #define STATIC_KSPROPSETID_StreamAllocator\ - 0xcf6e4342L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0xcf6e4342L, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("cf6e4342-ec87-11cf-a130-0020afd156e4", KSPROPSETID_StreamAllocator); #define KSPROPSETID_StreamAllocator DEFINE_GUIDNAMED(KSPROPSETID_StreamAllocator) @@ -855,7 +855,7 @@ typedef enum } KSPROPERTY_STREAMALLOCATOR; #define KSMETHODSETID_StreamAllocator \ - 0xcf6e4341L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0xcf6e4341L, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} typedef enum { @@ -893,7 +893,7 @@ typedef enum */ #define STATIC_KSPROPSETID_Topology\ - 0x720D4AC0L, 0x7533, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("720D4AC0-7533-11D0-A5D6-28DB04C10000", KSPROPSETID_Topology); #define KSPROPSETID_Topology DEFINE_GUIDNAMED(KSPROPSETID_Topology) @@ -1243,7 +1243,7 @@ typedef PVOID KSDEVICE_HEADER, */ #define STATIC_KSDATAFORMAT_SPECIFIER_NONE\ - 0x0F6417D6L, 0xC318, 0x11D0, 0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x0F6417D6L, 0xC318, 0x11D0, {0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("0F6417D6-C318-11D0-A43F-00A0C9223196", KSDATAFORMAT_SPECIFIER_NONE); #define KSDATAFORMAT_SPECIFIER_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_NONE) diff --git a/reactos/include/psdk/ksmedia.h b/reactos/include/psdk/ksmedia.h index a1b1c0c314e..32e5e3e5269 100644 --- a/reactos/include/psdk/ksmedia.h +++ b/reactos/include/psdk/ksmedia.h @@ -28,7 +28,7 @@ DEFINE_GUIDSTRUCT("FBF6F530-07B9-11D2-A71E-0000F8004788", KSCATEGORY_AUDIO_DEVIC /* video */ #define STATIC_PINNAME_VIDEO_CAPTURE \ - 0xfb6c4281, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba + 0xfb6c4281, 0x353, 0x11d1, {0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba} #define STATIC_PINNAME_CAPTURE STATIC_PINNAME_VIDEO_CAPTURE DEFINE_GUIDSTRUCT("FB6C4281-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CAPTURE); #define PINNAME_VIDEO_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CAPTURE) @@ -130,32 +130,32 @@ DEFINE_GUIDSTRUCT("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE", KSCATEGORY_AUDIO_SPLIT */ #define STATIC_KSNODETYPE_ADC\ - 0x4D837FE0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("4D837FE0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_ADC); #define KSNODETYPE_ADC DEFINE_GUIDNAMED(KSNODETYPE_ADC) #define STATIC_KSNODETYPE_AGC\ - 0xE88C9BA0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xE88C9BA0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("E88C9BA0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_AGC); #define KSNODETYPE_AGC DEFINE_GUIDNAMED(KSNODETYPE_AGC) #define STATIC_KSNODETYPE_3D_EFFECTS\ - 0x55515860L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x55515860L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("55515860-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_3D_EFFECTS); #define KSNODETYPE_3D_EFFECTS DEFINE_GUIDNAMED(KSNODETYPE_3D_EFFECTS) #define STATIC_KSNODETYPE_SUPERMIX\ - 0xE573ADC0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xE573ADC0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("E573ADC0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUPERMIX); #define KSNODETYPE_SUPERMIX DEFINE_GUIDNAMED(KSNODETYPE_SUPERMIX) #define STATIC_KSNODETYPE_SRC\ - 0x9DB7B9E0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x9DB7B9E0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("9DB7B9E0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SRC); #define KSNODETYPE_SRC DEFINE_GUIDNAMED(KSNODETYPE_SRC) #define STATIC_KSNODETYPE_DAC\ - 0x507AE360L, 0xC554, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("507AE360-C554-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DAC); #define KSNODETYPE_DAC DEFINE_GUIDNAMED(KSNODETYPE_DAC) @@ -175,12 +175,12 @@ DEFINE_GUIDSTRUCT("DFF220E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CD_PLAYER); #define KSNODETYPE_CD_PLAYER DEFINE_GUIDNAMED(KSNODETYPE_CD_PLAYER) #define STATIC_KSNODETYPE_CHORUS\ - 0x20173F20L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x20173F20L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("20173F20-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_CHORUS); #define KSNODETYPE_CHORUS DEFINE_GUIDNAMED(KSNODETYPE_CHORUS) #define STATIC_KSNODETYPE_REVERB\ - 0xEF0328E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xEF0328E0L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("EF0328E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_REVERB); #define KSNODETYPE_REVERB DEFINE_GUIDNAMED(KSNODETYPE_REVERB) @@ -201,127 +201,127 @@ DEFINE_GUIDSTRUCT("DFF21CE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKER); #define KSNODETYPE_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_SPEAKER) #define STATIC_KSAUDFNAME_RECORDING_CONTROL\ - 0x185FEDFAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_CONTROL); #define KSAUDFNAME_RECORDING_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_CONTROL) #define STATIC_KSNODETYPE_VOLUME\ - 0x3A5ACC00L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x3A5ACC00L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("3A5ACC00-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_VOLUME); #define KSNODETYPE_VOLUME DEFINE_GUIDNAMED(KSNODETYPE_VOLUME) #define STATIC_KSAUDFNAME_WAVE_VOLUME\ - 0x185FEDE5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_VOLUME); #define KSAUDFNAME_WAVE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_VOLUME) #define STATIC_KSNODETYPE_MUTE\ - 0x02B223C0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x02B223C0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("02B223C0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUTE); #define KSNODETYPE_MUTE DEFINE_GUIDNAMED(KSNODETYPE_MUTE) #define STATIC_KSAUDFNAME_WAVE_MUTE\ - 0x185FEDE6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE6L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_MUTE); #define KSAUDFNAME_WAVE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_MUTE) #define STATIC_KSAUDFNAME_MIC_VOLUME\ - 0x185FEDEDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDED-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_VOLUME); #define KSAUDFNAME_MIC_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_VOLUME) #define STATIC_KSNODETYPE_SUM\ - 0xDA441A60L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xDA441A60L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("DA441A60-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUM); #define KSNODETYPE_SUM DEFINE_GUIDNAMED(KSNODETYPE_SUM) #define STATIC_KSAUDFNAME_MASTER_VOLUME\ - 0x185FEDE3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_VOLUME); #define KSAUDFNAME_MASTER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_VOLUME) #define STATIC_KSAUDFNAME_CD_VOLUME\ - 0x185FEDE9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE9L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_VOLUME); #define KSAUDFNAME_CD_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_VOLUME) #define STATIC_KSAUDFNAME_RECORDING_SOURCE\ - 0x185FEDEFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEFL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_SOURCE); #define KSAUDFNAME_RECORDING_SOURCE DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_SOURCE) #define STATIC_KSAUDFNAME_LINE_IN_VOLUME\ - 0x185FEDF4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN_VOLUME); #define KSAUDFNAME_LINE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN_VOLUME) #define STATIC_KSAUDFNAME_AUX_VOLUME\ - 0x185FEDFCL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFCL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_VOLUME); #define KSAUDFNAME_AUX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_AUX_VOLUME) #define STATIC_KSAUDFNAME_MIC_IN_VOLUME\ - 0x185FEDF5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_IN_VOLUME); #define KSAUDFNAME_MIC_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_IN_VOLUME) #define STATIC_KSNODETYPE_LOUDNESS\ - 0x41887440L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x41887440L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("41887440-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_LOUDNESS); #define KSNODETYPE_LOUDNESS DEFINE_GUIDNAMED(KSNODETYPE_LOUDNESS) #define STATIC_KSAUDFNAME_MICROPHONE_BOOST\ - 0x2bc31d6aL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 + 0x2bc31d6aL, 0x96e3, 0x11d2, {0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68} DEFINE_GUIDSTRUCT("2BC31D6A-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MICROPHONE_BOOST); #define KSAUDFNAME_MICROPHONE_BOOST DEFINE_GUIDNAMED(KSAUDFNAME_MICROPHONE_BOOST) #define STATIC_KSAUDFNAME_CD_MUTE\ - 0x185FEDEAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_MUTE); #define KSAUDFNAME_CD_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_CD_MUTE) #define STATIC_KSAUDFNAME_LINE_MUTE\ - 0x185FEDECL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDECL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_MUTE); #define KSAUDFNAME_LINE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_LINE_MUTE) #define STATIC_KSAUDFNAME_MIC_MUTE\ - 0x185FEDEEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEEL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_MUTE); #define KSAUDFNAME_MIC_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIC_MUTE) #define STATIC_KSAUDFNAME_AUX_MUTE\ - 0x185FEDFDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFD-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_MUTE); #define KSAUDFNAME_AUX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_AUX_MUTE) #define STATIC_KSAUDFNAME_VOLUME_CONTROL\ - 0x185FEDF7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF7L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_VOLUME_CONTROL); #define KSAUDFNAME_VOLUME_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_VOLUME_CONTROL) #define STATIC_KSNODETYPE_MUX\ - 0x2CEAF780L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x2CEAF780L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("2CEAF780-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUX); #define KSNODETYPE_MUX DEFINE_GUIDNAMED(KSNODETYPE_MUX) #define STATIC_KSAUDFNAME_MASTER_MUTE\ - 0x185FEDE4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_MUTE); #define KSAUDFNAME_MASTER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_MUTE) #define STATIC_KSNODETYPE_PEAKMETER\ - 0xa085651eL, 0x5f0d, 0x4b36, 0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e + 0xa085651eL, 0x5f0d, 0x4b36, {0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e} DEFINE_GUIDSTRUCT("A085651E-5F0D-4b36-A869-D195D6AB4B9E", KSNODETYPE_PEAKMETER); #define KSNODETYPE_PEAKMETER DEFINE_GUIDNAMED(KSNODETYPE_PEAKMETER) #define STATIC_KSNODETYPE_STEREO_WIDE\ - 0xA9E69800L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xA9E69800L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("A9E69800-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_STEREO_WIDE); #define KSNODETYPE_STEREO_WIDE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_WIDE) #define STATIC_KSNODETYPE_TONE\ - 0x7607E580L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x7607E580L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("7607E580-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_TONE); #define KSNODETYPE_TONE DEFINE_GUIDNAMED(KSNODETYPE_TONE) @@ -375,11 +375,11 @@ typedef struct { } KSDATARANGE_AUDIO, *PKSDATARANGE_AUDIO; #if !defined( DEFINE_WAVEFORMATEX_GUID ) -#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #endif #define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX\ - 0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + 0x00000000L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX); #define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) @@ -403,12 +403,12 @@ DEFINE_GUIDSTRUCT("73647561-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_AUDI #define KSDATAFORMAT_TYPE_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUDIO) #define STATIC_KSDATAFORMAT_SPECIFIER_DSOUND\ - 0x518590a2L, 0xa184, 0x11d0, 0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 + 0x518590a2L, 0xa184, 0x11d0, {0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3} DEFINE_GUIDSTRUCT("518590a2-a184-11d0-8522-00c04fd9baf3", KSDATAFORMAT_SPECIFIER_DSOUND); #define KSDATAFORMAT_SPECIFIER_DSOUND DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DSOUND) #define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG\ - 0x6dba3190L, 0x67bd, 0x11cf, 0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0x6dba3190L, 0x67bd, 0x11cf, {0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("6dba3190-67bd-11cf-a0f7-0020afd156e4", KSDATAFORMAT_SUBTYPE_ANALOG); #define KSDATAFORMAT_SUBTYPE_ANALOG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ANALOG) @@ -446,22 +446,22 @@ DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_I #define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) #define STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\ - 0x05589f81L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a + 0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a} DEFINE_GUIDSTRUCT("05589f81-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_WAVEFORMATEX); #define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) #define STATIC_KSDATAFORMAT_SUBTYPE_AC3_AUDIO\ - 0xe06d802cL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea + 0xe06d802cL, 0xdb46, 0x11cf, {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea} DEFINE_GUIDSTRUCT("e06d802c-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_AC3_AUDIO); #define KSDATAFORMAT_SUBTYPE_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) #define STATIC_KSDATAFORMAT_SPECIFIER_AC3_AUDIO\ - 0xe06d80e4L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea + 0xe06d80e4L, 0xdb46, 0x11cf, {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea} DEFINE_GUIDSTRUCT("e06d80e4-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_AC3_AUDIO); #define KSDATAFORMAT_SPECIFIER_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_AC3_AUDIO) #define STATIC_KSPROPSETID_AC3\ - 0xBFABE720L, 0x6E1F, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 + 0xBFABE720L, 0x6E1F, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} DEFINE_GUIDSTRUCT("BFABE720-6E1F-11D0-BCF2-444553540000", KSPROPSETID_AC3); #define KSPROPSETID_AC3 DEFINE_GUIDNAMED(KSPROPSETID_AC3) @@ -532,7 +532,7 @@ typedef enum { } KSPROPERTY_AUDIO; #define STATIC_KSEVENTSETID_AudioControlChange\ - 0xE85E9698L, 0xFA2F, 0x11D1, 0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0xE85E9698L, 0xFA2F, 0x11D1, {0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("E85E9698-FA2F-11D1-95BD-00C04FB925D3", KSEVENTSETID_AudioControlChange); #define KSEVENTSETID_AudioControlChange DEFINE_GUIDNAMED(KSEVENTSETID_AudioControlChange) @@ -542,7 +542,7 @@ typedef enum { #define STATIC_KSEVENTSETID_LoopedStreaming\ - 0x4682B940L, 0xC6EF, 0x11D0, 0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D + 0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D} DEFINE_GUIDSTRUCT("4682B940-C6EF-11D0-96D8-00AA0051E51D", KSEVENTSETID_LoopedStreaming); #define KSEVENTSETID_LoopedStreaming DEFINE_GUIDNAMED(KSEVENTSETID_LoopedStreaming) @@ -551,7 +551,7 @@ typedef enum { } KSEVENT_LOOPEDSTREAMING; #define STATIC_KSEVENTSETID_Connection\ - 0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00 + 0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00} DEFINE_GUIDSTRUCT("7f4bcbe0-9ea5-11cf-a5d6-28db04c10000", KSEVENTSETID_Connection); #define KSEVENTSETID_Connection DEFINE_GUIDNAMED(KSEVENTSETID_Connection) From 72cb5886ab2d6040c0910c1e232048caaf983048 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 May 2010 15:27:14 +0000 Subject: [PATCH 159/292] [MMENT4] Fix warning about uninitialized variable svn path=/trunk/; revision=47499 --- reactos/lib/drivers/sound/mment4/control.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/lib/drivers/sound/mment4/control.c b/reactos/lib/drivers/sound/mment4/control.c index 7d8b437014c..077620bf7ec 100644 --- a/reactos/lib/drivers/sound/mment4/control.c +++ b/reactos/lib/drivers/sound/mment4/control.c @@ -117,6 +117,7 @@ GetNt4SoundDeviceCapabilities( { /* FIXME - need to support AUX and mixer devices */ SND_ASSERT( FALSE ); + IoCtl = 0; } /* Get the capabilities information from the driver */ From b95825c9318ef4cb54e8ca2766265f4b428b40cf Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Mon, 31 May 2010 17:58:05 +0000 Subject: [PATCH 160/292] [win32k] - Rename co_IntCreateWindowEx to co_UserCreateWindowEx and refactor it to make it readable - Also fix the sequence of messages in co_UserCreateWindowEx svn path=/trunk/; revision=47500 --- .../subsystems/win32/win32k/include/class.h | 3 + .../subsystems/win32/win32k/include/window.h | 2 +- .../subsystems/win32/win32k/include/winpos.h | 2 + .../subsystems/win32/win32k/ntuser/class.c | 51 + .../subsystems/win32/win32k/ntuser/desktop.c | 23 +- .../subsystems/win32/win32k/ntuser/window.c | 939 +++++++----------- .../subsystems/win32/win32k/ntuser/winpos.c | 50 +- 7 files changed, 455 insertions(+), 615 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/class.h b/reactos/subsystems/win32/win32k/include/class.h index ac36f6b32ce..2c8d0b0d0c1 100644 --- a/reactos/subsystems/win32/win32k/include/class.h +++ b/reactos/subsystems/win32/win32k/include/class.h @@ -77,6 +77,9 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL); +PCLS +IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance); + PCLS FASTCALL IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, diff --git a/reactos/subsystems/win32/win32k/include/window.h b/reactos/subsystems/win32/win32k/include/window.h index 90143244458..14cac125fef 100644 --- a/reactos/subsystems/win32/win32k/include/window.h +++ b/reactos/subsystems/win32/win32k/include/window.h @@ -155,7 +155,7 @@ IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam, VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG); -PWND APIENTRY co_IntCreateWindowEx(DWORD,PUNICODE_STRING,PLARGE_STRING,DWORD,LONG,LONG,LONG,LONG,HWND,HMENU,HINSTANCE,LPVOID,DWORD,BOOL); +PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING); WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL); /* EOF */ diff --git a/reactos/subsystems/win32/win32k/include/winpos.h b/reactos/subsystems/win32/win32k/include/winpos.h index 9bb6cfffaba..7d14676e630 100644 --- a/reactos/subsystems/win32/win32k/include/winpos.h +++ b/reactos/subsystems/win32/win32k/include/winpos.h @@ -25,6 +25,8 @@ co_WinPosSetWindowPos(PWINDOW_OBJECT Wnd, HWND WndInsertAfter, INT x, INT y, INT INT cy, UINT flags); BOOLEAN FASTCALL co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd); +void FASTCALL +co_WinPosSendSizeMove(PWINDOW_OBJECT Window); USHORT FASTCALL co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint, PWINDOW_OBJECT* Window); diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index b24b26f4199..c1726a69d8c 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -1207,6 +1207,57 @@ FoundClass: return Atom; } +PCLS +IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance) +{ + PCLS *ClassLink, Class = NULL; + RTL_ATOM ClassAtom; + PTHREADINFO pti; + + pti = PsGetCurrentThreadWin32Thread(); + + if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED )) + { + UserRegisterSystemClasses(); + } + + /* Check the class. */ + + DPRINT("Class %wZ\n", ClassName); + + ClassAtom = IntGetClassAtom(ClassName, + hInstance, + pti->ppi, + &Class, + &ClassLink); + + if (ClassAtom == (RTL_ATOM)0) + { + if (IS_ATOM(ClassName->Buffer)) + { + DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer); + } + else + { + DPRINT1("Class \"%wZ\" not found\n", ClassName); + } + + SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS); + return NULL; + } + DPRINT("ClassAtom %x\n", ClassAtom); + Class = IntReferenceClass(Class, + ClassLink, + pti->rpdesk); + if (Class == NULL) + { + DPRINT1("Failed to reference window class!\n"); + return NULL; + } + + return Class; +} + RTL_ATOM UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx, IN PUNICODE_STRING ClassName, diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 1c972f95075..6bfe10b0239 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -885,6 +885,7 @@ NtUserCreateDesktop( UNICODE_STRING ClassName, MenuName; LARGE_STRING WindowName; PWND pWnd = NULL; + CREATESTRUCTW Cs; DECLARE_RETURN(HDESK); DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); @@ -1079,20 +1080,14 @@ NtUserCreateDesktop( RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); - pWnd = co_IntCreateWindowEx( 0, - &ClassName, - &WindowName, - (WS_POPUP|WS_CLIPCHILDREN), - 0, - 0, - 100, - 100, - NULL, - NULL, - hModClient, - NULL, - 0, - TRUE); + RtlZeroMemory(&Cs, sizeof(Cs)); + Cs.cx = Cs.cy = 100; + Cs.style = WS_POPUP|WS_CLIPCHILDREN; + Cs.hInstance = hModClient; + Cs.lpszName = (LPCWSTR) &WindowName; + Cs.lpszClass = (LPCWSTR) &ClassName; + + pWnd = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName); if (!pWnd) { DPRINT1("Failed to create Message window handle\n"); diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 6c17e8cb931..e1965d8c02d 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1603,244 +1603,125 @@ NtUserChildWindowFromPointEx(HWND hwndParent, return Ret; } - -/* - * calculates the default position of a window - */ -BOOL FASTCALL -IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos) +void FASTCALL +IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* dwShowMode) { - SIZE Sz; - PMONITOR pMonitor; - POINT Pos = {0, 0}; - - pMonitor = IntGetPrimaryMonitor(); +#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000) - if(Parent != NULL) + /* default positioning for overlapped windows */ + if(!(Cs->style & (WS_POPUP | WS_CHILD))) { - RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor); + RECTL rc, WorkArea; + PRTL_USER_PROCESS_PARAMETERS ProcessParams; - if(IncPos) + UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0); + + rc = WorkArea; + ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters; + + if (IS_DEFAULT(Cs->x)) { - Pos.x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME)); - Pos.y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME)); - if (Pos.x > ((rc->right - rc->left) / 4) || - Pos.y > ((rc->bottom - rc->top) / 4)) - { - /* reset counter and position */ - Pos.x = 0; - Pos.y = 0; - pMonitor->cWndStack = 0; - } - pMonitor->cWndStack++; + if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y; + + if(ProcessParams->WindowFlags & STARTF_USEPOSITION) + { + Cs->x = ProcessParams->StartingX; + Cs->y = ProcessParams->StartingY; + } + else + { + Cs->x = WorkArea.left; + Cs->y = WorkArea.top; + } + } + + if (IS_DEFAULT(Cs->cx)) + { + if (ProcessParams->WindowFlags & STARTF_USEPOSITION) + { + Cs->cx = ProcessParams->CountX; + Cs->cy = ProcessParams->CountY; + } + else + { + Cs->cx = (WorkArea.right - WorkArea.left) * 3 / 4 - Cs->x; + Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y; + } + } + /* neither x nor cx are default. Check the y values . + * In the trace we see Outlook and Outlook Express using + * cy set to CW_USEDEFAULT when opening the address book. + */ + else if (IS_DEFAULT(Cs->cy)) + { + DPRINT("Strange use of CW_USEDEFAULT in nHeight\n"); + Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y; } - Pos.x += rc->left; - Pos.y += rc->top; } else { - Pos.x = rc->left; - Pos.y = rc->top; + /* if CW_USEDEFAULT is set for non-overlapped windows, both values are set to zero */ + if(IS_DEFAULT(Cs->x)) + { + Cs->x = 0; + Cs->y = 0; + } + if(IS_DEFAULT(Cs->cx)) + { + Cs->cx = 0; + Cs->cy = 0; + } } - Sz.cx = EngMulDiv(rc->right - rc->left, 3, 4); - Sz.cy = EngMulDiv(rc->bottom - rc->top, 3, 4); - - rc->left = Pos.x; - rc->top = Pos.y; - rc->right = rc->left + Sz.cx; - rc->bottom = rc->top + Sz.cy; - return TRUE; +#undef IS_DEFAULT } - -/* - * @implemented - */ -PWND APIENTRY -co_IntCreateWindowEx(DWORD dwExStyle, - PUNICODE_STRING ClassName, - PLARGE_STRING WindowName, - DWORD dwStyle, - LONG x, - LONG y, - LONG nWidth, - LONG nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam, - DWORD dwShowMode, - BOOL bUnicodeWindow) +/* Allocates and initializes a window*/ +PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, + PLARGE_STRING WindowName, + PCLS Class, + PWINDOW_OBJECT ParentWindow, + PWINDOW_OBJECT OwnerWindow) { - PWINSTATION_OBJECT WinSta; PWND Wnd = NULL; - PCLS *ClassLink, Class = NULL; - RTL_ATOM ClassAtom; - PWINDOW_OBJECT Window = NULL; - PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow; - HWND ParentWindowHandle = NULL; - HWND OwnerWindowHandle; - PMENU_OBJECT SystemMenu; + PWINDOW_OBJECT Window; HWND hWnd; - POINT Pos; - SIZE Size; - PTHREADINFO ti = NULL; -#if 0 - - POINT MaxSize, MaxPos, MinTrack, MaxTrack; -#else - - POINT MaxPos; -#endif - CREATESTRUCTW Cs; - CBT_CREATEWNDW CbtCreate; - LRESULT Result; + PTHREADINFO pti = NULL; + PMENU_OBJECT SystemMenu; BOOL MenuChanged; - DECLARE_RETURN(PWND); - BOOL HasOwner; - USER_REFERENCE_ENTRY ParentRef, Ref; - PTHREADINFO pti; + BOOL bUnicodeWindow; pti = PsGetCurrentThreadWin32Thread(); - if (pti->rpdesk) - { - ParentWindowHandle = pti->rpdesk->DesktopWindow; - } - - - if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED )) - { - UserRegisterSystemClasses(); - } - - OwnerWindowHandle = NULL; - - DPRINT("co_IntCreateWindowEx %wZ\n", ClassName); - - if (hWndParent == HWND_MESSAGE) - { - /* - * native ole32.OleInitialize uses HWND_MESSAGE to create the - * message window (style: WS_POPUP|WS_DISABLED) - */ - ParentWindowHandle = IntGetMessageWindow(); - DPRINT("Parent is HWND_MESSAGE 0x%x\n", ParentWindowHandle); - } - else if (hWndParent) - { - if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) - { //temp hack - PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root; - if (Par && (Root = UserGetAncestor(Par, GA_ROOT))) - OwnerWindowHandle = Root->hSelf; - } - else - ParentWindowHandle = hWndParent; - } - else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD) - { - SetLastWin32Error(ERROR_TLW_WITH_WSCHILD); - RETURN( (PWND)0); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ - } - - if (ParentWindowHandle) - { - ParentWindow = UserGetWindowObject(ParentWindowHandle); - - if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef); - } + /* Automatically add WS_EX_WINDOWEDGE */ + if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) || + ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) && + (Cs->style & (WS_DLGFRAME | WS_THICKFRAME)))) + Cs->dwExStyle |= WS_EX_WINDOWEDGE; else - { - ParentWindow = NULL; - } + Cs->dwExStyle &= ~WS_EX_WINDOWEDGE; - /* FIXME: parent must belong to the current process */ + /* Is it a unicode window? */ + bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR); + Cs->dwExStyle &= ~WS_EX_SETANSICREATOR; - /* Check the window station. */ - ti = GetW32ThreadInfo(); - if (ti == NULL || pti->rpdesk == NULL) - { - DPRINT1("Thread is not attached to a desktop! Cannot create window!\n"); - RETURN( (PWND)0); - } - - /* Check the class. */ - - DPRINT("Class %wZ\n", ClassName); - - ClassAtom = IntGetClassAtom(ClassName, - hInstance, - ti->ppi, - &Class, - &ClassLink); - - if (ClassAtom == (RTL_ATOM)0) - { - if (IS_ATOM(ClassName->Buffer)) - { - DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer); - } - else - { - DPRINT1("Class \"%wZ\" not found\n", ClassName); - } - - SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS); - RETURN((PWND)0); - } - DPRINT("ClassAtom %x\n", ClassAtom); - Class = IntReferenceClass(Class, - ClassLink, - pti->rpdesk); - if (Class == NULL) - { - DPRINT1("Failed to reference window class!\n"); - RETURN(NULL); - } - - WinSta = pti->rpdesk->rpwinstaParent; - - //FIXME: Reference thread/desktop instead - ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); - - /* Create the window object. */ + /* Allocate the new window */ Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable, pti->rpdesk, (PHANDLE)&hWnd, otWindow, sizeof(WINDOW_OBJECT)); - if (Window) - { - Window->Wnd = DesktopHeapAlloc(pti->rpdesk, - sizeof(WND) + Class->cbwndExtra); - if (!Window->Wnd) - goto AllocErr; - RtlZeroMemory(Window->Wnd, - sizeof(WND) + Class->cbwndExtra); - Window->Wnd->head.h = hWnd; - Wnd = Window->Wnd; - Wnd->fnid = 0; - Wnd->head.pti = ti; - Wnd->head.rpdesk = pti->rpdesk; - Wnd->hWndLastActive = hWnd; - Wnd->state2 |= WNDS2_WIN40COMPAT; + Wnd = DesktopHeapAlloc(pti->rpdesk, sizeof(WND) + Class->cbwndExtra); + + if(!Window || !Wnd) + { + goto AllocError; } + RtlZeroMemory(Wnd, sizeof(WND) + Class->cbwndExtra); + DPRINT("Created object with handle %X\n", hWnd); - if (!Window) - { -AllocErr: - ObDereferenceObject(WinSta); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( (PWND)0); - } - - UserRefObjectCo(Window, &Ref); - - ObDereferenceObject(WinSta); if (NULL == pti->rpdesk->DesktopWindow) { @@ -1852,39 +1733,44 @@ AllocErr: /* * Fill out the structure describing it. */ - Window->pti = ti; - Wnd->pcls = Class; - Class = NULL; - - Window->SystemMenu = (HMENU)0; - Wnd->IDMenu = 0; - Wnd->hModule = hInstance; + Window->Wnd = Wnd; + Window->pti = pti; Window->hSelf = hWnd; + Window->spwndParent = ParentWindow; + Window->hOwner = OwnerWindow ? OwnerWindow->hSelf : NULL; + + Wnd->head.h = hWnd; + Wnd->head.pti = pti; + Wnd->head.rpdesk = pti->rpdesk; + Wnd->fnid = 0; + Wnd->hWndLastActive = hWnd; + Wnd->state2 |= WNDS2_WIN40COMPAT; + Wnd->pcls = Class; + Wnd->hModule = Cs->hInstance; + Wnd->style = Cs->style & ~WS_VISIBLE; + Wnd->ExStyle = Cs->dwExStyle; + Wnd->rcWindow.left = Cs->x; + Wnd->rcWindow.top = Cs->y; + Wnd->rcWindow.right = Cs->x + Cs->cx; + Wnd->rcWindow.bottom = Cs->y + Cs->cy; + Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; + Wnd->spwndOwner = OwnerWindow ? OwnerWindow->Wnd : NULL; + Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL; + + if (Wnd->style & WS_CHILD && ParentWindow) + { + RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, + ParentWindow->Wnd->rcClient.top); + } + Wnd->rcClient = Wnd->rcWindow; IntReferenceMessageQueue(Window->pti->MessageQueue); - Window->spwndParent = ParentWindow; - Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL; - if (Wnd->spwndParent != NULL && hWndParent != 0) + if (Wnd->spwndParent != NULL && Cs->hwndParent != 0) { Wnd->HideFocus = Wnd->spwndParent->HideFocus; Wnd->HideAccel = Wnd->spwndParent->HideAccel; } - if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle))) - { - Window->hOwner = OwnerWindowHandle; - Wnd->spwndOwner = OwnerWindow->Wnd; - HasOwner = TRUE; - } - else - { - Window->hOwner = NULL; - Wnd->spwndOwner = NULL; - HasOwner = FALSE; - } - - Wnd->dwUserData = 0; - if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC) Wnd->state |= WNDS_SERVERSIDEWINDOWPROC; @@ -1929,15 +1815,15 @@ AllocErr: WndProc, unless the following overriding conditions occur: */ if ( !bUnicodeWindow && - ( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON] || - ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_DIALOG] || - ClassAtom == gpsi->atomSysClass[ICLS_EDIT] || - ClassAtom == gpsi->atomSysClass[ICLS_IME] || - ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] || - ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) ) + ( Class->atomClassName == gpsi->atomSysClass[ICLS_BUTTON] || + Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOLBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_DIALOG] || + Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT] || + Class->atomClassName == gpsi->atomSysClass[ICLS_IME] || + Class->atomClassName == gpsi->atomSysClass[ICLS_LISTBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] || + Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) ) { // Override Class and set the window Ansi WndProc. Wnd->state |= WNDS_ANSIWINDOWPROC; Wnd->Unicode = FALSE; @@ -1949,74 +1835,61 @@ AllocErr: } } - Window->spwndChild = NULL; - Window->spwndPrev = NULL; - Window->spwndNext = NULL; + /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx, + then my testing shows that windows (2k and XP) creates a CallProc for it immediately + Dont understand why it does this. */ + if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT]) + { + PCALLPROCDATA CallProc; + //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi); + CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi); - Wnd->spwndNext = NULL; - Wnd->spwndPrev = NULL; - Wnd->spwndChild = NULL; - - Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; + if (!CallProc) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd); + } + else + { + UserAddCallProcToClass(Wnd->pcls, CallProc); + } + } InitializeListHead(&Wnd->PropListHead); - if ( NULL != WindowName->Buffer && WindowName->Length > 0 ) + if ( WindowName->Buffer != NULL && WindowName->Length > 0 ) { Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk, - WindowName->Length + sizeof(UNICODE_NULL)); + WindowName->Length + sizeof(UNICODE_NULL)); if (Wnd->strName.Buffer == NULL) { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( (PWND)0); + goto AllocError; } + RtlCopyMemory(Wnd->strName.Buffer, WindowName->Buffer, WindowName->Length); Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0'; - _SEH2_TRY - { - RtlCopyMemory(Wnd->strName.Buffer, - WindowName->Buffer, - WindowName->Length); - Wnd->strName.Length = WindowName->Length; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - WindowName->Length = 0; - Wnd->strName.Buffer[0] = L'\0'; - } - _SEH2_END; + Wnd->strName.Length = WindowName->Length; } - /* - * This has been tested for WS_CHILD | WS_VISIBLE. It has not been - * tested for WS_POPUP - */ - if ((dwExStyle & WS_EX_DLGMODALFRAME) || - ((!(dwExStyle & WS_EX_STATICEDGE)) && - (dwStyle & (WS_DLGFRAME | WS_THICKFRAME)))) - dwExStyle |= WS_EX_WINDOWEDGE; - else - dwExStyle &= ~WS_EX_WINDOWEDGE; - - dwExStyle &= ~WS_EX_SETANSICREATOR; - - Wnd->style = dwStyle & ~WS_VISIBLE; - /* Correct the window style. */ if ((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) { Wnd->style |= WS_CLIPSIBLINGS; - DPRINT("3: Style is now %lx\n", dwStyle); if (!(Wnd->style & WS_POPUP)) { Wnd->style |= WS_CAPTION; Window->state |= WINDOWOBJECT_NEED_SIZE; - DPRINT("4: Style is now %lx\n", dwStyle); } } + if ((Wnd->ExStyle & WS_EX_DLGMODALFRAME) || + (Wnd->style & (WS_DLGFRAME | WS_THICKFRAME))) + Wnd->ExStyle |= WS_EX_WINDOWEDGE; + else + Wnd->ExStyle &= ~WS_EX_WINDOWEDGE; + /* create system menu */ - if((dwStyle & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION) + if((Cs->style & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION) { SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE); if(SystemMenu) @@ -2027,13 +1900,15 @@ AllocErr: } /* Set the window menu */ - if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) + if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) { - if (hMenu) - IntSetMenu(Window, hMenu, &MenuChanged); + if (Cs->hMenu) + IntSetMenu(Window, Cs->hMenu, &MenuChanged); else if (Wnd->pcls->lpszMenuName) // Take it from the parent. { UNICODE_STRING MenuName; + HMENU hMenu; + if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName)) { MenuName.Length = 0; @@ -2049,7 +1924,7 @@ AllocErr: } } else // Not a child - Wnd->IDMenu = (UINT) hMenu; + Wnd->IDMenu = (UINT) Cs->hMenu; /* Insert the window into the thread's window list. */ InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry); @@ -2064,163 +1939,138 @@ AllocErr: DceAllocDCE(Window, DCE_WINDOW_DC); } - Pos.x = x; - Pos.y = y; - Size.cx = nWidth; - Size.cy = nHeight; + return Window; - Wnd->ExStyle = dwExStyle; +AllocError: - /* call hook */ - Cs.lpCreateParams = lpParam; - Cs.hInstance = hInstance; - Cs.hMenu = hMenu; - Cs.hwndParent = hWndParent; //Pass the original Parent handle! - Cs.cx = Size.cx; - Cs.cy = Size.cy; - Cs.x = Pos.x; - Cs.y = Pos.y; - Cs.style = Wnd->style; -// Cs.lpszName = (LPCWSTR) WindowName->Buffer; -// Cs.lpszClass = (LPCWSTR) ClassName->Buffer; - Cs.lpszName = (LPCWSTR) WindowName; - Cs.lpszClass = (LPCWSTR) ClassName; - Cs.dwExStyle = dwExStyle; - CbtCreate.lpcs = &Cs; + if(Window) + UserDereferenceObject(Window); + + if(Wnd) + DesktopHeapFree(Wnd->head.rpdesk, Wnd); + + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return NULL; +} + +/* + * @implemented + */ +PWND FASTCALL +co_UserCreateWindowEx(CREATESTRUCTW* Cs, + PUNICODE_STRING ClassName, + PLARGE_STRING WindowName) +{ + PWINDOW_OBJECT Window = NULL, ParentWindow = NULL, OwnerWindow; + HWND hWnd, hWndParent, hWndOwner; + DWORD dwStyle; + PWINSTATION_OBJECT WinSta; + PWND Wnd = NULL; + PCLS Class = NULL; + SIZE Size; + POINT MaxPos; + CBT_CREATEWNDW CbtCreate; + LRESULT Result; + USER_REFERENCE_ENTRY ParentRef, Ref; + PTHREADINFO pti; + DWORD dwShowMode = SW_SHOW; + DECLARE_RETURN(PWND); + + /* Get the current window station and reference it */ + pti = GetW32ThreadInfo(); + if (pti == NULL || pti->rpdesk == NULL) + { + DPRINT1("Thread is not attached to a desktop! Cannot create window!\n"); + return NULL; //There is nothing to cleanup + } + WinSta = pti->rpdesk->rpwinstaParent; + ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); + + /* Get the class and reference it*/ + Class = IntGetAndReferenceClass(ClassName, Cs->hInstance); + if(!Class) + { + DPRINT1("Failed to find class %wZ\n", ClassName); + RETURN(NULL); + } + + /* Now find the parent and the owner window */ + hWndParent = IntGetDesktopWindow(); + hWndOwner = NULL; + + if (Cs->hwndParent == HWND_MESSAGE) + { + Cs->hwndParent = hWndParent = IntGetMessageWindow(); + } + else if (Cs->hwndParent) + { + if ((Cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) + hWndOwner = Cs->hwndParent; + else + hWndParent = Cs->hwndParent; + } + else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) + { + DPRINT1("Cannot create a child window without a parrent!\n"); + SetLastWin32Error(ERROR_TLW_WITH_WSCHILD); + RETURN(NULL); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + } + + ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL; + OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL; + + /* FIXME: is this correct?*/ + if(OwnerWindow) + OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT); + + /* Fix the position and the size of the window */ + if (ParentWindow) + { + UserRefObjectCo(ParentWindow, &ParentRef); + IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode); + } + + /* Allocate and initialize the new window */ + Window = IntCreateWindow(Cs, + WindowName, + Class, + ParentWindow, + OwnerWindow); + if(!Window) + { + DPRINT1("IntCreateWindow failed!\n"); + RETURN(0); + } + + Wnd = Window->Wnd; + hWnd = Window->hSelf; + + UserRefObjectCo(Window, &Ref); + ObDereferenceObject(WinSta); + + /* Call the WH_CBT hook */ + dwStyle = Cs->style; + Cs->style = Wnd->style; /* HCBT_CREATEWND needs the real window style */ + CbtCreate.lpcs = Cs; CbtCreate.hwndInsertAfter = HWND_TOP; if (ISITHOOKED(WH_CBT)) { if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate)) { - /* FIXME - Delete window object and remove it from the thread windows list */ - /* FIXME - delete allocated DCE */ - DPRINT1("CBT-hook returned !0\n"); + DPRINT1("HCBT_CREATEWND hook failed!\n"); RETURN( (PWND) NULL); } } - x = Cs.x; - y = Cs.y; - nWidth = Cs.cx; - nHeight = Cs.cy; + Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/ - Cs.style = dwStyle; -// FIXME: Need to set the Z order in the window link list if the hook callback changed it! -// hwndInsertAfter = CbtCreate.hwndInsertAfter; + /* Send the WM_GETMINMAXINFO message*/ + Size.cx = Cs->cx; + Size.cy = Cs->cy; - /* default positioning for overlapped windows */ - if(!(Wnd->style & (WS_POPUP | WS_CHILD))) - { - RECTL rc, WorkArea; - PRTL_USER_PROCESS_PARAMETERS ProcessParams; - BOOL CalculatedDefPosSize = FALSE; - - UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0); - - rc = WorkArea; - ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters; - - if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16) - { - CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE); - - if(ProcessParams->WindowFlags & STARTF_USEPOSITION) - { - ProcessParams->WindowFlags &= ~STARTF_USEPOSITION; - Pos.x = WorkArea.left + ProcessParams->StartingX; - Pos.y = WorkArea.top + ProcessParams->StartingY; - } - else - { - Pos.x = rc.left; - Pos.y = rc.top; - } - -/* - According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and - y is something else. and Quote! - */ - -/* Never believe Microsoft's documentation... CreateWindowEx doc says - * that if an overlapped window is created with WS_VISIBLE style bit - * set and the x parameter is set to CW_USEDEFAULT, the system ignores - * the y parameter. However, disassembling NT implementation (WIN32K.SYS) - * reveals that - * - * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16 - * 2) it does not ignore the y parameter as the docs claim; instead, it - * uses it as second parameter to ShowWindow() unless y is either - * CW_USEDEFAULT or CW_USEDEFAULT16. - * - * The fact that we didn't do 2) caused bogus windows pop up when wine - * was running apps that were using this obscure feature. Example - - * calc.exe that comes with Win98 (only Win98, it's different from - * the one that comes with Win95 and NT) - */ - if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16) - { - dwShowMode = y; - } - } - if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16) - { - if(!CalculatedDefPosSize) - { - IntCalcDefPosSize(ParentWindow, &rc, FALSE); - } - if(ProcessParams->WindowFlags & STARTF_USESIZE) - { - ProcessParams->WindowFlags &= ~STARTF_USESIZE; - Size.cx = ProcessParams->CountX; - Size.cy = ProcessParams->CountY; - } - else - { - Size.cx = rc.right - rc.left; - Size.cy = rc.bottom - rc.top; - } - - /* move the window if necessary */ - if(Pos.x > rc.left) - Pos.x = max(rc.left, 0); - if(Pos.y > rc.top) - Pos.y = max(rc.top, 0); - } - } - else - { - /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */ - if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16) - { - Pos.x = 0; - Pos.y = 0; - } - if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16) - { - Size.cx = 0; - Size.cy = 0; - } - } - - /* Initialize the window dimensions. */ - Wnd->rcWindow.left = Pos.x; - Wnd->rcWindow.top = Pos.y; - Wnd->rcWindow.right = Pos.x + Size.cx; - Wnd->rcWindow.bottom = Pos.y + Size.cy; - if (0 != (Wnd->style & WS_CHILD) && ParentWindow) - { - RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, - ParentWindow->Wnd->rcClient.top); - } - Wnd->rcClient = Wnd->rcWindow; - - /* - * Get the size and position of the window. - */ if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD))) { POINT MaxSize, MaxPos, MinTrack, MaxTrack; - /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */ co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack); if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x; if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y; @@ -2228,47 +2078,20 @@ AllocErr: if (Size.cy < MinTrack.y) Size.cy = MinTrack.y; } - Wnd->rcWindow.left = Pos.x; - Wnd->rcWindow.top = Pos.y; - Wnd->rcWindow.right = Pos.x + Size.cx; - Wnd->rcWindow.bottom = Pos.y + Size.cy; + Wnd->rcWindow.left = Cs->x; + Wnd->rcWindow.top = Cs->y; + Wnd->rcWindow.right = Cs->x + Size.cx; + Wnd->rcWindow.bottom = Cs->y + Size.cy; if (0 != (Wnd->style & WS_CHILD) && ParentWindow) { - RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, - ParentWindow->Wnd->rcClient.top); + RECTL_vOffsetRect(&Wnd->rcWindow, + ParentWindow->Wnd->rcClient.left, + ParentWindow->Wnd->rcClient.top); } Wnd->rcClient = Wnd->rcWindow; - /* FIXME: Initialize the window menu. */ - - /* Send a NCCREATE message. */ - DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent); - DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, Size.cx, Size.cy); - DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n"); - Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) &Cs); - if (!Result) - { - /* FIXME: Cleanup. */ - DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n"); - RETURN((PWND)0); - } - - /* Calculate the non-client size. */ - MaxPos.x = Window->Wnd->rcWindow.left; - MaxPos.y = Window->Wnd->rcWindow.top; - - - DPRINT("IntCreateWindowEx(): About to get non-client size.\n"); - /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */ - Result = co_WinPosGetNonClientSize(Window, - &Window->Wnd->rcWindow, - &Window->Wnd->rcClient); - - RECTL_vOffsetRect(&Window->Wnd->rcWindow, - MaxPos.x - Window->Wnd->rcWindow.left, - MaxPos.y - Window->Wnd->rcWindow.top); - + /* Link the window*/ if (NULL != ParentWindow) { /* link the window into the parent's child list */ @@ -2291,7 +2114,7 @@ AllocErr: { /* link window as top sibling (but after topmost siblings) */ PWINDOW_OBJECT InsertAfter, Sibling; - if (!(dwExStyle & WS_EX_TOPMOST)) + if (!(Cs->dwExStyle & WS_EX_TOPMOST)) { InsertAfter = NULL; Sibling = ParentWindow->spwndChild; @@ -2309,19 +2132,35 @@ AllocErr: IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */); } } + + /* Send the NCCREATE message */ + Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) Cs); + if (!Result) + { + DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); + RETURN((PWND)0); + } + + /* Send the WM_NCCALCSIZE message */ + MaxPos.x = Window->Wnd->rcWindow.left; + MaxPos.y = Window->Wnd->rcWindow.top; + + Result = co_WinPosGetNonClientSize(Window, &Wnd->rcWindow, &Wnd->rcClient); + + RECTL_vOffsetRect(&Wnd->rcWindow, MaxPos.x - Wnd->rcWindow.left, + MaxPos.y - Wnd->rcWindow.top); + /* Send the WM_CREATE message. */ - DPRINT("IntCreateWindowEx(): about to send CREATE message.\n"); - Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) &Cs); - + Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) Cs); if (Result == (LRESULT)-1) { - /* FIXME: Cleanup. */ - DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n"); + DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); IntUnlinkWindow(Window); RETURN((PWND)0); } + /* Send the EVENT_OBJECT_CREATE event*/ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0); /* By setting the flag below it can be examined to determine if the window @@ -2329,43 +2168,10 @@ AllocErr: from here the function has to succeed. */ Window->Wnd->state2 |= WNDS2_WMCREATEMSGPROCESSED; - /* Send move and size messages. */ + /* Send the WM_SIZE and WM_MOVE messages. */ if (!(Window->state & WINDOWOBJECT_NEED_SIZE)) { - LONG lParam; - - DPRINT("IntCreateWindow(): About to send WM_SIZE\n"); - - if ((Window->Wnd->rcClient.right - Window->Wnd->rcClient.left) < 0 || - (Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top) < 0) - { - DPRINT("Sending bogus WM_SIZE\n"); - } - - lParam = MAKE_LONG(Window->Wnd->rcClient.right - - Window->Wnd->rcClient.left, - Window->Wnd->rcClient.bottom - - Window->Wnd->rcClient.top); - co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED, - lParam); - - DPRINT("IntCreateWindow(): About to send WM_MOVE\n"); - - if (0 != (Wnd->style & WS_CHILD) && ParentWindow) - { - lParam = MAKE_LONG(Wnd->rcClient.left - ParentWindow->Wnd->rcClient.left, - Wnd->rcClient.top - ParentWindow->Wnd->rcClient.top); - } - else - { - lParam = MAKE_LONG(Wnd->rcClient.left, - Wnd->rcClient.top); - } - - co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam); - - /* Call WNDOBJ change procs */ - IntEngWindowChanged(Window, WOC_RGN_CLIENT); + co_WinPosSendSizeMove(Window); } /* Show or maybe minimize or maximize the window. */ @@ -2374,8 +2180,7 @@ AllocErr: RECTL NewPos; UINT16 SwFlag; - SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE : - SW_MAXIMIZE; + SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE; co_WinPosMinMaximize(Window, SwFlag, &NewPos); @@ -2383,32 +2188,25 @@ AllocErr: SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED : SWP_NOZORDER | SWP_FRAMECHANGED; - DPRINT("IntCreateWindow(): About to minimize/maximize\n"); - DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom); co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, SwFlag); } - /* Notify the parent window of a new child. */ + /* Send the WM_PARENTNOTIFY message */ if ((Wnd->style & WS_CHILD) && (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow) { - DPRINT("IntCreateWindow(): About to notify parent\n"); co_IntSendMessage(ParentWindow->hSelf, WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, Wnd->IDMenu), (LPARAM)Window->hSelf); } - if ((!hWndParent) && (!HasOwner)) + /* Notify the shell that a new window was created */ + if ((!hWndParent) && (!hWndOwner)) { - DPRINT("Sending CREATED notify\n"); co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd); } - else - { - DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner); - } /* Initialize and show the window's scrollbars */ if (Wnd->style & WS_VSCROLL) @@ -2420,14 +2218,14 @@ AllocErr: co_UserShowScrollBar(Window, SB_HORZ, TRUE); } - if (dwStyle & WS_VISIBLE) + /* Show the new window */ + if (Cs->style & WS_VISIBLE) { if (Wnd->style & WS_MAXIMIZE) dwShowMode = SW_SHOW; else if (Wnd->style & WS_MINIMIZE) dwShowMode = SW_SHOWMINIMIZED; - DPRINT("IntCreateWindow(): About to show window\n"); co_WinPosShowWindow(Window, dwShowMode); if (Wnd->ExStyle & WS_EX_MDICHILD) @@ -2438,49 +2236,26 @@ AllocErr: } } - /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx, - then my testing shows that windows (2k and XP) creates a CallProc for it immediately - Dont understand why it does this. */ - if (ClassAtom == gpsi->atomSysClass[ICLS_EDIT]) - { - PCALLPROCDATA CallProc; - //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi); - CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi); - - if (!CallProc) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd); - } - else - { - UserAddCallProcToClass(Wnd->pcls, CallProc); - } - } - - DPRINT("IntCreateWindow(): = %X\n", hWnd); - DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu); + DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd); RETURN( Wnd); CLEANUP: - if (!_ret_ && Window && Window->Wnd && ti) - co_UserDestroyWindow(Window); -// UserFreeWindowInfo(ti, Window); + if (!_ret_) + { + /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */ + if (Window) + co_UserDestroyWindow(Window); + else + IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi); + } + if (Window) { UserDerefObjectCo(Window); UserDereferenceObject(Window); } if (ParentWindow) UserDerefObjectCo(ParentWindow); - if (!_ret_ && ti != NULL) - { - if (Class != NULL) - { - IntDereferenceClass(Class, - ti->pDeskInfo, - ti->ppi); - } - } + END_CLEANUP; } @@ -2564,12 +2339,10 @@ NtUserCreateWindowEx( LARGE_STRING lstrWindowName; LARGE_STRING lstrClassName; UNICODE_STRING ustrClassName; + CREATESTRUCTW Cs; HWND hwnd = NULL; PWND pwnd; - DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); - UserEnterExclusive(); - lstrWindowName.Buffer = NULL; lstrClassName.Buffer = NULL; @@ -2580,8 +2353,9 @@ NtUserCreateWindowEx( Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName); if (!NT_SUCCESS(Status)) { + DPRINT1("NtUserCreateWindowEx: failed to capture plstrWindowName\n"); SetLastNtError(Status); - goto leave; + return NULL; } plstrWindowName = &lstrWindowName; } @@ -2600,6 +2374,7 @@ NtUserCreateWindowEx( Status = ProbeAndCaptureLargeString(&lstrClassName, plstrClassName); if (!NT_SUCCESS(Status)) { + DPRINT1("NtUserCreateWindowEx: failed to capture plstrClassName\n"); /* Set last error, cleanup and return */ SetLastNtError(Status); goto cleanup; @@ -2611,24 +2386,36 @@ NtUserCreateWindowEx( ustrClassName.MaximumLength = lstrClassName.MaximumLength; } - /* Call the internal function */ - pwnd = co_IntCreateWindowEx(dwExStyle, - &ustrClassName, - plstrWindowName, - dwStyle, - x, - y, - nWidth, - nHeight, - hWndParent, - hMenu, - hInstance, - lpParam, - SW_SHOW, - !(dwExStyle & WS_EX_SETANSICREATOR)); + /* Fill the CREATESTRUCTW */ + /* we will keep here the original parameters */ + Cs.style = dwStyle; + Cs.lpCreateParams = lpParam; + Cs.hInstance = hInstance; + Cs.hMenu = hMenu; + Cs.hwndParent = hWndParent; + Cs.cx = nWidth; + Cs.cy = nHeight; + Cs.x = x; + Cs.y = y; +// Cs.lpszName = (LPCWSTR) WindowName->Buffer; +// Cs.lpszClass = (LPCWSTR) ClassName->Buffer; + Cs.lpszName = (LPCWSTR) plstrWindowName; + Cs.lpszClass = (LPCWSTR) &ustrClassName; + Cs.dwExStyle = dwExStyle; + UserEnterExclusive(); + + /* Call the internal function */ + pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName); + + if(!pwnd) + { + DPRINT1("co_UserCreateWindowEx failed!\n"); + } hwnd = pwnd ? UserHMGetHandle(pwnd) : NULL; + UserLeave(); + cleanup: if (lstrWindowName.Buffer) { @@ -2639,10 +2426,6 @@ cleanup: ExFreePoolWithTag(lstrClassName.Buffer, TAG_STRING); } -leave: - DPRINT("Leave NtUserCreateWindowEx, hwnd=%i\n", hwnd); - UserLeave(); - return hwnd; } @@ -2957,11 +2740,11 @@ IntFindWindow(PWINDOW_OBJECT Parent, (Child->Wnd->strName.Length < 0xFFFF && !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE))) { - Ret = Child->hSelf; - break; - } + Ret = Child->hSelf; + break; } } + } ExFreePool(List); } diff --git a/reactos/subsystems/win32/win32k/ntuser/winpos.c b/reactos/subsystems/win32/win32k/ntuser/winpos.c index 67e5eadc92f..6a04e8c05c8 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winpos.c +++ b/reactos/subsystems/win32/win32k/ntuser/winpos.c @@ -1463,6 +1463,33 @@ co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientR return Result; } +void FASTCALL +co_WinPosSendSizeMove(PWINDOW_OBJECT Window) +{ + WPARAM wParam = SIZE_RESTORED; + PWND Wnd = Window->Wnd; + + Window->state &= ~WINDOWOBJECT_NEED_SIZE; + if (Wnd->style & WS_MAXIMIZE) + { + wParam = SIZE_MAXIMIZED; + } + else if (Wnd->style & WS_MINIMIZE) + { + wParam = SIZE_MINIMIZED; + } + + co_IntSendMessageNoWait(Window->hSelf, WM_SIZE, wParam, + MAKELONG(Wnd->rcClient.right - + Wnd->rcClient.left, + Wnd->rcClient.bottom - + Wnd->rcClient.top)); + co_IntSendMessageNoWait(Window->hSelf, WM_MOVE, 0, + MAKELONG(Wnd->rcClient.left, + Wnd->rcClient.top)); + IntEngWindowChanged(Window, WOC_RGN_CLIENT); +} + BOOLEAN FASTCALL co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd) { @@ -1621,28 +1648,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd) if ((Window->state & WINDOWOBJECT_NEED_SIZE) && !(Window->state & WINDOWSTATUS_DESTROYING)) { - WPARAM wParam = SIZE_RESTORED; - - Window->state &= ~WINDOWOBJECT_NEED_SIZE; - if (Wnd->style & WS_MAXIMIZE) - { - wParam = SIZE_MAXIMIZED; - } - else if (Wnd->style & WS_MINIMIZE) - { - wParam = SIZE_MINIMIZED; - } - - co_IntSendMessageNoWait(Window->hSelf, WM_SIZE, wParam, - MAKELONG(Wnd->rcClient.right - - Wnd->rcClient.left, - Wnd->rcClient.bottom - - Wnd->rcClient.top)); - co_IntSendMessageNoWait(Window->hSelf, WM_MOVE, 0, - MAKELONG(Wnd->rcClient.left, - Wnd->rcClient.top)); - IntEngWindowChanged(Window, WOC_RGN_CLIENT); - + co_WinPosSendSizeMove(Window); } /* Activate the window if activation is not requested and the window is not minimized */ From bd17e097faf2c38bfaf8ad9412f7a706eb01e36d Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Mon, 31 May 2010 18:38:48 +0000 Subject: [PATCH 161/292] [CMD] Protect certain actions with a critical section, patch by Katayama Hirofumi See issue #5406 for more details. svn path=/trunk/; revision=47502 --- reactos/base/shell/cmd/cmd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/reactos/base/shell/cmd/cmd.c b/reactos/base/shell/cmd/cmd.c index 59f00eada0a..54ff9b23edc 100644 --- a/reactos/base/shell/cmd/cmd.c +++ b/reactos/base/shell/cmd/cmd.c @@ -156,7 +156,7 @@ BOOL bCanExit = TRUE; /* indicates if this shell is exitable */ BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */ BOOL bIgnoreEcho = FALSE; /* Set this to TRUE to prevent a newline, when executing a command */ INT nErrorLevel = 0; /* Errorlevel of last launched external program */ -BOOL bChildProcessRunning = FALSE; +CRITICAL_SECTION ChildProcessRunningLock; BOOL bUnicodeOutput = FALSE; BOOL bDisableBatchEcho = FALSE; BOOL bDelayedExpansion = FALSE; @@ -436,14 +436,12 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) { if (IsConsoleProcess(prci.hProcess)) { - /* FIXME: Protect this with critical section */ - bChildProcessRunning = TRUE; + EnterCriticalSection(&ChildProcessRunningLock); dwChildProcessId = prci.dwProcessId; WaitForSingleObject (prci.hProcess, INFINITE); - /* FIXME: Protect this with critical section */ - bChildProcessRunning = FALSE; + LeaveCriticalSection(&ChildProcessRunningLock); GetExitCodeProcess (prci.hProcess, &dwExitCode); nErrorLevel = (INT)dwExitCode; @@ -665,9 +663,9 @@ ExecutePipeline(PARSED_COMMAND *Cmd) SetStdHandle(STD_INPUT_HANDLE, hOldConIn); /* Wait for all processes to complete */ - bChildProcessRunning = TRUE; + EnterCriticalSection(&ChildProcessRunningLock); WaitForMultipleObjects(nProcesses, hProcess, TRUE, INFINITE); - bChildProcessRunning = FALSE; + LeaveCriticalSection(&ChildProcessRunningLock); /* Use the exit code of the last process in the pipeline */ GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode); @@ -1439,13 +1437,16 @@ BOOL WINAPI BreakHandler (DWORD dwCtrlType) } } - if (bChildProcessRunning == TRUE) + if (!TryEnterCriticalSection(&ChildProcessRunningLock)) { SelfGenerated = TRUE; GenerateConsoleCtrlEvent (dwCtrlType, 0); return TRUE; } - + else + { + LeaveCriticalSection(&ChildProcessRunningLock); + } rec.EventType = KEY_EVENT; rec.Event.KeyEvent.bKeyDown = TRUE; @@ -1797,6 +1798,7 @@ static VOID Cleanup() RemoveBreakHandler (); SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ), ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); + DeleteCriticalSection(&ChildProcessRunningLock); } /* @@ -1808,6 +1810,7 @@ int cmd_main (int argc, const TCHAR *argv[]) TCHAR startPath[MAX_PATH]; CONSOLE_SCREEN_BUFFER_INFO Info; + InitializeCriticalSection(&ChildProcessRunningLock); lpOriginalEnvironment = DuplicateEnvironment(); GetCurrentDirectory(MAX_PATH,startPath); From 86140dbf5a29b2ac2b1177df53a482a88c3d2411 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Mon, 31 May 2010 19:16:14 +0000 Subject: [PATCH 162/292] [EXPLORER_NEW] Display a message box if the explorer registry key cannot be loaded, patch by Katayama Hirofumi See issue #5407 for more details. svn path=/trunk/; revision=47503 --- reactos/base/shell/explorer-new/explorer.c | 4 +++- reactos/base/shell/explorer-new/lang/bg-BG.rc | 1 + reactos/base/shell/explorer-new/lang/cs-CZ.rc | 1 + reactos/base/shell/explorer-new/lang/de-DE.rc | 1 + reactos/base/shell/explorer-new/lang/en-US.rc | 1 + reactos/base/shell/explorer-new/lang/es-ES.rc | 1 + reactos/base/shell/explorer-new/lang/fr-FR.rc | 1 + reactos/base/shell/explorer-new/lang/it-IT.rc | 1 + reactos/base/shell/explorer-new/lang/ja-JP.rc | 1 + reactos/base/shell/explorer-new/lang/ko-KR.rc | 1 + reactos/base/shell/explorer-new/lang/lt-LT.rc | 1 + reactos/base/shell/explorer-new/lang/nl-NL.rc | 1 + reactos/base/shell/explorer-new/lang/no-NO.rc | 1 + reactos/base/shell/explorer-new/lang/pl-PL.rc | 1 + reactos/base/shell/explorer-new/lang/ro-RO.rc | 1 + reactos/base/shell/explorer-new/lang/ru-RU.rc | 1 + reactos/base/shell/explorer-new/lang/sk-SK.rc | 1 + reactos/base/shell/explorer-new/lang/uk-UA.rc | 1 + reactos/base/shell/explorer-new/resource.h | 1 + 19 files changed, 21 insertions(+), 1 deletion(-) diff --git a/reactos/base/shell/explorer-new/explorer.c b/reactos/base/shell/explorer-new/explorer.c index 9c31f33a0fe..8716edc021f 100644 --- a/reactos/base/shell/explorer-new/explorer.c +++ b/reactos/base/shell/explorer-new/explorer.c @@ -284,7 +284,9 @@ _tWinMain(IN HINSTANCE hInstance, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkExplorer) != ERROR_SUCCESS) { - /* FIXME - display error */ + TCHAR Message[256]; + LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256); + MessageBox(NULL, Message, NULL, MB_ICONERROR); return 1; } diff --git a/reactos/base/shell/explorer-new/lang/bg-BG.rc b/reactos/base/shell/explorer-new/lang/bg-BG.rc index 482ae13cede..f4c08db2f04 100644 --- a/reactos/base/shell/explorer-new/lang/bg-BG.rc +++ b/reactos/base/shell/explorer-new/lang/bg-BG.rc @@ -121,6 +121,7 @@ BEGIN IDS_PROPERTIES "&Ñâîéñòâà" IDS_OPEN_ALL_USERS "&Îòâàðÿíå íà âñè÷êè ïîòðåáèòåëè" IDS_EXPLORE_ALL_USERS "&Ðàçëèñòâàíå íà âñè÷êè ïîòðåáèòåëè" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/cs-CZ.rc b/reactos/base/shell/explorer-new/lang/cs-CZ.rc index c82c31a89a0..5273c548ff1 100644 --- a/reactos/base/shell/explorer-new/lang/cs-CZ.rc +++ b/reactos/base/shell/explorer-new/lang/cs-CZ.rc @@ -126,6 +126,7 @@ BEGIN IDS_PROPERTIES "Vl&astnosti" IDS_OPEN_ALL_USERS "Ote&vøít složku All Users" IDS_EXPLORE_ALL_USERS "Pro&cházet složku All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/de-DE.rc b/reactos/base/shell/explorer-new/lang/de-DE.rc index 80aefc0c32a..1173c3ffd90 100644 --- a/reactos/base/shell/explorer-new/lang/de-DE.rc +++ b/reactos/base/shell/explorer-new/lang/de-DE.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "E&igenschaften" IDS_OPEN_ALL_USERS "Öffnen (&Alle Benutzer)" IDS_EXPLORE_ALL_USERS "Explorer (A&lle Benutzer)" + IDS_STARTUP_ERROR "Das System kann den Explorer nicht starten, weil die Registrierung nicht verfügbar bzw. fehlerhaft ist." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/en-US.rc b/reactos/base/shell/explorer-new/lang/en-US.rc index 9e1d6876fde..c98a1face25 100644 --- a/reactos/base/shell/explorer-new/lang/en-US.rc +++ b/reactos/base/shell/explorer-new/lang/en-US.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&roperties" IDS_OPEN_ALL_USERS "O&pen All Users" IDS_EXPLORE_ALL_USERS "E&xplore All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/es-ES.rc b/reactos/base/shell/explorer-new/lang/es-ES.rc index b0dcd7ef349..86e83e4ebf1 100644 --- a/reactos/base/shell/explorer-new/lang/es-ES.rc +++ b/reactos/base/shell/explorer-new/lang/es-ES.rc @@ -129,6 +129,7 @@ BEGIN IDS_PROPERTIES "P&ropiedades" IDS_OPEN_ALL_USERS "A&brir todos los usuarios" IDS_EXPLORE_ALL_USERS "E&xplorar todos los usuarios" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/fr-FR.rc b/reactos/base/shell/explorer-new/lang/fr-FR.rc index 57587e9882d..35227391c08 100644 --- a/reactos/base/shell/explorer-new/lang/fr-FR.rc +++ b/reactos/base/shell/explorer-new/lang/fr-FR.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&ropriétés" IDS_OPEN_ALL_USERS "Ouvrir tous les utilisateurs" IDS_EXPLORE_ALL_USERS "E&xplorer tous les utilisateurs" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/it-IT.rc b/reactos/base/shell/explorer-new/lang/it-IT.rc index 443c32d624e..ac243130ed6 100644 --- a/reactos/base/shell/explorer-new/lang/it-IT.rc +++ b/reactos/base/shell/explorer-new/lang/it-IT.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "&Proprietà" IDS_OPEN_ALL_USERS "&Apri tutti gli utenti" IDS_EXPLORE_ALL_USERS "&Esplora tutti gli utenti" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/ja-JP.rc b/reactos/base/shell/explorer-new/lang/ja-JP.rc index 5084e2c79b2..66b55a294a9 100644 --- a/reactos/base/shell/explorer-new/lang/ja-JP.rc +++ b/reactos/base/shell/explorer-new/lang/ja-JP.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "ƒvƒƒpƒeƒB(&R)" IDS_OPEN_ALL_USERS "ŠJ‚­ - All Users(&P)" IDS_EXPLORE_ALL_USERS "ƒGƒNƒXƒvƒ[ƒ‰ - All Users(&E)" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/ko-KR.rc b/reactos/base/shell/explorer-new/lang/ko-KR.rc index 0232ae1d59b..adbafd39641 100644 --- a/reactos/base/shell/explorer-new/lang/ko-KR.rc +++ b/reactos/base/shell/explorer-new/lang/ko-KR.rc @@ -125,6 +125,7 @@ BEGIN IDS_PROPERTIES "¼Ó¼º(&R)" IDS_OPEN_ALL_USERS "¿­±â - All Users(&P)" IDS_EXPLORE_ALL_USERS "Ž»ö - All Users(&X)" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/lt-LT.rc b/reactos/base/shell/explorer-new/lang/lt-LT.rc index 5c3c0c69efe..b0dd8e57f62 100644 --- a/reactos/base/shell/explorer-new/lang/lt-LT.rc +++ b/reactos/base/shell/explorer-new/lang/lt-LT.rc @@ -124,6 +124,7 @@ BEGIN IDS_PROPERTIES "&Parametrai" IDS_OPEN_ALL_USERS "&Atverti visus vartotojus" IDS_EXPLORE_ALL_USERS "&Narðyti visus vartotojus" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/nl-NL.rc b/reactos/base/shell/explorer-new/lang/nl-NL.rc index 3dcf5183a7e..135956e86c2 100644 --- a/reactos/base/shell/explorer-new/lang/nl-NL.rc +++ b/reactos/base/shell/explorer-new/lang/nl-NL.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "&Eigenschappen" IDS_OPEN_ALL_USERS "&Alle Gebruikers weergeven" IDS_EXPLORE_ALL_USERS "Alle Gebruikers V&erkennen" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/no-NO.rc b/reactos/base/shell/explorer-new/lang/no-NO.rc index 583fa140de8..d06d1aaf3f2 100644 --- a/reactos/base/shell/explorer-new/lang/no-NO.rc +++ b/reactos/base/shell/explorer-new/lang/no-NO.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "E&genskaper" IDS_OPEN_ALL_USERS "Å&pne alle brukere" IDS_EXPLORE_ALL_USERS "U&tforsk alle brukere" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/pl-PL.rc b/reactos/base/shell/explorer-new/lang/pl-PL.rc index 22a67438dfa..891c8c915c2 100644 --- a/reactos/base/shell/explorer-new/lang/pl-PL.rc +++ b/reactos/base/shell/explorer-new/lang/pl-PL.rc @@ -123,6 +123,7 @@ BEGIN IDS_PROPERTIES "W³aœ&ciwoœci" IDS_OPEN_ALL_USERS "&Otwórz - wszyscy u¿ytkownicy" IDS_EXPLORE_ALL_USERS "&Eksploruj - wszyscy u¿ytkownicy" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/ro-RO.rc b/reactos/base/shell/explorer-new/lang/ro-RO.rc index f18c0a8f57e..f583672499c 100644 --- a/reactos/base/shell/explorer-new/lang/ro-RO.rc +++ b/reactos/base/shell/explorer-new/lang/ro-RO.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&roprietãþi" IDS_OPEN_ALL_USERS "Deschidere& Toþi Utilizatorii" IDS_EXPLORE_ALL_USERS "E&xplorare Toþi Utilizatorii" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/ru-RU.rc b/reactos/base/shell/explorer-new/lang/ru-RU.rc index c5d54139dc4..7a21b150a74 100644 --- a/reactos/base/shell/explorer-new/lang/ru-RU.rc +++ b/reactos/base/shell/explorer-new/lang/ru-RU.rc @@ -122,6 +122,7 @@ BEGIN IDS_PROPERTIES "&Ñâîéñòâà" IDS_OPEN_ALL_USERS "&Âñå ïîëüçîâàòåëè" IDS_EXPLORE_ALL_USERS "&Îáçîð Âñåõ ïîëüçîâàòåëåé" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/sk-SK.rc b/reactos/base/shell/explorer-new/lang/sk-SK.rc index 8cd7c5b9aca..c6329c7e695 100644 --- a/reactos/base/shell/explorer-new/lang/sk-SK.rc +++ b/reactos/base/shell/explorer-new/lang/sk-SK.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "Vl&astnosti" IDS_OPEN_ALL_USERS "&Otvori profil All Users" IDS_EXPLORE_ALL_USERS "&Preskúma profil All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/lang/uk-UA.rc b/reactos/base/shell/explorer-new/lang/uk-UA.rc index d02ee30f9e2..65462be70a4 100644 --- a/reactos/base/shell/explorer-new/lang/uk-UA.rc +++ b/reactos/base/shell/explorer-new/lang/uk-UA.rc @@ -128,6 +128,7 @@ BEGIN IDS_PROPERTIES "Â&ëàñòèâîñò³" IDS_OPEN_ALL_USERS "&Âñ³ êîðèñòóâà÷³" IDS_EXPLORE_ALL_USERS "&Îãëÿä âñ³õ êîðèñòóâà÷³â" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/reactos/base/shell/explorer-new/resource.h b/reactos/base/shell/explorer-new/resource.h index 0ab9222f778..dbdf9c1bef9 100644 --- a/reactos/base/shell/explorer-new/resource.h +++ b/reactos/base/shell/explorer-new/resource.h @@ -8,6 +8,7 @@ #define IDS_PROPERTIES 102 #define IDS_OPEN_ALL_USERS 103 #define IDS_EXPLORE_ALL_USERS 104 +#define IDS_STARTUP_ERROR 105 #define IDC_STARTBTN 304 From 19d33c5dc1456df253a2cae89b656c3a0ae62416 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Mon, 31 May 2010 20:09:13 +0000 Subject: [PATCH 163/292] [RAPPS] Create a new download directory if the user agrees to do so, based on a patch by Seungju Kim. Translations except German and English should be updated to reflect the changed intention. See issue #5196 for more details. svn path=/trunk/; revision=47504 --- reactos/base/applications/rapps/lang/de-DE.rc | 2 +- reactos/base/applications/rapps/lang/en-US.rc | 2 +- reactos/base/applications/rapps/settingsdlg.c | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/reactos/base/applications/rapps/lang/de-DE.rc b/reactos/base/applications/rapps/lang/de-DE.rc index b48f0ea2229..ea4dbc80de6 100644 --- a/reactos/base/applications/rapps/lang/de-DE.rc +++ b/reactos/base/applications/rapps/lang/de-DE.rc @@ -185,7 +185,7 @@ BEGIN IDS_UPDATES "Aktualisierungen" IDS_APPLICATIONS "Anwendungen" IDS_CHOOSE_FOLDER_TEXT "Wählen Sie ein Verzeichnis aus, das zum Herunterladen verwendet werden soll:" - IDS_CHOOSE_FOLDER_ERROR "Sie haben ein nicht existentes Verzeichnis angegeben!" + IDS_CHOOSE_FOLDER_ERROR "Sie haben ein nicht existierendes Verzeichnis angegeben! Neu anlegen?" IDS_USER_NOT_ADMIN "Sie müssen als Administrator angemeldet sein, um den Anwendungsmanager zu starten!" IDS_APP_REG_REMOVE "Sind Sie sich sicher, dass Sie die Daten dieses Programms aus der Registry entfernen möchten?" IDS_INFORMATION "Informationen" diff --git a/reactos/base/applications/rapps/lang/en-US.rc b/reactos/base/applications/rapps/lang/en-US.rc index f8d018923dc..677ca86c13b 100644 --- a/reactos/base/applications/rapps/lang/en-US.rc +++ b/reactos/base/applications/rapps/lang/en-US.rc @@ -185,7 +185,7 @@ BEGIN IDS_UPDATES "Updates" IDS_APPLICATIONS "Applications" IDS_CHOOSE_FOLDER_TEXT "Choose a folder which will store Downloads:" - IDS_CHOOSE_FOLDER_ERROR "The folder you have specified does not exist." + IDS_CHOOSE_FOLDER_ERROR "The folder you have specified does not exist. Create it?" IDS_USER_NOT_ADMIN "You must be an administrator to start ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Are you sure you want to delete the data on the installed program from the registry?" IDS_INFORMATION "Information" diff --git a/reactos/base/applications/rapps/settingsdlg.c b/reactos/base/applications/rapps/settingsdlg.c index 3764f0140bb..77034c51f5a 100644 --- a/reactos/base/applications/rapps/settingsdlg.c +++ b/reactos/base/applications/rapps/settingsdlg.c @@ -115,7 +115,14 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) IDS_CHOOSE_FOLDER_ERROR, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)); - MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR); + if (MessageBoxW(hDlg, szMsgText, NULL, MB_YESNO) == IDYES) + { + if (CreateDirectoryW(szDir, NULL)) + { + EndDialog(hDlg, LOWORD(wParam)); + } + } + SetFocus(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT)); break; } From f4d415767d962f787b7897014933766667aa340e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 31 May 2010 22:34:16 +0000 Subject: [PATCH 164/292] [SMSS] - Create a new default paging file if no paging files exist. - Set the calculated paging file sizes in the registry. - Remove predefined paging file name from the hivesys*.inf files. Fixes bug #4048. svn path=/trunk/; revision=47505 --- reactos/base/system/smss/initpage.c | 290 +++++++++++++++++++++++-- reactos/boot/bootdata/hivesys_arm.inf | 5 +- reactos/boot/bootdata/hivesys_i386.inf | 5 +- 3 files changed, 276 insertions(+), 24 deletions(-) diff --git a/reactos/base/system/smss/initpage.c b/reactos/base/system/smss/initpage.c index 9b889377de6..7ec19985463 100644 --- a/reactos/base/system/smss/initpage.c +++ b/reactos/base/system/smss/initpage.c @@ -225,34 +225,288 @@ Cleanup: } +static NTSTATUS +SmpGetFreeDiskSpace(IN PWSTR PageFileName, + OUT PLARGE_INTEGER FreeDiskSpaceInMB) +{ + FILE_FS_SIZE_INFORMATION FileFsSize; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; + UNICODE_STRING NtPathU; + LARGE_INTEGER FreeBytes; + OBJECT_ATTRIBUTES ObjectAttributes; + WCHAR RootPath[5]; + NTSTATUS Status; + + /* + * copy the drive letter, the colon and the slash, + * tack a null on the end + */ + RootPath[0] = PageFileName[0]; + RootPath[1] = L':'; + RootPath[2] = L'\\'; + RootPath[3] = L'\0'; + + DPRINT("Root drive X:\\...\"%S\"\n",RootPath); + + if (!RtlDosPathNameToNtPathName_U(RootPath, + &NtPathU, + NULL, + NULL)) + { + DPRINT1("Invalid path to root of drive\n"); + return STATUS_OBJECT_PATH_INVALID; + } + + InitializeObjectAttributes(&ObjectAttributes, + &NtPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Get a handle to the root to find the free space on the drive */ + Status = NtCreateFile(&hFile, + 0, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL, + 0); + + RtlFreeHeap(RtlGetProcessHeap(), + 0, + NtPathU.Buffer); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not open a handle to the volume.\n"); + return Status; + } + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FileFsSize, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + + NtClose(hFile); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Querying the volume free space failed!\n"); + return Status; + } + + FreeBytes.QuadPart = FileFsSize.BytesPerSector * + FileFsSize.SectorsPerAllocationUnit * + FileFsSize.AvailableAllocationUnits.QuadPart; + + FreeDiskSpaceInMB->QuadPart = FreeBytes.QuadPart >> 20; + + return STATUS_SUCCESS; +} + + +static NTSTATUS +SmpSetDefaultPageFileData(IN PWSTR PageFileName, + IN PLARGE_INTEGER InitialSizeInMB, + IN PLARGE_INTEGER MaximumSizeInMB) +{ + WCHAR ValueString[MAX_PATH * 2]; + ULONG ValueLength; + + /* Format the value string */ + swprintf(ValueString, + L"%s %I64u %I64u", + PageFileName, + InitialSizeInMB->QuadPart, + MaximumSizeInMB->QuadPart); + + /* + * Append another zero character because it is a multi string value + * (REG_MULTI_SZ) and calculate the total string length. + */ + ValueLength = wcslen(ValueString) + 1; + ValueString[ValueLength] = 0; + ValueLength++; + + /* Write the page file data */ + return RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, + L"\\Session Manager\\Memory Management", + L"PagingFiles", + REG_MULTI_SZ, + ValueString, + ValueLength * sizeof(WCHAR)); +} + + +static NTSTATUS +SmpCreatePageFile(IN PWSTR PageFileName, + IN PLARGE_INTEGER InitialSizeInMB, + IN PLARGE_INTEGER MaximumSizeInMB) +{ + LARGE_INTEGER InitialSize; + LARGE_INTEGER MaximumSize; + UNICODE_STRING FileName; + NTSTATUS Status; + + /* Get the NT path name of the page file */ + if (!RtlDosPathNameToNtPathName_U(PageFileName, + &FileName, + NULL, + NULL)) + { + return STATUS_OBJECT_PATH_INVALID; + } + + /* Convert sizes in megabytes to sizes in bytes */ + InitialSize.QuadPart = InitialSizeInMB->QuadPart << 20; + MaximumSize.QuadPart = MaximumSizeInMB->QuadPart << 20; + + /* Create the pageing file */ + Status = NtCreatePagingFile(&FileName, + &InitialSize, + &MaximumSize, + 0); + if (! NT_SUCCESS(Status)) + { + DPRINT("Creation of paging file %wZ with size %I64d MB failed (status 0x%x)\n", + &FileName, InitialSizeInMB->QuadPart, Status); + } + + /* Release the file name */ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + FileName.Buffer); + + return Status; +} + + +static NTSTATUS +SmpCreateDefaultPagingFile(VOID) +{ + SYSTEM_BASIC_INFORMATION SysBasicInfo; + LARGE_INTEGER MemorySizeInMB; + LARGE_INTEGER FreeDiskSpaceInMB; + LARGE_INTEGER InitialSizeInMB; + LARGE_INTEGER MaximumSizeInMB; + NTSTATUS Status = STATUS_SUCCESS; + WCHAR PageFileName[MAX_PATH]; + + DPRINT("Creating a default paging file\n"); + + Status = NtQuerySystemInformation(SystemBasicInformation, + &SysBasicInfo, + sizeof(SysBasicInfo), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not query for physical memory size.\n"); + return Status; + } + + DPRINT("PageSize: %d, PhysicalPages: %d, TotalMem: %d\n", + SysBasicInfo.PageSize, + SysBasicInfo.NumberOfPhysicalPages, + (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) / 1024); + + MemorySizeInMB.QuadPart = (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) >> 20; + + DPRINT("MemorySize %I64u MB\n", + MemorySizeInMB.QuadPart); + + /* Build the default page file name */ + PageFileName[0] = SharedUserData->NtSystemRoot[0]; + PageFileName[1] = 0; + wcscat(PageFileName, L":\\pagefile.sys"); + + Status = SmpGetFreeDiskSpace(PageFileName, + &FreeDiskSpaceInMB); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + DPRINT("FreeDiskSpace %I64u MB\n", + FreeDiskSpaceInMB.QuadPart); + + InitialSizeInMB.QuadPart = MemorySizeInMB.QuadPart + (MemorySizeInMB.QuadPart / 2); + MaximumSizeInMB.QuadPart = InitialSizeInMB.QuadPart * 2; + + if (InitialSizeInMB.QuadPart > (FreeDiskSpaceInMB.QuadPart / 4)) + { + DPRINT("Inital Size took more then 25%% of free disk space\n"); + + /* + * Set by percentage of free space + * intial is 20%, and max is 25% + */ + InitialSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 5; + MaximumSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 4; + + /* The page file is more then a gig, size it down */ + if (InitialSizeInMB.QuadPart > 1024) + { + InitialSizeInMB.QuadPart = 1024; /* 1GB */ + MaximumSizeInMB.QuadPart = 1536; /* 1.5GB */ + } + } + + DPRINT("InitialSize %I64u MB MaximumSize %I64u MB\n", + InitialSizeInMB.QuadPart, + MaximumSizeInMB.QuadPart); + + Status = SmpSetDefaultPageFileData(PageFileName, + &InitialSizeInMB, + &MaximumSizeInMB); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + return SmpCreatePageFile(PageFileName, + &InitialSizeInMB, + &MaximumSizeInMB); +} + + NTSTATUS SmCreatePagingFiles(VOID) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + NTSTATUS Status; - DPRINT("creating system paging files\n"); - /* - * Disable paging file on MiniNT/Live CD. - */ - if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS) + DPRINT("creating system paging files\n"); + + /* Disable paging file on MiniNT/Live CD. */ + if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); - QueryTable[0].Name = L"PagingFiles"; - QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine; + QueryTable[0].Name = L"PagingFiles"; + QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; - Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, - L"\\Session Manager\\Memory Management", - QueryTable, - NULL, - NULL); + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, + L"\\Session Manager\\Memory Management", + QueryTable, + NULL, + NULL); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = SmpCreateDefaultPagingFile(); + } - return(Status); + return Status; } diff --git a/reactos/boot/bootdata/hivesys_arm.inf b/reactos/boot/bootdata/hivesys_arm.inf index dbe7d1b210c..51f2dc8dd63 100644 --- a/reactos/boot/bootdata/hivesys_arm.inf +++ b/reactos/boot/bootdata/hivesys_arm.inf @@ -783,9 +783,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","version",0x00 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wininet",0x00000000,"wininet.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll" -; Pagefile settings -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00010000, \ - "C:\pagefile.sys" +; Memory Management +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management",,0x00000012 ; Subsystems HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Debug",0x00020000,"" diff --git a/reactos/boot/bootdata/hivesys_i386.inf b/reactos/boot/bootdata/hivesys_i386.inf index f234ee90b98..544f51059f3 100644 --- a/reactos/boot/bootdata/hivesys_i386.inf +++ b/reactos/boot/bootdata/hivesys_i386.inf @@ -930,9 +930,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","version",0x00 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wininet",0x00000000,"wininet.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll" -; Pagefile settings -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00010000, \ - "C:\pagefile.sys" +; Memory Management +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management",,0x00000012 ; Subsystems HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Debug",0x00020000,"" From 85c99c26cb2e87d48052aa0b948a676ee9b6f80b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 1 Jun 2010 02:44:15 +0000 Subject: [PATCH 165/292] [NPFS] - Acquire the cancel spin lock before calling IoSetCancelRoutine - Remove the old cancellation code - Don't use the CCB stored in the IRP because it could be invalid depending on the state of the IRP - Simplify thread termination - Fixes random crash during rpcrt4:ndr_marshall test svn path=/trunk/; revision=47506 --- reactos/drivers/filesystems/npfs/rw.c | 59 +++++---------------------- 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index c9d7cfc64e6..6f8675ed754 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -122,14 +122,9 @@ NpfsWaiterThread(PVOID InitContext) ULONG CurrentCount; ULONG Count = 0, i; PIRP Irp = NULL; - PIRP NextIrp; NTSTATUS Status; - BOOLEAN Terminate = FALSE; - BOOLEAN Cancel = FALSE; PIO_STACK_LOCATION IoStack = NULL; - PNPFS_CONTEXT Context; - PNPFS_CONTEXT NextContext; - PNPFS_CCB Ccb; + KIRQL OldIrql; KeLockMutex(&ThreadContext->DeviceExt->PipeListLock); @@ -137,29 +132,23 @@ NpfsWaiterThread(PVOID InitContext) { CurrentCount = ThreadContext->Count; KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock); - if (Irp) + IoAcquireCancelSpinLock(&OldIrql); + if (Irp && IoSetCancelRoutine(Irp, NULL) != NULL) { - if (Cancel) + IoReleaseCancelSpinLock(OldIrql); + IoStack = IoGetCurrentIrpStackLocation(Irp); + switch (IoStack->MajorFunction) { - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - else - { - switch (IoStack->MajorFunction) - { case IRP_MJ_READ: NpfsRead(IoStack->DeviceObject, Irp); break; default: ASSERT(FALSE); - } } } - if (Terminate) + else { - break; + IoReleaseCancelSpinLock(OldIrql); } Status = KeWaitForMultipleObjects(CurrentCount, ThreadContext->WaitObjectArray, @@ -183,35 +172,6 @@ NpfsWaiterThread(PVOID InitContext) ThreadContext->DeviceExt->EmptyWaiterCount++; ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count]; ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count]; - - Cancel = (NULL == IoSetCancelRoutine(Irp, NULL)); - Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext; - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (Cancel) - { - Ccb = IoStack->FileObject->FsContext2; - ExAcquireFastMutex(&Ccb->DataListLock); - RemoveEntryList(&Context->ListEntry); - switch (IoStack->MajorFunction) - { - case IRP_MJ_READ: - if (!IsListEmpty(&Ccb->ReadRequestListHead)) - { - /* put the next request on the wait list */ - NextContext = CONTAINING_RECORD(Ccb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry); - ThreadContext->WaitObjectArray[ThreadContext->Count] = NextContext->WaitEvent; - NextIrp = CONTAINING_RECORD(NextContext, IRP, Tail.Overlay.DriverContext); - ThreadContext->WaitIrpArray[ThreadContext->Count] = NextIrp; - ThreadContext->Count++; - ThreadContext->DeviceExt->EmptyWaiterCount--; - } - break; - default: - ASSERT(FALSE); - } - ExReleaseFastMutex(&Ccb->DataListLock); - } } else { @@ -235,7 +195,8 @@ NpfsWaiterThread(PVOID InitContext) /* it exist an other thread with empty wait slots, we can remove our thread from the list */ RemoveEntryList(&ThreadContext->ListEntry); ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1; - Terminate = TRUE; + KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock); + break; } } ExFreePool(ThreadContext); From cfc0d726f231f8e18dff4651f52617de87be08a3 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Tue, 1 Jun 2010 06:43:47 +0000 Subject: [PATCH 166/292] Add the non yet working FF 3.6 and AbiWord 2.8.5 to rapps to simplify testing. Sync the rest svn path=/trunk/; revision=47507 --- .../applications/rapps/rapps/abiword28x.txt | 21 ++++++++++ .../applications/rapps/rapps/firefox36.txt | 42 +++++++++++++++++++ .../base/applications/rapps/rapps/rosbe.txt | 8 ++-- .../base/applications/rapps/rapps/scite.txt | 4 +- 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 reactos/base/applications/rapps/rapps/abiword28x.txt create mode 100644 reactos/base/applications/rapps/rapps/firefox36.txt diff --git a/reactos/base/applications/rapps/rapps/abiword28x.txt b/reactos/base/applications/rapps/rapps/abiword28x.txt new file mode 100644 index 00000000000..0e4001cd493 --- /dev/null +++ b/reactos/base/applications/rapps/rapps/abiword28x.txt @@ -0,0 +1,21 @@ +; UTF-8 + +[Section] +Name = AbiWord +Version = 2.8.5 +Licence = GPL +Description = Word processor. +Size = 7.9MB +Category = 6 +URLSite = http://www.abisource.com/ +URLDownload = http://www.abisource.com/downloads/abiword/2.8.5/Windows/abiword-setup-2.8.5.exe +CDPath = none + +[Section.0407] +Description = Textverarbeitung. + +[Section.040a] +Description = Procesador de textos. + +[Section.0415] +Description = Edytor tekstu. diff --git a/reactos/base/applications/rapps/rapps/firefox36.txt b/reactos/base/applications/rapps/rapps/firefox36.txt new file mode 100644 index 00000000000..f605dc063be --- /dev/null +++ b/reactos/base/applications/rapps/rapps/firefox36.txt @@ -0,0 +1,42 @@ +; UTF-8 + +[Section] +Name = Mozilla Firefox 3.6 +Version = 3.6.3 +Licence = MPL/GPL/LGPL +Description = The most popular and one of the best free Web Browsers out there. +Size = 8.0M +Category = 5 +URLSite = http://www.mozilla.com/en-US/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe +CDPath = none + +[Section.0407] +Description = Der populärste und einer der besten freien Webbrowser. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/de/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/de/Firefox%20Setup%203.6.3.exe + +[Section.040a] +Description = El más popular y uno de los mejores navegadores web gratuitos que hay. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/es/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/es-ES/Firefox%20Setup%203.6.3.exe + +[Section.0414] +Description = Mest populære og best ogsÃ¥ gratis nettleserene der ute. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/no/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/nb-NO/Firefox%20Setup%203.6.3.exe + +[Section.0415] +Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. +Size = 8.6M +URLSite = http://www.mozilla-europe.org/pl/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/pl/Firefox%20Setup%203.6.3.exe + +[Section.0419] +Description = Один из Ñамых популÑрных и лучших беÑплатных браузеров. +Size = 8.2M +URLSite = http://www.mozilla-europe.org/ru/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/ru/Firefox%20Setup%203.6.3.exe diff --git a/reactos/base/applications/rapps/rapps/rosbe.txt b/reactos/base/applications/rapps/rapps/rosbe.txt index 384df84563a..a019299b9d1 100644 --- a/reactos/base/applications/rapps/rapps/rosbe.txt +++ b/reactos/base/applications/rapps/rapps/rosbe.txt @@ -2,13 +2,13 @@ [Section] Name = ReactOS Build Environment -Version = 1.5.1 +Version = 1.5.1.1 Licence = GPL Description = Allows you to build the ReactOS Source. For more instructions see ReactOS wiki. -Size = 13.5MB +Size = 13.8MB Category = 7 -URLSite = http://reactos.org/wiki/Build_Environment/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/reactos/RosBE-1.5.1.exe +URLSite = http://reactos.org/wiki/Build_Environment +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/reactos/RosBE-1.5.1.1.exe CDPath = none [Section.0407] diff --git a/reactos/base/applications/rapps/rapps/scite.txt b/reactos/base/applications/rapps/rapps/scite.txt index c32df9cd195..2da34b49e95 100644 --- a/reactos/base/applications/rapps/rapps/scite.txt +++ b/reactos/base/applications/rapps/rapps/scite.txt @@ -2,13 +2,13 @@ [Section] Name = SciTE -Version = 2.11 +Version = 2.12 Licence = Freeware Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs. Size = 0.6M Category = 7 URLSite = http://www.scintilla.org/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc211.exe +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc212.exe CDPath = none [Section.0407] From f346021e6cec3f6a3631e88f84a4ee042b953748 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 1 Jun 2010 08:43:50 +0000 Subject: [PATCH 167/292] [NPFS] - Return buffer size if the buffer is too small svn path=/trunk/; revision=47508 --- reactos/drivers/filesystems/npfs/volume.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/volume.c b/reactos/drivers/filesystems/npfs/volume.c index 4241c88ec3d..63eb0773b91 100644 --- a/reactos/drivers/filesystems/npfs/volume.c +++ b/reactos/drivers/filesystems/npfs/volume.c @@ -23,12 +23,15 @@ NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo); if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) + { + *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION); return STATUS_BUFFER_OVERFLOW; + } FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE; FsDeviceInfo->Characteristics = 0; - *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION); + *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION); DPRINT("NpfsQueryFsDeviceInformation() finished.\n"); @@ -44,7 +47,10 @@ NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8) + { + *BufferLength = (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); return STATUS_BUFFER_OVERFLOW; + } FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; FsAttributeInfo->MaximumComponentNameLength = 255; @@ -53,7 +59,7 @@ NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, L"NPFS"); DPRINT("NpfsQueryFsAttributeInformation() finished.\n"); - *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); + *BufferLength = (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); return STATUS_SUCCESS; } @@ -102,10 +108,8 @@ NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, } Irp->IoStatus.Status = Status; - if (NT_SUCCESS(Status)) - Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength; - else - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = BufferLength; + IoCompleteRequest(Irp, IO_NO_INCREMENT); From 5e80db9d5e6a7f0a30ef00ad27b70d91c4e9ef4d Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 1 Jun 2010 09:12:32 +0000 Subject: [PATCH 168/292] [NPFS] - Add more buffer checks - Clear DO_DEVICE_INITIALIZING flag svn path=/trunk/; revision=47509 --- reactos/drivers/filesystems/npfs/finfo.c | 51 ++++++++++++++++++++---- reactos/drivers/filesystems/npfs/npfs.c | 1 + 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/finfo.c b/reactos/drivers/filesystems/npfs/finfo.c index 18c53414d64..fbb1d6090de 100644 --- a/reactos/drivers/filesystems/npfs/finfo.c +++ b/reactos/drivers/filesystems/npfs/finfo.c @@ -26,6 +26,13 @@ NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject, PFILE_PIPE_INFORMATION Request; DPRINT("NpfsSetPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_INFORMATION)) + { + /* Buffer too small */ + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* Get the Pipe and data */ Fcb = Ccb->Fcb; Request = (PFILE_PIPE_INFORMATION)Info; @@ -63,6 +70,12 @@ NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, PFILE_PIPE_REMOTE_INFORMATION Request; DPRINT("NpfsSetPipeRemoteInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + return STATUS_INFO_LENGTH_MISMATCH; + } + /* Get the Pipe and data */ Fcb = Ccb->Fcb; Request = (PFILE_PIPE_REMOTE_INFORMATION)Info; @@ -86,6 +99,13 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject, ULONG ConnectionSideReadMode; DPRINT("NpfsQueryPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + /* Get the Pipe */ Fcb = Ccb->Fcb; @@ -100,7 +120,7 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject, Info->ReadMode = ConnectionSideReadMode; /* Return success */ - *BufferLength -= sizeof(FILE_PIPE_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_INFORMATION); return STATUS_SUCCESS; } @@ -114,6 +134,13 @@ NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, PNPFS_FCB Fcb; DPRINT("NpfsQueryPipeRemoteInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + /* Get the Pipe */ Fcb = Ccb->Fcb; @@ -125,7 +152,7 @@ NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, Info->CollectDataTime = Fcb->TimeOut; /* Return success */ - *BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); return STATUS_SUCCESS; } @@ -140,11 +167,21 @@ NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject, DPRINT("NpfsQueryLocalPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + + /* Get the Pipe */ Fcb = Ccb->Fcb; + /* Clear Info */ RtlZeroMemory(Info, sizeof(FILE_PIPE_LOCAL_INFORMATION)); + /* Return Info */ Info->NamedPipeType = Fcb->PipeType; Info->NamedPipeConfiguration = Fcb->PipeConfiguration; Info->MaximumInstances = Fcb->MaximumInstances; @@ -165,7 +202,7 @@ NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject, Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable; } - *BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_LOCAL_INFORMATION); return STATUS_SUCCESS; } @@ -226,14 +263,12 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject, default: Status = STATUS_NOT_SUPPORTED; + BufferLength = 0; } Irp->IoStatus.Status = Status; - if (NT_SUCCESS(Status)) - Irp->IoStatus.Information = - IoStack->Parameters.QueryFile.Length - BufferLength; - else - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = BufferLength; + IoCompleteRequest (Irp, IO_NO_INCREMENT); return Status; diff --git a/reactos/drivers/filesystems/npfs/npfs.c b/reactos/drivers/filesystems/npfs/npfs.c index ed6d6005221..147f4107b52 100644 --- a/reactos/drivers/filesystems/npfs/npfs.c +++ b/reactos/drivers/filesystems/npfs/npfs.c @@ -70,6 +70,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, /* initialize the device object */ DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; /* initialize the device extension */ DeviceExtension = DeviceObject->DeviceExtension; From 5fafb510795f5dee26fb403c995a724389d0bcb9 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 1 Jun 2010 09:22:10 +0000 Subject: [PATCH 169/292] Add invariant checks and fix a bug: Copy+Paste error misusing OldFlink svn path=/trunk/; revision=47510 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 47 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 0a7ea0730b3..a86611b503e 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -16,6 +16,16 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +#define ASSERT_LIST_INVARIANT(x) \ +do { \ + ASSERT(((x)->Total == 0 && \ + (x)->Flink == LIST_HEAD && \ + (x)->Blink == LIST_HEAD) || \ + ((x)->Total != 0 && \ + (x)->Flink != LIST_HEAD && \ + (x)->Blink != LIST_HEAD)); \ +} while (0) + /* GLOBALS ********************************************************************/ BOOLEAN MmDynamicPfn; @@ -49,6 +59,9 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, { PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); + /* Get the back link */ OldBlink = ListHead->Blink; if (OldBlink != LIST_HEAD) @@ -69,6 +82,7 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, /* And now the head points back to us, since we are last */ ListHead->Blink = EntryIndex; ListHead->Total++; + ASSERT_LIST_INVARIANT(ListHead); } VOID @@ -97,6 +111,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* Use the zero list */ ListHead = &MmZeroedPageListHead; + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the back link */ @@ -136,6 +151,9 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* Otherwise check if we reached the high threshold and signal the event */ KeSetEvent(MiHighMemoryEvent, 0, FALSE); } + + ASSERT_LIST_INVARIANT(ListHead); + #if 0 /* Get the page color */ Color = EntryIndex & MmSecondaryColorMask; @@ -177,7 +195,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) /* Make sure the PFN lock is held */ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - + /* Make sure the PFN entry isn't in-use */ ASSERT(Entry->u3.e1.WriteInProgress == 0); ASSERT(Entry->u3.e1.ReadInProgress == 0); @@ -187,6 +205,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) ListName = ListHead->ListName; ASSERT(ListHead != NULL); ASSERT(ListName <= FreePageList); + ASSERT_LIST_INVARIANT(ListHead); /* Remove one count */ ASSERT(ListHead->Total != 0); @@ -205,7 +224,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) else { /* Set the list head's backlink instead */ - ListHead->Blink = OldFlink; + ListHead->Blink = OldBlink; } /* Check if the back entry is the list head */ @@ -222,6 +241,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) /* We are not on a list anymore */ Entry->u1.Flink = Entry->u2.Blink = 0; + ASSERT_LIST_INVARIANT(ListHead); /* FIXME: Deal with color list */ @@ -272,6 +292,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, /* Could be either on free or zero list */ ListHead = MmPageLocationList[Pfn1->u3.e1.PageLocation]; + ASSERT_LIST_INVARIANT(ListHead); ListName = ListHead->ListName; ASSERT(ListName <= FreePageList); @@ -313,6 +334,9 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, Pfn1->u3.e2.ShortFlags = 0; Pfn1->u3.e1.PageColor = OldColor; Pfn1->u3.e1.CacheAttribute = OldCache; + + ASSERT_LIST_INVARIANT(ListHead); + #if 0 // When switching to ARM3 /* Get the first page on the color list */ ColorTable = &MmFreePagesByColor[ListName][Color]; @@ -379,12 +403,13 @@ MiRemoveAnyPage(IN ULONG Color) { #endif /* Check the free list */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); PageIndex = MmFreePageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; if (PageIndex == LIST_HEAD) { /* Check the zero list */ - ASSERT(MmFreePageListHead.Total == 0); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); PageIndex = MmZeroedPageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; ASSERT(PageIndex != LIST_HEAD); @@ -410,6 +435,9 @@ MiRemoveAnyPage(IN ULONG Color) ASSERT(Pfn1->u2.ShareCount == 0); /* Return the page */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + return PageIndex; } @@ -420,6 +448,9 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) PFN_NUMBER Entry, Flink; PMMPFN Pfn1; + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); + /* Get the entry that's currently first on the list */ Entry = ListHead->Flink; Pfn1 = MiGetPfnEntry(Entry); @@ -444,6 +475,8 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) Pfn1->u1.Flink = Pfn1->u2.Blink = 0; ListHead->Total--; + ASSERT_LIST_INVARIANT(ListHead); + /* Return the head element */ return Pfn1; } @@ -461,6 +494,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) PMMCOLOR_TABLES ColorTable; #endif /* Make sure the page index is valid */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT((PageFrameIndex != 0) && (PageFrameIndex <= MmHighestPhysicalPage) && (PageFrameIndex >= MmLowestPhysicalPage)); @@ -477,6 +511,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Get the free page list and increment its count */ ListHead = &MmFreePageListHead; + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the last page on the list */ @@ -522,6 +557,8 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) KeSetEvent(MiHighMemoryEvent, 0, FALSE); } + ASSERT_LIST_INVARIANT(ListHead); + #if 0 // When using ARM3 PFN /* Get the page color */ Color = PageFrameIndex & MmSecondaryColorMask; @@ -641,6 +678,8 @@ MiAllocatePfn(IN PMMPTE PointerPte, } /* Grab a page */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); PageFrameIndex = MiRemoveAnyPage(0); /* Write the software PTE */ @@ -652,6 +691,8 @@ MiAllocatePfn(IN PMMPTE PointerPte, MiInitializePfn(PageFrameIndex, PointerPte, TRUE); /* Release the PFN lock and return the page */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); return PageFrameIndex; } From 9598f59dec998b671a532f59fa2e08b2ed4e39d9 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Tue, 1 Jun 2010 09:31:24 +0000 Subject: [PATCH 170/292] [rbuild] msvc backend: - Start implementing real support for vcxproj files - Fix generating sln files - Move msvc rules in a separate folder - Various fixes svn path=/trunk/; revision=47511 --- reactos/tools/rbuild/backend/msvc/msvc.cpp | 111 ++++--- reactos/tools/rbuild/backend/msvc/msvc.h | 67 ++-- .../tools/rbuild/backend/msvc/projmaker.cpp | 90 ++++++ .../tools/rbuild/backend/msvc/propsmaker.cpp | 197 +++++++++++ .../backend/msvc/rules/reactos.defaults.props | 27 ++ .../rbuild/backend/msvc/rules/reactos.targets | 6 + .../backend/msvc/rules/s_as_mscpp.props | 21 ++ .../backend/msvc/{ => rules}/s_as_mscpp.rules | 0 .../backend/msvc/rules/s_as_mscpp.targets | 84 +++++ .../rbuild/backend/msvc/rules/s_as_mscpp.xml | 145 +++++++++ .../rbuild/backend/msvc/rules/spec.props | 38 +++ .../backend/msvc/{ => rules}/spec.rules | 0 .../rbuild/backend/msvc/rules/spec.targets | 159 +++++++++ .../tools/rbuild/backend/msvc/rules/spec.xml | 274 ++++++++++++++++ .../tools/rbuild/backend/msvc/slnmaker.cpp | 61 +--- .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 196 ++--------- .../rbuild/backend/msvc/vcxprojmaker.cpp | 306 +++++++++--------- .../rbuild/backend/msvc/vspropsmaker.cpp | 20 +- reactos/tools/rbuild/module.cpp | 2 +- reactos/tools/rbuild/rbuild.h | 3 + reactos/tools/rbuild/rbuild.mak | 5 + 21 files changed, 1367 insertions(+), 445 deletions(-) create mode 100644 reactos/tools/rbuild/backend/msvc/propsmaker.cpp create mode 100644 reactos/tools/rbuild/backend/msvc/rules/reactos.defaults.props create mode 100644 reactos/tools/rbuild/backend/msvc/rules/reactos.targets create mode 100644 reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.props rename reactos/tools/rbuild/backend/msvc/{ => rules}/s_as_mscpp.rules (100%) create mode 100644 reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.targets create mode 100644 reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.xml create mode 100644 reactos/tools/rbuild/backend/msvc/rules/spec.props rename reactos/tools/rbuild/backend/msvc/{ => rules}/spec.rules (100%) create mode 100644 reactos/tools/rbuild/backend/msvc/rules/spec.targets create mode 100644 reactos/tools/rbuild/backend/msvc/rules/spec.xml diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 688758c44a3..6fc993d06b3 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -83,8 +83,6 @@ MSVCBackend::MSVCBackend(Project &project, void MSVCBackend::Process() { - bool only_msvc_headers = false; - while ( m_configurations.size () > 0 ) { const MSVCConfiguration* cfg = m_configurations.back(); @@ -92,17 +90,17 @@ void MSVCBackend::Process() delete cfg; } - m_configurations.push_back ( new MSVCConfiguration( Debug )); - m_configurations.push_back ( new MSVCConfiguration( Release )); -// m_configurations.push_back ( new MSVCConfiguration( Speed )); - m_configurations.push_back ( new MSVCConfiguration( RosBuild )); - - if (!only_msvc_headers) + //Don't generate configurations that require WDK if it can't be found + if(getenv ( "BASEDIR" ) != NULL) { - m_configurations.push_back ( new MSVCConfiguration( Debug, ReactOSHeaders )); - m_configurations.push_back ( new MSVCConfiguration( Release, ReactOSHeaders )); -// m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); + m_configurations.push_back ( new MSVCConfiguration( Debug )); + m_configurations.push_back ( new MSVCConfiguration( Release )); } + m_configurations.push_back ( new MSVCConfiguration( RosBuild )); + m_configurations.push_back ( new MSVCConfiguration( Debug, ReactOSHeaders )); + m_configurations.push_back ( new MSVCConfiguration( Release, ReactOSHeaders )); + // m_configurations.push_back ( new MSVCConfiguration( Speed )); + // m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); if ( configuration.CleanAsYouGo ) { _clean_project_files(); @@ -117,34 +115,45 @@ void MSVCBackend::Process() filename_sln += "_auto.sln"; printf ( "Creating MSVC workspace: %s\n", filename_sln.c_str() ); - //Write a property page for each configuration - for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + if (configuration.VSProjectVersion == "10.00") { - MSVCConfiguration* cfg = m_configurations[icfg]; - - //RosBuild doesn't need a property page - if(cfg->optimization == RosBuild) - continue; - - string filename_props( cfg->name ); - filename_props += ".vsprops"; - //Write the propery pages files - PropsMaker propsMaker( configuration, &ProjectNode, filename_props, cfg ); + PropsMaker propsMaker( &ProjectNode, "reactos.props", m_configurations ); propsMaker._generate_props( _get_solution_version(), _get_studio_version() ); } + else + { + //Write a property page for each configuration + for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + { + MSVCConfiguration* cfg = m_configurations[icfg]; + //RosBuild doesn't need a property page + if(cfg->optimization == RosBuild) + continue; + + //Write the propery pages files + string filename_props( cfg->name ); + + filename_props = filename_props + ".vsprops"; + VSPropsMaker propsMaker( configuration, &ProjectNode, filename_props, cfg ); + propsMaker._generate_props( _get_solution_version(), _get_studio_version() ); + } + } // Write out the project files ProcessModules(); - // Write the solution file - SlnMaker slnMaker( configuration, ProjectNode, m_configurations, filename_sln ); - slnMaker._generate_sln ( _get_solution_version(), _get_studio_version() ); - printf ( "Done.\n" ); } void MSVCBackend::ProcessModules() { + string filename_sln ( ProjectNode.name ); + + filename_sln += "_auto.sln"; + + // Write the solution file + SlnMaker slnMaker( configuration, m_configurations, filename_sln, _get_solution_version(), _get_studio_version() ); + for(std::map::const_iterator p = ProjectNode.modules.begin(); p != ProjectNode.modules.end(); ++ p) { Module &module = *p->second; @@ -156,17 +165,21 @@ void MSVCBackend::ProcessModules() if (configuration.VSProjectVersion == "10.00") { string vcxproj_file = VcxprojFileName(module); - projMaker = new VCXProjMaker( configuration, m_configurations, vcxproj_file ); + projMaker = new VCXProjMaker( configuration, m_configurations, vcxproj_file, module ); } else { string vcproj_file = VcprojFileName(module); - projMaker = new VCProjMaker( configuration, m_configurations, vcproj_file ); + projMaker = new VCProjMaker( configuration, m_configurations, vcproj_file, module ); } projMaker->_generate_proj_file ( module ); + + slnMaker._add_project(*projMaker, module); + delete projMaker; } + } static bool FileExists(string &filename) @@ -262,6 +275,25 @@ void MSVCBackend::OutputFolders() #endif } +std::string +MSVCBackend::UserFileName ( const Module& module, std::string vcproj_file ) const +{ + string computername; + string username; + + if (getenv ( "USERNAME" ) != NULL) + username = getenv ( "USERNAME" ); + if (getenv ( "COMPUTERNAME" ) != NULL) + computername = getenv ( "COMPUTERNAME" ); + else if (getenv ( "HOSTNAME" ) != NULL) + computername = getenv ( "HOSTNAME" ); + + if ((computername != "") && (username != "")) + return vcproj_file + "." + computername + "." + username + ".user"; + else + return ""; +} + std::string MSVCBackend::SuoFileName ( const Module& module ) const { @@ -416,25 +448,10 @@ MSVCBackend::_clean_project_files ( void ) vector out; printf("Cleaning project %s %s %s\n", module.name.c_str (), module.output->relative_path.c_str (), NcbFileName ( module ).c_str () ); - string basepath = module.output->relative_path; - remove ( NcbFileName ( module ).c_str () ); - remove ( SlnFileName ( module ).c_str () ); - remove ( SuoFileName ( module ).c_str () ); + string vcproj_file_user = UserFileName(module, VcprojFileName ( module )); + if(vcproj_file_user != "") + remove ( vcproj_file_user.c_str () ); - if ( configuration.VSProjectVersion == "10.00" ) - remove ( VcxprojFileName ( module ).c_str () ); - else - remove ( VcprojFileName ( module ).c_str () ); - - string username = getenv ( "USERNAME" ); - string computername = getenv ( "COMPUTERNAME" ); - string vcproj_file_user = ""; -#if 0 - if ((computername != "") && (username != "")) - vcproj_file_user = VcprojFileName ( module ) + "." + computername + "." + username + ".user"; - - remove ( vcproj_file_user.c_str () ); -#endif _get_object_files ( module, out ); _get_def_files ( module, out ); for ( size_t j = 0; j < out.size (); j++) diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h index a917c12e187..25bc70d0aa6 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.h +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -106,6 +106,7 @@ class MSVCBackend : public Backend std::string VcxprojFileName ( const Module& module ) const; std::string SlnFileName ( const Module& module ) const; std::string SuoFileName ( const Module& module ) const; + std::string UserFileName ( const Module& module, std::string vcproj_file ) const; std::string NcbFileName ( const Module& module ) const; std::vector m_configurations; @@ -141,6 +142,8 @@ class ProjMaker virtual void _generate_proj_file ( const Module& module ) = 0; virtual void _generate_user_configuration (); + std::string VcprojFileName ( const Module& module ) const; + protected: Configuration configuration; std::vector m_configurations; @@ -148,20 +151,24 @@ class ProjMaker FILE* OUT; std::vector header_files; + std::vector source_files; + std::vector resource_files; + std::vector generated_files; + std::vector defines; std::vector includes; - std::vector includes_ros; std::vector libraries; - std::set common_defines; + std::string baseaddr; + BinaryType binaryType; - std::string VcprojFileName ( const Module& module ) const; std::string _get_vc_dir ( void ) const; - std::string _strip_gcc_deffile(std::string Filename, std::string sourcedir, std::string objdir); std::string _get_solution_version ( void ); std::string _get_studio_version ( void ); std::string _replace_str( std::string string1, const std::string &find_str, const std::string &replace_str); + std::string _get_file_path( FileLocation* file, std::string relative_path); + void _collect_files(const Module& module); void _generate_standard_configuration( const Module& module, const MSVCConfiguration& cfg, BinaryType binaryType ); void _generate_makefile_configuration( const Module& module, const MSVCConfiguration& cfg ); }; @@ -170,13 +177,14 @@ class VCProjMaker : public ProjMaker { public: VCProjMaker ( ); - VCProjMaker ( Configuration& buildConfig, const std::vector& msvc_configs, std::string filename ); + VCProjMaker ( Configuration& buildConfig, const std::vector& msvc_configs, std::string filename, const Module& module ); virtual ~VCProjMaker (); void _generate_proj_file ( const Module& module ); void _generate_user_configuration (); private: + void _generate_standard_configuration( const Module& module, const MSVCConfiguration& cfg, BinaryType binaryType ); void _generate_makefile_configuration( const Module& module, const MSVCConfiguration& cfg ); std::string _get_file_path( FileLocation* file, std::string relative_path); @@ -186,13 +194,15 @@ class VCXProjMaker : public ProjMaker { public: VCXProjMaker ( ); - VCXProjMaker ( Configuration& buildConfig, const std::vector& msvc_configs, std::string filename ); + VCXProjMaker ( Configuration& buildConfig, const std::vector& msvc_configs, std::string filename, const Module& module ); virtual ~VCXProjMaker (); void _generate_proj_file ( const Module& module ); void _generate_user_configuration (); private: + std::string _get_configuration_type (); + void _generate_item_group (std::vector); void _generate_standard_configuration( const Module& module, const MSVCConfiguration& cfg, BinaryType binaryType ); void _generate_makefile_configuration( const Module& module, const MSVCConfiguration& cfg ); }; @@ -200,38 +210,30 @@ class VCXProjMaker : public ProjMaker class SlnMaker { public: - SlnMaker ( Configuration& buildConfig, Project& ProjectNode, const std::vector& configurations, std::string filename_sln ); + SlnMaker ( Configuration& buildConfig, const std::vector& configurations, std::string filename_sln, std::string solution_version, std::string studio_version); ~SlnMaker (); - void _generate_sln ( std::string solution_version, std::string studio_version ); - + void _add_project(ProjMaker &project, Module &module); private: Configuration m_configuration; - Project* m_ProjectNode; std::vector m_configurations; FILE* OUT; + std::vector modules; void _generate_sln_header ( std::string solution_version, std::string studio_version ); void _generate_sln_footer ( ); - //void _generate_rules_file ( FILE* OUT ); - void _generate_sln_project ( - const Module& module, - std::string vcproj_file, - std::string sln_guid, - std::string vcproj_guid, - const std::vector& libraries ); void _generate_sln_configurations ( std::string vcproj_guid ); }; -class PropsMaker +class VSPropsMaker { public: - PropsMaker ( Configuration& buildConfig, + VSPropsMaker ( Configuration& buildConfig, Project* ProjectNode, std::string filename_props, MSVCConfiguration* msvc_configs); - ~PropsMaker (); + ~VSPropsMaker (); void _generate_props ( std::string solution_version, std::string studio_version ); @@ -253,3 +255,28 @@ class PropsMaker void _generate_footer(); }; + + +class PropsMaker +{ + public: + PropsMaker ( Project* ProjectNode, + std::string filename_props, + std::vector configurations); + + ~PropsMaker (); + + void _generate_props ( std::string solution_version, std::string studio_version ); + + private: + Project* m_ProjectNode; + FILE* OUT; + std::vector m_configurations; + + void _generate_macro(std::string Name, std::string Value); + void _generate_global_includes(bool debug, bool use_ros_headers); + void _generate_global_definitions(bool debug, bool use_ros_headers); + void _generate_header(); + void _generate_footer(); + +}; \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/projmaker.cpp b/reactos/tools/rbuild/backend/msvc/projmaker.cpp index 89bf13bb5ef..2986e859d04 100644 --- a/reactos/tools/rbuild/backend/msvc/projmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/projmaker.cpp @@ -238,3 +238,93 @@ ProjMaker::_replace_str(std::string string1, const std::string &find_str, const return string1; } + + +std::string +ProjMaker::_get_file_path( FileLocation* file, std::string relative_path) +{ + if (file->directory == SourceDirectory) + { + // We want the full path here for directory support later on + return Path::RelativeFromDirectory (file->relative_path, relative_path ); + } + else if(file->directory == IntermediateDirectory) + { + return std::string("$(RootIntDir)\\") + file->relative_path; + } + else if(file->directory == OutputDirectory) + { + return std::string("$(RootOutDir)\\") + file->relative_path; + } + + return std::string(""); +} + +void +ProjMaker::_collect_files(const Module& module) +{ + size_t i; + const IfableData& data = module.non_if_data; + const vector& files = data.files; + for ( i = 0; i < files.size(); i++ ) + { + string path = _get_file_path(&files[i]->file, module.output->relative_path); + string file = path + std::string("\\") + files[i]->file.name; + + if (files[i]->file.directory != SourceDirectory) + generated_files.push_back ( file ); + else if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) + resource_files.push_back ( file ); + else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) + header_files.push_back ( file ); + else + source_files.push_back ( file ); + } + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + includes.push_back ( _get_file_path(incs[i]->directory, module.output->relative_path) ); + } + const vector& libs = data.libraries; + for ( i = 0; i < libs.size(); i++ ) + { + string libpath = "$(RootOutDir)\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\$(ConfigurationName)\\" + libs[i]->name + ".lib"; + libraries.push_back ( libpath ); + } + const vector& defs = data.defines; + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if( module.isUnicode && (defs[i]->name == "UNICODE" || defs[i]->name == "_UNICODE")) + continue; + + if ( defs[i]->value != "" ) + defines.push_back( defs[i]->name + "=" + defs[i]->value ); + else + defines.push_back( defs[i]->name ); + } + for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) + { + Property& prop = *p->second; + if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) + baseaddr = prop.value; + } + + if(module.importLibrary) + { + std::string ImportLibraryPath = _get_file_path(module.importLibrary->source, module.output->relative_path); + + switch (module.IsSpecDefinitionFile()) + { + case PSpec: + generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".spec")); + case Spec: + generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".stubs.c")); + generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".def")); + default: + source_files.push_back(ImportLibraryPath + std::string("\\") + module.importLibrary->source->name); + } + } +} \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/propsmaker.cpp b/reactos/tools/rbuild/backend/msvc/propsmaker.cpp new file mode 100644 index 00000000000..5fc860e5f58 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/propsmaker.cpp @@ -0,0 +1,197 @@ +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include +#include +#include +#include +#include + +#include + +#include "msvc.h" + +using std::string; +using std::vector; +using std::set; + +typedef set StringSet; + +#ifdef OUT +#undef OUT +#endif//OUT + + +PropsMaker::PropsMaker (Project* ProjectNode, + std::string filename_props, + std::vector configurations) +{ + m_ProjectNode = ProjectNode; + m_configurations = configurations; + + OUT = fopen ( filename_props.c_str(), "wb" ); + + if ( !OUT ) + { + printf ( "Could not create file '%s'.\n", filename_props.c_str() ); + } +} + +PropsMaker::~PropsMaker ( ) +{ + fclose ( OUT ); +} + +void +PropsMaker::_generate_header() +{ + fprintf ( OUT, "\r\n"); + fprintf ( OUT, "\r\n"); +} + +void +PropsMaker::_generate_footer() +{ + fprintf ( OUT, "\r\n"); +} + +void +PropsMaker::_generate_macro(std::string Name, std::string Value) +{ + fprintf ( OUT, "\t\t<%s>%s\r\n", Name.c_str(), Value.c_str(), Name.c_str()); +} + +void +PropsMaker::_generate_global_includes(bool debug, bool use_ros_headers) +{ + fprintf ( OUT, "\t\t"); + + const IfableData& data = m_ProjectNode->non_if_data; + //const vector& files = data.files; + size_t i; + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + if ((incs[i]->directory->relative_path == "include\\crt" || + incs[i]->directory->relative_path == "include\\ddk" || + incs[i]->directory->relative_path == "include\\GL" || + incs[i]->directory->relative_path == "include\\psdk") && + ! use_ros_headers) + { + continue; + } + + if(incs[i]->directory->directory == SourceDirectory) + fprintf ( OUT, "\"$(RootSrcDir)\\"); + else if (incs[i]->directory->directory == IntermediateDirectory) + fprintf ( OUT, "\"$(RootIntDir)\\"); + else if (incs[i]->directory->directory == OutputDirectory) + fprintf ( OUT, "\"$(RootOutDir)\\"); + else + continue; + + fprintf ( OUT, incs[i]->directory->relative_path.c_str()); + fprintf ( OUT, "\" ; "); + } + + fprintf ( OUT, "\"$(RootIntDir)\\include\" ; "); + fprintf ( OUT, "\"$(RootIntDir)\\include\\reactos\" ; "); + + if ( !use_ros_headers ) + { + // Add WDK or PSDK paths, if user provides them + if (getenv ( "BASEDIR" ) != NULL) + { + string WdkBase = getenv ( "BASEDIR" ); + fprintf ( OUT, "\"%s\\inc\\api\" ; ", WdkBase.c_str()); + fprintf ( OUT, "\"%s\\inc\\crt\" ; ", WdkBase.c_str()); + fprintf ( OUT, "\"%s\\inc\\ddk\" ; ", WdkBase.c_str()); + } + } + fprintf ( OUT, "\t\r\n"); +} + +void +PropsMaker::_generate_global_definitions(bool debug, bool use_ros_headers) +{ + fprintf ( OUT, "\t\t"); + + // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not + // using the safe functions introduced in MSVC8. + fprintf ( OUT, "_CRT_SECURE_NO_WARNINGS ; ") ; + + if ( debug ) + { + fprintf ( OUT, "_DEBUG ; "); + } + + if ( !use_ros_headers ) + { + // this is a define in MinGW w32api, but not Microsoft's headers + fprintf ( OUT, "STDCALL=__stdcall ; "); + } + + const IfableData& data = m_ProjectNode->non_if_data; + const vector& defs = data.defines; + size_t i; + + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value != "" ) + fprintf ( OUT, "%s=%s",defs[i]->name.c_str(), defs[i]->value.c_str()); + else + fprintf ( OUT, defs[i]->name.c_str()); + fprintf ( OUT, " ; "); + } + + fprintf ( OUT, "\t\r\n"); +} + +void +PropsMaker::_generate_props ( std::string solution_version, std::string studio_version ) +{ + + string srcdir = Environment::GetSourcePath(); + string intdir = Environment::GetIntermediatePath (); + string outdir = Environment::GetOutputPath (); + string rosbedir = Environment::GetVariable("_ROSBE_BASEDIR"); + + if ( intdir == "obj-i386" ) + intdir = srcdir + "\\obj-i386"; /* append relative dir from project dir */ + + if ( outdir == "output-i386" ) + outdir = srcdir + "\\output-i386"; + + _generate_header(); + + fprintf ( OUT, "\t\r\n"); + _generate_macro("RootSrcDir", srcdir); + _generate_macro("RootOutDir", outdir); + _generate_macro("RootIntDir", intdir); + _generate_macro("Tools", "$(RootOutDir)\\tools"); + _generate_macro("RosBE", rosbedir); + fprintf ( OUT, "\t\r\n"); + + for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + { + MSVCConfiguration* cfg = m_configurations[icfg]; + + if(cfg->optimization == RosBuild) + continue; + + fprintf ( OUT, "\t\r\n", cfg->name.c_str() ); + _generate_global_includes(cfg->optimization == Debug, cfg->headers == ReactOSHeaders); + _generate_global_definitions(cfg->optimization == Debug, cfg->headers == ReactOSHeaders); + fprintf ( OUT, "\t\r\n"); + } + + _generate_footer(); +} diff --git a/reactos/tools/rbuild/backend/msvc/rules/reactos.defaults.props b/reactos/tools/rbuild/backend/msvc/rules/reactos.defaults.props new file mode 100644 index 00000000000..205d35ad44b --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/reactos.defaults.props @@ -0,0 +1,27 @@ + + + + + + $(globalIncludes);$(IncludePath) + + + + $(globalIncludes);$(ProjectIncludes);%(AdditionalIncludeDirectories) + $(ProjectDefines);$(globalDefines);%(PreprocessorDefinitions) + true + CompileAsC + Cdecl + + + $(globalIncludes);$(ProjectIncludes) + __ASM__ + + + $(globalIncludes);$(ProjectIncludes) + + + $(globalIncludes);$(ProjectIncludes);%(AdditionalIncludeDirectories) + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/rules/reactos.targets b/reactos/tools/rbuild/backend/msvc/rules/reactos.targets new file mode 100644 index 00000000000..e7b583b4f0c --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/reactos.targets @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.props b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.props new file mode 100644 index 00000000000..67e87c81933 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.props @@ -0,0 +1,21 @@ + + + + Midl + CustomBuild + + + _SelectedFiles;$(s_as_mscppDependsOn) + + + + $(IntDir)%(Filename).obj + $(globalIncludes) + cl /nologo /E [sIncPaths] [sPPDefs] "%(FullPath)" | "$(RosBE)\i386\bin\as" -o [sOutF] + %(sOutF) + Assembling + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.rules similarity index 100% rename from reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules rename to reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.rules diff --git a/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.targets b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.targets new file mode 100644 index 00000000000..731117271f0 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.targets @@ -0,0 +1,84 @@ + + + + + + _s_as_mscpp + + + + $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml + + + + + + + + @(s_as_mscpp, '|') + + + + + + + + + $(ComputeLinkInputsTargets); + Computes_as_mscppOutput; + + + $(ComputeLibInputsTargets); + Computes_as_mscppOutput; + + + + + + + + + + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.xml b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.xml new file mode 100644 index 00000000000..b2a71f56073 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/s_as_mscpp.xml @@ -0,0 +1,145 @@ + + + + + + + + + + General + + + + + Command Line + + + + + + + + + + + + + + + Execute Before + + + Specifies the targets for the build customization to run before. + + + + + + + + + + + Execute After + + + Specifies the targets for the build customization to run after. + + + + + + + + + + + + + + Additional Options + + + Additional Options + + + + + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/rules/spec.props b/reactos/tools/rbuild/backend/msvc/rules/spec.props new file mode 100644 index 00000000000..5e738c7db6f --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/spec.props @@ -0,0 +1,38 @@ + + + + Midl + Pspec + + + _SelectedFiles;$(specDependsOn) + + + + $(IntDir)%(Filename).def + $(IntDir)%(Filename).stubs.c + "$(Tools)\winebuild\winebuild.exe" -F $(TargetFileName) -o [DefFile] --def -k -E [inputs] | "$(Tools)\winebuild\winebuild.exe" -F $(TargetFileName) -o [StubsFile] --pedll -k -E [inputs] + [DefFile] + Generating module definition file + + + + spec + CustomBuild + + + _SelectedFiles;$(PspecDependsOn) + + + + $(IntDir)%(Filename).spec + cl /nologo /EP [includes] [inputs] > [Specfile] + [Specfile] + Generating module definition file + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/spec.rules b/reactos/tools/rbuild/backend/msvc/rules/spec.rules similarity index 100% rename from reactos/tools/rbuild/backend/msvc/spec.rules rename to reactos/tools/rbuild/backend/msvc/rules/spec.rules diff --git a/reactos/tools/rbuild/backend/msvc/rules/spec.targets b/reactos/tools/rbuild/backend/msvc/rules/spec.targets new file mode 100644 index 00000000000..4671ea1cd36 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/spec.targets @@ -0,0 +1,159 @@ + + + + + + _spec + + + _Pspec + + + + $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml + + + $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml + + + + + + + + @(spec, '|') + + + + + + + + + $(ComputeLinkInputsTargets); + ComputespecOutput; + + + $(ComputeLibInputsTargets); + ComputespecOutput; + + + + + + + + + + + + + + + + + + @(Pspec, '|') + + + + + + + + + $(ComputeLinkInputsTargets); + ComputePspecOutput; + + + $(ComputeLibInputsTargets); + ComputePspecOutput; + + + + + + + + + + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/rules/spec.xml b/reactos/tools/rbuild/backend/msvc/rules/spec.xml new file mode 100644 index 00000000000..db15656b23b --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/rules/spec.xml @@ -0,0 +1,274 @@ + + + + + + + + + + General + + + + + Command Line + + + + + + + + + + + + + + Execute Before + + + Specifies the targets for the build customization to run before. + + + + + + + + + + + Execute After + + + Specifies the targets for the build customization to run after. + + + + + + + + + + + + + + Additional Options + + + Additional Options + + + + + + + + + + + + + + General + + + + + Command Line + + + + + + + + + + + + + + Execute Before + + + Specifies the targets for the build customization to run before. + + + + + + + + + + + Execute After + + + Specifies the targets for the build customization to run after. + + + + + + + + + + + + + + Additional Options + + + Additional Options + + + + + + + \ No newline at end of file diff --git a/reactos/tools/rbuild/backend/msvc/slnmaker.cpp b/reactos/tools/rbuild/backend/msvc/slnmaker.cpp index c17c510c300..ebc2dc8d6c5 100644 --- a/reactos/tools/rbuild/backend/msvc/slnmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/slnmaker.cpp @@ -42,12 +42,12 @@ using std::set; SlnMaker::SlnMaker ( Configuration& buildConfig, - Project& ProjectNode, const std::vector& configurations, - std::string filename_sln ) + std::string filename_sln, + std::string solution_version, + std::string studio_version) { m_configuration = buildConfig; - m_ProjectNode = &ProjectNode; m_configurations = configurations; OUT = fopen ( filename_sln.c_str(), "wb" ); @@ -56,10 +56,13 @@ SlnMaker::SlnMaker ( Configuration& buildConfig, { printf ( "Could not create file '%s'.\n", filename_sln.c_str() ); } + + _generate_sln_header( solution_version, studio_version); } SlnMaker::~SlnMaker() { + _generate_sln_footer ( ); fclose ( OUT ); } @@ -73,35 +76,6 @@ SlnMaker::_generate_sln_header ( std::string solution_version, std::string studi fprintf ( OUT, "\r\n" ); } - -void -SlnMaker::_generate_sln_project ( - const Module& module, - std::string vcproj_file, - std::string sln_guid, - std::string vcproj_guid, - const std::vector& libraries ) -{ - vcproj_file = DosSeparator ( std::string(".\\") + vcproj_file ); - - fprintf ( OUT, "Project(\"%s\") = \"%s\", \"%s\", \"%s\"\r\n", sln_guid.c_str() , module.name.c_str(), vcproj_file.c_str(), vcproj_guid.c_str() ); -/* - //FIXME: only omit ProjectDependencies in VS 2005 when there are no dependencies - //NOTE: VS 2002 do not use ProjectSection; it uses GlobalSection instead - if ((configuration.VSProjectVersion == "7.10") || (libraries.size() > 0)) { - fprintf ( OUT, "\tProjectSection(ProjectDependencies) = postProject\r\n" ); - for ( size_t i = 0; i < libraries.size(); i++ ) - { - const Module& module = *libraries[i]->importedModule; - fprintf ( OUT, "\t\t%s = %s\r\n", module.guid.c_str(), module.guid.c_str() ); - } - fprintf ( OUT, "\tEndProjectSection\r\n" ); - } -*/ - fprintf ( OUT, "EndProject\r\n" ); -} - - void SlnMaker::_generate_sln_footer ( ) { @@ -112,11 +86,9 @@ SlnMaker::_generate_sln_footer ( ) fprintf ( OUT, "\tEndGlobalSection\r\n" ); fprintf ( OUT, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n" ); - for( std::map::const_iterator p = m_ProjectNode->modules.begin(); p != m_ProjectNode->modules.end(); ++ p ) + for ( size_t i = 0; i < modules.size (); i++) { - Module& module = *p->second; - std::string guid = module.guid; - _generate_sln_configurations ( guid.c_str() ); + _generate_sln_configurations ( modules[i]->guid.c_str() ); } fprintf ( OUT, "\tEndGlobalSection\r\n" ); /* @@ -153,20 +125,13 @@ SlnMaker::_generate_sln_configurations ( std::string vcproj_guid ) } } -void -SlnMaker::_generate_sln ( std::string solution_version, std::string studio_version ) +void +SlnMaker::_add_project(ProjMaker &project, Module &module) { string sln_guid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; - vector guids; - _generate_sln_header( solution_version, studio_version); - // TODO FIXME - is it necessary to sort them? - for( std::map::const_iterator p = m_ProjectNode->modules.begin(); p != m_ProjectNode->modules.end(); ++ p ) - { - Module& module = *p->second; + fprintf ( OUT, "Project(\"%s\") = \"%s\", \".\\%s\",\"%s\"\n", sln_guid.c_str(), module.name.c_str() , project.VcprojFileName(module).c_str() , module.guid.c_str()); + fprintf ( OUT, "EndProject\r\n" ); - //std::string vcproj_file = - _generate_sln_project ( module, module.name, sln_guid, module.guid, module.non_if_data.libraries ); - } - _generate_sln_footer ( ); + modules.push_back(&module); } diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index ecd04e0d22b..b09658d18df 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -61,7 +61,8 @@ VCProjMaker::VCProjMaker ( ) VCProjMaker::VCProjMaker ( Configuration& buildConfig, const std::vector& msvc_configs, - std::string filename ) + std::string filename, + const Module& module) { configuration = buildConfig; m_configurations = msvc_configs; @@ -73,6 +74,21 @@ VCProjMaker::VCProjMaker ( Configuration& buildConfig, { printf ( "Could not create file '%s'.\n", vcproj_file.c_str() ); } + + // Set the binary type + string module_type = GetExtension(*module.output); + + if ((module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a")) + binaryType = Lib; + else if ((module_type == ".dll") || (module_type == ".cpl")) + binaryType = Dll; + else if ((module_type == ".exe") || (module_type == ".scr")) + binaryType = Exe; + else if (module_type == ".sys") + binaryType = Sys; + else + binaryType = BinUnknown; + } VCProjMaker::~VCProjMaker() @@ -80,117 +96,16 @@ VCProjMaker::~VCProjMaker() fclose ( OUT ); } -std::string -VCProjMaker::_get_file_path( FileLocation* file, std::string relative_path) -{ - if (file->directory == SourceDirectory) - { - // We want the full path here for directory support later on - return Path::RelativeFromDirectory (file->relative_path, relative_path ); - } - else if(file->directory == IntermediateDirectory) - { - return std::string("$(RootIntDir)\\") + file->relative_path; - } - else if(file->directory == OutputDirectory) - { - return std::string("$(RootOutDir)\\") + file->relative_path; - } - - return std::string(""); -} - - - void VCProjMaker::_generate_proj_file ( const Module& module ) { size_t i; - // make sure the containers are empty - header_files.clear(); - includes.clear(); - libraries.clear(); - common_defines.clear(); - printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); string path_basedir = module.GetPathToBaseDir (); - bool include_idl = false; - - vector source_files, resource_files, generated_files; - - const IfableData& data = module.non_if_data; - const vector& files = data.files; - for ( i = 0; i < files.size(); i++ ) - { - string path = _get_file_path(&files[i]->file, module.output->relative_path); - string file = path + std::string("\\") + files[i]->file.name; - - if (files[i]->file.directory != SourceDirectory) - generated_files.push_back ( file ); - else if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) - resource_files.push_back ( file ); - else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) - header_files.push_back ( file ); - else - source_files.push_back ( file ); - } - const vector& incs = data.includes; - for ( i = 0; i < incs.size(); i++ ) - { - string path = _get_file_path(incs[i]->directory, module.output->relative_path); - - if ( module.type != RpcServer && module.type != RpcClient ) - { - if ( path.find ("/include/reactos/idl") != string::npos) - { - include_idl = true; - continue; - } - } - includes.push_back ( path ); - } - const vector& libs = data.libraries; - for ( i = 0; i < libs.size(); i++ ) - { - string libpath = "$(RootOutDir)\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\$(ConfigurationName)\\" + libs[i]->name + ".lib"; - libraries.push_back ( libpath ); - } - const vector& defs = data.defines; - for ( i = 0; i < defs.size(); i++ ) - { - if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) - continue; - - if ( defs[i]->value[0] ) - common_defines.insert( defs[i]->name + "=" + defs[i]->value ); - else - common_defines.insert( defs[i]->name ); - } - for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) - { - Property& prop = *p->second; - if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) - baseaddr = prop.value; - } - - if(module.importLibrary) - { - std::string ImportLibraryPath = _get_file_path(module.importLibrary->source, module.output->relative_path); - - switch (module.IsSpecDefinitionFile()) - { - case PSpec: - generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".spec")); - case Spec: - generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".stubs.c")); - generated_files.push_back("$(IntDir)\\" + ReplaceExtension(module.importLibrary->source->name,".def")); - default: - source_files.push_back(ImportLibraryPath + std::string("\\") + module.importLibrary->source->name); - } - } + _collect_files(module); fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\t\t\r\n" ); fprintf ( OUT, "\t\t\r\n" ); fprintf ( OUT, "\t\r\n" ); - // Set the binary type - string module_type = GetExtension(*module.output); - BinaryType binaryType; - if ((module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a")) - binaryType = Lib; - else if ((module_type == ".dll") || (module_type == ".cpl")) - binaryType = Dll; - else if ((module_type == ".exe") || (module_type == ".scr")) - binaryType = Exe; - else if (module_type == ".sys") - binaryType = Sys; - else - binaryType = BinUnknown; - // Write out all the configurations fprintf ( OUT, "\t\r\n" ); for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) @@ -389,9 +290,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) fprintf ( OUT, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" ); for ( i = 0; i < header_files.size(); i++ ) { - const string& header_file = header_files[i]; fprintf ( OUT, "\t\t\t\r\n", header_file.c_str() ); + fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", header_files[i].c_str() ); fprintf ( OUT, "\t\t\t\r\n" ); } fprintf ( OUT, "\t\t\r\n" ); @@ -402,9 +302,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) fprintf ( OUT, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" ); for ( i = 0; i < resource_files.size(); i++ ) { - const string& resource_file = resource_files[i]; fprintf ( OUT, "\t\t\t\r\n", resource_file.c_str() ); + fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_files[i].c_str() ); fprintf ( OUT, "\t\t\t\r\n" ); } fprintf ( OUT, "\t\t\r\n" ); @@ -481,8 +380,8 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType ); - fprintf ( OUT, "\t\t\tInheritedPropertySheets=\"%s%s.vsprops\"\r\n", path_basedir.c_str (), cfg.name.c_str ()); - fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" ); + fprintf ( OUT, "\t\t\tInheritedPropertySheets=\"%s\\%s.vsprops\"\r\n", path_basedir.c_str (), cfg.name.c_str ()); + fprintf ( OUT, "\t\t\tCharacterSet=\"%s\"\r\n", module.isUnicode ? "1" : "2" ); fprintf ( OUT, "\t\t\t>\r\n" ); fprintf ( OUT, "\t\t\t& msvc_configs, - std::string filename ) + std::string filename, + const Module& module) { configuration = buildConfig; m_configurations = msvc_configs; @@ -65,157 +66,10 @@ VCXProjMaker::VCXProjMaker ( Configuration& buildConfig, { printf ( "Could not create file '%s'.\n", vcproj_file.c_str() ); } -} - -VCXProjMaker::~VCXProjMaker() -{ - fclose ( OUT ); -} - -void -VCXProjMaker::_generate_proj_file ( const Module& module ) -{ - size_t i; - - string computername; - string username; - - // make sure the containers are empty - header_files.clear(); - includes.clear(); - includes_ros.clear(); - libraries.clear(); - common_defines.clear(); - - if (getenv ( "USERNAME" ) != NULL) - username = getenv ( "USERNAME" ); - if (getenv ( "COMPUTERNAME" ) != NULL) - computername = getenv ( "COMPUTERNAME" ); - else if (getenv ( "HOSTNAME" ) != NULL) - computername = getenv ( "HOSTNAME" ); - - string vcproj_file_user = ""; - - if ((computername != "") && (username != "")) - vcproj_file_user = vcproj_file + "." + computername + "." + username + ".user"; - - printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); - - string path_basedir = module.GetPathToBaseDir (); - string intenv = Environment::GetIntermediatePath (); - string outenv = Environment::GetOutputPath (); - string outdir; - string intdir; - string vcdir; - - if ( intenv == "obj-i386" ) - intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ - else - intdir = intenv; - - if ( outenv == "output-i386" ) - outdir = path_basedir + "output-i386"; - else - outdir = outenv; - - if ( configuration.UseVSVersionInPath ) - { - vcdir = DEF_SSEP + _get_vc_dir(); - } - - bool include_idl = false; - - vector source_files, resource_files; - vector ifs_list; - ifs_list.push_back ( &module.project.non_if_data ); - ifs_list.push_back ( &module.non_if_data ); - - while ( ifs_list.size() ) - { - const IfableData& data = *ifs_list.back(); - ifs_list.pop_back(); - const vector& files = data.files; - for ( i = 0; i < files.size(); i++ ) - { - if (files[i]->file.directory != SourceDirectory) - continue; - - // We want the full path here for directory support later on - string path = Path::RelativeFromDirectory ( - files[i]->file.relative_path, - module.output->relative_path ); - string file = path + std::string("\\") + files[i]->file.name; - - if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) - resource_files.push_back ( file ); - else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) - header_files.push_back ( file ); - else - source_files.push_back ( file ); - } - const vector& incs = data.includes; - for ( i = 0; i < incs.size(); i++ ) - { - string path = Path::RelativeFromDirectory ( - incs[i]->directory->relative_path, - module.output->relative_path ); - if ( module.type != RpcServer && module.type != RpcClient ) - { - if ( path.find ("/include/reactos/idl") != string::npos) - { - include_idl = true; - continue; - } - } - // switch between general headers and ros headers - if ( !strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\ddk", 11 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\GL", 10 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\psdk", 12 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\reactos\\wine", 20 ) ) - { - if (strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 )) - // not crt include - includes_ros.push_back ( path ); - } - else - { - includes.push_back ( path ); - } - } - const vector& libs = data.libraries; - for ( i = 0; i < libs.size(); i++ ) - { - string libpath = outdir + "\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\---\\" + libs[i]->name + ".lib"; - libraries.push_back ( libpath ); - } - const vector& defs = data.defines; - for ( i = 0; i < defs.size(); i++ ) - { - if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) - continue; - - if ( defs[i]->value[0] ) - common_defines.insert( defs[i]->name + "=" + defs[i]->value ); - else - common_defines.insert( defs[i]->name ); - } - for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) - { - Property& prop = *p->second; - if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) - baseaddr = prop.value; - } - } - /* include intermediate path for reactos.rc */ - string version = intdir + "\\include"; - includes.push_back (version); - version += "\\reactos"; - includes.push_back (version); // Set the binary type string module_type = GetExtension(*module.output); - BinaryType binaryType; + if ((module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a")) binaryType = Lib; else if ((module_type == ".dll") || (module_type == ".cpl")) @@ -226,13 +80,76 @@ VCXProjMaker::_generate_proj_file ( const Module& module ) binaryType = Sys; else binaryType = BinUnknown; +} - string include_string; +VCXProjMaker::~VCXProjMaker() +{ + fclose ( OUT ); +} + +void +VCXProjMaker::_generate_item_group (std::vector files) +{ + size_t i; + + for( i = 0; i\r\n", files[i].c_str()); + else if( extension == ".s") + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + else if( extension == ".spec") + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + else if( extension == ".pspec") + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + else if( extension == ".rc") + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + else if( extension == ".h") + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + else + fprintf ( OUT, "\t\t\r\n", files[i].c_str()); + } +} + +string +VCXProjMaker::_get_configuration_type () +{ + switch (binaryType) + { + case Exe: + return "Application"; + case Dll: + case Sys: + return "DynamicLibrary"; + case Lib: + return "StaticLibrary"; + default: + return ""; + } +} + +void +VCXProjMaker::_generate_proj_file ( const Module& module ) +{ + string path_basedir = module.GetPathToBaseDir (); + size_t i; + string vcdir; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); + + _collect_files(module); fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\r\n" ); if (configuration.VSProjectVersion.empty()) @@ -245,15 +162,11 @@ VCXProjMaker::_generate_proj_file ( const Module& module ) const MSVCConfiguration& cfg = *m_configurations[icfg]; if ( cfg.optimization == RosBuild ) - { _generate_makefile_configuration( module, cfg ); - } else - { _generate_standard_configuration( module, cfg, binaryType ); - } } - fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n\r\n" ); // Write out the global info fprintf ( OUT, "\t\r\n" ); @@ -261,9 +174,88 @@ VCXProjMaker::_generate_proj_file ( const Module& module ) fprintf ( OUT, "\t\t%s\r\n", "Win32Proj" ); //FIXME: Win32Proj??? fprintf ( OUT, "\t\t%s\r\n", module.name.c_str() ); //FIXME: shouldn't this be the soltion name? fprintf ( OUT, "\t\r\n" ); - fprintf ( OUT, "" ); + fprintf ( OUT, "\r\n" ); + fprintf ( OUT, "\t\r\n"); + if( binaryType != BinUnknown) + fprintf ( OUT, "\t\t%s\r\n" , _get_configuration_type().c_str()); + fprintf ( OUT, "\t\t%s\r\n", module.isUnicode ? "Unicode" : "MultiByte"); + fprintf ( OUT, "\t\r\n"); + fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n"); + fprintf ( OUT, "\t\t\r\n", path_basedir.c_str()); + fprintf ( OUT, "\t\t\r\n", path_basedir.c_str()); + fprintf ( OUT, "\t\r\n"); + + fprintf ( OUT, "\t\r\n"); + fprintf ( OUT, "\t\t$(RootOutDir)\\%s%s\\$(Configuration)\\\r\n", module.output->relative_path.c_str (), vcdir.c_str ()); + fprintf ( OUT, "\t\t$(RootIntDir)\\%s%s\\$(Configuration)\\\r\n", module.output->relative_path.c_str (), vcdir.c_str ()); + + if( includes.size() != 0) + { + fprintf( OUT, "\t\t"); + for ( i = 0; i < includes.size(); i++ ) + fprintf ( OUT, "%s;", includes[i].c_str() ); + fprintf( OUT, "\r\n"); + } + + if(defines.size() != 0) + { + fprintf( OUT, "\t\t"); + for ( i = 0; i < defines.size(); i++ ) + fprintf ( OUT, "%s;", defines[i].c_str() ); + fprintf( OUT, "\r\n"); + } + + fprintf ( OUT, "\t\r\n\r\n"); + + fprintf ( OUT, "\t\r\n"); + fprintf ( OUT, "\t\t\r\n"); + if ( module.cplusplus ) + fprintf ( OUT, "\t\t\tCompileAsCpp\r\n"); + fprintf ( OUT, "\t\t\r\n"); + + fprintf ( OUT, "\t\t\r\n"); + if(libraries.size() != 0) + { + fprintf ( OUT, "\t\t\t"); + for ( i = 0; i < libraries.size(); i++ ) + { + string libpath = libraries[i].c_str(); + libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 ); + fprintf ( OUT, "%s;", libpath.c_str() ); + } + fprintf ( OUT, "%%(AdditionalDependencies)\r\n"); + + fprintf ( OUT, "\t\t\t"); + for ( i = 0; i < libraries.size(); i++ ) + { + string libpath = libraries[i].c_str(); + libpath = libpath.substr (0, libpath.find_last_of ("\\") ); + fprintf ( OUT, "%s;", libpath.c_str() ); + } + fprintf ( OUT, "%%(AdditionalLibraryDirectories)\r\n"); + } + + if( module.CRT != "msvcrt") + fprintf ( OUT, "\t\t\ttrue\r\n"); + + fprintf ( OUT, "\t\t\r\n"); + fprintf ( OUT, "\t\r\n"); + + fprintf ( OUT, "\t\r\n"); + _generate_item_group(header_files); + _generate_item_group(source_files); + _generate_item_group(resource_files); + _generate_item_group(generated_files); + fprintf ( OUT, "\t\r\n\r\n"); + + fprintf ( OUT, "\t\r\n"); + fprintf ( OUT, "\t\r\n", path_basedir.c_str()); + + fprintf ( OUT, "\r\n"); } void diff --git a/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp index 02ba4e376de..2e7bdf7d7f1 100644 --- a/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp @@ -23,7 +23,7 @@ typedef set StringSet; #undef OUT #endif//OUT -PropsMaker::PropsMaker ( Configuration& buildConfig, +VSPropsMaker::VSPropsMaker ( Configuration& buildConfig, Project* ProjectNode, std::string filename_props, MSVCConfiguration* msvc_configs) @@ -46,13 +46,13 @@ PropsMaker::PropsMaker ( Configuration& buildConfig, } } -PropsMaker::~PropsMaker ( ) +VSPropsMaker::~VSPropsMaker ( ) { fclose ( OUT ); } void -PropsMaker::_generate_header() +VSPropsMaker::_generate_header() { fprintf ( OUT, "\r\n" ); fprintf ( OUT, "backend != "" && defs[i]->backend != "msvc" ) continue; - if ( defs[i]->value[0] ) + if ( defs[i]->value != "" ) fprintf ( OUT, "%s=%s",defs[i]->name.c_str(), defs[i]->value.c_str()); else fprintf ( OUT, defs[i]->name.c_str()); @@ -233,14 +233,14 @@ PropsMaker::_generate_global_definitions() } void -PropsMaker::_generate_footer() +VSPropsMaker::_generate_footer() { fprintf ( OUT, "\r\n"); } void -PropsMaker::_generate_props ( std::string solution_version, +VSPropsMaker::_generate_props ( std::string solution_version, std::string studio_version ) { _generate_header(); diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index 38a104a12f9..d1c31385acc 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -138,7 +138,7 @@ GetSubPath ( return FixSeparator(path + cSep + att_value); } -static string +string GetExtension ( const string& filename ) { size_t index = filename.find_last_of ( '/' ); diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index fe2aca15d96..04d2d69e7f7 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -1087,6 +1087,9 @@ GetSubPath ( const std::string& path, const std::string& att_value ); +extern std::string +GetExtension ( const std::string& filename ); + extern std::string GetExtension ( const FileLocation& file ); diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index bf328f71fd1..5b0c5b55efe 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -184,6 +184,7 @@ RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ genguid.cpp \ msvc.cpp \ projmaker.cpp \ + propsmaker.cpp \ slnmaker.cpp \ vcprojmaker.cpp \ vcxprojmaker.cpp \ @@ -471,6 +472,10 @@ $(RBUILD_MSVC_INT_)vspropsmaker.o: $(RBUILD_MSVC_BASE_)vspropsmaker.cpp $(RBUILD $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ +$(RBUILD_MSVC_INT_)propsmaker.o: $(RBUILD_MSVC_BASE_)propsmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_MSVC_INT_)slnmaker.o: $(RBUILD_MSVC_BASE_)slnmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ From e2be36788716b711e6640b765e1ec52c35be8987 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 1 Jun 2010 09:52:16 +0000 Subject: [PATCH 171/292] [NPFS] - Check if MmGetSystemAddressForMdlSafe failed svn path=/trunk/; revision=47512 --- reactos/drivers/filesystems/npfs/rw.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index 6f8675ed754..5a03977a788 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -781,7 +781,16 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, } Status = STATUS_SUCCESS; - Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + Buffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, NormalPagePriority); + + if (!Buffer) + { + DPRINT("MmGetSystemAddressForMdlSafe failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + Length = 0; + goto done; + + } ExAcquireFastMutex(&ReaderCcb->DataListLock); From ba2a17a2ef24e72ed7cdb61652329e3dbb93bafc Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 1 Jun 2010 10:57:26 +0000 Subject: [PATCH 172/292] [NPFS] - Fix 2 memory leaks when creating a pipe fails - Fix minor style issue svn path=/trunk/; revision=47513 --- reactos/drivers/filesystems/npfs/create.c | 11 ++++++++++- reactos/drivers/filesystems/npfs/rw.c | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/filesystems/npfs/create.c b/reactos/drivers/filesystems/npfs/create.c index 2eb0aad9c0e..bef462fb8d7 100644 --- a/reactos/drivers/filesystems/npfs/create.c +++ b/reactos/drivers/filesystems/npfs/create.c @@ -255,8 +255,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, if (ClientCcb->Data) { ExFreePool(ClientCcb->Data); - ClientCcb->Data = NULL; } + + ExFreePool(ClientCcb); KeUnlockMutex(&Fcb->CcbListLock); Irp->IoStatus.Status = STATUS_OBJECT_PATH_NOT_FOUND; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -273,6 +274,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, else if (IsListEmpty(&Fcb->ServerCcbListHead)) { DPRINT("No server fcb found!\n"); + + if (ClientCcb->Data) + { + ExFreePool(ClientCcb->Data); + } + + ExFreePool(ClientCcb); + KeUnlockMutex(&Fcb->CcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/filesystems/npfs/rw.c b/reactos/drivers/filesystems/npfs/rw.c index 5a03977a788..e5ef963b9ad 100644 --- a/reactos/drivers/filesystems/npfs/rw.c +++ b/reactos/drivers/filesystems/npfs/rw.c @@ -163,7 +163,7 @@ NpfsWaiterThread(PVOID InitContext) ASSERT(FALSE); } KeLockMutex(&ThreadContext->DeviceExt->PipeListLock); - Count = Status - STATUS_SUCCESS; + Count = Status - STATUS_WAIT_0; ASSERT (Count < CurrentCount); if (Count > 0) { From 2acf45f081a3caa1635188ec0edbd17e1e6d8b4e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 1 Jun 2010 15:08:14 +0000 Subject: [PATCH 173/292] [NTOS] - Fix assertion hit during install - Fix identation - Remove superflous spaces svn path=/trunk/; revision=47514 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index a86611b503e..42b090da557 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -59,8 +59,8 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, { PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - ASSERT_LIST_INVARIANT(ListHead); + ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); /* Get the back link */ OldBlink = ListHead->Blink; @@ -111,7 +111,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* Use the zero list */ ListHead = &MmZeroedPageListHead; - ASSERT_LIST_INVARIANT(ListHead); + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the back link */ @@ -205,8 +205,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) ListName = ListHead->ListName; ASSERT(ListHead != NULL); ASSERT(ListName <= FreePageList); - ASSERT_LIST_INVARIANT(ListHead); - + ASSERT_LIST_INVARIANT(ListHead); + /* Remove one count */ ASSERT(ListHead->Total != 0); ListHead->Total--; @@ -241,8 +241,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) /* We are not on a list anymore */ Entry->u1.Flink = Entry->u2.Blink = 0; - ASSERT_LIST_INVARIANT(ListHead); - + ASSERT_LIST_INVARIANT(ListHead); + /* FIXME: Deal with color list */ /* See if we hit any thresholds */ @@ -292,7 +292,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, /* Could be either on free or zero list */ ListHead = MmPageLocationList[Pfn1->u3.e1.PageLocation]; - ASSERT_LIST_INVARIANT(ListHead); + ASSERT_LIST_INVARIANT(ListHead); ListName = ListHead->ListName; ASSERT(ListName <= FreePageList); @@ -403,13 +403,13 @@ MiRemoveAnyPage(IN ULONG Color) { #endif /* Check the free list */ - ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); PageIndex = MmFreePageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; if (PageIndex == LIST_HEAD) { /* Check the zero list */ - ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); PageIndex = MmZeroedPageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; ASSERT(PageIndex != LIST_HEAD); @@ -435,8 +435,8 @@ MiRemoveAnyPage(IN ULONG Color) ASSERT(Pfn1->u2.ShareCount == 0); /* Return the page */ - ASSERT_LIST_INVARIANT(&MmFreePageListHead); - ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); return PageIndex; } @@ -448,8 +448,8 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) PFN_NUMBER Entry, Flink; PMMPFN Pfn1; - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - ASSERT_LIST_INVARIANT(ListHead); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); /* Get the entry that's currently first on the list */ Entry = ListHead->Flink; @@ -494,7 +494,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) PMMCOLOR_TABLES ColorTable; #endif /* Make sure the page index is valid */ - ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT((PageFrameIndex != 0) && (PageFrameIndex <= MmHighestPhysicalPage) && (PageFrameIndex >= MmLowestPhysicalPage)); @@ -511,7 +511,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Get the free page list and increment its count */ ListHead = &MmFreePageListHead; - ASSERT_LIST_INVARIANT(ListHead); + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the last page on the list */ @@ -529,7 +529,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Now make the list head point back to us (since we go at the end) */ ListHead->Blink = PageFrameIndex; - + /* And initialize our own list pointers */ Pfn1->u1.Flink = LIST_HEAD; Pfn1->u2.Blink = LastPage; @@ -537,7 +537,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Set the list name and default priority */ Pfn1->u3.e1.PageLocation = FreePageList; Pfn1->u4.Priority = 3; - + /* Clear some status fields */ Pfn1->u4.InPageError = 0; Pfn1->u4.AweAllocation = 0; @@ -557,7 +557,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) KeSetEvent(MiHighMemoryEvent, 0, FALSE); } - ASSERT_LIST_INVARIANT(ListHead); + ASSERT_LIST_INVARIANT(ListHead); #if 0 // When using ARM3 PFN /* Get the page color */ @@ -678,10 +678,10 @@ MiAllocatePfn(IN PMMPTE PointerPte, } /* Grab a page */ - ASSERT_LIST_INVARIANT(&MmFreePageListHead); - ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); PageFrameIndex = MiRemoveAnyPage(0); - + /* Write the software PTE */ ASSERT(PointerPte->u.Hard.Valid == 0); *PointerPte = TempPte; @@ -691,8 +691,8 @@ MiAllocatePfn(IN PMMPTE PointerPte, MiInitializePfn(PageFrameIndex, PointerPte, TRUE); /* Release the PFN lock and return the page */ - ASSERT_LIST_INVARIANT(&MmFreePageListHead); - ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); return PageFrameIndex; } From b5781444a5f29a21b7aca32b1abff53887633ae6 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Tue, 1 Jun 2010 19:36:43 +0000 Subject: [PATCH 174/292] [FONTVIEW] Select the oldest font back into the DC, leftover from bug #5182 svn path=/trunk/; revision=47515 --- reactos/base/applications/fontview/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/fontview/display.c b/reactos/base/applications/fontview/display.c index 1362e4a822a..55272eec754 100644 --- a/reactos/base/applications/fontview/display.c +++ b/reactos/base/applications/fontview/display.c @@ -103,7 +103,7 @@ Display_DrawText(HDC hDC, DISPLAYDATA* pData, int nYPos) /* TODO: Output font info */ /* Output Character set */ - hOldFont = SelectObject(hDC, pData->hCharSetFont); + SelectObject(hDC, pData->hCharSetFont); GetTextMetrics(hDC, &tm); swprintf(szCaption, L"abcdefghijklmnopqrstuvwxyz"); TextOutW(hDC, 0, y, szCaption, wcslen(szCaption)); From 59aacb176fdb60c0c8b04d4c92389d58b86e3135 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 1 Jun 2010 20:06:53 +0000 Subject: [PATCH 175/292] [NTOSKRNL] - Revert the hack in r47514 - The ASSERT is there to make sure the PFN lock is held - Fix the issue properly by holding the PFN lock while initializing svn path=/trunk/; revision=47516 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 2 +- reactos/ntoskrnl/mm/freelist.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 42b090da557..29777f6990a 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -59,7 +59,7 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, { PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry); - ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT_LIST_INVARIANT(ListHead); /* Get the back link */ diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index b6b9806e4b0..afdad865dfe 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -457,12 +457,16 @@ MmInitializePageList(VOID) PMEMORY_ALLOCATION_DESCRIPTOR Md; PLIST_ENTRY NextEntry; ULONG NrSystemPages = 0; + KIRQL OldIrql; /* This is what a used page looks like */ RtlZeroMemory(&UsedPage, sizeof(UsedPage)); UsedPage.u3.e1.PageLocation = ActiveAndValid; UsedPage.u3.e2.ReferenceCount = 1; + /* Lock PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + /* Loop the memory descriptors */ for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; @@ -518,6 +522,9 @@ MmInitializePageList(VOID) MmPfnDatabase[0][i] = UsedPage; NrSystemPages++; } + + /* Release the PFN database lock */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); DPRINT("Pages: %x %x\n", MmAvailablePages, NrSystemPages); From 840624212a92b4a1bd7a11cc26054abaf6cda995 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 2 Jun 2010 11:26:19 +0000 Subject: [PATCH 176/292] [HAL] - Fix a typo. svn path=/trunk/; revision=47517 --- reactos/hal/halx86/generic/bus/pcibus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/hal/halx86/generic/bus/pcibus.c b/reactos/hal/halx86/generic/bus/pcibus.c index 3c46e805122..ef3def412bd 100644 --- a/reactos/hal/halx86/generic/bus/pcibus.c +++ b/reactos/hal/halx86/generic/bus/pcibus.c @@ -391,7 +391,6 @@ HalpGetPCIData(IN PBUS_HANDLER BusHandler, if (PciConfig->VendorID == PCI_INVALID_VENDORID) { /* It's invalid, but we want to return this much */ - PciConfig->VendorID = PCI_INVALID_VENDORID; Len = sizeof(USHORT); } From ebed05d2d46ab21baccb2242b0654760ab779f3b Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 2 Jun 2010 11:34:56 +0000 Subject: [PATCH 177/292] Polish Translation Updates by Maciej Bialas. svn path=/trunk/; revision=47518 --- reactos/base/applications/calc/lang/pl-PL.rc | 214 +++++++++--------- reactos/base/applications/rapps/lang/pl-PL.rc | 2 +- reactos/base/shell/explorer-new/lang/pl-PL.rc | 2 +- 3 files changed, 109 insertions(+), 109 deletions(-) diff --git a/reactos/base/applications/calc/lang/pl-PL.rc b/reactos/base/applications/calc/lang/pl-PL.rc index fac1f7975af..59cf444ef50 100644 --- a/reactos/base/applications/calc/lang/pl-PL.rc +++ b/reactos/base/applications/calc/lang/pl-PL.rc @@ -464,9 +464,9 @@ END // TYPES OF ANGLES STRINGTABLE DISCARDABLE BEGIN - IDS_ANGLE_DEGREES "Stopni" - IDS_ANGLE_GRADIANS "Gradianów" - IDS_ANGLE_RADIANS "Radianów" + IDS_ANGLE_DEGREES "Stopnie" + IDS_ANGLE_GRADIANS "Gradiany" + IDS_ANGLE_RADIANS "Radiany" END // TYPES OF AREAS @@ -489,21 +489,21 @@ BEGIN IDS_AREA_PYEONGBANGJA "Pyeongbangja" IDS_AREA_RAI "Rai" IDS_AREA_SE "Se" - IDS_AREA_SQUARE_CENTIMETERS "Centymetrów kwadratowych" - IDS_AREA_SQUARE_CHR "Chr kwadratowych" - IDS_AREA_SQUARE_FATHOMS "S¹¿ni kwadratowych" - IDS_AREA_SQUARE_FATHOMS_HUNGARY "S¹¿ni kwadratowych (Wêgry)" - IDS_AREA_SQUARE_FEET "Stóp kwadratowych" - IDS_AREA_SQUARE_INCHES "Cali kwadratowych" - IDS_AREA_SQUARE_KILOMETERS "Kilometrów kwadratowych" - IDS_AREA_SQUARE_LAR "Lar kwadratowych" - IDS_AREA_SQUARE_METER "Metrów kwadratowych" - IDS_AREA_SQUARE_MILES "Mil kwadratowych" - IDS_AREA_SQUARE_MILLIMETERS "Milimetrów kwadratowych" - IDS_AREA_SQUARE_SHAKU "Shaku kwadratowych" - IDS_AREA_SQUARE_TSUEN "Tsuen kwadratowych" - IDS_AREA_SQUARE_VA "Va kwadratowych" - IDS_AREA_SQUARE_YARD "Jardów kwadratowych" + IDS_AREA_SQUARE_CENTIMETERS "Centymetry kwadratowe" + IDS_AREA_SQUARE_CHR "Chr kwadratowe" + IDS_AREA_SQUARE_FATHOMS "S¹¿nie kwadratowe" + IDS_AREA_SQUARE_FATHOMS_HUNGARY "S¹¿nie kwadratowe (Wêgry)" + IDS_AREA_SQUARE_FEET "Stopy kwadratowe" + IDS_AREA_SQUARE_INCHES "Cale kwadratowe" + IDS_AREA_SQUARE_KILOMETERS "Kilometry kwadratowe" + IDS_AREA_SQUARE_LAR "Lar kwadratowe" + IDS_AREA_SQUARE_METER "Metry kwadratowe" + IDS_AREA_SQUARE_MILES "Mile kwadratowe" + IDS_AREA_SQUARE_MILLIMETERS "Milimetry kwadratowe" + IDS_AREA_SQUARE_SHAKU "Shaku kwadratowe" + IDS_AREA_SQUARE_TSUEN "Tsuen kwadratowe" + IDS_AREA_SQUARE_VA "Va kwadratowe" + IDS_AREA_SQUARE_YARD "Jardy kwadratowe" IDS_AREA_TAN "Tan" IDS_AREA_TSUBO "Tsubo" END @@ -511,10 +511,10 @@ END // TYPES OF COMSUMPTIONS STRINGTABLE DISCARDABLE BEGIN - IDS_CONSUMPTION_KM_PER_L "Kilometrów/litr" - IDS_CONSUMPTION_L_PER_100_KM "Litrów/100 kilometróws" - IDS_CONSUMPTION_MILES_GALLON_UK "Mil/galon (UK)" - IDS_CONSUMPTION_MILES_GALLON_US "Mil/galon (USA)" + IDS_CONSUMPTION_KM_PER_L "Kilometry/litr" + IDS_CONSUMPTION_L_PER_100_KM "Litry/100 kilometrów" + IDS_CONSUMPTION_MILES_GALLON_UK "Mile/galon (UK)" + IDS_CONSUMPTION_MILES_GALLON_US "Mile/galon (USA)" END // TYPES OF CURRENCIES @@ -543,56 +543,56 @@ END // TYPES OF ENERGIES STRINGTABLE DISCARDABLE BEGIN - IDS_ENERGY_15_C_CALORIES "15 °C kalorii" + IDS_ENERGY_15_C_CALORIES "15 °C kalorie" IDS_ENERGY_BTUS "British Thermal Unit" - IDS_ENERGY_ERGS "Ergów" - IDS_ENERGY_EVS "Elektronowolt" - IDS_ENERGY_FOOT_POUNDS "Foot-pound" + IDS_ENERGY_ERGS "Ergi" + IDS_ENERGY_EVS "Elektronowolty" + IDS_ENERGY_FOOT_POUNDS "Stopo-funty" IDS_ENERGY_IT_CALORIES "Miêdzynarodowa Tablica kalorii" IDS_ENERGY_IT_KILOCALORIES "Miêdzynarodowa Tablica kilokalorii" - IDS_ENERGY_JOULES "D¿uli" - IDS_ENERGY_KILOJOULES "Kilod¿uli" - IDS_ENERGY_KILOWATT_HOURS "Kilowatogodzin" - IDS_ENERGY_NUTRITION_CALORIES "Kalorii spo¿ywczych" - IDS_ENERGY_TH_CALORIES "Kalorii termochemicznych" + IDS_ENERGY_JOULES "D¿ule" + IDS_ENERGY_KILOJOULES "Kilod¿ule" + IDS_ENERGY_KILOWATT_HOURS "Kilowatogodziny" + IDS_ENERGY_NUTRITION_CALORIES "Kalorie spo¿ywcze" + IDS_ENERGY_TH_CALORIES "Kalorie termochemiczne" END // TYPES OF LENGTHS STRINGTABLE DISCARDABLE BEGIN - IDS_LENGTH_ANGSTROMS "Angsztremów" - IDS_LENGTH_ASTRONOMICAL_UNITS "Jednostek Astronomicznych" - IDS_LENGTH_BARLEYCORNS "Palców" - IDS_LENGTH_CENTIMETERS "Centimetrów" + IDS_LENGTH_ANGSTROMS "Angsztremy" + IDS_LENGTH_ASTRONOMICAL_UNITS "Jednostki Astronomiczne" + IDS_LENGTH_BARLEYCORNS "Palce" + IDS_LENGTH_CENTIMETERS "Centymetry" IDS_LENGTH_CHAINS_UK "Chains (UK)" IDS_LENGTH_CHI "Chi" IDS_LENGTH_CHOU "Chou" IDS_LENGTH_CHR "Chr" IDS_LENGTH_CUN "Cun" - IDS_LENGTH_FATHOMS "S¹¿ni" - IDS_LENGTH_FATHOMS_HUNGARY "S¹¿ni (Wêgry)" - IDS_LENGTH_FEET "Stóp" + IDS_LENGTH_FATHOMS "S¹¿nie" + IDS_LENGTH_FATHOMS_HUNGARY "S¹¿nie (Wêgry)" + IDS_LENGTH_FEET "Stopy" IDS_LENGTH_FURLONGS "Furlongs" IDS_LENGTH_GAN "Gan" - IDS_LENGTH_HANDS "D³oni" + IDS_LENGTH_HANDS "D³onie" IDS_LENGTH_HUNH "Hunh" - IDS_LENGTH_INCHES "Cali" + IDS_LENGTH_INCHES "Cale" IDS_LENGTH_JA "Ja" IDS_LENGTH_JEONG "Jeong" IDS_LENGTH_KABIET "Kabiet" IDS_LENGTH_KEN "Ken" IDS_LENGTH_KEUB "Keub" - IDS_LENGTH_KILOMETERS "Kilometerów" + IDS_LENGTH_KILOMETERS "Kilometry" IDS_LENGTH_LAR "Lar" - IDS_LENGTH_LIGHT_YEARS "Lat œwietlnych" + IDS_LENGTH_LIGHT_YEARS "Lata œwietlne" IDS_LENGTH_LINKS_UK "Links (UK)" - IDS_LENGTH_METERS "Metrów" - IDS_LENGTH_MICRONS "Mikrometrów" - IDS_LENGTH_MILES "Mil" - IDS_LENGTH_MILLIMETERS "Millimetrów" - IDS_LENGTH_NAUTICAL_MILES "Mil morskich" + IDS_LENGTH_METERS "Metry" + IDS_LENGTH_MICRONS "Mikrometry" + IDS_LENGTH_MILES "Mile" + IDS_LENGTH_MILLIMETERS "Milimetry" + IDS_LENGTH_NAUTICAL_MILES "Mile morskie" IDS_LENGTH_NIEU "Nieu" - IDS_LENGTH_PARSECS "Parseków" + IDS_LENGTH_PARSECS "Parseki" IDS_LENGTH_PICAS "Picas" IDS_LENGTH_RI_JAPAN "Ri (Japan)" IDS_LENGTH_RI_KOREA "Ri (Korea)" @@ -604,7 +604,7 @@ BEGIN IDS_LENGTH_SUN "Sun" IDS_LENGTH_TSUEN "Tsuen" IDS_LENGTH_VA "Va" - IDS_LENGTH_YARDS "Jardów" + IDS_LENGTH_YARDS "Jardy" IDS_LENGTH_YOTE "Yote" IDS_LENGTH_ZHANG "Zhang" END @@ -613,23 +613,23 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_POWER_BTUS_PER_MINUTE "BTU na minutê" - IDS_POWER_FPS_PER_MINUTE "Foot-pound na minutê" - IDS_POWER_HORSEPOWER "Koni mechanicznych" - IDS_POWER_KILOWATTS "Kilowatów" - IDS_POWER_MEGAWATTS "Megawatów" - IDS_POWER_WATTS "Watów" + IDS_POWER_FPS_PER_MINUTE "Stopo-funty na minutê" + IDS_POWER_HORSEPOWER "Konie mechaniczne" + IDS_POWER_KILOWATTS "Kilowaty" + IDS_POWER_MEGAWATTS "Megawaty" + IDS_POWER_WATTS "Waty" END // TYPE OF PRESSURES STRINGTABLE DISCARDABLE BEGIN - IDS_PRESSURE_ATMOSPHERES "Atmosfer" - IDS_PRESSURE_BARS "Barów" - IDS_PRESSURE_HECTOPASCALS "Hektopaskali" - IDS_PRESSURE_KILOPASCALS "Kilopaskali" - IDS_PRESSURE_MM_OF_MERCURY "Millimetrów s³upka rtêci" - IDS_PRESSURE_PASCALS "Paskali" - IDS_PRESSURE_PSI "Funtów na cal kwadratowy" + IDS_PRESSURE_ATMOSPHERES "Atmosfery" + IDS_PRESSURE_BARS "Bary" + IDS_PRESSURE_HECTOPASCALS "Hektopaskale" + IDS_PRESSURE_KILOPASCALS "Kilopaskale" + IDS_PRESSURE_MM_OF_MERCURY "Milimetry s³upka rtêci" + IDS_PRESSURE_PASCALS "Paskale" + IDS_PRESSURE_PSI "Funty na cal kwadratowy" END // TYPES OF TEMPERATURES @@ -645,61 +645,61 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dni" - IDS_TIME_HOURS "Godzin" - IDS_TIME_NANOSECONDS "Nanoseconds" - IDS_TIME_MICROSECONDS "Mikrosekund" - IDS_TIME_MILLISECONDS "Milisekund" - IDS_TIME_MINUTES "Minut" - IDS_TIME_SECONDS "Sekund" - IDS_TIME_WEEKS "Tygodni" - IDS_TIME_YEARS "Lat" + IDS_TIME_HOURS "Godziny" + IDS_TIME_NANOSECONDS "Nanosekundy" + IDS_TIME_MICROSECONDS "Mikrosekundy" + IDS_TIME_MILLISECONDS "Milisekundy" + IDS_TIME_MINUTES "Minuty" + IDS_TIME_SECONDS "Sekundy" + IDS_TIME_WEEKS "Tygodnie" + IDS_TIME_YEARS "Lata" END // TYPES OF VELOCITIES STRINGTABLE DISCARDABLE BEGIN - IDS_VELOCITY_CMS_SECOND "Centimetrów/sekundê" - IDS_VELOCITY_FEET_HOUR "Stóp/godzinê" - IDS_VELOCITY_FEET_SECOND "Stóp/sekundê" - IDS_VELOCITY_KILOMETERS_HOUR "Kilometrów/godzinê" - IDS_VELOCITY_KNOTS "Wêz³ów" - IDS_VELOCITY_MACH "Machów" - IDS_VELOCITY_METERS_SECOND "Metrów/sekundê" - IDS_VELOCITY_MILES_HOUR "Mil/godzinê" + IDS_VELOCITY_CMS_SECOND "Centymetry/sekundê" + IDS_VELOCITY_FEET_HOUR "Stopy/godzinê" + IDS_VELOCITY_FEET_SECOND "Stopy/sekundê" + IDS_VELOCITY_KILOMETERS_HOUR "Kilometry/godzinê" + IDS_VELOCITY_KNOTS "Wêz³y" + IDS_VELOCITY_MACH "Machy" + IDS_VELOCITY_METERS_SECOND "Metry/sekundê" + IDS_VELOCITY_MILES_HOUR "Mile/godzinê" END // TYPES OF VOLUMES STRINGTABLE DISCARDABLE BEGIN - IDS_VOLUME_BARRELS_UK "Bary³ek (UK)" - IDS_VOLUME_BARRELS_OIL "Bary³ek" + IDS_VOLUME_BARRELS_UK "Bary³ki (UK)" + IDS_VOLUME_BARRELS_OIL "Bary³ki" IDS_VOLUME_BUN "Bun" - IDS_VOLUME_BUSHELS_UK "Buszli (UK)" - IDS_VOLUME_BUSHELS_US "Buszli (US)" - IDS_VOLUME_CUBIC_CENTIMETERS "Centymetrów szeœciennych" - IDS_VOLUME_CUBIC_FEET "Stóp szeœciennych" - IDS_VOLUME_CUBIC_INCHES "Cali szeœciennych" - IDS_VOLUME_CUBIC_METERS "Metrów szeœciennych" - IDS_VOLUME_CUBIC_YARDS "Jardów szeœciennych" + IDS_VOLUME_BUSHELS_UK "Buszle (UK)" + IDS_VOLUME_BUSHELS_US "Buszle (US)" + IDS_VOLUME_CUBIC_CENTIMETERS "Centymetry szeœcienne" + IDS_VOLUME_CUBIC_FEET "Stopy szeœcienne" + IDS_VOLUME_CUBIC_INCHES "Cale szeœcienne" + IDS_VOLUME_CUBIC_METERS "Metry szeœcienne" + IDS_VOLUME_CUBIC_YARDS "Jardy szeœcienne" IDS_VOLUME_DOE "Doe" - IDS_VOLUME_FLUID_OUNCES_UK "Uncji, p³yn (UK)" - IDS_VOLUME_FLUID_OUNCES_US "Uncji, p³yn (US)" - IDS_VOLUME_GALLONS_UK "Galonów (UK)" - IDS_VOLUME_GALLONS_DRY_US "Galonów, sypkie (US)" - IDS_VOLUME_GALLONS_LIQUID_US "Gallons, p³yn (US)" + IDS_VOLUME_FLUID_OUNCES_UK "Uncje, p³yn (UK)" + IDS_VOLUME_FLUID_OUNCES_US "Uncje, p³yn (US)" + IDS_VOLUME_GALLONS_UK "Galony (UK)" + IDS_VOLUME_GALLONS_DRY_US "Galony, sypkie (US)" + IDS_VOLUME_GALLONS_LIQUID_US "Galony, p³yn (US)" IDS_VOLUME_GOU "Gou" IDS_VOLUME_HOP "Hop" IDS_VOLUME_ICCE "Icce" IDS_VOLUME_KWIAN "Kwian" - IDS_VOLUME_LITERS "Litrów" + IDS_VOLUME_LITERS "Litry" IDS_VOLUME_MAL "Mal" - IDS_VOLUME_MILLILITERS "Milliliters" - IDS_VOLUME_PINTS_UK "Pint (UK)" - IDS_VOLUME_PINTS_DRY_US "Pint, sypkie (US)" - IDS_VOLUME_PINTS_LIQUID_US "Pint, p³yn (US)" - IDS_VOLUME_QUARTS_UK "Kwart (UK)" - IDS_VOLUME_QUARTS_DRY_US "Kwart, sypkie (US)" - IDS_VOLUME_QUARTS_LIQUID_US "Kwart, p³yn (US)" + IDS_VOLUME_MILLILITERS "Mililitry" + IDS_VOLUME_PINTS_UK "Pinty (UK)" + IDS_VOLUME_PINTS_DRY_US "Pinty, sypkie (US)" + IDS_VOLUME_PINTS_LIQUID_US "Pinty, p³yn (US)" + IDS_VOLUME_QUARTS_UK "Kwarty (UK)" + IDS_VOLUME_QUARTS_DRY_US "Kwarty, sypkie (US)" + IDS_VOLUME_QUARTS_LIQUID_US "Kwarty, p³yn (US)" IDS_VOLUME_SEKI "Seki" IDS_VOLUME_SYOU "Syou" IDS_VOLUME_TANANLOUNG "Tananloung" @@ -710,26 +710,26 @@ END // TYPES OF WEIGHTS STRINGTABLE DISCARDABLE BEGIN - IDS_WEIGHT_BAHT "Bahtów" - IDS_WEIGHT_CARATS "Karatów" + IDS_WEIGHT_BAHT "Bahty" + IDS_WEIGHT_CARATS "Karaty" IDS_WEIGHT_CHUNG "Chung" IDS_WEIGHT_DON "Don" IDS_WEIGHT_GEUN "Geun" - IDS_WEIGHT_GRAMS "Gramów" + IDS_WEIGHT_GRAMS "Gramy" IDS_WEIGHT_GWAN "Gwan" IDS_WEIGHT_HARB "Harb" IDS_WEIGHT_JIN_CHINA "Jin (China)" IDS_WEIGHT_JIN_TAIWAN "Jin (Taiwan)" IDS_WEIGHT_KAN "Kan" - IDS_WEIGHT_KILOGRAMS "Kilogramów" + IDS_WEIGHT_KILOGRAMS "Kilogramy" IDS_WEIGHT_KIN "Kin" IDS_WEIGHT_LIANG_CHINA "Liang (China)" IDS_WEIGHT_LIANG_TAIWAN "Liang (Taiwan)" IDS_WEIGHT_MONME "Monme" - IDS_WEIGHT_OUNCES_AVOIRDUPOIS "Uncji, avoirdupois" - IDS_WEIGHT_OUNCES_TROY "Uncji, aptekarskie" - IDS_WEIGHT_POUNDS "Funtów" - IDS_WEIGHT_QUINTAL_METRIC "Kwintali" + IDS_WEIGHT_OUNCES_AVOIRDUPOIS "Uncje, avoirdupois" + IDS_WEIGHT_OUNCES_TROY "Uncje, aptekarskie" + IDS_WEIGHT_POUNDS "Funty" + IDS_WEIGHT_QUINTAL_METRIC "Kwintale" IDS_WEIGHT_SALOUNG "Saloung" IDS_WEIGHT_STONES "Kamieni" IDS_WEIGHT_TAMLUNG "Tamlung" diff --git a/reactos/base/applications/rapps/lang/pl-PL.rc b/reactos/base/applications/rapps/lang/pl-PL.rc index 60fd20b7530..5b68948a7e7 100644 --- a/reactos/base/applications/rapps/lang/pl-PL.rc +++ b/reactos/base/applications/rapps/lang/pl-PL.rc @@ -187,7 +187,7 @@ BEGIN IDS_UPDATES "Uaktualnienia" IDS_APPLICATIONS "Aplikacje" IDS_CHOOSE_FOLDER_TEXT "Wybierz katalog w którym bêda zapisywane pobrane programy:" - IDS_CHOOSE_FOLDER_ERROR "Wybra³eœ nieistniej¹cy katalog!" + IDS_CHOOSE_FOLDER_ERROR "Wybra³eœ nieistniej¹cy katalog! Czy chcesz utworzyæ nowy?" IDS_USER_NOT_ADMIN "Musisz mieæ uprawnienia administratora aby uruchomiæ ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Czy na pewno chcesz usun¹æ wpis tego programu z rejestru?" IDS_INFORMATION "Informacja" diff --git a/reactos/base/shell/explorer-new/lang/pl-PL.rc b/reactos/base/shell/explorer-new/lang/pl-PL.rc index 891c8c915c2..7b8e9de9cb6 100644 --- a/reactos/base/shell/explorer-new/lang/pl-PL.rc +++ b/reactos/base/shell/explorer-new/lang/pl-PL.rc @@ -123,7 +123,7 @@ BEGIN IDS_PROPERTIES "W³aœ&ciwoœci" IDS_OPEN_ALL_USERS "&Otwórz - wszyscy u¿ytkownicy" IDS_EXPLORE_ALL_USERS "&Eksploruj - wszyscy u¿ytkownicy" - IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." + IDS_STARTUP_ERROR "System nie mo¿e uruchomiæ eksploratora poniewa¿ rejestr jest niedostêpny lub uszkodzony." END STRINGTABLE DISCARDABLE From f1f3d045d4a1f4e7e5bc0eadcde01224d50471ba Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Wed, 2 Jun 2010 13:59:47 +0000 Subject: [PATCH 178/292] [HAL] Fix compiler preprocessor checks for the IRQL masks so other compilers than GCC get proper entries too. [HAL] Define the HalpHardwareInterrupt macro for MSVC too. [HAL] Replace IRQL_DEBUG with DBG so we always check for incorrect IRQL on debug. I believe incorrect IRQL raise/lower is a common and serious enough error to always be checked for on debug builds without defining some special debug option. svn path=/trunk/; revision=47519 --- reactos/hal/halx86/up/pic.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/reactos/hal/halx86/up/pic.c b/reactos/hal/halx86/up/pic.c index a710d862567..91b902b1a35 100644 --- a/reactos/hal/halx86/up/pic.c +++ b/reactos/hal/halx86/up/pic.c @@ -94,8 +94,8 @@ PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] = /* This table contains the static x86 PIC mapping between IRQLs and IRQs */ ULONG KiI8259MaskTable[32] = { -#ifdef __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404 +#if defined(__GNUC__) && \ + (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) /* * It Device IRQLs only start at 4 or higher, so these are just software * IRQLs that don't really change anything on the hardware @@ -206,14 +206,13 @@ ULONG KiI8259MaskTable[32] = 0xFFFFFFFB, /* IRQL 30 */ 0xFFFFFFFB /* IRQL 31 */ #endif -#endif }; /* This table indicates which IRQs, if pending, can preempt a given IRQL level */ ULONG FindHigherIrqlMask[32] = { -#ifdef __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404 +#if defined(__GNUC__) && \ + (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) /* * Software IRQLs, at these levels all hardware interrupts can preempt. * Each higher IRQL simply enables which software IRQL can preempt the @@ -313,7 +312,6 @@ ULONG FindHigherIrqlMask[32] = 0, /* IRQL 30 */ 0 /* IRQL 31 */ #endif -#endif }; /* Denotes minimum required IRQL before we can process pending SW interrupts */ @@ -329,6 +327,8 @@ KIRQL SWInterruptLookUpTable[8] = DISPATCH_LEVEL /* IRR 7 */ }; +#if defined(__GNUC__) + #define HalpDelayedHardwareInterrupt(x) \ VOID HalpHardwareInterrupt##x(VOID); \ VOID \ @@ -337,6 +337,23 @@ KIRQL SWInterruptLookUpTable[8] = asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \ } +#elif defined(_MSC_VER) + +#define HalpDelayedHardwareInterrupt(x) \ + VOID HalpHardwareInterrupt##x(VOID); \ + VOID \ + HalpHardwareInterrupt##x(VOID) \ + { \ + __asm \ + { \ + int PRIMARY_VECTOR_BASE + x \ + } \ + } + +#else +#error Unsupported compiler +#endif + /* Pending/delayed hardware interrupt handlers */ HalpDelayedHardwareInterrupt(0); HalpDelayedHardwareInterrupt(1); @@ -522,7 +539,7 @@ KeRaiseIrqlToDpcLevel(VOID) CurrentIrql = Pcr->Irql; Pcr->Irql = DISPATCH_LEVEL; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL); #endif @@ -545,7 +562,7 @@ KeRaiseIrqlToSynchLevel(VOID) CurrentIrql = Pcr->Irql; Pcr->Irql = SYNCH_LEVEL; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > SYNCH_LEVEL) { @@ -575,7 +592,7 @@ KfRaiseIrql(IN KIRQL NewIrql) /* Read current IRQL */ CurrentIrql = Pcr->Irql; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > NewIrql) { @@ -605,7 +622,7 @@ KfLowerIrql(IN KIRQL OldIrql) PKPCR Pcr = KeGetPcr(); PIC_MASK Mask; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct lower */ if (OldIrql > Pcr->Irql) { From ee7e83a4cd5544aef58412826fe7891d5d341ced Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 2 Jun 2010 14:04:07 +0000 Subject: [PATCH 179/292] Several Italian translation updates by Paolo Devoti. See issue #5438 for more details. svn path=/trunk/; revision=47520 --- reactos/base/applications/calc/lang/it-IT.rc | 2 +- reactos/base/applications/rapps/lang/it-IT.rc | 8 ++++---- reactos/base/applications/regedit/lang/it-IT.rc | 2 +- reactos/base/shell/explorer-new/lang/it-IT.rc | 10 +++++----- reactos/dll/cpl/intl/lang/it-IT.rc | 2 +- reactos/subsystems/win32/csrss/win32csr/lang/it-IT.rc | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/reactos/base/applications/calc/lang/it-IT.rc b/reactos/base/applications/calc/lang/it-IT.rc index fb0f8b6c12f..2e96c209fb5 100644 --- a/reactos/base/applications/calc/lang/it-IT.rc +++ b/reactos/base/applications/calc/lang/it-IT.rc @@ -639,7 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Giorni" IDS_TIME_HOURS "Ore" - IDS_TIME_NANOSECONDS "Nanoseconds" + IDS_TIME_NANOSECONDS "Nanosecondi" IDS_TIME_MICROSECONDS "Microsecondi" IDS_TIME_MILLISECONDS "Millisecondi" IDS_TIME_MINUTES "Minuti" diff --git a/reactos/base/applications/rapps/lang/it-IT.rc b/reactos/base/applications/rapps/lang/it-IT.rc index 44fcfab4a8a..35366716d7d 100644 --- a/reactos/base/applications/rapps/lang/it-IT.rc +++ b/reactos/base/applications/rapps/lang/it-IT.rc @@ -156,7 +156,7 @@ BEGIN IDS_CAT_DEVEL "Sviluppo" IDS_CAT_DRIVERS "Drivers" IDS_CAT_EDU "Edutainment" - IDS_CAT_ENGINEER "Engineering" + IDS_CAT_ENGINEER "Scienze" IDS_CAT_FINANCE "Finanza" IDS_CAT_GAMES "Giochi e divertimento" IDS_CAT_GRAPHICS "Graphica" @@ -174,18 +174,18 @@ BEGIN IDS_APPTITLE "ReactOS Applications Manager" IDS_SEARCH_TEXT "Cerca..." IDS_INSTALL "Installa" - IDS_UNINSTALL "Disinstall" + IDS_UNINSTALL "Disinstalla" IDS_MODIFY "Modifica" IDS_APPS_COUNT "Numero applicazioni: %d" IDS_WELCOME_TITLE "Benvenuto!\n\n" IDS_WELCOME_TEXT "Scegliere una categoria a sinistra, poi scegliere una applicazione da installare o disinstallare.\nReactOS Web Site: " IDS_WELCOME_URL "http://www.reactos.org" IDS_INSTALLED "Installato" - IDS_AVAILABLEFORINST "Disponibile" + IDS_AVAILABLEFORINST "Disponibile per l'installazione" IDS_UPDATES "Aggiornamenti" IDS_APPLICATIONS "Applicazioni" IDS_CHOOSE_FOLDER_TEXT "Scegliere una cartella dove scaricare le applicazioni:" - IDS_CHOOSE_FOLDER_ERROR "La cartella indicata non esiste." + IDS_CHOOSE_FOLDER_ERROR "La cartella indicata non esiste. Vuoi crearla?" IDS_USER_NOT_ADMIN "Dovete essere Amministratore per avviare ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Sicuro di voler cancellare dal registry i dati sui programmi installati?" IDS_INFORMATION "Informazioni" diff --git a/reactos/base/applications/regedit/lang/it-IT.rc b/reactos/base/applications/regedit/lang/it-IT.rc index 47960b8da5b..f5a2fc96540 100644 --- a/reactos/base/applications/regedit/lang/it-IT.rc +++ b/reactos/base/applications/regedit/lang/it-IT.rc @@ -192,7 +192,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | CAPTION "Modifica Multi-Stringa" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Name:",IDC_STATIC,6,6,134,8 + LTEXT "&Nome:",IDC_STATIC,6,6,134,8 EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "&Dati:",IDC_STATIC,6,35,161,8 EDITTEXT IDC_VALUE_DATA,6,46,240,102,ES_MULTILINE | diff --git a/reactos/base/shell/explorer-new/lang/it-IT.rc b/reactos/base/shell/explorer-new/lang/it-IT.rc index ac243130ed6..eaf2c0b9328 100644 --- a/reactos/base/shell/explorer-new/lang/it-IT.rc +++ b/reactos/base/shell/explorer-new/lang/it-IT.rc @@ -78,11 +78,11 @@ BEGIN LTEXT "This menu style gives you easy access to your folders, favorite programs, and search.", IDC_STATIC, 20,17,150,24, WS_DISABLED PUSHBUTTON "&Personalizzare...", IDC_TASKBARPROP_STARTMENUCUST, 192,4,53,14, WS_DISABLED AUTORADIOBUTTON "Menù avvio &classico", IDC_TASKBARPROP_STARTMENUCLASSIC, 7,47,105,10, WS_DISABLED - LTEXT "This menu style gives you the classic look and functionality",-1,20,57,150,24, WS_DISABLED - PUSHBUTTON "&Customize...", IDC_TASKBARPROP_STARTMENUCLASSICCUST, 192,44,53,14, WS_DISABLED + LTEXT "Questo stile di menù ha funzionalità e aspetto classici",-1,20,57,150,24, WS_DISABLED + PUSHBUTTON "&Personalizza...", IDC_TASKBARPROP_STARTMENUCLASSICCUST, 192,44,53,14, WS_DISABLED GROUPBOX "Privacy",IDC_STATIC, 7,100,238,42 - AUTOCHECKBOX "Store and display a list of recently opened &files", IDC_TASKBARPROP_RECENTFILES, 14,114,224,10, WS_DISABLED - AUTOCHECKBOX "Store and display a list of recently opened &programs",IDC_TASKBARPROP_RECENTFOLDERS, 14,128,224,10, WS_DISABLED + AUTOCHECKBOX "Memorizza e mostra un elenco di &file aperti di recente", IDC_TASKBARPROP_RECENTFILES, 14,114,224,10, WS_DISABLED + AUTOCHECKBOX "Memorizza e mostra un elenco di &programmi aperti di recente",IDC_TASKBARPROP_RECENTFOLDERS, 14,128,224,10, WS_DISABLED END IDD_TASKBARPROP_NOTIFICATION DIALOGEX 0, 0, 252, 218 @@ -120,7 +120,7 @@ BEGIN IDS_PROPERTIES "&Proprietà" IDS_OPEN_ALL_USERS "&Apri tutti gli utenti" IDS_EXPLORE_ALL_USERS "&Esplora tutti gli utenti" - IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." + IDS_STARTUP_ERROR "Impossibile avviare explorer perché il registro è danneggiato o non disponibile." END STRINGTABLE DISCARDABLE diff --git a/reactos/dll/cpl/intl/lang/it-IT.rc b/reactos/dll/cpl/intl/lang/it-IT.rc index ee1513a685c..eaaf6683f05 100644 --- a/reactos/dll/cpl/intl/lang/it-IT.rc +++ b/reactos/dll/cpl/intl/lang/it-IT.rc @@ -181,7 +181,7 @@ FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Ordinamento", -1, 7, 7, 230, 74 LTEXT "Il metodo di ordinamento definisce come considerare l'ordine di caratteri, parole, file e cartelle.", -1, 14, 17, 220, 25 - LTEXT "Scegliere il metodo di orinamento per il vostro linguaggio:", -1, 14, 37, 220, 22 + LTEXT "Scegliere il metodo di ordinamento per il vostro linguaggio:", -1, 14, 37, 220, 22 COMBOBOX IDC_SORTLIST_COMBO, 14, 56, 217, 83, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL END diff --git a/reactos/subsystems/win32/csrss/win32csr/lang/it-IT.rc b/reactos/subsystems/win32/csrss/win32csr/lang/it-IT.rc index 4aecce782f1..21d87610dc5 100644 --- a/reactos/subsystems/win32/csrss/win32csr/lang/it-IT.rc +++ b/reactos/subsystems/win32/csrss/win32csr/lang/it-IT.rc @@ -11,10 +11,10 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Fine del programma - " +CAPTION "Arresto del programma - " FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Fine del programma... Attendere",IDC_STATIC,7,7,186,11 + LTEXT "Arresto del programma... Attendere",IDC_STATIC,7,7,186,11 CONTROL "Progresso",IDC_PROGRESS,"msctls_progress32",WS_BORDER, 7,20,186,13 LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.", @@ -24,7 +24,7 @@ END IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "End Program - " +CAPTION "Arresto del programma - " FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "Annulla",IDCANCEL,142,98,43,17 From c1de13be76327ced0649168117fe26bad3078c7b Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 2 Jun 2010 15:43:07 +0000 Subject: [PATCH 180/292] [netshell] - Improve current network connection status icons. svn path=/trunk/; revision=47521 --- reactos/dll/win32/netshell/res/neterror.ico | Bin 3638 -> 3638 bytes reactos/dll/win32/netshell/res/netidle.ico | Bin 3638 -> 3638 bytes reactos/dll/win32/netshell/res/netoff.ico | Bin 3638 -> 3638 bytes reactos/dll/win32/netshell/res/netrec.ico | Bin 3638 -> 3638 bytes reactos/dll/win32/netshell/res/nettrans.ico | Bin 3638 -> 3638 bytes reactos/dll/win32/netshell/res/nettrrec.ico | Bin 3638 -> 3638 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/win32/netshell/res/neterror.ico b/reactos/dll/win32/netshell/res/neterror.ico index c80f6b7c97da2cc513e07106127a25b970329313..f20a0a4995ba938b4c28d5d305982ead23c8351f 100644 GIT binary patch delta 799 zcmdlcvrWd7fq{{Mi9taDL~}5#;9y`-V_;wq5P>M9&Ym00)HhG|#J0ONZsUHv?l(OK4SOlReP^cZ;GAtn5C&L*(U?M<9JxEGS zOauv-nXxk)fPs*ZhzM4Bh_nGj9@*_6)j(iiAgG|g%nX&sP{1z;l!nOH11$iBEex=; zi--tWzyQnum@Fs`h>#aT0992i<|Cwq>M<2yga(=e@yla)7S(>BPar`AC6$0Q*mwLu x5`>wd7%bQTBpZMU)Y=@xIsnA~Kj6SW7#RQmVPFO&ZeV%`Cva%u-WX)V3IM9gTp9oX delta 791 zcma)4%}T>S5T4B@B?oD?%aUG#$)!aKLQlm*L$$qn=+#rNzD3?Z0{aqPMd;Z_@D+T6 zoJCk?|LhuD^@GVbGvCa&N!Wd{FO~oVB47*i79Io>@^l-;vLozlJRS~f2Q(2pY}ggq#^(`$r!FoDNPOOS zN95INHjARNyhJdz+3a?89mpqixlN3-qt;fAUTx)w4a}sY?VvE9B)^i@cQ9%6$$2gU zEEbf`4LBF#n0{yFx!1$DCxlbfM^#1X2|de3C|kWT2ZRPf@GFmF2LI6c0h3ASt#jND ru>LvF{~LXSzK&O6-6#c_ju!yx0+2yM=C1V5aI=$Rp?^bZ z33PEN#&@~9^zy@$jzS(hF7Lj)@7{e0cMm9mq16J7RSc@Y9)NmX#8(yIi{|!ej$XkL zIe#zDf*?S*caPhX1AGpLc)32s;PD2N$pqu^7*FTN=s(=ywR48~e2(XfHhka5Xf(oG zuY=iahUs*Q{$(5Q6c<(~P$=*}6kr*qSDpd0I9^Q{TNAI<%$Ozf^KqmL)XT#voH57I zmv@{b;VRrTZOu%Rv85oKYkhoKPj-G9w=7ixUtcrYK3{(|ZiQysJYVq(Eku4ku2#40 zT8%LkiCW_OPvhmXT91!>&3Jx3p7DKSTBLt~xEA`)qO{WYx<0O|7h0tA^YHXu^7L}B3#vds07Kx95=M+dUuV`TtUQG!`Pvd*>J<#&*kyPR%O#@ z2p&+}tT&q!a~fii`P+=s(EDY@FIb|Z))FkT>WD?g5sQo?7FD*~25?9-(!H)k)sQ%a LJ(^!={zLdLZOM;M literal 3638 zcmeHI!A`Yj_zZ6H1tfd} zfsk+|*4ge(DGQ&2uR;?<(R{-89c0#U9kztGS zq|~j*tUbaoM62_Jhx1eX3&CqtOVjS7+!xKjO1_iTQkv_v;2`vl)iN zA-+0IOs7*!CKGgT8u%tZlWYRn1pdbaL@cUbQP3i^?>dnL+6U+B>j^)I#OHWmM-nI^ zAP4PuSe+id+wn|zj3A^`&r7naS*ZH$IG^r$uDg6!y{z7U9na-f&ot}P@Z|ThtnGJA!_B)Ux%peD zNyv$Ap7pYS*WFaV4L9#<)~DfSe!5Tp{z&?$g-KnH!|o%goS%#>-@^s$t*Q_B15#|V A>i_@% diff --git a/reactos/dll/win32/netshell/res/netoff.ico b/reactos/dll/win32/netshell/res/netoff.ico index 0d3bb295e2a967fe4d5b3465fb05777b38aae1e5..9cb3f62e89551db0ec387953f780e2c9dd8df974 100644 GIT binary patch literal 3638 zcmeHK&ubGw6#k}}wAr2PW)t(nY(nWtL_B-;WbN5w(Sst`YeC3CFi1tgLknKSvr7LA zZ&oTE1M%QL5E4Rz)k8GCx3in30l=L(+Hf zdT$ql!2tb!ANzN<@P_OZX$8^>{JRP`b68!K2Igod$rlVrnU6tA$1&(alCM_X7?>}W zJc4cK^Q>RYV{U`2_qlr zXhx|dpUp<`_{lM&T4?=Ze*SzZU?r*r>ycQ{Xqf!$w-@X+W9B+z*;BF>N#4x$_xNP4 zrhYM>NR`t!z~>Q%K^jJzEFOP~HVNO-m<)e0zCldJ$Z(%RtxM3W{B56dmi{E|O{mx@ z(hB@%6^Op7VS54MPw7WZTv)N=fW*bUQBI4O|Pu8A27Ck6}y%vNV1dCJ@1S@zE&no>H z-mKJfARhb!At5waFVXnk&dg?#wcQ>S_JhgHo9}(^@m}Cf0>GdIz7Gf+9+m;F;HlG* z_Mr{%3h%C>NiKBF(2uaek}dNwo6TTz^BcUrw}sq$_ z*s+sgwjWX!o)(9W&Ea~D6!D_ zMUA4ggzO?_QBjngMp1SeMRi@5O~Wz8UV2gogQJ^0TvKEHMxN$u2iFEJJ!gTVp+PZJ zoV+=E?fP4snLjTyZ;y|E6f;-%xY&yh{AV3lQ3F?wL2gcrq>?OOT>$5DF01K``USe0 z<)g?mKztDR2-mGtD1RQm*kIE8eh@SozAyE8d>k9;J*j61tcmM@oeKHB3r40SK0K94uQU&e$8L){ChU*_xevw5u5GHW%px|TfN uto3jD^Z4ajm-Tu4vVXpff3bkpCv-K}S@))oI$OAB)@%yaxeI@E5dHv3AJans diff --git a/reactos/dll/win32/netshell/res/netrec.ico b/reactos/dll/win32/netshell/res/netrec.ico index 5aaffe27e6e913bf59890091a5340291c44a00a9..3ada0c28d99ced2e3cb509d858c077c3abf00316 100644 GIT binary patch literal 3638 zcmeHJzi-n}5dIS9CBYD!n8Y}(Njo9_0wyF7LKU4mhk-6IHWCs8s1YhKFcgUebuK7> z01^uWVxba4@M zIlf!M3t?I6_LdcQSjOvmQGu?jig2ve`7ob!|0EBX1WtqZS3u?S{>ynOn)J`v5>gB4 zukt=^hkPhNqag(6!r9n%GXEs6X<pIw z>te%YQ}++fExx$)^16sE( zwpz6II;fSa@{O#luF^+_Ku695%7Nhw~|#{ Xr$T(|?#JZGMb}+ga!U^E5AlBiiSfqM literal 3638 zcmeHJL2DC16#h25vq@LuCgWz^v}?>s`~{wb7Lj7lJ;#H+=&=F8gVG{Z4}ulEh-a1j z0KtogVh`>O?-LQL2v6OCX)$X-QB=+Iz_+V$NRl5{`?%` z3e{*#3KC0@+g zHpv=^p0lvX&=5IPo?_1GrWCs9K+%E4I-m!$*6C>N*E-EN)FhYl+;JA=)B6{-eP5p} zwC|_m^LWRx6L1`TPoYJwMfqek^Wx|6K>Vyw9ohbg^YeLmYY}f4hJ2I)*$Ww;HFr}^!CR%z-p9~tRLn9W^zdTV>y9& PNRs5lIwIehq7L{6CU)lw diff --git a/reactos/dll/win32/netshell/res/nettrans.ico b/reactos/dll/win32/netshell/res/nettrans.ico index b3f647f20e94874b67aca12aabeb2d1a32ccad85..cfad0528c9957f545e68391f2d9958dbffc4a50a 100644 GIT binary patch literal 3638 zcmeHJJ#W)M7=9f4;uu1l9EmY)J~|_)2as40tbqCh z5G)Lcg-W1~k@6ctqCk+yP+{ITK7Z746FRZ@kzU#FJ$_!_J$Jf0Ktm2|YoKQVdj;SE zfO6T-?+D<4+AdNXeS)hL{M{mWo`;VQH}PeEANQ|c!uHN19K5=R*X_%Av(v#~Fu?P> zo9OrZ_^`E(-J2VD`uG8+zeaf3Y2)*gHui2`!+1Q#vs*VXnM}~@_3-sY2fu#|@NR1Z zqtOV{pWiVY4)MOTj<;0z8}S)32Qml#p93NV@!q7+w8KOY;&cMygnX@L9YIpRn8$nv zqt5Z$5?%<$abs|tq+l8Ex~3@=Ow)Daj&QAIylqR_P>_=KksYl67e1e_RC2jSLrU9b zO$Zu3>tnnYa{LnV`5An@>-s(Lz3}zN^GC)fHL7naSQh_c8L#V+{hFrhN&R9zWqwOM z8QcZ_|NH_dCHQE$kXNKDDFphH@U#?SsMV5d*^05IInV2QH20Rp{zrf3ku2s@yok%` zo#!JCrfn}Rx@dVEi30Idql6N2~lWcL&@B17gt=D?f- z(XQoF;k85UkV4%e>cNf~2vjAZPWkY7cV~yT>H39)Se1=pu_)cy>09SKU&)=9t9~6& z-a6N6QC=rd6{WX@L7?x|Ddvc3wMu!o)t1Vq&KN5}FIS9aq1lY`I;#!iY{2VWo$CkP aR>J_UP>YK0wqk=vVi)dG`(Z5p5dRkfGRRf{ literal 3638 zcmeHIJ#Q015Pj#n^V(p1_F|hO@mCe`3#gD1p(uhnwJD&1GM11iK#5SGK>{Qi6k0&} z0SFq3h=xcYN=yC?#+JcIq=+yxx4ZUYBQCCJ?n&d>nKv`LJ7>)T4pJx-K*->x53JCt z*;Mv^26#-q3uJN#yB&&StT~aI`x%eNcz9Guju#tc-vmbYpVO1_ykD@k`Da84)_zOGx(=9XofKSayCL$+c5EphF=LI zRE$3qk|07=$oH3JEtkv5(C0E$w$sJbdAY3OL3ZO@qd|6+Kvi^p;Clp$cTN3LsYLc< z|9s)p8E?s)a>=V_>h-Bz0&XJs@0?n0?x6)`4+Ed z{xm}I=?I+9eNbnpM7@aP|G1xY95I19e;n`Xmz4K)9M_$s3zZ+oPj5oKstJ+Lt1lsR z{zAOue1*T}$ME!5uuv}Bd-FPLu|mxAu4{jN)qlH29B;>-Y)x-}gafROZJGDOJ%BAH P-u6w`<72r06urT3!|Uj{ diff --git a/reactos/dll/win32/netshell/res/nettrrec.ico b/reactos/dll/win32/netshell/res/nettrrec.ico index 8c7420827c196d71d62fd5041a828c011f5c4ec6..27a2c1aaf4de2da92480a222433c98110c5631e2 100644 GIT binary patch literal 3638 zcmeHJJx|;~5PiN|J9qKz*#_=fsG|G`q(lhu2dJrNXhEV�f!K+DK_r@B^ZxNrBP? zDd@_R?l&A4B^(l0Ak2(+z5e7Jx)dI1w4Qx_v%AmM&Hxq~SX%>)Eu6Q2R{(rp#d|g| zq`B8LN3Y;5Ils5a!Z5`5_uKe+d5NQwV+=nX;`7crCX)%q<1xPNZ{qCq9p<;c@#Dh| z&UZI3o6Rs9jqvN^0q*`z@MV7s)9DoRn`?YM*u)jh*H$Y~EAW3SAWAH~;}Te8@m9{n zGx2WsMaJ^{#W;!^Om7cWxDcKfq|Ed339IlRa2%=4ae_dIL=etZg}bhlJ#A7lKaqp^ z|AO0gr_*TkdQ!SBbBxjPnO}|Dktu#Ghtfjv)3~KyP^ zRx3~|P*5PbxfEoItnN01?jn}s?jt7XOhQ+AQ{IE9Xgh&QB*cpBwcBkOMAdhhW4qH> zk}E0?DDM0HKE+X$qOzv=E>}CsB6Jn=gvw&B+LtPe-nGf1W0OV4CQH0+b5Xyc8SR53 RjmAUn79P<2eaasQe*{aFq$L0V literal 3638 zcmeHIv2GJV5PfIwoo(*czP-e*T_HXKDG`eJ0qRsVw24FqN`!zCS|nPEd;o%mBBCJ@ zD5WKTgE0~qi4+mX%x0`^E|<9Y_8D&u_wb40t+WiZ4E)~=s7lnX>94e$_?%s*4|6#szjLB6@rzs5imBJf`?%O@9*3dv;2?OX~M5 zJXaK>pi?sKo@GK>X&Go4*qi~sn7s`<__((rK9o)F_IaW}17$UYy1^-Z`j zi9Id$yd=i>ce3SPO?aAWJr>d07|#P+uKyQ2jHo`uuwA>btx| J_pd5{@CybK#bW>f From 4f491e282e688496992daa9ea82f8edaf7bbfc22 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 2 Jun 2010 16:55:21 +0000 Subject: [PATCH 181/292] [win32k[win32k] -Allow menus to be shown over the taskbar See issue #5415 for more details. svn path=/trunk/; revision=47522 --- reactos/dll/win32/user32/windows/menu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index d5723bb3271..eed233f4947 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -1605,25 +1605,25 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl if( flags & TPM_BOTTOMALIGN ) y -= height; if( flags & TPM_VCENTERALIGN ) y -= height / 2; - if( x + width > info.rcWork.right) + if( x + width > info.rcMonitor.right) { if( xanchor && x >= width - xanchor ) x -= width - xanchor; - if( x + width > info.rcWork.right) - x = info.rcWork.right - width; + if( x + width > info.rcMonitor.right) + x = info.rcMonitor.right - width; } - if( x < info.rcWork.left ) x = info.rcWork.left; + if( x < info.rcMonitor.left ) x = info.rcMonitor.left; - if( y + height > info.rcWork.bottom) + if( y + height > info.rcMonitor.bottom) { if( yanchor && y >= height + yanchor ) y -= height + yanchor; - if( y + height > info.rcWork.bottom) - y = info.rcWork.bottom - height; + if( y + height > info.rcMonitor.bottom) + y = info.rcMonitor.bottom - height; } - if( y < info.rcWork.top ) y = info.rcWork.top; + if( y < info.rcMonitor.top ) y = info.rcMonitor.top; /* NOTE: In Windows, top menu popup is not owned. */ MenuInfo.Wnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL, From 40ff1fac4b1beadb5be9db9dcd1b681c0d2b5404 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 2 Jun 2010 18:14:53 +0000 Subject: [PATCH 182/292] [win32k] - Fix detection of file type while generating vcxproj files svn path=/trunk/; revision=47523 --- reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp index b2fbff9c486..33331130043 100644 --- a/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp @@ -94,7 +94,7 @@ VCXProjMaker::_generate_item_group (std::vector files) for( i = 0; i\r\n", files[i].c_str()); From 4fad7fd6167df49b3746c321874ae4a8d558f454 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 2 Jun 2010 22:28:37 +0000 Subject: [PATCH 183/292] [usetup] - The last error messages were swapped in some languages, spotted by Paolo Devoti. - Added the minimum required disk space also in the debug print. See issue #5440 for more details. svn path=/trunk/; revision=47524 --- reactos/base/setup/usetup/interface/usetup.c | 2 +- reactos/base/setup/usetup/lang/bg-BG.h | 10 +++++----- reactos/base/setup/usetup/lang/es-ES.h | 10 +++++----- reactos/base/setup/usetup/lang/et-EE.h | 10 +++++----- reactos/base/setup/usetup/lang/fr-FR.h | 10 +++++----- reactos/base/setup/usetup/lang/it-IT.h | 10 +++++----- reactos/base/setup/usetup/lang/lt-LT.h | 10 +++++----- reactos/base/setup/usetup/lang/nl-NL.h | 10 +++++----- reactos/base/setup/usetup/lang/pl-PL.h | 10 +++++----- reactos/base/setup/usetup/lang/ru-RU.h | 10 +++++----- reactos/base/setup/usetup/lang/sk-SK.h | 10 +++++----- reactos/base/setup/usetup/lang/sv-SE.h | 10 +++++----- reactos/base/setup/usetup/lang/uk-UA.h | 10 +++++----- 13 files changed, 61 insertions(+), 61 deletions(-) diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 63738b320c4..57b4efca6bd 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -1418,7 +1418,7 @@ static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) if( m < RequiredPartitionDiskSpace) { /* partition is too small so ask for another partion */ - DPRINT1("Partition too small"); + DPRINT1("Partition is too small, required disk space is %lu MB\n", RequiredPartitionDiskSpace); return FALSE; } else diff --git a/reactos/base/setup/usetup/lang/bg-BG.h b/reactos/base/setup/usetup/lang/bg-BG.h index 074f6baac6e..b6b22fdbf13 100644 --- a/reactos/base/setup/usetup/lang/bg-BG.h +++ b/reactos/base/setup/usetup/lang/bg-BG.h @@ -1483,17 +1483,17 @@ MUI_ERROR bgBGErrorEntries[] = "¥ãᯥ譮 ¤®¡ ¢ï­¥ ­  ª« ¢¨ âã୨⥠¯®¤à¥¤¡¨ ¢ ॣ¨áâêà .\n" "ENTER = १ ¯ã᪠­¥ ­  ª®¬¯îâêà " }, + { + //ERROR_UPDATE_GEOID, + " áâனª â  ­¥ ¬®¦  ¤  ãáâ ­®¢¨ ®§­ ç¨â¥«ï ­  £¥®£à ä᪮⮠¯®«®¦¥­¨¥.\n" + "ENTER = १ ¯ã᪠­¥ ­  ª®¬¯îâêà " + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " *  â¨á­¥â¥ ª« ¢¨è, §  ¤  ¯à®¤ê«¦¨â¥.", NULL }, - { - //ERROR_UPDATE_GEOID, - " áâனª â  ­¥ ¬®¦  ¤  ãáâ ­®¢¨ ®§­ ç¨â¥«ï ­  £¥®£à ä᪮⮠¯®«®¦¥­¨¥.\n" - "ENTER = १ ¯ã᪠­¥ ­  ª®¬¯îâêà " - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index c01630efcb7..bc2fe1340af 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -1478,6 +1478,11 @@ MUI_ERROR esESErrorEntries[] = "El instalador no ha podido agregar los layouts de teclado al registro.\n" "ENTER = Reiniciar el equipo" }, + { + //ERROR_UPDATE_GEOID, + "El instalador no ha podido configurar el ID geogr fico.\n" + "ENTER = Reiniciar el equipo" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "No hay suficiente espacio disponible en la partici¢n seleccionada.\n" @@ -1485,11 +1490,6 @@ MUI_ERROR esESErrorEntries[] = NULL }, { - //ERROR_UPDATE_GEOID, - "El instalador no ha podido configurar el ID geogr fico.\n" - "ENTER = Reiniciar el equipo" - }, -{ NULL, NULL } diff --git a/reactos/base/setup/usetup/lang/et-EE.h b/reactos/base/setup/usetup/lang/et-EE.h index 819a2d47f08..f0b7e8bd328 100644 --- a/reactos/base/setup/usetup/lang/et-EE.h +++ b/reactos/base/setup/usetup/lang/et-EE.h @@ -1468,17 +1468,17 @@ MUI_ERROR etEEErrorEntries[] = "Klaviatuuriasetusi ei ännestunud registrisse lisada.\n" "ENTER = Taask„ivita arvuti" }, + { + //ERROR_UPDATE_GEOID, + "Geograafilist asukohta ei ännestunud seadistada.\n" + "ENTER = Taask„ivita arvuti" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Valitud partitsioonil pole piisavalt ruumi.\n" " * Vajuta suvalist klahvi, et j„tkata.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Geograafilist asukohta ei ännestunud seadistada.\n" - "ENTER = Taask„ivita arvuti" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/fr-FR.h b/reactos/base/setup/usetup/lang/fr-FR.h index c1790341522..aa3b3df809a 100644 --- a/reactos/base/setup/usetup/lang/fr-FR.h +++ b/reactos/base/setup/usetup/lang/fr-FR.h @@ -1484,17 +1484,17 @@ MUI_ERROR frFRErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup could not set the geo id.\n" + "ENTER = Reboot computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/it-IT.h b/reactos/base/setup/usetup/lang/it-IT.h index b3e6ef496ed..3b4ac5670cd 100644 --- a/reactos/base/setup/usetup/lang/it-IT.h +++ b/reactos/base/setup/usetup/lang/it-IT.h @@ -1472,17 +1472,17 @@ MUI_ERROR itITErrorEntries[] = "Impossibile aggiungere le nazionalit… di tastiera al registro.\n" "INVIO = Riavviare il computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup non ha potuto impostare l'id geografico.\n" + "INVIO = Riavviare il computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Lo spazio disponibile nella partizione selezionata Š insufficiente.\n" " * Premere un tasto qualsiasi per continuare.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup non ha potuto impostare l'id geografico.\n" - "INVIO = Riavviare il computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/lt-LT.h b/reactos/base/setup/usetup/lang/lt-LT.h index bb0c26fcc20..7020ebbaba1 100644 --- a/reactos/base/setup/usetup/lang/lt-LT.h +++ b/reactos/base/setup/usetup/lang/lt-LT.h @@ -1481,17 +1481,17 @@ MUI_ERROR ltLTErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup could not set the geo id.\n" + "ENTER = Reboot computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/nl-NL.h b/reactos/base/setup/usetup/lang/nl-NL.h index 2a0b2836b11..0141359d290 100644 --- a/reactos/base/setup/usetup/lang/nl-NL.h +++ b/reactos/base/setup/usetup/lang/nl-NL.h @@ -1499,17 +1499,17 @@ MUI_ERROR nlNLErrorEntries[] = "Setup kan de toetsenbord indelingen niet toevoegen aan de registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup kan de geografische positie niet instellen.\n" + "ENTER = Reboot computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup kan de geografische positie niet instellen.\n" - "ENTER = Reboot computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/pl-PL.h b/reactos/base/setup/usetup/lang/pl-PL.h index 104f8a1e41b..de0a55fcd5c 100644 --- a/reactos/base/setup/usetup/lang/pl-PL.h +++ b/reactos/base/setup/usetup/lang/pl-PL.h @@ -1480,17 +1480,17 @@ MUI_ERROR plPLErrorEntries[] = "Instalator nie m¢gˆ doda† ukˆad¢w klawiatury do rejestru.\n" "ENTER = Restart komputera" }, + { + //ERROR_UPDATE_GEOID, + "Instalator nie m¢gˆ ustawi† lokalizacji geograficznej.\n" + "ENTER = Restart komputera" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Brak wystarczaj¥cej wolnej przestrzeni w wybranej partycji.\n" " * Naci˜nij dowolny klawisz aby kontynuowa†.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Instalator nie m¢gˆ ustawi† lokalizacji geograficznej.\n" - "ENTER = Restart komputera" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/ru-RU.h b/reactos/base/setup/usetup/lang/ru-RU.h index ddf6062b62a..b74d17b8e1a 100644 --- a/reactos/base/setup/usetup/lang/ru-RU.h +++ b/reactos/base/setup/usetup/lang/ru-RU.h @@ -1472,17 +1472,17 @@ MUI_ERROR ruRUErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup could not set the geo id.\n" + "ENTER = Reboot computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/sk-SK.h b/reactos/base/setup/usetup/lang/sk-SK.h index 3a003761748..5bb0d60fb53 100644 --- a/reactos/base/setup/usetup/lang/sk-SK.h +++ b/reactos/base/setup/usetup/lang/sk-SK.h @@ -1482,17 +1482,17 @@ MUI_ERROR skSKErrorEntries[] = "Inçtal tor zlyhal pri prid van¡ rozlo§en¡ kl vesnice do registrov.\n" "ENTER = Reçtart poŸ¡taŸa" }, + { + //ERROR_UPDATE_GEOID, + "Inçtal tor nemohol nastaviœ geo id.\n" + "ENTER = Reçtart poŸ¡taŸa" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Inçtal tor nemohol nastaviœ geo id.\n" - "ENTER = Reçtart poŸ¡taŸa" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/sv-SE.h b/reactos/base/setup/usetup/lang/sv-SE.h index 352bb6c8124..17b0fa5ddad 100644 --- a/reactos/base/setup/usetup/lang/sv-SE.h +++ b/reactos/base/setup/usetup/lang/sv-SE.h @@ -1472,17 +1472,17 @@ MUI_ERROR svSEErrorEntries[] = "Setup failed to add keyboard layouts to registry.\n" "ENTER = Reboot computer" }, + { + //ERROR_UPDATE_GEOID, + "Setup could not set the geo id.\n" + "ENTER = Reboot computer" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" - }, { NULL, NULL diff --git a/reactos/base/setup/usetup/lang/uk-UA.h b/reactos/base/setup/usetup/lang/uk-UA.h index 1227dfe6188..7f7a7a7b7e1 100644 --- a/reactos/base/setup/usetup/lang/uk-UA.h +++ b/reactos/base/setup/usetup/lang/uk-UA.h @@ -1478,17 +1478,17 @@ MUI_ERROR ukUAErrorEntries[] = "¥ ¢¤ «®áì ¤®¤ â¨ à®§ª« ¤ª¨ ª« ¢i âãਠ¤® à¥óáâàã.\n" "ENTER = ¥à¥§ ¢ ­â ¦¨â¨ ª®¬¯'îâ¥à" }, + { + //ERROR_UPDATE_GEOID, + "¥ ¢¤ «®áì ¢áâ ­®¢¨â¨ geo id.\n" + "ENTER = ¥à¥§ ¢ ­â ¦¨â¨ ª®¬¯'îâ¥à" + }, { //ERROR_INSUFFICIENT_DISKSPACE, "Not enough free space in the selected partition.\n" " * Press any key to continue.", NULL }, - { - //ERROR_UPDATE_GEOID, - "¥ ¢¤ «®áì ¢áâ ­®¢¨â¨ geo id.\n" - "ENTER = ¥à¥§ ¢ ­â ¦¨â¨ ª®¬¯'îâ¥à" - }, { NULL, NULL From 23e08cb25eb507f574c229361bf35ecfd7ea3d2c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 2 Jun 2010 22:29:19 +0000 Subject: [PATCH 184/292] [SYSDM] - Fix a bug in the creation of the 'PagingFiles' registry value. - Set paging file sizes only if both user defined sizes are valid numerical values and display a warning otherwise. - Translators: Please translate the message strings! svn path=/trunk/; revision=47525 --- reactos/dll/cpl/sysdm/lang/bg-BG.rc | 3 ++ reactos/dll/cpl/sysdm/lang/cs-CZ.rc | 3 ++ reactos/dll/cpl/sysdm/lang/da-DK.rc | 3 ++ reactos/dll/cpl/sysdm/lang/de-DE.rc | 3 ++ reactos/dll/cpl/sysdm/lang/el-GR.rc | 3 ++ reactos/dll/cpl/sysdm/lang/en-US.rc | 3 ++ reactos/dll/cpl/sysdm/lang/es-ES.rc | 3 ++ reactos/dll/cpl/sysdm/lang/fr-FR.rc | 3 ++ reactos/dll/cpl/sysdm/lang/hu-HU.rc | 3 ++ reactos/dll/cpl/sysdm/lang/id-ID.rc | 3 ++ reactos/dll/cpl/sysdm/lang/it-IT.rc | 3 ++ reactos/dll/cpl/sysdm/lang/ja-JP.rc | 3 ++ reactos/dll/cpl/sysdm/lang/nl-NL.rc | 4 +- reactos/dll/cpl/sysdm/lang/no-NO.rc | 3 ++ reactos/dll/cpl/sysdm/lang/pl-PL.rc | 3 ++ reactos/dll/cpl/sysdm/lang/ro-RO.rc | 5 +- reactos/dll/cpl/sysdm/lang/ru-RU.rc | 3 ++ reactos/dll/cpl/sysdm/lang/sk-SK.rc | 3 ++ reactos/dll/cpl/sysdm/lang/sv-SE.rc | 3 ++ reactos/dll/cpl/sysdm/lang/uk-UA.rc | 3 ++ reactos/dll/cpl/sysdm/lang/zh-CN.rc | 3 ++ reactos/dll/cpl/sysdm/resource.h | 3 ++ reactos/dll/cpl/sysdm/virtmem.c | 83 ++++++++++++++++++----------- 23 files changed, 120 insertions(+), 32 deletions(-) diff --git a/reactos/dll/cpl/sysdm/lang/bg-BG.rc b/reactos/dll/cpl/sysdm/lang/bg-BG.rc index cd0cca37d03..f12c3be00f3 100644 --- a/reactos/dll/cpl/sysdm/lang/bg-BG.rc +++ b/reactos/dll/cpl/sysdm/lang/bg-BG.rc @@ -284,4 +284,7 @@ BEGIN IDS_USERPROFILE_TYPE "Âèä" IDS_USERPROFILE_STATUS "Ñúñòîÿíèå" IDS_USERPROFILE_MODIFIED "Èçìåíåí" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/cs-CZ.rc b/reactos/dll/cpl/sysdm/lang/cs-CZ.rc index 5be033c26d3..4672cff1743 100644 --- a/reactos/dll/cpl/sysdm/lang/cs-CZ.rc +++ b/reactos/dll/cpl/sysdm/lang/cs-CZ.rc @@ -289,4 +289,7 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Upraveno" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/da-DK.rc b/reactos/dll/cpl/sysdm/lang/da-DK.rc index 4e680cba885..b4e1f31ce42 100644 --- a/reactos/dll/cpl/sysdm/lang/da-DK.rc +++ b/reactos/dll/cpl/sysdm/lang/da-DK.rc @@ -123,4 +123,7 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/de-DE.rc b/reactos/dll/cpl/sysdm/lang/de-DE.rc index 92282242d97..52393863607 100644 --- a/reactos/dll/cpl/sysdm/lang/de-DE.rc +++ b/reactos/dll/cpl/sysdm/lang/de-DE.rc @@ -289,5 +289,8 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Geändert" + IDS_MESSAGEBOXTITLE "Systemsteuerungsoption ""System""" + IDS_WARNINITIALSIZE "Geben Sie einen numerischen Wert für die Anfangsgröße der Auslagerungsdatei an." + IDS_WARNMAXIMUMSIZE "Geben Sie einen numerischen Wert für die Maximalgröße der Auslagerungsdatei an." IDS_DEVS "\nReactOS Team\n\nProjektkoordinator\n\nAleksey Bragin\n\nEntwicklerteam\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Verantwortliche\n\nColin Finck\nZ98\n\nWebseitenteam\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedienteam\n\nMindflyer\nWierd_W\n\nweiterer Dank geht an\n\nalle Mitwirkenden\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/lang/el-GR.rc b/reactos/dll/cpl/sysdm/lang/el-GR.rc index 98ff6946bd1..909769d5545 100644 --- a/reactos/dll/cpl/sysdm/lang/el-GR.rc +++ b/reactos/dll/cpl/sysdm/lang/el-GR.rc @@ -285,4 +285,7 @@ BEGIN IDS_USERPROFILE_TYPE "Ôýðïò" IDS_USERPROFILE_STATUS "ÊáôÜóôáóç" IDS_USERPROFILE_MODIFIED "ÔñïðïðïéÞèçêå" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/en-US.rc b/reactos/dll/cpl/sysdm/lang/en-US.rc index 73b8a17d3aa..d0f971c0bd9 100644 --- a/reactos/dll/cpl/sysdm/lang/en-US.rc +++ b/reactos/dll/cpl/sysdm/lang/en-US.rc @@ -284,5 +284,8 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modified" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." IDS_DEVS "\nReactOS Team\n\nProject Coordinator\n\nAleksey Bragin\n\nDevelopment Team\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nfurther thanks go to\n\nall Contributers\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/lang/es-ES.rc b/reactos/dll/cpl/sysdm/lang/es-ES.rc index 69e46cfc606..e5d50050e01 100644 --- a/reactos/dll/cpl/sysdm/lang/es-ES.rc +++ b/reactos/dll/cpl/sysdm/lang/es-ES.rc @@ -287,4 +287,7 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Estado" IDS_USERPROFILE_MODIFIED "Modificado" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/fr-FR.rc b/reactos/dll/cpl/sysdm/lang/fr-FR.rc index e649b59beff..bce50f954c2 100644 --- a/reactos/dll/cpl/sysdm/lang/fr-FR.rc +++ b/reactos/dll/cpl/sysdm/lang/fr-FR.rc @@ -287,4 +287,7 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Statut" IDS_USERPROFILE_MODIFIED "Modifié" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/hu-HU.rc b/reactos/dll/cpl/sysdm/lang/hu-HU.rc index 9b3a4624d62..09bd09d6e16 100644 --- a/reactos/dll/cpl/sysdm/lang/hu-HU.rc +++ b/reactos/dll/cpl/sysdm/lang/hu-HU.rc @@ -126,4 +126,7 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/id-ID.rc b/reactos/dll/cpl/sysdm/lang/id-ID.rc index 1025b1f5b6d..ad67a22ed61 100644 --- a/reactos/dll/cpl/sysdm/lang/id-ID.rc +++ b/reactos/dll/cpl/sysdm/lang/id-ID.rc @@ -281,4 +281,7 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modified" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/it-IT.rc b/reactos/dll/cpl/sysdm/lang/it-IT.rc index 253a4bd1084..876a9458890 100644 --- a/reactos/dll/cpl/sysdm/lang/it-IT.rc +++ b/reactos/dll/cpl/sysdm/lang/it-IT.rc @@ -284,5 +284,8 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Stato" IDS_USERPROFILE_MODIFIED "Modificato" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." IDS_DEVS "\nReactOS Team\n\nCoordinatore\n\nAleksey Bragin\n\nGruppo di sviluppo\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nUlteriori ringraziamenti\n\na tutti i Contributers\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/lang/ja-JP.rc b/reactos/dll/cpl/sysdm/lang/ja-JP.rc index 2ce3b7c5f41..e8fc6147c8d 100644 --- a/reactos/dll/cpl/sysdm/lang/ja-JP.rc +++ b/reactos/dll/cpl/sysdm/lang/ja-JP.rc @@ -284,4 +284,7 @@ BEGIN IDS_USERPROFILE_TYPE "Ží—Þ" IDS_USERPROFILE_STATUS "ó‘Ô" IDS_USERPROFILE_MODIFIED "•ÏX“ú" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/nl-NL.rc b/reactos/dll/cpl/sysdm/lang/nl-NL.rc index 888857b6205..ccfc99897ff 100644 --- a/reactos/dll/cpl/sysdm/lang/nl-NL.rc +++ b/reactos/dll/cpl/sysdm/lang/nl-NL.rc @@ -125,5 +125,7 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" - + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/no-NO.rc b/reactos/dll/cpl/sysdm/lang/no-NO.rc index 98beebe5b50..b8d4e57df61 100644 --- a/reactos/dll/cpl/sysdm/lang/no-NO.rc +++ b/reactos/dll/cpl/sysdm/lang/no-NO.rc @@ -283,4 +283,7 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modifisert" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/pl-PL.rc b/reactos/dll/cpl/sysdm/lang/pl-PL.rc index b138c0afd90..99bc47761ea 100644 --- a/reactos/dll/cpl/sysdm/lang/pl-PL.rc +++ b/reactos/dll/cpl/sysdm/lang/pl-PL.rc @@ -288,4 +288,7 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Stan" IDS_USERPROFILE_MODIFIED "Zmodyfikowano" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/ro-RO.rc b/reactos/dll/cpl/sysdm/lang/ro-RO.rc index 7e5de71be46..5262a8ecc76 100644 --- a/reactos/dll/cpl/sysdm/lang/ro-RO.rc +++ b/reactos/dll/cpl/sysdm/lang/ro-RO.rc @@ -1,4 +1,4 @@ -LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -284,6 +284,9 @@ BEGIN IDS_USERPROFILE_TYPE "Tip" IDS_USERPROFILE_STATUS "Stare" IDS_USERPROFILE_MODIFIED "Modificat" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END #pragma code_page(default) diff --git a/reactos/dll/cpl/sysdm/lang/ru-RU.rc b/reactos/dll/cpl/sysdm/lang/ru-RU.rc index caaef697bf2..8a377e9cb14 100644 --- a/reactos/dll/cpl/sysdm/lang/ru-RU.rc +++ b/reactos/dll/cpl/sysdm/lang/ru-RU.rc @@ -282,4 +282,7 @@ BEGIN IDS_USERPROFILE_TYPE "Òèï" IDS_USERPROFILE_STATUS "Ñîñòîÿíèå" IDS_USERPROFILE_MODIFIED "Èçìåíåí" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/sk-SK.rc b/reactos/dll/cpl/sysdm/lang/sk-SK.rc index 82fbc6035e9..9845921b66b 100644 --- a/reactos/dll/cpl/sysdm/lang/sk-SK.rc +++ b/reactos/dll/cpl/sysdm/lang/sk-SK.rc @@ -290,4 +290,7 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Stav" IDS_USERPROFILE_MODIFIED "Modifikovaný" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/sv-SE.rc b/reactos/dll/cpl/sysdm/lang/sv-SE.rc index c72592cdb89..e394e7f31fb 100644 --- a/reactos/dll/cpl/sysdm/lang/sv-SE.rc +++ b/reactos/dll/cpl/sysdm/lang/sv-SE.rc @@ -284,4 +284,7 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Ändrad" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/uk-UA.rc b/reactos/dll/cpl/sysdm/lang/uk-UA.rc index 651a167d1ea..e8951f425af 100644 --- a/reactos/dll/cpl/sysdm/lang/uk-UA.rc +++ b/reactos/dll/cpl/sysdm/lang/uk-UA.rc @@ -290,4 +290,7 @@ BEGIN IDS_USERPROFILE_TYPE "Òèï" IDS_USERPROFILE_STATUS "Ñòàí" IDS_USERPROFILE_MODIFIED "Çì³íåíî" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/lang/zh-CN.rc b/reactos/dll/cpl/sysdm/lang/zh-CN.rc index 1abbce7477f..e3bda3ce72c 100644 --- a/reactos/dll/cpl/sysdm/lang/zh-CN.rc +++ b/reactos/dll/cpl/sysdm/lang/zh-CN.rc @@ -287,4 +287,7 @@ BEGIN IDS_USERPROFILE_TYPE "ÀàÐÍ" IDS_USERPROFILE_STATUS "״̬" IDS_USERPROFILE_MODIFIED "ÐÞ¸Ä" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." END diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index f0918a35d9f..10cd614b2ba 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -32,6 +32,9 @@ #define IDS_USERPROFILE_STATUS 75 #define IDS_USERPROFILE_MODIFIED 76 +#define IDS_MESSAGEBOXTITLE 77 +#define IDS_WARNINITIALSIZE 78 +#define IDS_WARNMAXIMUMSIZE 79 /* propsheet - general */ #define IDD_PROPPAGEGENERAL 100 diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 6dcd9ad6457..5dc572c0138 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -220,7 +220,7 @@ WritePageFileSettings(PVIRTMEM pVirtMem) pVirtMem->Pagefile[i].MaxValue); /* Add it to our overall registry string */ - lstrcat(szPagingFiles + nPos, szText); + lstrcpy(szPagingFiles + nPos, szText); /* Record the position where the next string will start */ nPos += (INT)lstrlen(szText) + 1; @@ -299,8 +299,11 @@ static VOID OnSet(PVIRTMEM pVirtMem) { INT Index; - UINT Value; + UINT InitValue; + UINT MaxValue; BOOL bTranslated; + TCHAR szTitle[64]; + TCHAR szMessage[256]; pVirtMem->bSave = TRUE; @@ -315,41 +318,61 @@ OnSet(PVIRTMEM pVirtMem) if (IsDlgButtonChecked(pVirtMem->hSelf, IDC_CUSTOM) == BST_CHECKED) { - Value = GetDlgItemInt(pVirtMem->hSelf, - IDC_INITIALSIZE, - &bTranslated, - FALSE); + InitValue = GetDlgItemInt(pVirtMem->hSelf, + IDC_INITIALSIZE, + &bTranslated, + FALSE); if (!bTranslated) { - /* FIXME: Show error message instead of setting the edit - field to the previous value */ - SetDlgItemInt(pVirtMem->hSelf, - IDC_INITIALSIZE, - pVirtMem->Pagefile[Index].InitialValue, - FALSE); - } - else - { - pVirtMem->Pagefile[Index].InitialValue = Value; + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + if (LoadString(hApplet, + IDS_WARNINITIALSIZE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])) == 0) + _tcscpy(szMessage, _T("Enter a numeric value for the initial size of the paging file.")); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; } - Value = GetDlgItemInt(pVirtMem->hSelf, - IDC_MAXSIZE, - &bTranslated, - FALSE); + MaxValue = GetDlgItemInt(pVirtMem->hSelf, + IDC_MAXSIZE, + &bTranslated, + FALSE); if (!bTranslated) { - /* FIXME: Show error message instead of setting the edit - field to the previous value */ - SetDlgItemInt(pVirtMem->hSelf, - IDC_MAXSIZE, - pVirtMem->Pagefile[Index].MaxValue, - FALSE); - } - else - { - pVirtMem->Pagefile[Index].MaxValue = Value; + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + if (LoadString(hApplet, + IDS_WARNMAXIMUMSIZE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])) == 0) + _tcscpy(szMessage, _T("Enter a numeric value for the maximum size of the paging file.")); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; } + + /* FIXME: Add more file size checks! */ + + pVirtMem->Pagefile[Index].InitialValue = InitValue; + pVirtMem->Pagefile[Index].MaxValue = MaxValue; + pVirtMem->Pagefile[Index].bUsed = TRUE; } else { From 8f37e32fd6262fc24ca6525c94062648a3095ca0 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 2 Jun 2010 22:49:27 +0000 Subject: [PATCH 185/292] [SYSDM] - Update Italian and Spanish translations. svn path=/trunk/; revision=47526 --- reactos/dll/cpl/sysdm/lang/es-ES.rc | 6 +++--- reactos/dll/cpl/sysdm/lang/it-IT.rc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/dll/cpl/sysdm/lang/es-ES.rc b/reactos/dll/cpl/sysdm/lang/es-ES.rc index e5d50050e01..ce6c22ece8a 100644 --- a/reactos/dll/cpl/sysdm/lang/es-ES.rc +++ b/reactos/dll/cpl/sysdm/lang/es-ES.rc @@ -287,7 +287,7 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Estado" IDS_USERPROFILE_MODIFIED "Modificado" - IDS_MESSAGEBOXTITLE "System control panel applet" - IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." - IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_MESSAGEBOXTITLE "Applet de sistema del panel de control" + IDS_WARNINITIALSIZE "Ingresar el valor inicial del tamaño del archivo de paginación." + IDS_WARNMAXIMUMSIZE "Ingresar el valor máximo del tamaño del archivo de paginación." END diff --git a/reactos/dll/cpl/sysdm/lang/it-IT.rc b/reactos/dll/cpl/sysdm/lang/it-IT.rc index 876a9458890..68d4bc0dc22 100644 --- a/reactos/dll/cpl/sysdm/lang/it-IT.rc +++ b/reactos/dll/cpl/sysdm/lang/it-IT.rc @@ -284,8 +284,8 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Stato" IDS_USERPROFILE_MODIFIED "Modificato" - IDS_MESSAGEBOXTITLE "System control panel applet" - IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." - IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_MESSAGEBOXTITLE "Applet di sistema del pannello di controllo" + IDS_WARNINITIALSIZE "Immettere il valore per la dimensione iniziale del file di paging." + IDS_WARNMAXIMUMSIZE "Immettere il valore per la dimensione massima del file di paging." IDS_DEVS "\nReactOS Team\n\nCoordinatore\n\nAleksey Bragin\n\nGruppo di sviluppo\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nUlteriori ringraziamenti\n\na tutti i Contributers\nWine Team\n\n" END From f6d5918b3117afae456a4f4eb6d5e6bbd7a494c4 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Wed, 2 Jun 2010 23:58:28 +0000 Subject: [PATCH 186/292] [crt] - mbstowcs: Fix incorrect size passed as the second parameter for call to RtlMultiByteToUnicodeN. Fixes loading assemblies when manifest is in a manifest file due to parsing failure. svn path=/trunk/; revision=47527 --- reactos/lib/sdk/crt/string/mbstowcs_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/sdk/crt/string/mbstowcs_nt.c b/reactos/lib/sdk/crt/string/mbstowcs_nt.c index 8ab1edd23e3..4b613368c3e 100644 --- a/reactos/lib/sdk/crt/string/mbstowcs_nt.c +++ b/reactos/lib/sdk/crt/string/mbstowcs_nt.c @@ -47,7 +47,7 @@ size_t mbstowcs (wchar_t *wcstr, const char *mbstr, size_t count) } Status = RtlMultiByteToUnicodeN (wcstr, - count, + count * sizeof(WCHAR), &Size, mbstr, Length); From be344838ef925f349a84e63613d4cc4f6c686749 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Thu, 3 Jun 2010 07:08:07 +0000 Subject: [PATCH 187/292] [rtl] - len returned from mbstowcs is the required size of the destination string, so only allocate the needed size. - When doing the actual conversion pass in the size of the ansi string not the needed size of destination. - These changes were missed in 47527. svn path=/trunk/; revision=47529 --- reactos/lib/rtl/actctx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/lib/rtl/actctx.c b/reactos/lib/rtl/actctx.c index 7960f587490..9ad67e053fd 100644 --- a/reactos/lib/rtl/actctx.c +++ b/reactos/lib/rtl/actctx.c @@ -1578,6 +1578,7 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident { /* let's assume utf-8 for now */ int len; + WCHAR *new_buff; _SEH2_TRY { @@ -1591,17 +1592,16 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident _SEH2_END; DPRINT("len = %x\n", len); - WCHAR *new_buff; if (len == -1) { DPRINT1( "utf-8 conversion failed\n" ); return STATUS_SXS_CANT_GEN_ACTCTX; } - if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR) ))) + if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len))) return STATUS_NO_MEMORY; - mbstowcs( new_buff, buffer, len); + mbstowcs( new_buff, buffer, size); xmlbuf.ptr = new_buff; DPRINT("Buffer %S\n", new_buff); xmlbuf.end = xmlbuf.ptr + len; From 0f49f63b6367ea1c05fb4cf262fdca25d6bd6207 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 3 Jun 2010 07:48:35 +0000 Subject: [PATCH 188/292] [FREELDR] - Verify that Int 13 extensions are supported before trying to use them svn path=/trunk/; revision=47530 --- reactos/boot/freeldr/freeldr/arch/i386/i386disk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c index a1e9877e50e..beeb15c7471 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c @@ -135,6 +135,9 @@ BOOLEAN DiskGetExtendedDriveParameters(ULONG DriveNumber, PVOID Buffer, USHORT B DPRINTM(DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"); + if (!DiskInt13ExtensionsSupported(DriveNumber)) + return FALSE; + // Initialize transfer buffer *Ptr = BufferSize; From 520f69199573f989be93bc6635260569207a2e78 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 3 Jun 2010 08:09:42 +0000 Subject: [PATCH 189/292] [FREELDR] - Remove an overzealous API check and the work-around for it svn path=/trunk/; revision=47531 --- .../boot/freeldr/freeldr/arch/i386/pcdisk.c | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c index c0eeb0b7d41..0a89a84796b 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -279,18 +279,6 @@ static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber) return LastSupported; } - // Some BIOSes report that extended disk access functions are not supported - // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping - // with Intel Macs). Therefore we just return TRUE if we're booting from a CD - - // we can assume that all El Torito capable BIOSes support INT 13 extensions. - // We simply detect whether we're booting from CD by checking whether the drive - // number is >= 0x90. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes. - if (DriveNumber >= 0x90) - { - LastSupported = TRUE; - return TRUE; - } - LastDriveNumber = DriveNumber; // IBM/MS INT 13 Extensions - INSTALLATION CHECK @@ -338,15 +326,6 @@ static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber) return FALSE; } - if (!(RegsOut.w.cx & 0x0001)) - { - // CX = API subset support bitmap - // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - printf("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber); - LastSupported = FALSE; - return FALSE; - } - LastSupported = TRUE; return TRUE; } From 447be42c33e925ad7e97f1c7a5a4d6d696957edd Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 12:47:40 +0000 Subject: [PATCH 190/292] Merge 46523 from amd64 branch: - Fix assert macro - Add crt="MSVC" to a number of modules to resolve _assert svn path=/trunk/; revision=47533 --- reactos/dll/directx/qedit/qedit.rbuild | 2 +- reactos/dll/directx/quartz/quartz.rbuild | 2 +- reactos/dll/directx/wine/ddraw/ddraw.rbuild | 2 +- reactos/dll/win32/avifil32/avifil32.rbuild | 2 +- reactos/dll/win32/comctl32/comctl32.rbuild | 2 +- reactos/dll/win32/comdlg32/comdlg32.rbuild | 2 +- reactos/dll/win32/imaadp32.acm/imaadp32.acm.rbuild | 2 +- reactos/dll/win32/inetmib1/inetmib1.rbuild | 2 +- reactos/dll/win32/mciwave/mciwave.rbuild | 2 +- reactos/dll/win32/msacm32/msacm32.rbuild | 2 +- reactos/dll/win32/msadp32.acm/msadp32.acm.rbuild | 2 +- reactos/dll/win32/msg711.acm/msg711.acm.rbuild | 2 +- reactos/dll/win32/msrle32/msrle32.rbuild | 2 +- reactos/dll/win32/odbccp32/odbccp32.rbuild | 2 +- reactos/dll/win32/ole32/ole32.rbuild | 2 +- reactos/dll/win32/riched20/riched20.rbuild | 2 +- reactos/dll/win32/winemp3.acm/winemp3.acm.rbuild | 2 +- reactos/dll/win32/wintrust/wintrust.rbuild | 2 +- reactos/include/crt/assert.h | 3 +-- 19 files changed, 19 insertions(+), 20 deletions(-) diff --git a/reactos/dll/directx/qedit/qedit.rbuild b/reactos/dll/directx/qedit/qedit.rbuild index f3285f4ef48..0fd54bf8ea3 100644 --- a/reactos/dll/directx/qedit/qedit.rbuild +++ b/reactos/dll/directx/qedit/qedit.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/quartz/quartz.rbuild b/reactos/dll/directx/quartz/quartz.rbuild index b7097f6ff1f..4a86c54b112 100644 --- a/reactos/dll/directx/quartz/quartz.rbuild +++ b/reactos/dll/directx/quartz/quartz.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/reactos/dll/directx/wine/ddraw/ddraw.rbuild b/reactos/dll/directx/wine/ddraw/ddraw.rbuild index f8d9c92c279..962cd7a96ad 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.rbuild +++ b/reactos/dll/directx/wine/ddraw/ddraw.rbuild @@ -1,6 +1,6 @@ - + . diff --git a/reactos/dll/win32/avifil32/avifil32.rbuild b/reactos/dll/win32/avifil32/avifil32.rbuild index 1741f2a481d..da4f495711d 100644 --- a/reactos/dll/win32/avifil32/avifil32.rbuild +++ b/reactos/dll/win32/avifil32/avifil32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/reactos/dll/win32/comctl32/comctl32.rbuild b/reactos/dll/win32/comctl32/comctl32.rbuild index 3cc1ce2c0ad..150241f9440 100644 --- a/reactos/dll/win32/comctl32/comctl32.rbuild +++ b/reactos/dll/win32/comctl32/comctl32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/reactos/dll/win32/comdlg32/comdlg32.rbuild b/reactos/dll/win32/comdlg32/comdlg32.rbuild index d9ea84d9e28..70c0322000f 100644 --- a/reactos/dll/win32/comdlg32/comdlg32.rbuild +++ b/reactos/dll/win32/comdlg32/comdlg32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/imaadp32.acm/imaadp32.acm.rbuild b/reactos/dll/win32/imaadp32.acm/imaadp32.acm.rbuild index f2b04bb6914..073f714f979 100644 --- a/reactos/dll/win32/imaadp32.acm/imaadp32.acm.rbuild +++ b/reactos/dll/win32/imaadp32.acm/imaadp32.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/inetmib1/inetmib1.rbuild b/reactos/dll/win32/inetmib1/inetmib1.rbuild index 77c39b582a1..27079b19c05 100644 --- a/reactos/dll/win32/inetmib1/inetmib1.rbuild +++ b/reactos/dll/win32/inetmib1/inetmib1.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/mciwave/mciwave.rbuild b/reactos/dll/win32/mciwave/mciwave.rbuild index be21c0711ed..69e3c094388 100644 --- a/reactos/dll/win32/mciwave/mciwave.rbuild +++ b/reactos/dll/win32/mciwave/mciwave.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/msacm32/msacm32.rbuild b/reactos/dll/win32/msacm32/msacm32.rbuild index b6f802ee5bb..e32845920d7 100644 --- a/reactos/dll/win32/msacm32/msacm32.rbuild +++ b/reactos/dll/win32/msacm32/msacm32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/msadp32.acm/msadp32.acm.rbuild b/reactos/dll/win32/msadp32.acm/msadp32.acm.rbuild index 89911f484c5..3dcc1c96085 100644 --- a/reactos/dll/win32/msadp32.acm/msadp32.acm.rbuild +++ b/reactos/dll/win32/msadp32.acm/msadp32.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/msg711.acm/msg711.acm.rbuild b/reactos/dll/win32/msg711.acm/msg711.acm.rbuild index 468d9927b2f..88e87f98add 100644 --- a/reactos/dll/win32/msg711.acm/msg711.acm.rbuild +++ b/reactos/dll/win32/msg711.acm/msg711.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/msrle32/msrle32.rbuild b/reactos/dll/win32/msrle32/msrle32.rbuild index 6ef26447334..2b8a6ca4dc6 100644 --- a/reactos/dll/win32/msrle32/msrle32.rbuild +++ b/reactos/dll/win32/msrle32/msrle32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/odbccp32/odbccp32.rbuild b/reactos/dll/win32/odbccp32/odbccp32.rbuild index 253485a359e..15bb8d84bb4 100644 --- a/reactos/dll/win32/odbccp32/odbccp32.rbuild +++ b/reactos/dll/win32/odbccp32/odbccp32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/ole32/ole32.rbuild b/reactos/dll/win32/ole32/ole32.rbuild index 85710a6b20f..57c6b9f64a6 100644 --- a/reactos/dll/win32/ole32/ole32.rbuild +++ b/reactos/dll/win32/ole32/ole32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/reactos/dll/win32/riched20/riched20.rbuild b/reactos/dll/win32/riched20/riched20.rbuild index 0191c64390a..b176049bb8a 100644 --- a/reactos/dll/win32/riched20/riched20.rbuild +++ b/reactos/dll/win32/riched20/riched20.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/winemp3.acm/winemp3.acm.rbuild b/reactos/dll/win32/winemp3.acm/winemp3.acm.rbuild index fec518725e0..be4a53bc8eb 100644 --- a/reactos/dll/win32/winemp3.acm/winemp3.acm.rbuild +++ b/reactos/dll/win32/winemp3.acm/winemp3.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/wintrust/wintrust.rbuild b/reactos/dll/win32/wintrust/wintrust.rbuild index 910d2278f8e..bcb1c2b8304 100644 --- a/reactos/dll/win32/wintrust/wintrust.rbuild +++ b/reactos/dll/win32/wintrust/wintrust.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/include/crt/assert.h b/reactos/include/crt/assert.h index 252fd54a269..9107ee5a272 100644 --- a/reactos/include/crt/assert.h +++ b/reactos/include/crt/assert.h @@ -28,8 +28,7 @@ extern "C" { #endif #ifndef assert -//#define assert(_Expression) (void)((!!(_Expression)) || (_assert(#_Expression,__FILE__,__LINE__),0)) -#define assert(_Expression) (void)((!!(_Expression)))// || (_wassert(_CRT_WIDE(#_Expression),_CRT_WIDE(__FILE__),__LINE__),0)) +#define assert(_Expression) (void)((!!(_Expression)) || (_assert(#_Expression,__FILE__,__LINE__),0)) #endif #ifndef wassert From 65435e1b84f223df234ac16b3431460a5d2ef7cb Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 3 Jun 2010 13:17:33 +0000 Subject: [PATCH 191/292] [SYSDM] - Check the custom paging file sizes for being within useful limits and display warnings if these limit were exceeded. - Translators: Please translate the message strings! svn path=/trunk/; revision=47534 --- reactos/dll/cpl/sysdm/lang/de-DE.rc | 4 +- reactos/dll/cpl/sysdm/lang/en-US.rc | 2 + reactos/dll/cpl/sysdm/precomp.h | 5 +- reactos/dll/cpl/sysdm/resource.h | 2 + reactos/dll/cpl/sysdm/virtmem.c | 102 ++++++++++++++++++++-------- 5 files changed, 83 insertions(+), 32 deletions(-) diff --git a/reactos/dll/cpl/sysdm/lang/de-DE.rc b/reactos/dll/cpl/sysdm/lang/de-DE.rc index 52393863607..eec7d1eff51 100644 --- a/reactos/dll/cpl/sysdm/lang/de-DE.rc +++ b/reactos/dll/cpl/sysdm/lang/de-DE.rc @@ -202,7 +202,7 @@ BEGIN LTEXT "", IDC_SPACEAVAIL, 105, 92, 104, 9 LTEXT "&Anfangsgröße (MB):", -1, 22, 118, 70, 9 LTEXT "Ma&ximale Größe (MB):", -1, 22, 131, 75, 9 - AUTORADIOBUTTON "&Benutzerdefinierte Größe", IDC_CUSTOM, 20, 105, 90, 9, WS_GROUP + AUTORADIOBUTTON "&Benutzerdefinierte Größe", IDC_CUSTOM, 20, 105, 95, 9, WS_GROUP AUTORADIOBUTTON "Größe wird vom &System verwaltet", IDC_SYSMANSIZE, 20, 145, 120, 9 AUTORADIOBUTTON "&Keine Auslagerungsdatei", IDC_NOPAGEFILE, 20, 158, 90, 9 EDITTEXT IDC_INITIALSIZE, 100, 114, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE @@ -292,5 +292,7 @@ BEGIN IDS_MESSAGEBOXTITLE "Systemsteuerungsoption ""System""" IDS_WARNINITIALSIZE "Geben Sie einen numerischen Wert für die Anfangsgröße der Auslagerungsdatei an." IDS_WARNMAXIMUMSIZE "Geben Sie einen numerischen Wert für die Maximalgröße der Auslagerungsdatei an." + IDS_WARNINITIALRANGE "Die Anfangsgröße der Auslagerungsdatei darf nicht kleiner als 2 MB sein und darf den verfügbaren Speicherplatz auf dem gewählten Laufwerk nicht überschreiten." + IDS_WARNMAXIMUMRANGE "Die Maximalgröße der Auslagerungsdatei darf nicht kleiner als die Anfangsgröße sein und darf den verfügbaren Speicherplatz auf dem gewählten Laufwerk nicht überschreiten." IDS_DEVS "\nReactOS Team\n\nProjektkoordinator\n\nAleksey Bragin\n\nEntwicklerteam\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Verantwortliche\n\nColin Finck\nZ98\n\nWebseitenteam\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedienteam\n\nMindflyer\nWierd_W\n\nweiterer Dank geht an\n\nalle Mitwirkenden\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/lang/en-US.rc b/reactos/dll/cpl/sysdm/lang/en-US.rc index d0f971c0bd9..c1d7fa93eeb 100644 --- a/reactos/dll/cpl/sysdm/lang/en-US.rc +++ b/reactos/dll/cpl/sysdm/lang/en-US.rc @@ -287,5 +287,7 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." IDS_DEVS "\nReactOS Team\n\nProject Coordinator\n\nAleksey Bragin\n\nDevelopment Team\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nfurther thanks go to\n\nall Contributers\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index 3ef2ee0d259..cf3afd6f62a 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -50,8 +50,9 @@ INT_PTR CALLBACK LicenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM l typedef struct _PAGEFILE { TCHAR szDrive[3]; - INT InitialValue; - INT MaxValue; + INT InitialSize; + INT MaximumSize; + INT FreeSize; BOOL bUsed; } PAGEFILE, *PPAGEFILE; diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index 10cd614b2ba..885aae6c003 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -35,6 +35,8 @@ #define IDS_MESSAGEBOXTITLE 77 #define IDS_WARNINITIALSIZE 78 #define IDS_WARNMAXIMUMSIZE 79 +#define IDS_WARNINITIALRANGE 80 +#define IDS_WARNMAXIMUMRANGE 81 /* propsheet - general */ #define IDD_PROPPAGEGENERAL 100 diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 5dc572c0138..c09b6e40dcf 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -110,7 +110,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) TCHAR szVolume[MAX_PATH]; TCHAR *szDisplayString; INT InitialSize = 0; - INT MaxSize = 0; + INT MaximumSize = 0; INT DriveLen; INT PgCnt = 0; @@ -141,17 +141,17 @@ ParseMemSettings(PVIRTMEM pVirtMem) /* FIXME: we only check the first available pagefile in the reg */ GetPageFileSizes(pVirtMem->szPagingFiles, &InitialSize, - &MaxSize); + &MaximumSize); - pVirtMem->Pagefile[PgCnt].InitialValue = InitialSize; - pVirtMem->Pagefile[PgCnt].MaxValue = MaxSize; + pVirtMem->Pagefile[PgCnt].InitialSize = InitialSize; + pVirtMem->Pagefile[PgCnt].MaximumSize = MaximumSize; pVirtMem->Pagefile[PgCnt].bUsed = TRUE; lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); } else { - pVirtMem->Pagefile[PgCnt].InitialValue = 0; - pVirtMem->Pagefile[PgCnt].MaxValue = 0; + pVirtMem->Pagefile[PgCnt].InitialSize = 0; + pVirtMem->Pagefile[PgCnt].MaximumSize = 0; pVirtMem->Pagefile[PgCnt].bUsed = FALSE; lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); } @@ -177,11 +177,11 @@ ParseMemSettings(PVIRTMEM pVirtMem) } } - if ((InitialSize != 0) || (MaxSize != 0)) + if ((InitialSize != 0) || (MaximumSize != 0)) { TCHAR szSize[64]; - _stprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); + _stprintf(szSize, _T("%i - %i"), InitialSize, MaximumSize); _tcscat(szDisplayString, _T("\t")); _tcscat(szDisplayString, szSize); } @@ -216,8 +216,8 @@ WritePageFileSettings(PVIRTMEM pVirtMem) { _stprintf(szText, _T("%s\\pagefile.sys %i %i"), pVirtMem->Pagefile[i].szDrive, - pVirtMem->Pagefile[i].InitialValue, - pVirtMem->Pagefile[i].MaxValue); + pVirtMem->Pagefile[i].InitialSize, + pVirtMem->Pagefile[i].MaximumSize); /* Add it to our overall registry string */ lstrcpy(szPagingFiles + nPos, szText); @@ -299,8 +299,8 @@ static VOID OnSet(PVIRTMEM pVirtMem) { INT Index; - UINT InitValue; - UINT MaxValue; + UINT InitialSize; + UINT MaximumSize; BOOL bTranslated; TCHAR szTitle[64]; TCHAR szMessage[256]; @@ -318,10 +318,10 @@ OnSet(PVIRTMEM pVirtMem) if (IsDlgButtonChecked(pVirtMem->hSelf, IDC_CUSTOM) == BST_CHECKED) { - InitValue = GetDlgItemInt(pVirtMem->hSelf, - IDC_INITIALSIZE, - &bTranslated, - FALSE); + InitialSize = GetDlgItemInt(pVirtMem->hSelf, + IDC_INITIALSIZE, + &bTranslated, + FALSE); if (!bTranslated) { if (LoadString(hApplet, @@ -343,10 +343,10 @@ OnSet(PVIRTMEM pVirtMem) return; } - MaxValue = GetDlgItemInt(pVirtMem->hSelf, - IDC_MAXSIZE, - &bTranslated, - FALSE); + MaximumSize = GetDlgItemInt(pVirtMem->hSelf, + IDC_MAXSIZE, + &bTranslated, + FALSE); if (!bTranslated) { if (LoadString(hApplet, @@ -368,16 +368,59 @@ OnSet(PVIRTMEM pVirtMem) return; } - /* FIXME: Add more file size checks! */ + /* Check the valid range of the inial size */ + if (InitialSize < 2 || + InitialSize > pVirtMem->Pagefile[Index].FreeSize) + { + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); - pVirtMem->Pagefile[Index].InitialValue = InitValue; - pVirtMem->Pagefile[Index].MaxValue = MaxValue; + LoadString(hApplet, + IDS_WARNINITIALRANGE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; + } + + /* Check the valid range of the maximum size */ + if (MaximumSize < InitialSize || + MaximumSize > pVirtMem->Pagefile[Index].FreeSize) + { + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + LoadString(hApplet, + IDS_WARNMAXIMUMRANGE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; + } + + pVirtMem->Pagefile[Index].InitialSize = InitialSize; + pVirtMem->Pagefile[Index].MaximumSize = MaximumSize; pVirtMem->Pagefile[Index].bUsed = TRUE; } else { /* set sizes to 0 */ - pVirtMem->Pagefile[Index].InitialValue = pVirtMem->Pagefile[Index].MaxValue = 0; + pVirtMem->Pagefile[Index].InitialSize = 0; + pVirtMem->Pagefile[Index].MaximumSize = 0; // check to see if this drive is used for a paging file if (IsDlgButtonChecked(pVirtMem->hSelf, @@ -420,12 +463,13 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) if (GetDiskFreeSpaceEx(pVirtMem->Pagefile[Index].szDrive, NULL, NULL, &FreeBytes)) { + pVirtMem->Pagefile[Index].FreeSize = FreeBytes.QuadPart >> 20; _stprintf(szBuffer, _T("%I64u MB"), FreeBytes.QuadPart / (1024 * 1024)); SetDlgItemText(hwndDlg, IDC_SPACEAVAIL, szBuffer); } - if (pVirtMem->Pagefile[Index].InitialValue != 0 && - pVirtMem->Pagefile[Index].MaxValue != 0) + if (pVirtMem->Pagefile[Index].InitialSize != 0 && + pVirtMem->Pagefile[Index].MaximumSize != 0) { /* enable and fill the custom values */ EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); @@ -433,12 +477,12 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) SetDlgItemInt(pVirtMem->hSelf, IDC_INITIALSIZE, - pVirtMem->Pagefile[Index].InitialValue, + pVirtMem->Pagefile[Index].InitialSize, FALSE); SetDlgItemInt(pVirtMem->hSelf, IDC_MAXSIZE, - pVirtMem->Pagefile[Index].MaxValue, + pVirtMem->Pagefile[Index].MaximumSize, FALSE); CheckDlgButton(pVirtMem->hSelf, @@ -482,7 +526,7 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) FileSize = 0; for (i = 0; i < 26; i++) { - FileSize += pVirtMem->Pagefile[i].InitialValue; + FileSize += pVirtMem->Pagefile[i].InitialSize; } _stprintf(szBuffer, _T("%u MB"), FileSize); SetDlgItemText(hwndDlg, IDC_CURRENT, szBuffer); From fc20aaf185f5b936808b907050c57bb9fd6fdd5a Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 3 Jun 2010 13:36:50 +0000 Subject: [PATCH 192/292] [NTOSKRNL] NtDuplicateToken: If the called does not provide any desired access rights the duplicate token will inherit the granted rights of the original token. svn path=/trunk/; revision=47535 --- reactos/ntoskrnl/se/token.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 04fe7c2a5b0..aa281bc68d5 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1806,6 +1806,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, PTOKEN NewToken; PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService; BOOLEAN QoSPresent; + OBJECT_HANDLE_INFORMATION HandleInformation; NTSTATUS Status; PAGED_CODE(); @@ -1843,7 +1844,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, SepTokenObjectType, PreviousMode, (PVOID*)&Token, - NULL); + &HandleInformation); if (!NT_SUCCESS(Status)) { SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, @@ -1884,7 +1885,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, { Status = ObInsertObject((PVOID)NewToken, NULL, - DesiredAccess, + (DesiredAccess ? DesiredAccess : HandleInformation.GrantedAccess), 0, NULL, &hToken); From 489842b3821e87ec587b9ca258fcddf28ff31d98 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 14:19:18 +0000 Subject: [PATCH 193/292] merge 46805 from amd64 branch: [RBUILD] Fix some parameters (starting with --, not with -) svn path=/trunk/; revision=47538 --- reactos/tools/rbuild/backend/mingw/linkers/ld.mak | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index 88da818491e..d7fc3b78e40 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -1,12 +1,12 @@ # -exclude-all-symbols disables autoexporting all symbols *if none were found* (either in a DEF file or using __declspec(dllexport) -LDFLAG_DLL:=-shared -exclude-all-symbols -LDFLAG_DRIVER:=-shared --subsystem=native -exclude-all-symbols -LDFLAG_NOSTDLIB:=-nostartfiles -nostdlib +LDFLAG_DLL:=--shared --exclude-all-symbols +LDFLAG_DRIVER:=--shared --subsystem=native --exclude-all-symbols +LDFLAG_NOSTDLIB:=--nostartfiles --nostdlib LDFLAG_CONSOLE:=--subsystem=console LDFLAG_WINDOWS:=--subsystem=windows LDFLAG_NATIVE:=--subsystem=native -LDFLAG_EXCLUDE_ALL_SYMBOLS=-exclude-all-symbols +LDFLAG_EXCLUDE_ALL_SYMBOLS=--exclude-all-symbols DLLTOOL_FLAGS=--kill-at ifeq ($(ARCH),amd64) DLLTOOL_FLAGS= --no-leading-underscore @@ -87,4 +87,4 @@ endef #~ #(module, def, deps, ldflags, libs, entry, base) #~ RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} #(module, def, deps, ldflags, libs, entry, base, extralibs) -RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(value $(1)_LIBS),$(6),$(7),$(5)} \ No newline at end of file +RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(value $(1)_LIBS),$(6),$(7),$(5)} From 997911a7bea70cfdfbd9a3a980ce04125bb0cba0 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 14:49:47 +0000 Subject: [PATCH 194/292] [RBUILD] - append stdcall decoration only for i386 target svn path=/trunk/; revision=47539 --- reactos/tools/rbuild/module.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index d1c31385acc..95af1d0c8db 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -1113,23 +1113,23 @@ Module::GetDefaultModuleEntrypoint () const switch ( type ) { case Kernel: - if (Environment::GetArch() == "arm") return "KiSystemStartup"; - return "KiSystemStartup@4"; + if (Environment::GetArch() == "i386") return "KiSystemStartup@4"; + return "KiSystemStartup"; case KeyboardLayout: case KernelModeDLL: case KernelModeDriver: - if (Environment::GetArch() == "arm") return "DriverEntry"; - return "DriverEntry@8"; + if (Environment::GetArch() == "i386") return "DriverEntry@8"; + return "DriverEntry"; case NativeDLL: - if (Environment::GetArch() == "arm") return "DllMainCRTStartup"; - return "DllMainCRTStartup@12"; + if (Environment::GetArch() == "i386") return "DllMainCRTStartup@12"; + return "DllMainCRTStartup"; case NativeCUI: - if (Environment::GetArch() == "arm") return "NtProcessStartup"; - return "NtProcessStartup@4"; + if (Environment::GetArch() == "i386") return "NtProcessStartup@4"; + return "NtProcessStartup"; case Win32DLL: case Win32OCX: - if (Environment::GetArch() == "arm") return "DllMain"; - return "DllMain@12"; + if (Environment::GetArch() == "i386") return "DllMain@12"; + return "DllMain"; case Win32CUI: case Test: return "mainCRTStartup"; From cce23ec5f3753ad065fd829c2e70f9e79e8c3ea3 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 14:55:25 +0000 Subject: [PATCH 195/292] [ACPICA] - Hack acwin64.h, don't assume msvc for win64 svn path=/trunk/; revision=47540 --- .../drivers/bus/acpi/acpica/include/platform/acwin64.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/bus/acpi/acpica/include/platform/acwin64.h b/reactos/drivers/bus/acpi/acpica/include/platform/acwin64.h index faec855e22d..59a8adda807 100644 --- a/reactos/drivers/bus/acpi/acpica/include/platform/acwin64.h +++ b/reactos/drivers/bus/acpi/acpica/include/platform/acwin64.h @@ -118,10 +118,14 @@ /*! [Begin] no source code translation (Keep the include) */ -#include "acintel.h" +//#include "acintel.h" +// HACK +#define INT32 _ACPI_INT32 +#define UINT32 _ACPI_UINT32 + /*! [End] no source code translation !*/ -#define ACPI_MACHINE_WIDTH 64 +#define ACPI_MACHINE_WIDTH 64 #define ACPI_USE_STANDARD_HEADERS From 54a043669e4a12bfc6f8eb86ed07c4c08d9316dd Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Thu, 3 Jun 2010 15:09:08 +0000 Subject: [PATCH 196/292] [SYSDM] - Update Italian and Spanish translations. - Add untranslated strings to the rest of the languages. svn path=/trunk/; revision=47541 --- reactos/dll/cpl/sysdm/lang/bg-BG.rc | 2 ++ reactos/dll/cpl/sysdm/lang/cs-CZ.rc | 2 ++ reactos/dll/cpl/sysdm/lang/da-DK.rc | 2 ++ reactos/dll/cpl/sysdm/lang/el-GR.rc | 2 ++ reactos/dll/cpl/sysdm/lang/es-ES.rc | 6 ++++-- reactos/dll/cpl/sysdm/lang/fr-FR.rc | 2 ++ reactos/dll/cpl/sysdm/lang/hu-HU.rc | 2 ++ reactos/dll/cpl/sysdm/lang/id-ID.rc | 2 ++ reactos/dll/cpl/sysdm/lang/it-IT.rc | 6 ++++-- reactos/dll/cpl/sysdm/lang/ja-JP.rc | 2 ++ reactos/dll/cpl/sysdm/lang/nl-NL.rc | 2 ++ reactos/dll/cpl/sysdm/lang/no-NO.rc | 2 ++ reactos/dll/cpl/sysdm/lang/pl-PL.rc | 2 ++ reactos/dll/cpl/sysdm/lang/ro-RO.rc | 2 ++ reactos/dll/cpl/sysdm/lang/ru-RU.rc | 2 ++ reactos/dll/cpl/sysdm/lang/sk-SK.rc | 2 ++ reactos/dll/cpl/sysdm/lang/sv-SE.rc | 2 ++ reactos/dll/cpl/sysdm/lang/uk-UA.rc | 2 ++ reactos/dll/cpl/sysdm/lang/zh-CN.rc | 2 ++ 19 files changed, 42 insertions(+), 4 deletions(-) diff --git a/reactos/dll/cpl/sysdm/lang/bg-BG.rc b/reactos/dll/cpl/sysdm/lang/bg-BG.rc index f12c3be00f3..c358cf4e3e1 100644 --- a/reactos/dll/cpl/sysdm/lang/bg-BG.rc +++ b/reactos/dll/cpl/sysdm/lang/bg-BG.rc @@ -287,4 +287,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/cs-CZ.rc b/reactos/dll/cpl/sysdm/lang/cs-CZ.rc index 4672cff1743..2e11444dea1 100644 --- a/reactos/dll/cpl/sysdm/lang/cs-CZ.rc +++ b/reactos/dll/cpl/sysdm/lang/cs-CZ.rc @@ -292,4 +292,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/da-DK.rc b/reactos/dll/cpl/sysdm/lang/da-DK.rc index b4e1f31ce42..136a1dec301 100644 --- a/reactos/dll/cpl/sysdm/lang/da-DK.rc +++ b/reactos/dll/cpl/sysdm/lang/da-DK.rc @@ -126,4 +126,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/el-GR.rc b/reactos/dll/cpl/sysdm/lang/el-GR.rc index 909769d5545..426438a5853 100644 --- a/reactos/dll/cpl/sysdm/lang/el-GR.rc +++ b/reactos/dll/cpl/sysdm/lang/el-GR.rc @@ -288,4 +288,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/es-ES.rc b/reactos/dll/cpl/sysdm/lang/es-ES.rc index ce6c22ece8a..7383919a99b 100644 --- a/reactos/dll/cpl/sysdm/lang/es-ES.rc +++ b/reactos/dll/cpl/sysdm/lang/es-ES.rc @@ -288,6 +288,8 @@ BEGIN IDS_USERPROFILE_STATUS "Estado" IDS_USERPROFILE_MODIFIED "Modificado" IDS_MESSAGEBOXTITLE "Applet de sistema del panel de control" - IDS_WARNINITIALSIZE "Ingresar el valor inicial del tamaño del archivo de paginación." - IDS_WARNMAXIMUMSIZE "Ingresar el valor máximo del tamaño del archivo de paginación." + IDS_WARNINITIALSIZE "Ingresar el tamaño inicial del archivo de paginación." + IDS_WARNMAXIMUMSIZE "Ingresar el tamaño máximo del archivo de paginación." + IDS_WARNINITIALRANGE "El tamaño inicial del archivo de paginación no puede ser inferior a 2 MB y no puede exceder el espacio disponible en la unidad seleccionada." + IDS_WARNMAXIMUMRANGE "El tamaño máximo del archivo de paginación no puede ser inferior al tamaño inicial y no puede exceder el espacio disponible en la unidad seleccionada." END diff --git a/reactos/dll/cpl/sysdm/lang/fr-FR.rc b/reactos/dll/cpl/sysdm/lang/fr-FR.rc index bce50f954c2..17fe2e15d6b 100644 --- a/reactos/dll/cpl/sysdm/lang/fr-FR.rc +++ b/reactos/dll/cpl/sysdm/lang/fr-FR.rc @@ -290,4 +290,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/hu-HU.rc b/reactos/dll/cpl/sysdm/lang/hu-HU.rc index 09bd09d6e16..1324096ab32 100644 --- a/reactos/dll/cpl/sysdm/lang/hu-HU.rc +++ b/reactos/dll/cpl/sysdm/lang/hu-HU.rc @@ -129,4 +129,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/id-ID.rc b/reactos/dll/cpl/sysdm/lang/id-ID.rc index ad67a22ed61..6bd09c9f406 100644 --- a/reactos/dll/cpl/sysdm/lang/id-ID.rc +++ b/reactos/dll/cpl/sysdm/lang/id-ID.rc @@ -284,4 +284,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/it-IT.rc b/reactos/dll/cpl/sysdm/lang/it-IT.rc index 68d4bc0dc22..0175497f2a9 100644 --- a/reactos/dll/cpl/sysdm/lang/it-IT.rc +++ b/reactos/dll/cpl/sysdm/lang/it-IT.rc @@ -285,7 +285,9 @@ BEGIN IDS_USERPROFILE_STATUS "Stato" IDS_USERPROFILE_MODIFIED "Modificato" IDS_MESSAGEBOXTITLE "Applet di sistema del pannello di controllo" - IDS_WARNINITIALSIZE "Immettere il valore per la dimensione iniziale del file di paging." - IDS_WARNMAXIMUMSIZE "Immettere il valore per la dimensione massima del file di paging." + IDS_WARNINITIALSIZE "Immettere la dimensione iniziale del file di paging." + IDS_WARNMAXIMUMSIZE "Immettere la dimensione massima del file di paging." + IDS_WARNINITIALRANGE "La dimensione iniziale del file di paging non può essere inferiore a 2 MB e non può superare lo spazio disponibile nell'unità selezionata." + IDS_WARNMAXIMUMRANGE "La dimensione massima del file di paging non può essere inferiore a quella iniziale e non può superare lo spazio disponibile nell'unità selezionata." IDS_DEVS "\nReactOS Team\n\nCoordinatore\n\nAleksey Bragin\n\nGruppo di sviluppo\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nUlteriori ringraziamenti\n\na tutti i Contributers\nWine Team\n\n" END diff --git a/reactos/dll/cpl/sysdm/lang/ja-JP.rc b/reactos/dll/cpl/sysdm/lang/ja-JP.rc index e8fc6147c8d..7b86e4e0f92 100644 --- a/reactos/dll/cpl/sysdm/lang/ja-JP.rc +++ b/reactos/dll/cpl/sysdm/lang/ja-JP.rc @@ -287,4 +287,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/nl-NL.rc b/reactos/dll/cpl/sysdm/lang/nl-NL.rc index ccfc99897ff..94eca7ef70b 100644 --- a/reactos/dll/cpl/sysdm/lang/nl-NL.rc +++ b/reactos/dll/cpl/sysdm/lang/nl-NL.rc @@ -128,4 +128,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/no-NO.rc b/reactos/dll/cpl/sysdm/lang/no-NO.rc index b8d4e57df61..4c6d9997b75 100644 --- a/reactos/dll/cpl/sysdm/lang/no-NO.rc +++ b/reactos/dll/cpl/sysdm/lang/no-NO.rc @@ -286,4 +286,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/pl-PL.rc b/reactos/dll/cpl/sysdm/lang/pl-PL.rc index 99bc47761ea..91f7db5ed4c 100644 --- a/reactos/dll/cpl/sysdm/lang/pl-PL.rc +++ b/reactos/dll/cpl/sysdm/lang/pl-PL.rc @@ -291,4 +291,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/ro-RO.rc b/reactos/dll/cpl/sysdm/lang/ro-RO.rc index 5262a8ecc76..ea9ea85bf1c 100644 --- a/reactos/dll/cpl/sysdm/lang/ro-RO.rc +++ b/reactos/dll/cpl/sysdm/lang/ro-RO.rc @@ -287,6 +287,8 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END #pragma code_page(default) diff --git a/reactos/dll/cpl/sysdm/lang/ru-RU.rc b/reactos/dll/cpl/sysdm/lang/ru-RU.rc index 8a377e9cb14..72ecb3cc417 100644 --- a/reactos/dll/cpl/sysdm/lang/ru-RU.rc +++ b/reactos/dll/cpl/sysdm/lang/ru-RU.rc @@ -285,4 +285,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/sk-SK.rc b/reactos/dll/cpl/sysdm/lang/sk-SK.rc index 9845921b66b..497720ce90d 100644 --- a/reactos/dll/cpl/sysdm/lang/sk-SK.rc +++ b/reactos/dll/cpl/sysdm/lang/sk-SK.rc @@ -293,4 +293,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/sv-SE.rc b/reactos/dll/cpl/sysdm/lang/sv-SE.rc index e394e7f31fb..124bbe935e9 100644 --- a/reactos/dll/cpl/sysdm/lang/sv-SE.rc +++ b/reactos/dll/cpl/sysdm/lang/sv-SE.rc @@ -287,4 +287,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/uk-UA.rc b/reactos/dll/cpl/sysdm/lang/uk-UA.rc index e8951f425af..a92a15d4c0c 100644 --- a/reactos/dll/cpl/sysdm/lang/uk-UA.rc +++ b/reactos/dll/cpl/sysdm/lang/uk-UA.rc @@ -293,4 +293,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/reactos/dll/cpl/sysdm/lang/zh-CN.rc b/reactos/dll/cpl/sysdm/lang/zh-CN.rc index e3bda3ce72c..0ce9e187dd9 100644 --- a/reactos/dll/cpl/sysdm/lang/zh-CN.rc +++ b/reactos/dll/cpl/sysdm/lang/zh-CN.rc @@ -290,4 +290,6 @@ BEGIN IDS_MESSAGEBOXTITLE "System control panel applet" IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END From 33b6671aa1b2849e26e27a65c1b10d0f56ed1625 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 15:50:19 +0000 Subject: [PATCH 197/292] [rbuild] - cleanup obsolete rbuild flags for amd64 - undefine WIN32 for amd64, only _WIN32 should be defined svn path=/trunk/; revision=47542 --- reactos/ReactOS-amd64.rbuild | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reactos/ReactOS-amd64.rbuild b/reactos/ReactOS-amd64.rbuild index 6d9f8640d08..7a33724e4fc 100644 --- a/reactos/ReactOS-amd64.rbuild +++ b/reactos/ReactOS-amd64.rbuild @@ -34,8 +34,8 @@ -U_X86_ + -UWIN32 -Wno-format - -fno-leading-underscore @@ -44,8 +44,6 @@ -section-alignment=0x1000 --unique=.eh_frame -static - -fno-leading-underscore - -shared --exclude-all-symbols From a101fb302987f147ab213a812a7c8447aa481e08 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 15:57:52 +0000 Subject: [PATCH 198/292] [DDK] Make RtlLargeIntegerDivide FORCEINLINE instead of __inline to avoid multiple definitions svn path=/trunk/; revision=47543 --- reactos/include/ddk/ntddk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index f9281f95bac..4189edf733f 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -2772,7 +2772,7 @@ RtlConvertUlongToLuid( #if defined(_AMD64_) || defined(_IA64_) //DECLSPEC_DEPRECATED_DDK_WINXP -__inline +FORCEINLINE LARGE_INTEGER NTAPI_INLINE RtlLargeIntegerDivide( From 5ec99910727cf57d55a1757a5bd2cc5c1fe6c6fc Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Thu, 3 Jun 2010 16:12:43 +0000 Subject: [PATCH 199/292] [user32] - Remove a reactos only export (PrivateCsrssInitialized) - Don't call NtUserGetClassLong - Move implementation of AnyPopup to user mode - Fix a small bug in GetParent and in IsChild [csrss] - Don't call PrivateCsrssInitialized [win32k] - Call CsrInit in NtUserInitialize so we can remove PrivateCsrssInitialized - Romove a reactos only syscall (NtUserGetClassLong) - Remove UserGetClassLongPtr, UserGetWindow, UserGetWindowLong, IntGetOwner. Instead access objects directly - In WINDOW_OBJECT store pointer to the ownder window instead of a handle svn path=/trunk/; revision=47544 --- reactos/dll/win32/user32/include/user32p.h | 3 - reactos/dll/win32/user32/misc/misc.c | 7 - reactos/dll/win32/user32/user32.pspec | 1 - reactos/dll/win32/user32/windows/class.c | 43 ++- reactos/dll/win32/user32/windows/window.c | 35 ++- reactos/include/reactos/win32k/ntuser.h | 1 - .../subsystems/win32/csrss/win32csr/dllmain.c | 3 - .../subsystems/win32/win32k/include/class.h | 5 - .../win32/win32k/include/userfuncs.h | 4 - .../subsystems/win32/win32k/include/window.h | 12 +- .../subsystems/win32/win32k/ntuser/callproc.c | 4 +- .../subsystems/win32/win32k/ntuser/class.c | 129 --------- .../subsystems/win32/win32k/ntuser/defwnd.c | 2 +- .../subsystems/win32/win32k/ntuser/desktop.c | 2 +- .../subsystems/win32/win32k/ntuser/focus.c | 16 +- .../subsystems/win32/win32k/ntuser/ntuser.c | 2 + .../win32/win32k/ntuser/simplecall.c | 10 +- .../subsystems/win32/win32k/ntuser/window.c | 264 ++---------------- .../subsystems/win32/win32k/ntuser/winpos.c | 17 +- reactos/subsystems/win32/win32k/w32ksvc.db | 1 - 20 files changed, 102 insertions(+), 459 deletions(-) diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index 31f38a1a7db..1ab637eeea0 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -33,9 +33,6 @@ #define NtUserMsqClearWakeMask() \ NtUserCallNoParam(NOPARAM_ROUTINE_MSQCLEARWAKEMASK) -#define NtUserAnyPopup() \ - (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ANYPOPUP) - #define NtUserValidateRgn(hWnd, hRgn) \ (BOOL)NtUserCallTwoParam((DWORD_PTR)hWnd, (DWORD_PTR)hRgn, TWOPARAM_ROUTINE_VALIDATERGN) diff --git a/reactos/dll/win32/user32/misc/misc.c b/reactos/dll/win32/user32/misc/misc.c index 4d786c51e52..32438366a5e 100644 --- a/reactos/dll/win32/user32/misc/misc.c +++ b/reactos/dll/win32/user32/misc/misc.c @@ -45,13 +45,6 @@ PrivateCsrssManualGuiCheck(LONG Check) NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); } -VOID -WINAPI -PrivateCsrssInitialized(VOID) -{ - NtUserCallNoParam(NOPARAM_ROUTINE_CSRSS_INITIALIZED); -} - /* * @implemented diff --git a/reactos/dll/win32/user32/user32.pspec b/reactos/dll/win32/user32/user32.pspec index 45eb26b2b64..d58fb951d1b 100644 --- a/reactos/dll/win32/user32/user32.pspec +++ b/reactos/dll/win32/user32/user32.pspec @@ -750,7 +750,6 @@ ; ROS specific exports @ stdcall PrivateCsrssManualGuiCheck(long) -@ stdcall PrivateCsrssInitialized() ; Functions exported by Win Vista @ stdcall SetProcessDPIAware() diff --git a/reactos/dll/win32/user32/windows/class.c b/reactos/dll/win32/user32/windows/class.c index f546aa45952..1c66fd7606f 100644 --- a/reactos/dll/win32/user32/windows/class.c +++ b/reactos/dll/win32/user32/windows/class.c @@ -423,22 +423,15 @@ GetClassLongA(HWND hWnd, int nIndex) } else { - /* This is a race condition! Call win32k to make sure we're getting - the correct result */ - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ + Ret = 0; } _SEH2_END; - if (Wnd == NULL) - Ret = NtUserGetClassLong(hWnd, nIndex, TRUE); - return Ret; } @@ -534,22 +527,14 @@ GetClassLongW ( HWND hWnd, int nIndex ) } else { - /* This is a race condition! Call win32k to make sure we're getting - the correct result */ - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ } _SEH2_END; - if (Wnd == NULL) - Ret = NtUserGetClassLong(hWnd, nIndex, FALSE); - return Ret; } @@ -617,18 +602,28 @@ GetClassNameW( WORD WINAPI GetClassWord( - HWND hWnd, - int nIndex) -/* - * NOTE: Obsoleted in 32-bit windows - */ + HWND hwnd, + int offset) { - TRACE("%p %x\n", hWnd, nIndex); + PWND Wnd; + PCLS class; + WORD retvalue = 0; - if ((nIndex < 0) && (nIndex != GCW_ATOM)) + if (offset < 0) return GetClassLongA( hwnd, offset ); + + Wnd = ValidateHwnd(hwnd); + if (!Wnd) return 0; - return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE ); + class = DesktopPtrToUser(Wnd->pcls); + if (class == NULL) return 0; + + if (offset <= class->cbclsExtra - sizeof(WORD)) + memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) ); + else + SetLastError( ERROR_INVALID_INDEX ); + + return retvalue; } diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index e0c657cdfa9..04533ff0aa1 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -1030,16 +1030,16 @@ GetParent(HWND hWnd) _SEH2_TRY { WndParent = NULL; - if (Wnd->style & WS_CHILD) - { - if (Wnd->spwndParent != NULL) - WndParent = DesktopPtrToUser(Wnd->spwndParent); - } - else if (Wnd->style & WS_POPUP) + if (Wnd->style & WS_POPUP) { if (Wnd->spwndOwner != NULL) WndParent = DesktopPtrToUser(Wnd->spwndOwner); } + else if (Wnd->style & WS_CHILD) + { + if (Wnd->spwndParent != NULL) + WndParent = DesktopPtrToUser(Wnd->spwndParent); + } if (WndParent != NULL) Ret = UserHMGetHandle(WndParent); @@ -1464,7 +1464,7 @@ BOOL WINAPI IsChild(HWND hWndParent, HWND hWnd) { - PWND WndParent, Wnd; + PWND WndParent, DesktopWnd, Wnd; BOOL Ret = FALSE; WndParent = ValidateHwnd(hWndParent); @@ -1474,6 +1474,10 @@ IsChild(HWND hWndParent, if (!Wnd) return FALSE; + DesktopWnd = GetThreadDesktopWnd(); + if (!DesktopWnd) + return FALSE; + _SEH2_TRY { while (Wnd != NULL) @@ -1481,6 +1485,10 @@ IsChild(HWND hWndParent, if (Wnd->spwndParent != NULL) { Wnd = DesktopPtrToUser(Wnd->spwndParent); + + if(Wnd == DesktopWnd) + Wnd = NULL; + if (Wnd == WndParent) { Ret = TRUE; @@ -2062,7 +2070,18 @@ ScrollWindowEx(HWND hWnd, BOOL WINAPI AnyPopup(VOID) { - return NtUserAnyPopup(); + int i; + BOOL retvalue; + HWND *list = WIN_ListChildren( GetDesktopWindow() ); + + if (!list) return FALSE; + for (i = 0; list[i]; i++) + { + if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break; + } + retvalue = (list[i] != 0); + HeapFree( GetProcessHeap(), 0, list ); + return retvalue; } /* diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 0d6d7811db7..007fa887200 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -3135,7 +3135,6 @@ typedef struct tagKMDDELPARAM #define NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO 0xffff0005 #define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 -#define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007 #define ONEPARAM_ROUTINE_CSRSS_GUICHECK 0xffff0008 #define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0xfffe0008 #define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0xfffe000c diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 7d8b7e2aaf8..640f0fb163e 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -13,7 +13,6 @@ /* Not defined in any header file */ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); -extern VOID WINAPI PrivateCsrssInitialized(); extern VOID WINAPI InitializeAppSwitchHook(); /* GLOBALS *******************************************************************/ @@ -111,8 +110,6 @@ Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, static BOOL WINAPI Win32CsrInitComplete(void) { - PrivateCsrssInitialized(); - return TRUE; } diff --git a/reactos/subsystems/win32/win32k/include/class.h b/reactos/subsystems/win32/win32k/include/class.h index 2c8d0b0d0c1..27b3baf1f83 100644 --- a/reactos/subsystems/win32/win32k/include/class.h +++ b/reactos/subsystems/win32/win32k/include/class.h @@ -65,11 +65,6 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance, OUT PCLSMENUNAME pClassMenuName); -ULONG_PTR -UserGetClassLongPtr(IN PCLS Class, - IN INT Index, - IN BOOL Ansi); - RTL_ATOM IntGetClassAtom(IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, diff --git a/reactos/subsystems/win32/win32k/include/userfuncs.h b/reactos/subsystems/win32/win32k/include/userfuncs.h index 7ad47e625bc..d31e66faea9 100644 --- a/reactos/subsystems/win32/win32k/include/userfuncs.h +++ b/reactos/subsystems/win32/win32k/include/userfuncs.h @@ -122,15 +122,11 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread); HWND FASTCALL UserGetShellWindow(VOID); -HWND FASTCALL UserGetWindow(HWND hWnd, UINT Relationship); - HDC FASTCALL UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags); BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Wnd); -LONG FASTCALL UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi); - PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); /*************** MENU.C ***************/ diff --git a/reactos/subsystems/win32/win32k/include/window.h b/reactos/subsystems/win32/win32k/include/window.h index 14cac125fef..79a8df2d003 100644 --- a/reactos/subsystems/win32/win32k/include/window.h +++ b/reactos/subsystems/win32/win32k/include/window.h @@ -37,11 +37,8 @@ typedef struct _WINDOW_OBJECT struct _WINDOW_OBJECT* spwndChild; struct _WINDOW_OBJECT* spwndNext; struct _WINDOW_OBJECT* spwndPrev; - /* Handle to the parent window. */ struct _WINDOW_OBJECT* spwndParent; - /* Handle to the owner window. */ - HWND hOwner; // Use spwndOwner - + struct _WINDOW_OBJECT* spwndOwner; /* Scrollbar info */ PSBINFOEX pSBInfo; // convert to PSBINFO @@ -125,10 +122,6 @@ IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); PWINDOW_OBJECT FASTCALL IntGetParent(PWINDOW_OBJECT Wnd); -PWINDOW_OBJECT FASTCALL -IntGetOwner(PWINDOW_OBJECT Wnd); - - INT FASTCALL IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn); @@ -141,9 +134,6 @@ IntGetWindowInfo(PWINDOW_OBJECT WindowObject, PWINDOWINFO pwi); VOID FASTCALL IntGetWindowBorderMeasures(PWINDOW_OBJECT WindowObject, UINT *cx, UINT *cy); -BOOL FASTCALL -IntAnyPopup(VOID); - BOOL FASTCALL IntIsWindowInDestroy(PWINDOW_OBJECT Window); diff --git a/reactos/subsystems/win32/win32k/ntuser/callproc.c b/reactos/subsystems/win32/win32k/ntuser/callproc.c index dc8496dd431..f2298256d08 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callproc.c +++ b/reactos/subsystems/win32/win32k/ntuser/callproc.c @@ -185,9 +185,7 @@ UserGetCPD( Example: If pWnd is created from Ansi and lpfnXxyz is assumed to be Ansi, caller will ask for Unicode Proc return Proc or CallProcData handle. - - This function should replaced NtUserGetClassLong and NtUserGetWindowLong. - */ +*/ ULONG_PTR APIENTRY NtUserGetCPD( diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index c1726a69d8c..814aadb67dc 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -1515,96 +1515,6 @@ UserGetClassName(IN PCLS Class, return Ret; } -ULONG_PTR -UserGetClassLongPtr(IN PCLS Class, - IN INT Index, - IN BOOL Ansi) -{ - ULONG_PTR Ret = 0; - - if (Index >= 0) - { - PULONG_PTR Data; - - TRACE("GetClassLong(%d)\n", Index); - if (Index + sizeof(ULONG_PTR) < Index || - Index + sizeof(ULONG_PTR) > Class->cbclsExtra) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - - Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index); - - /* FIXME - Data might be a unaligned pointer! Might be a problem on - certain architectures, maybe using RtlCopyMemory is a - better choice for those architectures! */ - - TRACE("Result: %x\n", Ret); - return *Data; - } - - switch (Index) - { - case GCL_CBWNDEXTRA: - Ret = (ULONG_PTR)Class->cbwndExtra; - break; - - case GCL_CBCLSEXTRA: - Ret = (ULONG_PTR)Class->cbclsExtra; - break; - - case GCLP_HBRBACKGROUND: - Ret = (ULONG_PTR)Class->hbrBackground; - break; - - case GCLP_HCURSOR: - /* FIXME - get handle from pointer to CURSOR object */ - Ret = (ULONG_PTR)Class->hCursor; - break; - - case GCLP_HICON: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIcon; - break; - - case GCLP_HICONSM: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; - break; - - case GCLP_HMODULE: - Ret = (ULONG_PTR)Class->hModule; - break; - - case GCLP_MENUNAME: - /* NOTE: Returns pointer in kernel heap! */ - if (Ansi) - Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName; - else - Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName; - break; - - case GCL_STYLE: - Ret = (ULONG_PTR)Class->style; - break; - - case GCLP_WNDPROC: - Ret = (ULONG_PTR)IntGetClassWndProc(Class, Ansi); - break; - - case GCW_ATOM: - Ret = (ULONG_PTR)Class->atomClassName; - break; - - default: - SetLastWin32Error(ERROR_INVALID_INDEX); - break; - } - - return Ret; -} - static BOOL IntSetClassMenuName(IN PCLS Class, IN PUNICODE_STRING MenuName) @@ -2190,45 +2100,6 @@ InvalidParameter: return Ret; } -ULONG_PTR APIENTRY -NtUserGetClassLong(IN HWND hWnd, - IN INT Offset, - IN BOOL Ansi) -{ - PWINDOW_OBJECT Window; - ULONG_PTR Ret = 0; - - if (Offset != GCLP_WNDPROC) - { - UserEnterShared(); - } - else - { - UserEnterExclusive(); - } - - Window = UserGetWindowObject(hWnd); - if (Window != NULL) - { - Ret = UserGetClassLongPtr(Window->Wnd->pcls, - Offset, - Ansi); - - if ( Ret != 0 && - Offset == GCLP_MENUNAME && - Window->Wnd->pcls->MenuNameIsString) - { - Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret); - } - } - - UserLeave(); - - return Ret; -} - - - ULONG_PTR APIENTRY NtUserSetClassLong(HWND hWnd, INT Offset, diff --git a/reactos/subsystems/win32/win32k/ntuser/defwnd.c b/reactos/subsystems/win32/win32k/ntuser/defwnd.c index 6cf4fd010c6..afc60e852ae 100644 --- a/reactos/subsystems/win32/win32k/ntuser/defwnd.c +++ b/reactos/subsystems/win32/win32k/ntuser/defwnd.c @@ -129,7 +129,7 @@ IntDefWindowProc( { if ((Wnd->style & WS_VISIBLE) && wParam) break; if (!(Wnd->style & WS_VISIBLE) && !wParam) break; - if (!Window->hOwner) break; + if (!Window->spwndOwner) break; if (LOWORD(lParam)) { if (wParam) diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 6bfe10b0239..57a5be135e7 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -1423,7 +1423,7 @@ NtUserPaintDesktop(HDC hDC) RETURN(FALSE); } - DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->pcls, GCL_HBRBACKGROUND, FALSE); + DesktopBrush = (HBRUSH)WndDesktop->Wnd->pcls->hbrBackground; /* diff --git a/reactos/subsystems/win32/win32k/ntuser/focus.c b/reactos/subsystems/win32/win32k/ntuser/focus.c index ee9c2ff93ad..59f364ed548 100644 --- a/reactos/subsystems/win32/win32k/ntuser/focus.c +++ b/reactos/subsystems/win32/win32k/ntuser/focus.c @@ -51,12 +51,14 @@ IntGetThreadFocusWindow(VOID) VOID FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd) { - if (hWndPrev) + PWINDOW_OBJECT WndPrev ; + + if (hWndPrev && (WndPrev = UserGetWindowObject(hWndPrev))) { co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0); co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE, - MAKEWPARAM(WA_INACTIVE, UserGetWindowLong(hWndPrev, GWL_STYLE, FALSE) & WS_MINIMIZE), - (LPARAM)hWnd); + MAKEWPARAM(WA_INACTIVE, WndPrev->Wnd->style & WS_MINIMIZE), + (LPARAM)hWnd); } } @@ -83,11 +85,11 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) 0); } - if (UserGetWindow(hWnd, GW_HWNDPREV) != NULL) + if (Window->spwndPrev != NULL) co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd); } @@ -153,7 +155,7 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) /* FIXME: WA_CLICKACTIVE */ co_IntSendMessageNoWait(hWnd, WM_ACTIVATE, MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, - UserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE), + Window->Wnd->style & WS_MINIMIZE), (LPARAM)hWndPrev); } } @@ -184,7 +186,7 @@ IntFindChildWindowToOwner(PWINDOW_OBJECT Root, PWINDOW_OBJECT Owner) for(Child = Root->spwndChild; Child; Child = Child->spwndNext) { - OwnerWnd = UserGetWindowObject(Child->hOwner); + OwnerWnd = Child->spwndOwner; if(!OwnerWnd) continue; diff --git a/reactos/subsystems/win32/win32k/ntuser/ntuser.c b/reactos/subsystems/win32/win32k/ntuser/ntuser.c index 569acfdc54c..b8f17849195 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntuser.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntuser.c @@ -124,6 +124,8 @@ UserInitialize( NtUserUpdatePerUserSystemParameters(0, TRUE); + CsrInit(); + return STATUS_SUCCESS; } diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index cdd4a22a6b1..f46a75da2aa 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -110,14 +110,6 @@ NtUserCallNoParam(DWORD Routine) Result = (DWORD_PTR)MsqGetMessageExtraInfo(); break; - case NOPARAM_ROUTINE_ANYPOPUP: - Result = (DWORD_PTR)IntAnyPopup(); - break; - - case NOPARAM_ROUTINE_CSRSS_INITIALIZED: - Result = (DWORD_PTR)CsrInit(); - break; - case NOPARAM_ROUTINE_MSQCLEARWAKEMASK: RETURN( (DWORD_PTR)IntMsqClearWakeMask()); @@ -525,7 +517,7 @@ NtUserCallHwndLock( SWP_NOZORDER| SWP_NOACTIVATE| SWP_FRAMECHANGED ); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd); } diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index e1965d8c02d..ee1f7aea849 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -96,6 +96,8 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd) ASSERT(Window->head.cLockObj >= 0); Window->head.cLockObj++; + + ASSERT(Window->Wnd); } return Window; } @@ -130,6 +132,9 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd) } ASSERT(Window->head.cLockObj >= 0); + + ASSERT(Window->Wnd); + return Window; } @@ -163,20 +168,12 @@ IntIsWindow(HWND hWnd) -/* - Caller must NOT dereference retval! - But if caller want the returned value to persist spanning a co_ call, - it must reference the value (because the owner is not garanteed to - exist just because the owned window exist)! -*/ PWINDOW_OBJECT FASTCALL IntGetParent(PWINDOW_OBJECT Wnd) { - if (!Wnd->Wnd) return NULL; - if (Wnd->Wnd->style & WS_POPUP) { - return UserGetWindowObject(Wnd->hOwner); + return Wnd->spwndOwner; } else if (Wnd->Wnd->style & WS_CHILD) { @@ -187,20 +184,6 @@ IntGetParent(PWINDOW_OBJECT Wnd) } -/* - Caller must NOT dereference retval! - But if caller want the returned value to persist spanning a co_ call, - it must reference the value (because the owner is not garanteed to - exist just because the owned window exist)! -*/ -PWINDOW_OBJECT FASTCALL -IntGetOwner(PWINDOW_OBJECT Wnd) -{ - return UserGetWindowObject(Wnd->hOwner); -} - - - /* * IntWinListChildren * @@ -265,7 +248,7 @@ static void IntSendDestroyMsg(HWND hWnd) // USER_REFERENCE_ENTRY Ref; // UserRefObjectCo(Window, &Ref); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd); } @@ -1091,26 +1074,19 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) if(!Wnd) return NULL; - WndOldOwner = IntGetWindowObject(Wnd->hOwner); - if (WndOldOwner) - { - ret = WndOldOwner->hSelf; - UserDereferenceObject(WndOldOwner); - } - else - { - ret = 0; - } + WndOldOwner = Wnd->spwndOwner; + + ret = WndOldOwner ? WndOldOwner->hSelf : 0; if((WndNewOwner = UserGetWindowObject(hWndNewOwner))) { - Wnd->hOwner = hWndNewOwner; - Wnd->Wnd->spwndOwner = WndNewOwner->Wnd; + Wnd->spwndOwner= WndNewOwner; + Wnd->Wnd->spwndOwner = WndNewOwner->Wnd; } else { - Wnd->hOwner = NULL; - Wnd->Wnd->spwndOwner = NULL; + Wnd->spwndOwner = NULL; + Wnd->Wnd->spwndOwner = NULL; } UserDereferenceObject(Wnd); @@ -1279,31 +1255,6 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd) Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL; } -BOOL FASTCALL -IntAnyPopup(VOID) -{ - PWINDOW_OBJECT Window, Child; - - if(!(Window = UserGetWindowObject(IntGetDesktopWindow()))) - { - return FALSE; - } - - for(Child = Window->spwndChild; Child; Child = Child->spwndNext) - { - if(Child->hOwner && Child->Wnd->style & WS_VISIBLE) - { - /* - * The desktop has a popup window if one of them has - * an owner window and is visible - */ - return TRUE; - } - } - - return FALSE; -} - BOOL FASTCALL IntIsWindowInDestroy(PWINDOW_OBJECT Window) { @@ -1511,7 +1462,7 @@ NtUserBuildHwndList( Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry); ASSERT(Window); - if(bChildren || Window->hOwner != NULL) + if(bChildren || Window->spwndOwner != NULL) { if(dwCount < *pBufSize && pWnd) { @@ -1737,7 +1688,7 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, Window->pti = pti; Window->hSelf = hWnd; Window->spwndParent = ParentWindow; - Window->hOwner = OwnerWindow ? OwnerWindow->hSelf : NULL; + Window->spwndOwner = OwnerWindow; Wnd->head.h = hWnd; Wnd->head.pti = pti; @@ -2560,7 +2511,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) Child = UserGetWindowObject(*ChildHandle); if (Child == NULL) continue; - if (Child->hOwner != Window->hSelf) + if (Child->spwndOwner != Window) { continue; } @@ -2576,9 +2527,9 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) continue; } - if (Child->hOwner != NULL) + if (Child->spwndOwner != NULL) { - Child->hOwner = NULL; + Child->spwndOwner = NULL; Child->Wnd->spwndOwner = NULL; } @@ -3041,9 +2992,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type) break; } - //temp hack -// UserDereferenceObject(Parent); - WndAncestor = Parent; } break; @@ -3374,7 +3322,7 @@ BOOL APIENTRY NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) { PWINSTATION_OBJECT WinStaObject; - PWINDOW_OBJECT WndShell; + PWINDOW_OBJECT WndShell, WndListView; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; NTSTATUS Status; @@ -3388,6 +3336,11 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) RETURN(FALSE); } + if(!(WndListView = UserGetWindowObject(hwndListView))) + { + RETURN(FALSE); + } + Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, KernelMode, 0, @@ -3421,14 +3374,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); #endif - if (UserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST) + if (WndListView->Wnd->ExStyle & WS_EX_TOPMOST) { ObDereferenceObject(WinStaObject); RETURN( FALSE); } } - if (UserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST) + if (WndShell->Wnd->ExStyle & WS_EX_TOPMOST) { ObDereferenceObject(WinStaObject); RETURN( FALSE); @@ -3553,162 +3506,6 @@ CLEANUP: END_CLEANUP; } -HWND FASTCALL -UserGetWindow(HWND hWnd, UINT Relationship) -{ - PWINDOW_OBJECT Parent, Window; - HWND hWndResult = NULL; - - if (!(Window = UserGetWindowObject(hWnd))) - return NULL; - - switch (Relationship) - { - case GW_HWNDFIRST: - if((Parent = Window->spwndParent)) - { - if (Parent->spwndChild) - hWndResult = Parent->spwndChild->hSelf; - } - break; - - case GW_HWNDLAST: - if((Parent = Window->spwndParent)) - { - if (Parent->spwndChild) - { - Window = Parent->spwndChild; - if(Window) - { - while(Window->spwndNext) - Window = Window->spwndNext; - } - hWndResult = Window->hSelf; - } - } - break; - - case GW_HWNDNEXT: - if (Window->spwndNext) - hWndResult = Window->spwndNext->hSelf; - break; - - case GW_HWNDPREV: - if (Window->spwndPrev) - hWndResult = Window->spwndPrev->hSelf; - break; - - case GW_OWNER: - if((Parent = UserGetWindowObject(Window->hOwner))) - { - hWndResult = Parent->hSelf; - } - break; - case GW_CHILD: - if (Window->spwndChild) - hWndResult = Window->spwndChild->hSelf; - break; - } - - return hWndResult; -} - -/* - * NtUserGetWindowLong - * - * The NtUserGetWindowLong function retrieves information about the specified - * window. The function also retrieves the 32-bit (long) value at the - * specified offset into the extra window memory. - * - * Status - * @implemented - */ - -LONG FASTCALL -UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) -{ - PWINDOW_OBJECT Window, Parent; - PWND Wnd; - LONG Result = 0; - - DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi); - - if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd) - { - return 0; - } - - Wnd = Window->Wnd; - - /* - * WndProc is only available to the owner process - */ - if (GWL_WNDPROC == Index - && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess()) - { - SetLastWin32Error(ERROR_ACCESS_DENIED); - return 0; - } - - if ((INT)Index >= 0) - { - if ((Index + sizeof(LONG)) > Window->Wnd->cbwndExtra) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - Result = *((LONG *)((PCHAR)(Window->Wnd + 1) + Index)); - } - else - { - switch (Index) - { - case GWL_EXSTYLE: - Result = Wnd->ExStyle; - break; - - case GWL_STYLE: - Result = Wnd->style; - break; - - case GWL_WNDPROC: - Result = (LONG)IntGetWindowProc(Wnd, Ansi); - break; - - case GWL_HINSTANCE: - Result = (LONG) Wnd->hModule; - break; - - case GWL_HWNDPARENT: - Parent = Window->spwndParent; - if(Parent) - { - if (Parent && Parent->hSelf == IntGetDesktopWindow()) - Result = (LONG) UserGetWindow(Window->hSelf, GW_OWNER); - else - Result = (LONG) Parent->hSelf; - } - break; - - case GWL_ID: - Result = (LONG) Wnd->IDMenu; - break; - - case GWL_USERDATA: - Result = Wnd->dwUserData; - break; - - default: - DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - Result = 0; - break; - } - } - - return Result; -} - LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) { @@ -4807,7 +4604,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText) // In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than // RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc. /* Send shell notifications */ - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd); } @@ -4908,11 +4705,10 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow ) count++; while (--count >= 0) { - if (UserGetWindow( win_array[count], GW_OWNER ) != OwnerWnd->hSelf) - continue; if (!(pWnd = UserGetWindowObject( win_array[count] ))) continue; - // if (pWnd == WND_OTHER_PROCESS) continue; + if (pWnd->spwndOwner != OwnerWnd) + continue; if (fShow) { diff --git a/reactos/subsystems/win32/win32k/ntuser/winpos.c b/reactos/subsystems/win32/win32k/ntuser/winpos.c index 6a04e8c05c8..8bdd29969a3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winpos.c +++ b/reactos/subsystems/win32/win32k/ntuser/winpos.c @@ -151,7 +151,7 @@ co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window) } /* If this is popup window, try to activate the owner first. */ - if ((Wnd->style & WS_POPUP) && (WndTo = IntGetOwner(Window))) + if ((Wnd->style & WS_POPUP) && (WndTo = Window->spwndOwner)) { WndTo = UserGetAncestor( WndTo, GA_ROOT ); if (can_activate_window(WndTo)) goto done; @@ -741,11 +741,15 @@ HWND FASTCALL WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter) { HWND *List = NULL; - HWND Owner = UserGetWindow(hWnd, GW_OWNER); - LONG Style = UserGetWindowLong(hWnd, GWL_STYLE, FALSE); - PWINDOW_OBJECT DesktopWindow, ChildObject; + HWND Owner; + LONG Style; + PWINDOW_OBJECT Window ,DesktopWindow, ChildObject; int i; + Window = UserGetWindowObject(hWnd); + Owner = Window->spwndOwner ? Window->spwndOwner->hSelf : NULL; + Style = Window->Wnd->style; + if ((Style & WS_POPUP) && Owner) { /* Make sure this popup stays above the owner */ @@ -804,8 +808,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter) if (!(Wnd = UserGetWindowObject(List[i]))) continue; - if ((Wnd->Wnd->style & WS_POPUP) && - UserGetWindow(List[i], GW_OWNER) == hWnd) + if (Wnd->Wnd->style & WS_POPUP && Wnd->spwndOwner == Window) { USER_REFERENCE_ENTRY Ref; UserRefObjectCo(Wnd, &Ref); @@ -958,7 +961,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window) * itself. */ if ((WinPos->hwnd == WinPos->hwndInsertAfter) || - (WinPos->hwnd == UserGetWindow(WinPos->hwndInsertAfter, GW_HWNDNEXT))) + (WinPos->hwnd == InsAfterWnd->spwndNext->hSelf)) { WinPos->flags |= SWP_NOZORDER; } diff --git a/reactos/subsystems/win32/win32k/w32ksvc.db b/reactos/subsystems/win32/win32k/w32ksvc.db index acce60122d2..0b90145a90f 100644 --- a/reactos/subsystems/win32/win32k/w32ksvc.db +++ b/reactos/subsystems/win32/win32k/w32ksvc.db @@ -684,7 +684,6 @@ NtGdiOffsetWindowOrgEx 4 # NtUserBuildMenuItemList 4 NtUserCreateCursorIconHandle 2 -NtUserGetClassLong 3 NtUserGetMenuDefaultItem 3 NtUserGetLastInputInfo 1 NtUserGetMinMaxInfo 3 From fbb71f36dce7549ebf7c8586f01c97143d61bc1e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 17:44:52 +0000 Subject: [PATCH 200/292] [BROWSEUI] merge r44391 from amd64 branch fix 64bit build svn path=/trunk/; revision=47545 --- reactos/dll/win32/browseui/shellbrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/browseui/shellbrowser.cpp b/reactos/dll/win32/browseui/shellbrowser.cpp index 3a27a1137d8..50e00d656cb 100644 --- a/reactos/dll/win32/browseui/shellbrowser.cpp +++ b/reactos/dll/win32/browseui/shellbrowser.cpp @@ -282,7 +282,7 @@ void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar) LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - LRESULT result; + long int result; HRESULT hResult; result = 0; From 279fb0890786bcd35c4ade70eeb73fdab7c89edc Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 17:52:23 +0000 Subject: [PATCH 201/292] [PSDK] add LVSIL_GROUPHEADER definition to commctrl.h svn path=/trunk/; revision=47546 --- reactos/include/psdk/commctrl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/include/psdk/commctrl.h b/reactos/include/psdk/commctrl.h index 2b51c2e072f..bc452a2f9db 100644 --- a/reactos/include/psdk/commctrl.h +++ b/reactos/include/psdk/commctrl.h @@ -2240,6 +2240,7 @@ extern "C" { #define LVSIL_NORMAL 0 #define LVSIL_SMALL 1 #define LVSIL_STATE 2 +#define LVSIL_GROUPHEADER 3 #define LVM_SETIMAGELIST (LVM_FIRST+3) #define ListView_SetImageList(hwnd,himl,iImageList) (HIMAGELIST)SNDMSG((hwnd),LVM_SETIMAGELIST,(WPARAM)(iImageList),(LPARAM)(HIMAGELIST)(himl)) From 42667f14a0d6a8864709925e928755208351ed36 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 17:56:15 +0000 Subject: [PATCH 202/292] [COMCTRL32] Sync listview.c with wine 1.2 rc2 svn path=/trunk/; revision=47547 --- reactos/dll/win32/comctl32/listview.c | 1496 ++++++++++++++++--------- 1 file changed, 983 insertions(+), 513 deletions(-) diff --git a/reactos/dll/win32/comctl32/listview.c b/reactos/dll/win32/comctl32/listview.c index 1c0f58bbd69..4e13577b48f 100644 --- a/reactos/dll/win32/comctl32/listview.c +++ b/reactos/dll/win32/comctl32/listview.c @@ -7,6 +7,7 @@ * Copyright 2001 CodeWeavers Inc. * Copyright 2002 Dimitrie O. Paun * Copyright 2009 Nikolay Sivov + * Copyright 2009 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,7 +74,6 @@ * * States * -- LVIS_ACTIVATING (not currently supported by comctl32.dll version 6.0) - * -- LVIS_CUT * -- LVIS_DROPHILITED * -- LVIS_OVERLAYMASK * @@ -98,9 +98,7 @@ * -- LVN_BEGINSCROLL, LVN_ENDSCROLL * -- LVN_GETINFOTIP * -- LVN_HOTTRACK - * -- LVN_MARQUEEBEGIN * -- LVN_SETDISPINFO - * -- NM_HOVER * -- LVN_BEGINRDRAG * * Messages: @@ -170,9 +168,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(listview); -/* make sure you set this to 0 for production use! */ -#define DEBUG_RANGES 1 - typedef struct tagCOLUMN_INFO { RECT rcHeader; /* tracks the header's rectangle */ @@ -237,81 +232,120 @@ typedef struct tagDELAYED_ITEM_EDIT typedef struct tagLISTVIEW_INFO { + /* control window */ HWND hwndSelf; - HBRUSH hBkBrush; - COLORREF clrBk; - COLORREF clrText; - COLORREF clrTextBk; - HIMAGELIST himlNormal; - HIMAGELIST himlSmall; - HIMAGELIST himlState; - BOOL bLButtonDown; - BOOL bRButtonDown; - BOOL bDragging; - POINT ptClickPos; /* point where the user clicked */ - BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ - INT nItemHeight; - INT nItemWidth; - RANGES selectionRanges; - INT nSelectionMark; - INT nHotItem; - SHORT notifyFormat; - HWND hwndNotify; RECT rcList; /* This rectangle is really the window * client rectangle possibly reduced by the * horizontal scroll bar and/or header - see * LISTVIEW_UpdateSize. This rectangle offset * by the LISTVIEW_GetOrigin value is in * client coordinates */ - SIZE iconSize; - SIZE iconSpacing; - SIZE iconStateSize; - UINT uCallbackMask; - HWND hwndHeader; - HCURSOR hHotCursor; - HFONT hDefaultFont; - HFONT hFont; - INT ntmHeight; /* Some cached metrics of the font used */ - INT ntmMaxCharWidth; /* by the listview to draw items */ - INT nEllipsisWidth; - BOOL bRedraw; /* Turns on/off repaints & invalidations */ - BOOL bAutoarrange; /* Autoarrange flag when NOT in LVS_AUTOARRANGE */ - BOOL bFocus; + + /* notification window */ + SHORT notifyFormat; + HWND hwndNotify; BOOL bDoChangeNotify; /* send change notification messages? */ - INT nFocusedItem; - RECT rcFocus; - DWORD dwStyle; /* the cached window GWL_STYLE */ - DWORD dwLvExStyle; /* extended listview style */ - DWORD uView; /* current view available through LVM_[G,S]ETVIEW */ + UINT uCallbackMask; + + /* tooltips */ + HWND hwndToolTip; + + /* items */ INT nItemCount; /* the number of items in the list */ HDPA hdpaItems; /* array ITEM_INFO pointers */ HDPA hdpaItemIds; /* array of ITEM_ID pointers */ HDPA hdpaPosX; /* maintains the (X, Y) coordinates of the */ HDPA hdpaPosY; /* items in LVS_ICON, and LVS_SMALLICON modes */ + RANGES selectionRanges; + INT nSelectionMark; /* item to start next multiselection from */ + INT nHotItem; + BOOL bAutoarrange; /* Autoarrange flag when NOT in LVS_AUTOARRANGE */ + + /* columns */ HDPA hdpaColumns; /* array of COLUMN_INFO pointers */ BOOL colRectsDirty; /* trigger column rectangles requery from header */ - POINT currIconPos; /* this is the position next icon will be placed */ - PFNLVCOMPARE pfnCompare; + + /* item metrics */ + BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ + INT nItemHeight; + INT nItemWidth; + + /* sorting */ + PFNLVCOMPARE pfnCompare; /* sorting callback pointer */ LPARAM lParamSort; + + /* style */ + DWORD dwStyle; /* the cached window GWL_STYLE */ + DWORD dwLvExStyle; /* extended listview style */ + DWORD uView; /* current view available through LVM_[G,S]ETVIEW */ + + /* edit item */ HWND hwndEdit; WNDPROC EditWndProc; INT nEditLabelItem; - INT nLButtonDownItem; /* tracks item to reset multiselection on WM_LBUTTONUP */ + DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ + + /* icons */ + HIMAGELIST himlNormal; + HIMAGELIST himlSmall; + HIMAGELIST himlState; + SIZE iconSize; + SIZE iconSpacing; + SIZE iconStateSize; + POINT currIconPos; /* this is the position next icon will be placed */ + + /* header */ + HWND hwndHeader; + INT xTrackLine; /* The x coefficient of the track line or -1 if none */ + + /* marquee selection */ + BOOL bMarqueeSelect; /* marquee selection/highlight underway */ + BOOL bScrolling; + RECT marqueeRect; /* absolute coordinates of marquee selection */ + RECT marqueeDrawRect; /* relative coordinates for drawing marquee */ + POINT marqueeOrigin; /* absolute coordinates of marquee click origin */ + + /* focus drawing */ + BOOL bFocus; /* control has focus */ + INT nFocusedItem; + RECT rcFocus; /* focus bounds */ + + /* colors */ + HBRUSH hBkBrush; + COLORREF clrBk; + COLORREF clrText; + COLORREF clrTextBk; + + /* font */ + HFONT hDefaultFont; + HFONT hFont; + INT ntmHeight; /* Some cached metrics of the font used */ + INT ntmMaxCharWidth; /* by the listview to draw items */ + INT nEllipsisWidth; + + /* mouse operation */ + BOOL bLButtonDown; + BOOL bRButtonDown; + BOOL bDragging; + POINT ptClickPos; /* point where the user clicked */ + INT nLButtonDownItem; /* tracks item to reset multiselection on WM_LBUTTONUP */ DWORD dwHoverTime; - HWND hwndToolTip; - - DWORD cditemmode; /* Keep the custom draw flags for an item/row */ + HCURSOR hHotCursor; + /* keyboard operation */ DWORD lastKeyPressTimestamp; WPARAM charCode; INT nSearchParamLength; WCHAR szSearchParam[ MAX_PATH ]; - BOOL bIsDrawing; - INT nMeasureItemHeight; - INT xTrackLine; /* The x coefficient of the track line or -1 if none */ - DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ - DWORD iVersion; /* CCM_[G,S]ETVERSION */ + /* painting */ + DWORD cditemmode; /* Keep the custom draw flags for an item/row */ + BOOL bIsDrawing; /* Drawing in progress */ + INT nMeasureItemHeight; /* WM_MEASUREITEM result */ + BOOL bRedraw; /* WM_SETREDRAW switch */ + + /* misc */ + DWORD iVersion; /* CCM_[G,S]ETVERSION */ } LISTVIEW_INFO; /* @@ -414,7 +448,6 @@ static void LISTVIEW_GetItemBox(const LISTVIEW_INFO *, INT, LPRECT); static void LISTVIEW_GetItemOrigin(const LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemPosition(const LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemRect(const LISTVIEW_INFO *, INT, LPRECT); -static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *, INT); static void LISTVIEW_GetOrigin(const LISTVIEW_INFO *, LPPOINT); static BOOL LISTVIEW_GetViewRect(const LISTVIEW_INFO *, LPRECT); static void LISTVIEW_UpdateSize(LISTVIEW_INFO *); @@ -426,10 +459,10 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *, INT, const LVITEMW *); static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *, INT, INT, HWND); static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *, INT, INT, HWND); static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL); -static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, BOOL); static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *, INT, HIMAGELIST); static INT LISTVIEW_HitTest(const LISTVIEW_INFO *, LPLVHITTESTINFO, BOOL, BOOL); static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *, BOOL, BOOL); +static BOOL LISTVIEW_Scroll(LISTVIEW_INFO *, INT, INT); /******** Text handling functions *************************************/ @@ -716,25 +749,37 @@ static int get_ansi_notification(UINT unicodeNotificationCode) { switch (unicodeNotificationCode) { + case LVN_BEGINLABELEDITA: case LVN_BEGINLABELEDITW: return LVN_BEGINLABELEDITA; + case LVN_ENDLABELEDITA: case LVN_ENDLABELEDITW: return LVN_ENDLABELEDITA; + case LVN_GETDISPINFOA: case LVN_GETDISPINFOW: return LVN_GETDISPINFOA; + case LVN_SETDISPINFOA: case LVN_SETDISPINFOW: return LVN_SETDISPINFOA; + case LVN_ODFINDITEMA: case LVN_ODFINDITEMW: return LVN_ODFINDITEMA; + case LVN_GETINFOTIPA: case LVN_GETINFOTIPW: return LVN_GETINFOTIPA; /* header forwards */ + case HDN_TRACKA: case HDN_TRACKW: return HDN_TRACKA; + case HDN_ENDTRACKA: case HDN_ENDTRACKW: return HDN_ENDTRACKA; case HDN_BEGINDRAG: return HDN_BEGINDRAG; case HDN_ENDDRAG: return HDN_ENDDRAG; + case HDN_ITEMCHANGINGA: case HDN_ITEMCHANGINGW: return HDN_ITEMCHANGINGA; + case HDN_ITEMCHANGEDA: case HDN_ITEMCHANGEDW: return HDN_ITEMCHANGEDA; + case HDN_ITEMCLICKA: case HDN_ITEMCLICKW: return HDN_ITEMCLICKA; + case HDN_DIVIDERDBLCLICKA: case HDN_DIVIDERDBLCLICKW: return HDN_DIVIDERDBLCLICKA; + default: break; } - ERR("unknown notification %x\n", unicodeNotificationCode); - assert(FALSE); - return 0; + FIXME("unknown notification %x\n", unicodeNotificationCode); + return unicodeNotificationCode; } /* forwards header notifications to listview parent */ @@ -748,12 +793,12 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, const NMHEADE /* on unicode format exit earlier */ if (infoPtr->notifyFormat == NFR_UNICODE) - return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)lpnmh->hdr.idFrom, (LPARAM)lpnmh); + return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, lpnmh->hdr.idFrom, + (LPARAM)lpnmh); /* header always supplies unicode notifications, all we have to do is to convert strings to ANSI */ - nmhA = *(NMHEADERA*)lpnmh; + nmhA = *(const NMHEADERA*)lpnmh; if (lpnmh->pitem) { hditema = *(HDITEMA*)lpnmh->pitem; @@ -778,8 +823,8 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, const NMHEADE } nmhA.hdr.code = get_ansi_notification(lpnmh->hdr.code); - ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)nmhA.hdr.idFrom, (LPARAM)&nmhA); + ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhA.hdr.idFrom, + (LPARAM)&nmhA); /* cleanup */ Free(text); @@ -1266,20 +1311,17 @@ static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) } /*** - * Creates an iterator over the items which intersect lprc. + * Creates an iterator over the items which intersect frame. + * Uses absolute coordinates rather than compensating for the current offset. */ -static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *lprc) +static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame) { - RECT frame = *lprc, rcItem, rcTemp; - POINT Origin; + RECT rcItem, rcTemp; /* in case we fail, we want to return an empty iterator */ if (!iterator_empty(i)) return FALSE; - LISTVIEW_GetOrigin(infoPtr, &Origin); - - TRACE("(lprc=%s)\n", wine_dbgstr_rect(lprc)); - OffsetRect(&frame, -Origin.x, -Origin.y); + TRACE("(frame=%s)\n", wine_dbgstr_rect(frame)); if (infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON) { @@ -1288,7 +1330,7 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons if (infoPtr->uView == LV_VIEW_ICON && infoPtr->nFocusedItem != -1) { LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcItem); - if (IntersectRect(&rcTemp, &rcItem, lprc)) + if (IntersectRect(&rcTemp, &rcItem, frame)) i->nSpecial = infoPtr->nFocusedItem; } if (!(iterator_rangesitems(i, ranges_create(50)))) return FALSE; @@ -1300,7 +1342,7 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons rcItem.top = (LONG_PTR)DPA_GetPtr(infoPtr->hdpaPosY, nItem); rcItem.right = rcItem.left + infoPtr->nItemWidth; rcItem.bottom = rcItem.top + infoPtr->nItemHeight; - if (IntersectRect(&rcTemp, &rcItem, &frame)) + if (IntersectRect(&rcTemp, &rcItem, frame)) ranges_additem(i->ranges, nItem); } return TRUE; @@ -1309,11 +1351,11 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons { RANGE range; - if (frame.left >= infoPtr->nItemWidth) return TRUE; - if (frame.top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE; + if (frame->left >= infoPtr->nItemWidth) return TRUE; + if (frame->top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE; - range.lower = max(frame.top / infoPtr->nItemHeight, 0); - range.upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; + range.lower = max(frame->top / infoPtr->nItemHeight, 0); + range.upper = min((frame->bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; if (range.upper <= range.lower) return TRUE; if (!iterator_rangeitems(i, range)) return FALSE; TRACE(" report=%s\n", debugrange(&i->range)); @@ -1321,8 +1363,8 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons else { INT nPerCol = max((infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight, 1); - INT nFirstRow = max(frame.top / infoPtr->nItemHeight, 0); - INT nLastRow = min((frame.bottom - 1) / infoPtr->nItemHeight, nPerCol - 1); + INT nFirstRow = max(frame->top / infoPtr->nItemHeight, 0); + INT nLastRow = min((frame->bottom - 1) / infoPtr->nItemHeight, nPerCol - 1); INT nFirstCol; INT nLastCol; INT lower; @@ -1331,13 +1373,13 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons if (infoPtr->nItemWidth) { - nFirstCol = max(frame.left / infoPtr->nItemWidth, 0); - nLastCol = min((frame.right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); + nFirstCol = max(frame->left / infoPtr->nItemWidth, 0); + nLastCol = min((frame->right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); } else { - nFirstCol = max(frame.left, 0); - nLastCol = min(frame.right - 1, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); + nFirstCol = max(frame->left, 0); + nLastCol = min(frame->right - 1, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); } lower = nFirstCol * nPerCol + nFirstRow; @@ -1362,6 +1404,22 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons return TRUE; } +/*** + * Creates an iterator over the items which intersect lprc. + */ +static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *lprc) +{ + RECT frame = *lprc; + POINT Origin; + + TRACE("(lprc=%s)\n", wine_dbgstr_rect(lprc)); + + LISTVIEW_GetOrigin(infoPtr, &Origin); + OffsetRect(&frame, -Origin.x, -Origin.y); + + return iterator_frameditems_absolute(i, infoPtr, &frame); +} + /*** * Creates an iterator over the items which intersect the visible region of hdc. */ @@ -1525,7 +1583,7 @@ static INT LISTVIEW_CreateHeader(LISTVIEW_INFO *infoPtr) SendMessageW(infoPtr->hwndHeader, HDM_SETUNICODEFORMAT, TRUE, 0); /* set header font */ - SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE); + SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, TRUE); LISTVIEW_UpdateSize(infoPtr); @@ -1536,6 +1594,13 @@ static inline void LISTVIEW_GetHeaderRect(const LISTVIEW_INFO *infoPtr, INT nSub { *lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader; } + +static inline BOOL LISTVIEW_IsHeaderEnabled(const LISTVIEW_INFO *infoPtr) +{ + return (infoPtr->uView == LV_VIEW_DETAILS || + infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) && + !(infoPtr->dwStyle & LVS_NOCOLUMNHEADER); +} static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem) { @@ -1683,14 +1748,15 @@ static inline INT LISTVIEW_GetCountPerColumn(const LISTVIEW_INFO *infoPtr) */ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData) { - INT nItem; - INT endidx,idx; - LVITEMW item; WCHAR buffer[MAX_PATH]; - DWORD lastKeyPressTimestamp = infoPtr->lastKeyPressTimestamp; + INT endidx, startidx; + DWORD prevTime; + LVITEMW item; + INT nItem; + INT diff; /* simple parameter checking */ - if (!charCode || !keyData) return 0; + if (!charCode || !keyData || infoPtr->nItemCount == 0) return 0; /* only allow the valid WM_CHARs through */ if (!isalnumW(charCode) && @@ -1705,86 +1771,95 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L charCode != '<' && charCode != ',' && charCode != '~') return 0; - /* if there's one item or less, there is no where to go */ - if (infoPtr->nItemCount <= 1) return 0; - /* update the search parameters */ + prevTime = infoPtr->lastKeyPressTimestamp; infoPtr->lastKeyPressTimestamp = GetTickCount(); - if (infoPtr->lastKeyPressTimestamp - lastKeyPressTimestamp < KEY_DELAY) { - if (infoPtr->nSearchParamLength < MAX_PATH-1) - infoPtr->szSearchParam[infoPtr->nSearchParamLength++]=charCode; + diff = infoPtr->lastKeyPressTimestamp - prevTime; + + if (diff >= 0 && diff < KEY_DELAY) + { + if (infoPtr->nSearchParamLength < MAX_PATH - 1) + infoPtr->szSearchParam[infoPtr->nSearchParamLength++] = charCode; + if (infoPtr->charCode != charCode) infoPtr->charCode = charCode = 0; - } else { - infoPtr->charCode=charCode; - infoPtr->szSearchParam[0]=charCode; - infoPtr->nSearchParamLength=1; - /* Redundant with the 1 char string */ - charCode=0; + } + else + { + infoPtr->charCode = charCode; + infoPtr->szSearchParam[0] = charCode; + infoPtr->nSearchParamLength = 1; + /* redundant with the 1 char string */ + charCode = 0; } /* and search from the current position */ - nItem=-1; - if (infoPtr->nFocusedItem >= 0) { - endidx=infoPtr->nFocusedItem; - idx=endidx; - /* if looking for single character match, - * then we must always move forward - */ - if (infoPtr->nSearchParamLength == 1) - idx++; - } else { - endidx=infoPtr->nItemCount; - idx=0; - } + nItem = -1; + endidx = infoPtr->nItemCount; - /* Let application handle this for virtual listview */ + /* should start from next after focused item, so next item that matches + will be selected, if there isn't any and focused matches it will be selected + on second search stage from beginning of the list */ + if (infoPtr->nFocusedItem >= 0 && infoPtr->nItemCount > 1) + startidx = infoPtr->nFocusedItem + 1; + else + startidx = 0; + + /* let application handle this for virtual listview */ if (infoPtr->dwStyle & LVS_OWNERDATA) { NMLVFINDITEMW nmlv; - LVFINDINFOW lvfi; - ZeroMemory(&lvfi, sizeof(lvfi)); - lvfi.flags = (LVFI_WRAP | LVFI_PARTIAL); - infoPtr->szSearchParam[infoPtr->nSearchParamLength] = '\0'; - lvfi.psz = infoPtr->szSearchParam; - nmlv.iStart = idx; - nmlv.lvfi = lvfi; + memset(&nmlv.lvfi, 0, sizeof(nmlv.lvfi)); + nmlv.lvfi.flags = (LVFI_WRAP | LVFI_PARTIAL); + nmlv.lvfi.psz = infoPtr->szSearchParam; + nmlv.iStart = startidx; + + infoPtr->szSearchParam[infoPtr->nSearchParamLength] = 0; nItem = notify_hdr(infoPtr, LVN_ODFINDITEMW, (LPNMHDR)&nmlv.hdr); - - if (nItem != -1) - LISTVIEW_KeySelection(infoPtr, nItem, FALSE); - - return 0; } + else + { + INT i = startidx; - do { - if (idx == infoPtr->nItemCount) { - if (endidx == infoPtr->nItemCount || endidx == 0) + /* first search in [startidx, endidx), on failure continue in [0, startidx) */ + while (1) + { + /* start from first item if not found with >= startidx */ + if (i == infoPtr->nItemCount && startidx > 0) + { + endidx = startidx; + startidx = 0; + } + + for (i = startidx; i < endidx; i++) + { + /* retrieve text */ + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = buffer; + item.cchTextMax = MAX_PATH; + if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0; + + if (lstrncmpiW(item.pszText, infoPtr->szSearchParam, infoPtr->nSearchParamLength) == 0) + { + nItem = i; + break; + } + else if (nItem == -1 && lstrncmpiW(item.pszText, infoPtr->szSearchParam, 1) == 0) + { + /* this would work but we must keep looking for a longer match */ + nItem = i; + } + } + + /* found something or second search completed with any result */ + if (nItem != -1 || endidx != infoPtr->nItemCount) break; - idx=0; - } - - /* get item */ - item.mask = LVIF_TEXT; - item.iItem = idx; - item.iSubItem = 0; - item.pszText = buffer; - item.cchTextMax = MAX_PATH; - if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0; - - /* check for a match */ - if (lstrncmpiW(item.pszText,infoPtr->szSearchParam,infoPtr->nSearchParamLength) == 0) { - nItem=idx; - break; - } else if ( (charCode != 0) && (nItem == -1) && (nItem != infoPtr->nFocusedItem) && - (lstrncmpiW(item.pszText,infoPtr->szSearchParam,1) == 0) ) { - /* This would work but we must keep looking for a longer match */ - nItem=idx; - } - idx++; - } while (idx != endidx); + }; + } if (nItem != -1) LISTVIEW_KeySelection(infoPtr, nItem, FALSE); @@ -1874,7 +1949,23 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr) if (LISTVIEW_GetViewRect(infoPtr, &rcView)) horzInfo.nMax = rcView.right - rcView.left; } - + + if (LISTVIEW_IsHeaderEnabled(infoPtr)) + { + if (DPA_GetPtrCount(infoPtr->hdpaColumns)) + { + RECT rcHeader; + INT index; + + index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, + DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0); + + LISTVIEW_GetHeaderRect(infoPtr, index, &rcHeader); + horzInfo.nMax = rcHeader.right; + TRACE("horzInfo.nMax=%d\n", horzInfo.nMax); + } + } + horzInfo.fMask = SIF_RANGE | SIF_PAGE; horzInfo.nMax = max(horzInfo.nMax - 1, 0); dx = GetScrollPos(infoPtr->hwndSelf, SB_HORZ); @@ -1924,7 +2015,7 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr) } /* Update the Header Control */ - if (infoPtr->uView == LV_VIEW_DETAILS) + if (infoPtr->hwndHeader) { horzInfo.fMask = SIF_POS; GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &horzInfo); @@ -2733,15 +2824,27 @@ static INT LISTVIEW_CalculateItemWidth(const LISTVIEW_INFO *infoPtr) } else /* LV_VIEW_SMALLICON, or LV_VIEW_LIST */ { + WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' }; + LVITEMW lvItem; INT i; - + + lvItem.mask = LVIF_TEXT; + lvItem.iSubItem = 0; + for (i = 0; i < infoPtr->nItemCount; i++) - nItemWidth = max(LISTVIEW_GetLabelWidth(infoPtr, i), nItemWidth); + { + lvItem.iItem = i; + lvItem.pszText = szDispText; + lvItem.cchTextMax = DISP_TEXT_SIZE; + if (LISTVIEW_GetItemW(infoPtr, &lvItem)) + nItemWidth = max(LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE), + nItemWidth); + } if (infoPtr->himlSmall) nItemWidth += infoPtr->iconSize.cx; if (infoPtr->himlState) nItemWidth += infoPtr->iconStateSize.cx; - nItemWidth = max(DEFAULT_COLUMN_WIDTH, nItemWidth + WIDTH_PADDING); + nItemWidth = max(DEFAULT_COLUMN_WIDTH, nItemWidth + WIDTH_PADDING); } return nItemWidth; @@ -2862,11 +2965,7 @@ static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags) return cmp; } -#if DEBUG_RANGES -#define ranges_check(ranges, desc) ranges_assert(ranges, desc, __FUNCTION__, __LINE__) -#else -#define ranges_check(ranges, desc) do { } while(0) -#endif +#define ranges_check(ranges, desc) if (TRACE_ON(listview)) ranges_assert(ranges, desc, __FUNCTION__, __LINE__) static void ranges_assert(RANGES ranges, LPCSTR desc, const char *func, int line) { @@ -3091,28 +3190,30 @@ static BOOL ranges_del(RANGES ranges, RANGE range) TRACE("(%s)\n", debugrange(&range)); ranges_check(ranges, "before del"); - + /* we don't use DPAS_SORTED here, since we need * * to find the first overlapping range */ index = DPA_Search(ranges->hdpa, &range, 0, ranges_cmp, 0, 0); - while(index != -1) + while(index != -1) { chkrgn = DPA_GetPtr(ranges->hdpa, index); - - TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); + + TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); /* case 1: Same range */ if ( (chkrgn->upper == range.upper) && (chkrgn->lower == range.lower) ) { DPA_DeletePtr(ranges->hdpa, index); + Free(chkrgn); break; } /* case 2: engulf */ else if ( (chkrgn->upper <= range.upper) && - (chkrgn->lower >= range.lower) ) + (chkrgn->lower >= range.lower) ) { DPA_DeletePtr(ranges->hdpa, index); + Free(chkrgn); } /* case 3: overlap upper */ else if ( (chkrgn->upper <= range.upper) && @@ -3536,7 +3637,7 @@ static BOOL LISTVIEW_GetItemAtPt(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVIte return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE); } -static inline BOOL LISTVIEW_isHotTracking(const LISTVIEW_INFO *infoPtr) +static inline BOOL LISTVIEW_IsHotTracking(const LISTVIEW_INFO *infoPtr) { return ((infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) || (infoPtr->dwLvExStyle & LVS_EX_ONECLICKACTIVATE) || @@ -3561,9 +3662,13 @@ static inline BOOL LISTVIEW_isHotTracking(const LISTVIEW_INFO *infoPtr) * over the item for a certain period of time. * */ -static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, INT y) +static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, INT x, INT y) { - if (LISTVIEW_isHotTracking(infoPtr)) + NMHDR hdr; + + if (notify_hdr(infoPtr, NM_HOVER, &hdr)) return 0; + + if (LISTVIEW_IsHotTracking(infoPtr)) { LVITEMW item; POINT pt; @@ -3573,11 +3678,204 @@ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, I if (LISTVIEW_GetItemAtPt(infoPtr, &item, pt)) LISTVIEW_SetSelection(infoPtr, item.iItem); + + SetFocus(infoPtr->hwndSelf); } return 0; } +#define SCROLL_LEFT 0x1 +#define SCROLL_RIGHT 0x2 +#define SCROLL_UP 0x4 +#define SCROLL_DOWN 0x8 + +/*** + * DESCRIPTION: + * Utility routine to draw and highlight items within a marquee selection rectangle. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] coords_orig : original co-ordinates of the cursor + * [I] coords_offs : offsetted coordinates of the cursor + * [I] offset : offset amount + * [I] scroll : Bitmask of which directions we should scroll, if at all + * + * RETURN: + * None. + */ +static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, LPPOINT coords_orig, LPPOINT coords_offs, LPPOINT offset, INT scroll) +{ + BOOL controlDown = FALSE; + LVITEMW item; + ITERATOR i; + RECT rect; + + if (coords_offs->x > infoPtr->marqueeOrigin.x) + { + rect.left = infoPtr->marqueeOrigin.x; + rect.right = coords_offs->x; + } + else + { + rect.left = coords_offs->x; + rect.right = infoPtr->marqueeOrigin.x; + } + + if (coords_offs->y > infoPtr->marqueeOrigin.y) + { + rect.top = infoPtr->marqueeOrigin.y; + rect.bottom = coords_offs->y; + } + else + { + rect.top = coords_offs->y; + rect.bottom = infoPtr->marqueeOrigin.y; + } + + /* Cancel out the old marquee rectangle and draw the new one */ + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); + + /* Scroll by the appropriate distance if applicable - speed up scrolling as + the cursor is further away */ + + if ((scroll & SCROLL_LEFT) && (coords_orig->x <= 0)) + LISTVIEW_Scroll(infoPtr, coords_orig->x, 0); + + if ((scroll & SCROLL_RIGHT) && (coords_orig->x >= infoPtr->rcList.right)) + LISTVIEW_Scroll(infoPtr, (coords_orig->x - infoPtr->rcList.right), 0); + + if ((scroll & SCROLL_UP) && (coords_orig->y <= 0)) + LISTVIEW_Scroll(infoPtr, 0, coords_orig->y); + + if ((scroll & SCROLL_DOWN) && (coords_orig->y >= infoPtr->rcList.bottom)) + LISTVIEW_Scroll(infoPtr, 0, (coords_orig->y - infoPtr->rcList.bottom)); + + /* Invert the items in the old marquee rectangle */ + iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect); + + while (iterator_next(&i)) + { + if (i.nItem > -1) + { + if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED) == LVIS_SELECTED) + item.state = 0; + else + item.state = LVIS_SELECTED; + + item.stateMask = LVIS_SELECTED; + + LISTVIEW_SetItemState(infoPtr, i.nItem, &item); + } + } + + iterator_destroy(&i); + + CopyRect(&infoPtr->marqueeRect, &rect); + + CopyRect(&infoPtr->marqueeDrawRect, &rect); + OffsetRect(&infoPtr->marqueeDrawRect, offset->x, offset->y); + + /* Iterate over the items within our marquee rectangle */ + iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect); + + if (GetKeyState(VK_CONTROL) & 0x8000) + controlDown = TRUE; + + while (iterator_next(&i)) + { + if (i.nItem > -1) + { + /* If CTRL is pressed, invert. If not, always select the item. */ + if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED))) + item.state = 0; + else + item.state = LVIS_SELECTED; + + item.stateMask = LVIS_SELECTED; + + LISTVIEW_SetItemState(infoPtr, i.nItem, &item); + } + } + + iterator_destroy(&i); + LISTVIEW_InvalidateRect(infoPtr, &rect); +} + +/*** + * DESCRIPTION: + * Called when we are in a marquee selection that involves scrolling the listview (ie, + * the cursor is outside the bounds of the client area). This is a TIMERPROC. + * + * PARAMETER(S): + * [I] hwnd : Handle to the listview + * [I] uMsg : WM_TIMER (ignored) + * [I] idEvent : The timer ID interpreted as a pointer to a LISTVIEW_INFO struct + * [I] dwTimer : The elapsed time (ignored) + * + * RETURN: + * None. + */ +static VOID CALLBACK LISTVIEW_ScrollTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + LISTVIEW_INFO *infoPtr; + SCROLLINFO scrollInfo; + POINT coords_orig; + POINT coords_offs; + POINT offset; + INT scroll = 0; + + infoPtr = (LISTVIEW_INFO *) idEvent; + + if (!infoPtr) + return; + + /* Get the current cursor position and convert to client coordinates */ + GetCursorPos(&coords_orig); + ScreenToClient(hWnd, &coords_orig); + + /* Ensure coordinates are within client bounds */ + coords_offs.x = max(min(coords_orig.x, infoPtr->rcList.right), 0); + coords_offs.y = max(min(coords_orig.y, infoPtr->rcList.bottom), 0); + + /* Get offset */ + LISTVIEW_GetOrigin(infoPtr, &offset); + + /* Offset coordinates by the appropriate amount */ + coords_offs.x -= offset.x; + coords_offs.y -= offset.y; + + scrollInfo.cbSize = sizeof(SCROLLINFO); + scrollInfo.fMask = SIF_ALL; + + /* Work out in which directions we can scroll */ + if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) + { + if (scrollInfo.nPos != scrollInfo.nMin) + scroll |= SCROLL_UP; + + if (((scrollInfo.nPage + scrollInfo.nPos) - 1) != scrollInfo.nMax) + scroll |= SCROLL_DOWN; + } + + if (GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) + { + if (scrollInfo.nPos != scrollInfo.nMin) + scroll |= SCROLL_LEFT; + + if (((scrollInfo.nPage + scrollInfo.nPos) - 1) != scrollInfo.nMax) + scroll |= SCROLL_RIGHT; + } + + if (((coords_orig.x <= 0) && (scroll & SCROLL_LEFT)) || + ((coords_orig.y <= 0) && (scroll & SCROLL_UP)) || + ((coords_orig.x >= infoPtr->rcList.right) && (scroll & SCROLL_RIGHT)) || + ((coords_orig.y >= infoPtr->rcList.bottom) && (scroll & SCROLL_DOWN))) + { + LISTVIEW_MarqueeHighlight(infoPtr, &coords_orig, &coords_offs, &offset, scroll); + } +} + /*** * DESCRIPTION: * Called whenever WM_MOUSEMOVE is received. @@ -3592,8 +3890,6 @@ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, I */ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, INT y) { - TRACKMOUSEEVENT trackinfo; - if (!(fwKeys & MK_LBUTTON)) infoPtr->bLButtonDown = FALSE; @@ -3605,6 +3901,48 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN WORD wDragWidth = GetSystemMetrics(SM_CXDRAG); WORD wDragHeight= GetSystemMetrics(SM_CYDRAG); + if (infoPtr->bMarqueeSelect) + { + POINT coords_orig; + POINT coords_offs; + POINT offset; + + coords_orig.x = x; + coords_orig.y = y; + + /* Get offset */ + LISTVIEW_GetOrigin(infoPtr, &offset); + + /* Ensure coordinates are within client bounds */ + coords_offs.x = max(min(x, infoPtr->rcList.right), 0); + coords_offs.y = max(min(y, infoPtr->rcList.bottom), 0); + + /* Offset coordinates by the appropriate amount */ + coords_offs.x -= offset.x; + coords_offs.y -= offset.y; + + /* Enable the timer if we're going outside our bounds, in case the user doesn't + move the mouse again */ + + if ((x <= 0) || (y <= 0) || (x >= infoPtr->rcList.right) || + (y >= infoPtr->rcList.bottom)) + { + if (!infoPtr->bScrolling) + { + infoPtr->bScrolling = TRUE; + SetTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr, 1, LISTVIEW_ScrollTimer); + } + } + else + { + infoPtr->bScrolling = FALSE; + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); + } + + LISTVIEW_MarqueeHighlight(infoPtr, &coords_orig, &coords_offs, &offset, 0); + return 0; + } + rect.left = infoPtr->ptClickPos.x - wDragWidth; rect.right = infoPtr->ptClickPos.x + wDragWidth; rect.top = infoPtr->ptClickPos.y - wDragHeight; @@ -3640,17 +3978,42 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN if (!infoPtr->bDragging) { - NMLISTVIEW nmlv; - lvHitTestInfo.pt = infoPtr->ptClickPos; LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE); - ZeroMemory(&nmlv, sizeof(nmlv)); - nmlv.iItem = lvHitTestInfo.iItem; - nmlv.ptAction = infoPtr->ptClickPos; + /* If the click is outside the range of an item, begin a + highlight. If not, begin an item drag. */ + if (lvHitTestInfo.iItem == -1) + { + NMHDR hdr; - notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); - infoPtr->bDragging = TRUE; + /* If we're allowing multiple selections, send notification. + If return value is non-zero, cancel. */ + if (!(infoPtr->dwStyle & LVS_SINGLESEL) && (notify_hdr(infoPtr, LVN_MARQUEEBEGIN, &hdr) == 0)) + { + /* Store the absolute coordinates of the click */ + POINT offset; + LISTVIEW_GetOrigin(infoPtr, &offset); + + infoPtr->marqueeOrigin.x = infoPtr->ptClickPos.x - offset.x; + infoPtr->marqueeOrigin.y = infoPtr->ptClickPos.y - offset.y; + + /* Begin selection and capture mouse */ + infoPtr->bMarqueeSelect = TRUE; + SetCapture(infoPtr->hwndSelf); + } + } + else + { + NMLISTVIEW nmlv; + + ZeroMemory(&nmlv, sizeof(nmlv)); + nmlv.iItem = lvHitTestInfo.iItem; + nmlv.ptAction = infoPtr->ptClickPos; + + notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); + infoPtr->bDragging = TRUE; + } } return 0; @@ -3658,18 +4021,19 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN } /* see if we are supposed to be tracking mouse hovering */ - if (LISTVIEW_isHotTracking(infoPtr)) { - /* fill in the trackinfo struct */ + if (LISTVIEW_IsHotTracking(infoPtr)) { + TRACKMOUSEEVENT trackinfo; + trackinfo.cbSize = sizeof(TRACKMOUSEEVENT); trackinfo.dwFlags = TME_QUERY; - trackinfo.hwndTrack = infoPtr->hwndSelf; - trackinfo.dwHoverTime = infoPtr->dwHoverTime; /* see if we are already tracking this hwnd */ _TrackMouseEvent(&trackinfo); - if(!(trackinfo.dwFlags & TME_HOVER)) { - trackinfo.dwFlags = TME_HOVER; + if(!(trackinfo.dwFlags & TME_HOVER) || trackinfo.hwndTrack != infoPtr->hwndSelf) { + trackinfo.dwFlags = TME_HOVER; + trackinfo.dwHoverTime = infoPtr->dwHoverTime; + trackinfo.hwndTrack = infoPtr->hwndSelf; /* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */ _TrackMouseEvent(&trackinfo); @@ -3914,12 +4278,11 @@ static BOOL set_sub_item(const LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, *bChanged = TRUE; } - if (lpLVItem->mask & LVIF_IMAGE) - if (lpSubItem->hdr.iImage != lpLVItem->iImage) - { - lpSubItem->hdr.iImage = lpLVItem->iImage; - *bChanged = TRUE; - } + if ((lpLVItem->mask & LVIF_IMAGE) && (lpSubItem->hdr.iImage != lpLVItem->iImage)) + { + lpSubItem->hdr.iImage = lpLVItem->iImage; + *bChanged = TRUE; + } if ((lpLVItem->mask & LVIF_TEXT) && textcmpWT(lpSubItem->hdr.pszText, lpLVItem->pszText, isW)) { @@ -4089,7 +4452,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; if (nSubItem == 0) lvItem.mask |= LVIF_STATE; if (infoPtr->uView == LV_VIEW_DETAILS) lvItem.mask |= LVIF_INDENT; - lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK; + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT; lvItem.iItem = nItem; lvItem.iSubItem = nSubItem; lvItem.state = 0; @@ -4192,14 +4555,23 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS } } - /* small icons */ + /* item icons */ himl = (infoPtr->uView == LV_VIEW_ICON ? infoPtr->himlNormal : infoPtr->himlSmall); if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon)) { + UINT style; + TRACE("iImage=%d\n", lvItem.iImage); + + if (lvItem.state & (LVIS_SELECTED | LVIS_CUT) && infoPtr->bFocus) + style = ILD_SELECTED; + else + style = ILD_NORMAL; + ImageList_DrawEx(himl, lvItem.iImage, hdc, rcIcon.left, rcIcon.top, - rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, infoPtr->clrBk, CLR_DEFAULT, - (lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus) ? ILD_SELECTED : ILD_NORMAL); + rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, infoPtr->clrBk, + lvItem.state & LVIS_CUT ? RGB(255, 255, 255) : CLR_DEFAULT, + style); } /* Don't bother painting item being edited */ @@ -4643,6 +5015,10 @@ enddraw: if ((infoPtr->uView == LV_VIEW_DETAILS) && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) LISTVIEW_RefreshReportGrid(infoPtr, hdc); + /* Draw marquee rectangle if appropriate */ + if (infoPtr->bMarqueeSelect) + DrawFocusRect(hdc, &infoPtr->marqueeDrawRect); + if (cdmode & CDRF_NOTIFYPOSTPAINT) notify_postpaint(infoPtr, &nmlvcd); @@ -4744,10 +5120,46 @@ static DWORD LISTVIEW_ApproximateViewRect(const LISTVIEW_INFO *infoPtr, INT nIte dwViewRect = MAKELONG(wWidth, wHeight); } + else if (infoPtr->uView == LV_VIEW_ICON) + { + UINT rows,cols; + UINT nItemWidth; + UINT nItemHeight; + + nItemWidth = infoPtr->iconSpacing.cx; + nItemHeight = infoPtr->iconSpacing.cy; + + if (nItemCount == -1) + nItemCount = infoPtr->nItemCount; + + if (wWidth == 0xffff) + wWidth = infoPtr->rcList.right - infoPtr->rcList.left; + + if (wWidth < nItemWidth) + wWidth = nItemWidth; + + cols = wWidth / nItemWidth; + if (cols > nItemCount) + cols = nItemCount; + if (cols < 1) + cols = 1; + + if (nItemCount) + { + rows = nItemCount / cols; + if (nItemCount % cols) + rows++; + } + else + rows = 0; + + wHeight = (nItemHeight * rows)+2; + wWidth = (nItemWidth * cols)+2; + + dwViewRect = MAKELONG(wWidth, wHeight); + } else if (infoPtr->uView == LV_VIEW_SMALLICON) FIXME("uView == LV_VIEW_SMALLICON: not implemented\n"); - else if (infoPtr->uView == LV_VIEW_ICON) - FIXME("uView == LV_VIEW_ICON: not implemented\n"); return dwViewRect; } @@ -4764,11 +5176,14 @@ static DWORD LISTVIEW_ApproximateViewRect(const LISTVIEW_INFO *infoPtr, INT nIte */ static LRESULT LISTVIEW_CancelEditLabel(LISTVIEW_INFO *infoPtr) { - /* handle value will be lost after LISTVIEW_EndEditLabelT */ - HWND edit = infoPtr->hwndEdit; + if (infoPtr->hwndEdit) + { + /* handle value will be lost after LISTVIEW_EndEditLabelT */ + HWND edit = infoPtr->hwndEdit; - LISTVIEW_EndEditLabelT(infoPtr, TRUE, IsWindowUnicode(infoPtr->hwndEdit)); - SendMessageW(edit, WM_CLOSE, 0, 0); + LISTVIEW_EndEditLabelT(infoPtr, TRUE, IsWindowUnicode(infoPtr->hwndEdit)); + SendMessageW(edit, WM_CLOSE, 0, 0); + } return TRUE; } @@ -4795,7 +5210,7 @@ static HIMAGELIST LISTVIEW_CreateDragImage(LISTVIEW_INFO *infoPtr, INT iItem, LP HIMAGELIST dragList = 0; TRACE("iItem=%d Count=%d\n", iItem, infoPtr->nItemCount); - if (iItem < 0 || iItem >= infoPtr->nItemCount) + if (iItem < 0 || iItem >= infoPtr->nItemCount || !lppt) return 0; rcItem.left = LVIR_BOUNDS; @@ -4855,6 +5270,8 @@ static BOOL LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr, BOOL destroy) HDPA hdpaSubItems = NULL; BOOL bSuppress; ITEMHDR *hdrItem; + ITEM_INFO *lpItem; + ITEM_ID *lpID; INT i, j; TRACE("()\n"); @@ -4876,13 +5293,20 @@ static BOOL LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr, BOOL destroy) { if (!(infoPtr->dwStyle & LVS_OWNERDATA)) { - /* send LVN_DELETEITEM notification, if not suppressed - and if it is not a virtual listview */ - if (!bSuppress) notify_deleteitem(infoPtr, i); - hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, i); + /* send LVN_DELETEITEM notification, if not suppressed + and if it is not a virtual listview */ + if (!bSuppress) notify_deleteitem(infoPtr, i); + hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, i); + lpItem = DPA_GetPtr(hdpaSubItems, 0); + /* free id struct */ + j = DPA_GetPtrIndex(infoPtr->hdpaItemIds, lpItem->id); + lpID = DPA_GetPtr(infoPtr->hdpaItemIds, j); + DPA_DeletePtr(infoPtr->hdpaItemIds, j); + Free(lpID); + /* both item and subitem start with ITEMHDR header */ for (j = 0; j < DPA_GetPtrCount(hdpaSubItems); j++) { - hdrItem = DPA_GetPtr(hdpaSubItems, j); + hdrItem = DPA_GetPtr(hdpaSubItems, j); if (is_textW(hdrItem->pszText)) Free(hdrItem->pszText); Free(hdrItem); } @@ -5212,6 +5636,7 @@ static BOOL LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem) static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL isW) { HWND hwndSelf = infoPtr->hwndSelf; + WCHAR szDispText[DISP_TEXT_SIZE] = { 0 }; NMLVDISPINFOW dispInfo; INT editedItem = infoPtr->nEditLabelItem; BOOL bSame; @@ -5242,7 +5667,9 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL dispInfo.item.iItem = editedItem; dispInfo.item.iSubItem = 0; dispInfo.item.stateMask = ~0; - if (!LISTVIEW_GetItemW(infoPtr, &dispInfo.item)) + dispInfo.item.pszText = szDispText; + dispInfo.item.cchTextMax = DISP_TEXT_SIZE; + if (!LISTVIEW_GetItemT(infoPtr, &dispInfo.item, isW)) { res = FALSE; goto cleanup; @@ -5256,16 +5683,11 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL bSame = (lstrcmpW(dispInfo.item.pszText, tmp) == 0); textfreeT(tmp, FALSE); } - if (bSame) - { - res = TRUE; - goto cleanup; - } /* add the text from the edit in */ dispInfo.item.mask |= LVIF_TEXT; - dispInfo.item.pszText = pszText; - dispInfo.item.cchTextMax = textlenT(pszText, isW); + dispInfo.item.pszText = bSame ? NULL : pszText; + dispInfo.item.cchTextMax = bSame ? 0 : textlenT(pszText, isW); /* Do we need to update the Item Text */ if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) @@ -5279,6 +5701,11 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL goto cleanup; } if (!pszText) return TRUE; + if (bSame) + { + res = TRUE; + goto cleanup; + } if (!(infoPtr->dwStyle & LVS_OWNERDATA)) { @@ -5306,6 +5733,133 @@ cleanup: return res; } +/*** + * DESCRIPTION: + * Subclassed edit control windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * [I] isW : TRUE if input is Unicode + * + * RETURN: + * Zero. + */ +static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL isW) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0); + BOOL save = TRUE; + + TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx, isW=%d)\n", + hwnd, uMsg, wParam, lParam, isW); + + switch (uMsg) + { + case WM_GETDLGCODE: + return DLGC_WANTARROWS | DLGC_WANTALLKEYS; + + case WM_DESTROY: + { + WNDPROC editProc = infoPtr->EditWndProc; + infoPtr->EditWndProc = 0; + SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc); + return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW); + } + + case WM_KEYDOWN: + if (VK_ESCAPE == (INT)wParam) + { + save = FALSE; + break; + } + else if (VK_RETURN == (INT)wParam) + break; + + default: + return CallWindowProcT(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam, isW); + } + + /* kill the edit */ + if (infoPtr->hwndEdit) + LISTVIEW_EndEditLabelT(infoPtr, save, isW); + + SendMessageW(hwnd, WM_CLOSE, 0, 0); + return 0; +} + +/*** + * DESCRIPTION: + * Subclassed edit control Unicode windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * + * RETURN: + */ +static LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE); +} + +/*** + * DESCRIPTION: + * Subclassed edit control ANSI windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * + * RETURN: + */ +static LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE); +} + +/*** + * DESCRIPTION: + * Creates a subclassed edit control + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] text : initial text for the edit + * [I] style : the window style + * [I] isW : TRUE if input is Unicode + * + * RETURN: + */ +static HWND CreateEditLabelT(LISTVIEW_INFO *infoPtr, LPCWSTR text, BOOL isW) +{ + static const DWORD style = WS_CHILDWINDOW|WS_CLIPSIBLINGS|ES_LEFT|ES_AUTOHSCROLL|WS_BORDER|WS_VISIBLE; + HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE); + HWND hedit; + + TRACE("(%p, text=%s, isW=%d)\n", infoPtr, debugtext_t(text, isW), isW); + + /* Window will be resized and positioned after LVN_BEGINLABELEDIT */ + if (isW) + hedit = CreateWindowW(WC_EDITW, text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); + else + hedit = CreateWindowA(WC_EDITA, (LPCSTR)text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); + + if (!hedit) return 0; + + infoPtr->EditWndProc = (WNDPROC) + (isW ? SetWindowLongPtrW(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcW) : + SetWindowLongPtrA(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcA) ); + + SendMessageW(hedit, WM_SETFONT, (WPARAM)infoPtr->hFont, FALSE); + + return hedit; +} + /*** * DESCRIPTION: * Begin in place editing of specified list view item @@ -5361,7 +5915,7 @@ static HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *infoPtr, INT nItem, BOOL isW) dispInfo.item.cchTextMax = DISP_TEXT_SIZE; if (!LISTVIEW_GetItemT(infoPtr, &dispInfo.item, isW)) return 0; - infoPtr->hwndEdit = CreateEditLabelT(infoPtr, dispInfo.item.pszText, WS_VISIBLE, isW); + infoPtr->hwndEdit = CreateEditLabelT(infoPtr, dispInfo.item.pszText, isW); if (!infoPtr->hwndEdit) return 0; if (notify_dispinfoT(infoPtr, LVN_BEGINLABELEDITW, &dispInfo, isW)) @@ -5525,7 +6079,8 @@ static INT LISTVIEW_FindItemW(const LISTVIEW_INFO *infoPtr, INT nStart, if (!lpFindInfo || nItem < 0) return -1; lvItem.mask = 0; - if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL)) + if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL) || + lpFindInfo->flags & LVFI_SUBSTRING) { lvItem.mask |= LVIF_TEXT; lvItem.pszText = szDispText; @@ -5586,12 +6141,13 @@ again: else continue; } - + if (lvItem.mask & LVIF_TEXT) { - if (lpFindInfo->flags & LVFI_PARTIAL) + if (lpFindInfo->flags & (LVFI_PARTIAL | LVFI_SUBSTRING)) { - if (strstrW(lvItem.pszText, lpFindInfo->psz) == NULL) continue; + WCHAR *p = strstrW(lvItem.pszText, lpFindInfo->psz); + if (!p || p != lvItem.pszText) continue; } else { @@ -5600,7 +6156,7 @@ again: } if (!bNearest) return nItem; - + /* This is very inefficient. To do a good job here, * we need a sorted array of (x,y) item positions */ LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position); @@ -5645,7 +6201,8 @@ again: static INT LISTVIEW_FindItemA(const LISTVIEW_INFO *infoPtr, INT nStart, const LVFINDINFOA *lpFindInfo) { - BOOL hasText = lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL); + BOOL hasText = lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL) || + lpFindInfo->flags & LVFI_SUBSTRING; LVFINDINFOW fiw; INT res; LPWSTR strW = NULL; @@ -5842,8 +6399,13 @@ static HIMAGELIST LISTVIEW_GetImageList(const LISTVIEW_INFO *infoPtr, INT nImage switch (nImageList) { case LVSIL_NORMAL: return infoPtr->himlNormal; - case LVSIL_SMALL: return infoPtr->himlSmall; - case LVSIL_STATE: return infoPtr->himlState; + case LVSIL_SMALL: return infoPtr->himlSmall; + case LVSIL_STATE: return infoPtr->himlState; + case LVSIL_GROUPHEADER: + FIXME("LVSIL_GROUPHEADER not supported\n"); + break; + default: + WARN("got unknown imagelist index - %d\n", nImageList); } return NULL; } @@ -6000,7 +6562,7 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, if (isubitem) { - SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, isubitem); + SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, isubitem); pItemHdr = lpSubItem ? &lpSubItem->hdr : &callbackHdr; if (!lpSubItem) { @@ -6384,7 +6946,7 @@ static BOOL LISTVIEW_GetItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPRECT */ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) { - POINT Position; + POINT Position, Origin; LVITEMW lvItem; INT nColumn; @@ -6392,7 +6954,7 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR nColumn = lprc->top; - TRACE("(nItem=%d, nSubItem=%d)\n", nItem, lprc->top); + TRACE("(nItem=%d, nSubItem=%d, type=%d)\n", nItem, lprc->top, lprc->left); /* On WinNT, a subitem of '0' calls LISTVIEW_GetItemRect */ if (lprc->top == 0) return LISTVIEW_GetItemRect(infoPtr, nItem, lprc); @@ -6418,6 +6980,7 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR } if (!LISTVIEW_GetItemPosition(infoPtr, nItem, &Position)) return FALSE; + LISTVIEW_GetOrigin(infoPtr, &Origin); if (nColumn < 0 || nColumn >= DPA_GetPtrCount(infoPtr->hdpaColumns)) return FALSE; @@ -6425,7 +6988,6 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR lvItem.iItem = nItem; lvItem.iSubItem = nColumn; - if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE; switch(lprc->left) { case LVIR_ICON: @@ -6442,39 +7004,12 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR return FALSE; } - OffsetRect(lprc, 0, Position.y); + OffsetRect(lprc, Origin.x, Position.y); + TRACE("return rect %s\n", wine_dbgstr_rect(lprc)); + return TRUE; } - -/*** - * DESCRIPTION: - * Retrieves the width of a label. - * - * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure - * - * RETURN: - * SUCCESS : string width (in pixels) - * FAILURE : zero - */ -static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *infoPtr, INT nItem) -{ - WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' }; - LVITEMW lvItem; - - TRACE("(nItem=%d)\n", nItem); - - lvItem.mask = LVIF_TEXT; - lvItem.iItem = nItem; - lvItem.iSubItem = 0; - lvItem.pszText = szDispText; - lvItem.cchTextMax = DISP_TEXT_SIZE; - if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return 0; - - return LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE); -} - /*** * DESCRIPTION: * Retrieves the spacing between listview control items. @@ -6918,6 +7453,14 @@ static INT LISTVIEW_HitTest(const LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, } } TRACE("lpht->iSubItem=%d\n", lpht->iSubItem); + + /* if we're outside horizontal columns bounds there's nothing to test further */ + if (lpht->iSubItem == -1) + { + lpht->iItem = -1; + lpht->flags = LVHT_NOWHERE; + return -1; + } } TRACE("lpht->flags=0x%x\n", lpht->flags); @@ -7067,9 +7610,9 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, while (i < infoPtr->nItemCount) { hItem = DPA_GetPtr( infoPtr->hdpaItems, i); - item_s = (ITEM_INFO*)DPA_GetPtr(hItem, 0); + item_s = DPA_GetPtr(hItem, 0); - cmpv = textcmpWT(item_s->hdr.pszText, lpLVItem->pszText, TRUE); + cmpv = textcmpWT(item_s->hdr.pszText, lpLVItem->pszText, isW); if (infoPtr->dwStyle & LVS_SORTDESCENDING) cmpv *= -1; if (cmpv >= 0) break; @@ -7451,7 +7994,7 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, /* insert item in header control */ nNewColumn = SendMessageW(infoPtr->hwndHeader, isW ? HDM_INSERTITEMW : HDM_INSERTITEMA, - (WPARAM)nColumn, (LPARAM)&hdi); + nColumn, (LPARAM)&hdi); if (nNewColumn == -1) return -1; if (nNewColumn != nColumn) ERR("nColumn=%d, nNewColumn=%d\n", nColumn, nNewColumn); @@ -7470,7 +8013,14 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, SUBITEM_INFO *lpSubItem; HDPA hdpaSubItems; INT nItem, i; - + LVITEMW item; + BOOL changed; + + item.iSubItem = nNewColumn; + item.mask = LVIF_TEXT | LVIF_IMAGE; + item.iImage = I_IMAGECALLBACK; + item.pszText = LPSTR_TEXTCALLBACKW; + for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) { hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, nItem); @@ -7480,6 +8030,10 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, if (lpSubItem->iSubItem >= nNewColumn) lpSubItem->iSubItem++; } + + /* add new subitem for each item */ + item.iItem = nItem; + set_sub_item(infoPtr, &item, isW, &changed); } } @@ -7534,7 +8088,7 @@ static BOOL LISTVIEW_SetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn, column_fill_hditem(infoPtr, &hdi, nColumn, lpColumn, isW); /* set header item attributes */ - bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, (WPARAM)nColumn, (LPARAM)&hdi); + bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, nColumn, (LPARAM)&hdi); if (!bResult) return FALSE; if (lpColumn->mask & LVCF_FMT) @@ -7774,10 +8328,18 @@ static DWORD LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwM LISTVIEW_SetItemState(infoPtr, -1, &item); himl = LISTVIEW_CreateCheckBoxIL(infoPtr); + if(!(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) + ImageList_Destroy(infoPtr->himlState); } - LISTVIEW_SetImageList(infoPtr, LVSIL_STATE, himl); + himl = LISTVIEW_SetImageList(infoPtr, LVSIL_STATE, himl); + /* checkbox list replaces prevous custom list or... */ + if(((infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES) && + !(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) || + /* ...previous was checkbox list */ + (dwOldExStyle & LVS_EX_CHECKBOXES)) + ImageList_Destroy(himl); } - + if((infoPtr->dwLvExStyle ^ dwOldExStyle) & LVS_EX_HEADERDRAGDROP) { DWORD dwStyle; @@ -7805,6 +8367,16 @@ static DWORD LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwM LISTVIEW_SetBkColor(infoPtr, CLR_NONE); } + if((infoPtr->dwLvExStyle ^ dwOldExStyle) & LVS_EX_HEADERINALLVIEWS) + { + if (infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) + LISTVIEW_CreateHeader(infoPtr); + else + ShowWindow(infoPtr->hwndHeader, SW_HIDE); + LISTVIEW_UpdateSize(infoPtr); + LISTVIEW_UpdateScroll(infoPtr); + } + LISTVIEW_InvalidateList(infoPtr); return dwOldExStyle; } @@ -8105,34 +8677,35 @@ static BOOL LISTVIEW_SetItemCount(LISTVIEW_INFO *infoPtr, INT nItems, DWORD dwFl * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt) +static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT *pt) { - POINT Origin; + POINT Origin, Pt; - TRACE("(nItem=%d, &pt=%s\n", nItem, wine_dbgstr_point(&pt)); + TRACE("(nItem=%d, pt=%s\n", nItem, wine_dbgstr_point(pt)); - if (nItem < 0 || nItem >= infoPtr->nItemCount || + if (!pt || nItem < 0 || nItem >= infoPtr->nItemCount || !(infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON)) return FALSE; + Pt = *pt; LISTVIEW_GetOrigin(infoPtr, &Origin); /* This point value seems to be an undocumented feature. * The best guess is that it means either at the origin, * or at true beginning of the list. I will assume the origin. */ - if ((pt.x == -1) && (pt.y == -1)) - pt = Origin; + if ((Pt.x == -1) && (Pt.y == -1)) + Pt = Origin; if (infoPtr->uView == LV_VIEW_ICON) { - pt.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; - pt.y -= ICON_TOP_PADDING; + Pt.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; + Pt.y -= ICON_TOP_PADDING; } - pt.x -= Origin.x; - pt.y -= Origin.y; + Pt.x -= Origin.x; + Pt.y -= Origin.y; infoPtr->bAutoarrange = FALSE; - return LISTVIEW_MoveIconTo(infoPtr, nItem, &pt, FALSE); + return LISTVIEW_MoveIconTo(infoPtr, nItem, &Pt, FALSE); } /*** @@ -8671,7 +9244,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING); infoPtr->nEditLabelItem = -1; infoPtr->nLButtonDownItem = -1; - infoPtr->dwHoverTime = -1; /* default system hover time */ + infoPtr->dwHoverTime = HOVER_DEFAULT; /* default system hover time */ infoPtr->nMeasureItemHeight = 0; infoPtr->xTrackLine = -1; /* no track line */ infoPtr->itemEdit.fEnabled = FALSE; @@ -8728,7 +9301,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) map_style_view(infoPtr); infoPtr->notifyFormat = SendMessageW(infoPtr->hwndNotify, WM_NOTIFYFORMAT, - (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY); + (WPARAM)infoPtr->hwndSelf, NF_QUERY); /* on error defaulting to ANSI notifications */ if (infoPtr->notifyFormat == 0) infoPtr->notifyFormat = NFR_ANSI; @@ -8772,10 +9345,14 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) * Success: 0 * Failure: -1 */ -static LRESULT LISTVIEW_Destroy(const LISTVIEW_INFO *infoPtr) +static LRESULT LISTVIEW_Destroy(LISTVIEW_INFO *infoPtr) { HTHEME theme = GetWindowTheme(infoPtr->hwndSelf); CloseThemeData(theme); + + /* delete all items */ + LISTVIEW_DeleteAllItems(infoPtr, TRUE); + return 0; } @@ -8791,7 +9368,7 @@ static LRESULT LISTVIEW_Destroy(const LISTVIEW_INFO *infoPtr) * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_Enable(const LISTVIEW_INFO *infoPtr, BOOL bEnable) +static BOOL LISTVIEW_Enable(const LISTVIEW_INFO *infoPtr) { if (infoPtr->dwStyle & LVS_OWNERDRAWFIXED) InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); @@ -9045,37 +9622,32 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode, scrollInfo.fMask = SIF_POS; scrollInfo.nPos = nNewScrollPos; nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE); - + /* carry on only if it really changed */ if (nNewScrollPos == nOldScrollPos) return 0; - - if (infoPtr->uView == LV_VIEW_DETAILS) - LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); - + + if (infoPtr->hwndHeader) LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); + /* now adjust to client coordinates */ nScrollDiff = nOldScrollPos - nNewScrollPos; if (infoPtr->uView == LV_VIEW_LIST) nScrollDiff *= infoPtr->nItemWidth; - + /* and scroll the window */ scroll_list(infoPtr, nScrollDiff, 0); - return 0; + return 0; } static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta) { INT gcWheelDelta = 0; INT pulScrollLines = 3; - SCROLLINFO scrollInfo; TRACE("(wheelDelta=%d)\n", wheelDelta); SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); gcWheelDelta -= wheelDelta; - scrollInfo.cbSize = sizeof(SCROLLINFO); - scrollInfo.fMask = SIF_POS; - switch(infoPtr->uView) { case LV_VIEW_ICON: @@ -9233,7 +9805,21 @@ static LRESULT LISTVIEW_KillFocus(LISTVIEW_INFO *infoPtr) /* if we have a focus rectangle, get rid of it */ LISTVIEW_ShowFocusRect(infoPtr, FALSE); - + + /* if have a marquee selection, stop it */ + if (infoPtr->bMarqueeSelect) + { + /* Remove the marquee rectangle and release our mouse capture */ + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeRect); + ReleaseCapture(); + + SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0); + + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); + } + /* set window focus flag */ infoPtr->bFocus = FALSE; @@ -9312,6 +9898,8 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN infoPtr->bLButtonDown = TRUE; infoPtr->ptClickPos = pt; infoPtr->bDragging = FALSE; + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; lvHitTestInfo.pt.x = x; lvHitTestInfo.pt.y = y; @@ -9389,6 +9977,9 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN } else { + if (!infoPtr->bFocus) + SetFocus(infoPtr->hwndSelf); + /* remove all selections */ if (!(wKey & MK_CONTROL) && !(wKey & MK_SHIFT)) LISTVIEW_DeselectAll(infoPtr); @@ -9433,9 +10024,23 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT LISTVIEW_SetSelection(infoPtr, infoPtr->nLButtonDownItem); infoPtr->nLButtonDownItem = -1; - if (infoPtr->bDragging) + if (infoPtr->bDragging || infoPtr->bMarqueeSelect) { + /* Remove the marquee rectangle and release our mouse capture */ + if (infoPtr->bMarqueeSelect) + { + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); + ReleaseCapture(); + } + + SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0); + SetRect(&infoPtr->marqueeDrawRect, 0, 0, 0, 0); + infoPtr->bDragging = FALSE; + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; + + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); return 0; } @@ -9471,28 +10076,27 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT */ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr) { - TRACE("()\n"); + INT i; - /* delete all items */ - LISTVIEW_DeleteAllItems(infoPtr, TRUE); + TRACE("()\n"); /* destroy data structure */ DPA_Destroy(infoPtr->hdpaItems); DPA_Destroy(infoPtr->hdpaItemIds); DPA_Destroy(infoPtr->hdpaPosX); DPA_Destroy(infoPtr->hdpaPosY); + /* columns */ + for (i = 0; i < DPA_GetPtrCount(infoPtr->hdpaColumns); i++) + Free(DPA_GetPtr(infoPtr->hdpaColumns, i)); DPA_Destroy(infoPtr->hdpaColumns); ranges_destroy(infoPtr->selectionRanges); /* destroy image lists */ if (!(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) { - if (infoPtr->himlNormal) - ImageList_Destroy(infoPtr->himlNormal); - if (infoPtr->himlSmall) - ImageList_Destroy(infoPtr->himlSmall); - if (infoPtr->himlState) - ImageList_Destroy(infoPtr->himlState); + ImageList_Destroy(infoPtr->himlNormal); + ImageList_Destroy(infoPtr->himlSmall); + ImageList_Destroy(infoPtr->himlState); } /* destroy font, bkgnd brush */ @@ -9675,6 +10279,9 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE case HDN_DIVIDERDBLCLICKW: case HDN_DIVIDERDBLCLICKA: + /* FIXME: for LVS_EX_HEADERINALLVIEWS and not LV_VIEW_DETAILS + we should use LVSCW_AUTOSIZE_USEHEADER, helper rework or + split needed for that */ LISTVIEW_SetColumnWidth(infoPtr, lpnmh->iItem, LVSCW_AUTOSIZE); notify_forward_header(infoPtr, lpnmh); break; @@ -9704,7 +10311,8 @@ static BOOL LISTVIEW_NCPaint(const LISTVIEW_INFO *infoPtr, HRGN region) int cxEdge = GetSystemMetrics (SM_CXEDGE), cyEdge = GetSystemMetrics (SM_CYEDGE); - if (!theme) return FALSE; + if (!theme) + return DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)region, 0); GetWindowRect(infoPtr->hwndSelf, &r); @@ -9725,7 +10333,7 @@ static BOOL LISTVIEW_NCPaint(const LISTVIEW_INFO *infoPtr, HRGN region) /* Call default proc to get the scrollbars etc. painted */ DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)cliprgn, 0); - return TRUE; + return FALSE; } /*** @@ -9975,20 +10583,24 @@ static LRESULT LISTVIEW_RButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT * TRUE if cursor is set * FALSE otherwise */ -static BOOL LISTVIEW_SetCursor(const LISTVIEW_INFO *infoPtr, HWND hwnd, UINT nHittest, UINT wMouseMsg) +static BOOL LISTVIEW_SetCursor(const LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { LVHITTESTINFO lvHitTestInfo; - if(!(LISTVIEW_isHotTracking(infoPtr))) return FALSE; + if (!LISTVIEW_IsHotTracking(infoPtr)) goto forward; - if(!infoPtr->hHotCursor) return FALSE; + if (!infoPtr->hHotCursor) goto forward; GetCursorPos(&lvHitTestInfo.pt); - if (LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, FALSE, FALSE) < 0) return FALSE; + if (LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, FALSE, FALSE) < 0) goto forward; SetCursor(infoPtr->hHotCursor); return TRUE; + +forward: + + return DefWindowProcW(infoPtr->hwndSelf, WM_SETCURSOR, wParam, lParam); } /*** @@ -10161,7 +10773,9 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr) infoPtr->rcList.bottom -= GetSystemMetrics(SM_CYHSCROLL); infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0); } - else if (infoPtr->uView == LV_VIEW_DETAILS) + + /* if control created invisible header isn't created */ + if (infoPtr->hwndHeader) { HDLAYOUT hl; WINDOWPOS wp; @@ -10169,15 +10783,24 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr) hl.prc = &infoPtr->rcList; hl.pwpos = ℘ SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl ); - TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy); - SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, - wp.flags | ((infoPtr->dwStyle & LVS_NOCOLUMNHEADER) - ? SWP_HIDEWINDOW : SWP_SHOWWINDOW)); - TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy); + TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy); + + if (LISTVIEW_IsHeaderEnabled(infoPtr)) + wp.flags |= SWP_SHOWWINDOW; + else + { + wp.flags |= SWP_HIDEWINDOW; + wp.cy = 0; + } + + SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags); + TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy); infoPtr->rcList.top = max(wp.cy, 0); - infoPtr->rcList.top += (infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) ? 2 : 0; } + /* extra padding for grid */ + if (infoPtr->uView == LV_VIEW_DETAILS && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) + infoPtr->rcList.top += 2; TRACE(" rcList=%s\n", wine_dbgstr_rect(&infoPtr->rcList)); } @@ -10258,7 +10881,7 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, LISTVIEW_UpdateItemSize(infoPtr); } - if (uNewView == LVS_REPORT) + if (uNewView == LVS_REPORT || infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) { if ((lpss->styleOld ^ lpss->styleNew) & LVS_NOCOLUMNHEADER) { @@ -10300,14 +10923,13 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, * Processes WM_STYLECHANGING messages. * * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure * [I] wStyleType : window style type (normal or extended) * [I0] lpss : window style information * * RETURN: * Zero */ -static INT LISTVIEW_StyleChanging(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, +static INT LISTVIEW_StyleChanging(WPARAM wStyleType, STYLESTRUCT *lpss) { TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n", @@ -10337,7 +10959,7 @@ static INT LISTVIEW_StyleChanging(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, * RETURN: * Zero */ -static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iStatus) +static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, WPARAM bShown, LPARAM iStatus) { /* header delayed creation */ if ((infoPtr->uView == LV_VIEW_DETAILS) && bShown) @@ -10348,7 +10970,7 @@ static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iSta ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL); } - return 0; + return DefWindowProcW(infoPtr->hwndSelf, WM_SHOWWINDOW, bShown, iStatus); } /*** @@ -10402,7 +11024,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0); - TRACE("(uMsg=%x wParam=%lx lParam=%lx)\n", uMsg, wParam, lParam); + TRACE("(hwnd=%p uMsg=%x wParam=%lx lParam=%lx)\n", hwnd, uMsg, wParam, lParam); if (!infoPtr && (uMsg != WM_NCCREATE)) return DefWindowProcW(hwnd, uMsg, wParam, lParam); @@ -10430,12 +11052,10 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case LVM_DELETEITEM: return LISTVIEW_DeleteItem(infoPtr, (INT)wParam); - case LVM_EDITLABELW: - return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, TRUE); - case LVM_EDITLABELA: - return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, FALSE); - + case LVM_EDITLABELW: + return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, + uMsg == LVM_EDITLABELW); /* case LVM_ENABLEGROUPVIEW: */ case LVM_ENSUREVISIBLE: @@ -10456,10 +11076,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return infoPtr->uCallbackMask; case LVM_GETCOLUMNA: - return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_GETCOLUMNW: - return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_GETCOLUMNW); case LVM_GETCOLUMNORDERARRAY: return LISTVIEW_GetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam); @@ -10507,10 +11126,8 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return FALSE; case LVM_GETITEMA: - return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, FALSE); - case LVM_GETITEMW: - return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, uMsg == LVM_GETITEMW); case LVM_GETITEMCOUNT: return infoPtr->nItemCount; @@ -10528,10 +11145,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_GetItemState(infoPtr, (INT)wParam, (UINT)lParam); case LVM_GETITEMTEXTA: - return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE); - case LVM_GETITEMTEXTW: - return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, + uMsg == LVM_GETITEMTEXTW); case LVM_GETNEXTITEM: return LISTVIEW_GetNextItem(infoPtr, (INT)wParam, LOWORD(lParam)); @@ -10558,10 +11174,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return infoPtr->nSelectionMark; case LVM_GETSTRINGWIDTHA: - return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, FALSE); - case LVM_GETSTRINGWIDTHW: - return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, TRUE); + return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, + uMsg == LVM_GETSTRINGWIDTHW); case LVM_GETSUBITEMRECT: return LISTVIEW_GetSubItemRect(infoPtr, (UINT)wParam, (LPRECT)lParam); @@ -10603,20 +11218,17 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, FALSE, TRUE); case LVM_INSERTCOLUMNA: - return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_INSERTCOLUMNW: - return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_INSERTCOLUMNW); /* case LVM_INSERTGROUP: */ /* case LVM_INSERTGROUPSORTED: */ case LVM_INSERTITEMA: - return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, FALSE); - case LVM_INSERTITEMW: - return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, uMsg == LVM_INSERTITEMW); /* case LVM_INSERTMARKHITTEST: */ @@ -10655,10 +11267,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TRUE; case LVM_SETCOLUMNA: - return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_SETCOLUMNW: - return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_SETCOLUMNW); case LVM_SETCOLUMNORDERARRAY: return LISTVIEW_SetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam); @@ -10680,7 +11291,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_SetHotItem(infoPtr, (INT)wParam); case LVM_SETHOVERTIME: - return LISTVIEW_SetHoverTime(infoPtr, (DWORD)wParam); + return LISTVIEW_SetHoverTime(infoPtr, (DWORD)lParam); case LVM_SETICONSPACING: return LISTVIEW_SetIconSpacing(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -10709,22 +11320,20 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) POINT pt; pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, pt); + return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, &pt); } case LVM_SETITEMPOSITION32: - if (lParam == 0) return FALSE; - return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, *((POINT*)lParam)); + return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, (POINT*)lParam); case LVM_SETITEMSTATE: if (lParam == 0) return FALSE; return LISTVIEW_SetItemState(infoPtr, (INT)wParam, (LPLVITEMW)lParam); case LVM_SETITEMTEXTA: - return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE); - case LVM_SETITEMTEXTW: - return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, + uMsg == LVM_SETITEMTEXTW); /* case LVM_SETOUTLINECOLOR: */ @@ -10759,11 +11368,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* case LVM_SORTGROUPS: */ case LVM_SORTITEMS: - return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, (LPARAM)wParam, FALSE); - case LVM_SORTITEMSEX: - return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, (LPARAM)wParam, TRUE); - + return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, wParam, + uMsg == LVM_SORTITEMSEX); case LVM_SUBITEMHITTEST: return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, TRUE, FALSE); @@ -10792,7 +11399,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_Destroy(infoPtr); case WM_ENABLE: - return LISTVIEW_Enable(infoPtr, (BOOL)wParam); + return LISTVIEW_Enable(infoPtr); case WM_ERASEBKGND: return LISTVIEW_EraseBkgnd(infoPtr, (HDC)wParam); @@ -10825,15 +11432,13 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_MouseMove (infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_MOUSEHOVER: - return LISTVIEW_MouseHover(infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); + return LISTVIEW_MouseHover(infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_NCDESTROY: return LISTVIEW_NCDestroy(infoPtr); case WM_NCPAINT: - if (LISTVIEW_NCPaint(infoPtr, (HRGN)wParam)) - return 0; - goto fwd_msg; + return LISTVIEW_NCPaint(infoPtr, (HRGN)wParam); case WM_NOTIFY: if (lParam && ((LPNMHDR)lParam)->hwndFrom == infoPtr->hwndHeader) @@ -10859,9 +11464,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_RButtonUp(infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_SETCURSOR: - if(LISTVIEW_SetCursor(infoPtr, (HWND)wParam, LOWORD(lParam), HIWORD(lParam))) - return TRUE; - goto fwd_msg; + return LISTVIEW_SetCursor(infoPtr, wParam, lParam); case WM_SETFOCUS: return LISTVIEW_SetFocus(infoPtr, (HWND)wParam); @@ -10873,8 +11476,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_SetRedraw(infoPtr, (BOOL)wParam); case WM_SHOWWINDOW: - LISTVIEW_ShowWindow(infoPtr, (BOOL)wParam, (INT)lParam); - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + return LISTVIEW_ShowWindow(infoPtr, wParam, lParam); case WM_SIZE: return LISTVIEW_Size(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -10883,7 +11485,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam); case WM_STYLECHANGING: - return LISTVIEW_StyleChanging(infoPtr, wParam, (LPSTYLESTRUCT)lParam); + return LISTVIEW_StyleChanging(wParam, (LPSTYLESTRUCT)lParam); case WM_SYSCOLORCHANGE: COMCTL32_RefreshSysColors(); @@ -10923,8 +11525,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); - fwd_msg: - /* call default window procedure */ return DefWindowProcW(hwnd, uMsg, wParam, lParam); } @@ -10984,6 +11584,11 @@ void LISTVIEW_Unregister(void) */ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { + + TRACE("(%p %x %x %lx)\n", infoPtr, HIWORD(wParam), LOWORD(wParam), lParam); + + if (!infoPtr->hwndEdit) return 0; + switch (HIWORD(wParam)) { case EN_UPDATE: @@ -11003,7 +11608,7 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP /* Select font to get the right dimension of the string */ hFont = (HFONT)SendMessageW(infoPtr->hwndEdit, WM_GETFONT, 0, 0); - if(hFont != 0) + if (hFont) { hOldFont = SelectObject(hdc, hFont); } @@ -11016,16 +11621,10 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP GetTextMetricsW(hdc, &textMetric); sz.cx += (textMetric.tmMaxCharWidth * 2); - SetWindowPos ( - infoPtr->hwndEdit, - HWND_TOP, - 0, - 0, - sz.cx, - rect.bottom - rect.top, - SWP_DRAWFRAME|SWP_NOMOVE); + SetWindowPos(infoPtr->hwndEdit, NULL, 0, 0, sz.cx, + rect.bottom - rect.top, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOZORDER); } - if(hFont != 0) + if (hFont) SelectObject(hdc, hOldFont); ReleaseDC(infoPtr->hwndEdit, hdc); @@ -11035,6 +11634,7 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP case EN_KILLFOCUS: { LISTVIEW_CancelEditLabel(infoPtr); + break; } default: @@ -11043,133 +11643,3 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP return 0; } - - -/*** - * DESCRIPTION: - * Subclassed edit control windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * [I] isW : TRUE if input is Unicode - * - * RETURN: - * Zero. - */ -static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL isW) -{ - LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0); - BOOL save = TRUE; - - TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx, isW=%d)\n", - hwnd, uMsg, wParam, lParam, isW); - - switch (uMsg) - { - case WM_GETDLGCODE: - return DLGC_WANTARROWS | DLGC_WANTALLKEYS; - - case WM_DESTROY: - { - WNDPROC editProc = infoPtr->EditWndProc; - infoPtr->EditWndProc = 0; - SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc); - return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW); - } - - case WM_KEYDOWN: - if (VK_ESCAPE == (INT)wParam) - { - save = FALSE; - break; - } - else if (VK_RETURN == (INT)wParam) - break; - - default: - return CallWindowProcT(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam, isW); - } - - /* kill the edit */ - if (infoPtr->hwndEdit) - LISTVIEW_EndEditLabelT(infoPtr, save, isW); - - SendMessageW(hwnd, WM_CLOSE, 0, 0); - return 0; -} - -/*** - * DESCRIPTION: - * Subclassed edit control Unicode windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * - * RETURN: - */ -static LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE); -} - -/*** - * DESCRIPTION: - * Subclassed edit control ANSI windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * - * RETURN: - */ -static LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE); -} - -/*** - * DESCRIPTION: - * Creates a subclassed edit control - * - * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure - * [I] text : initial text for the edit - * [I] style : the window style - * [I] isW : TRUE if input is Unicode - * - * RETURN: - */ -static HWND CreateEditLabelT(LISTVIEW_INFO *infoPtr, LPCWSTR text, DWORD style, BOOL isW) -{ - WCHAR editName[5] = { 'E', 'd', 'i', 't', '\0' }; - HWND hedit; - HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE); - - TRACE("(text=%s, ..., isW=%d)\n", debugtext_t(text, isW), isW); - - style |= WS_CHILDWINDOW|WS_CLIPSIBLINGS|ES_LEFT|ES_AUTOHSCROLL|WS_BORDER; - - /* Window will be resized and positioned after LVN_BEGINLABELEDIT */ - if (isW) - hedit = CreateWindowW(editName, text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); - else - hedit = CreateWindowA("Edit", (LPCSTR)text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); - - if (!hedit) return 0; - - infoPtr->EditWndProc = (WNDPROC) - (isW ? SetWindowLongPtrW(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcW) : - SetWindowLongPtrA(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcA) ); - - SendMessageW(hedit, WM_SETFONT, (WPARAM)infoPtr->hFont, FALSE); - - return hedit; -} From 10dc21e801b751394730e1fd65634949da0708aa Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Thu, 3 Jun 2010 18:47:37 +0000 Subject: [PATCH 203/292] [DESK] - Rearrange screensaver wait codes around the MsgWaitForMultipleObjects function - Fixes screensaver configuration windows blocking the control panel - Refs: http://blogs.msdn.com/b/oldnewthing/archive/2005/02/17/375307.aspx and http://codereflect.com/2008/09/19/when-and-how-should-we-use-msgwaitformultipleobjects/ See issue #4213 for more details. svn path=/trunk/; revision=47548 --- reactos/dll/cpl/desk/screensaver.c | 41 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/reactos/dll/cpl/desk/screensaver.c b/reactos/dll/cpl/desk/screensaver.c index c24cf78620c..00ce09568b2 100644 --- a/reactos/dll/cpl/desk/screensaver.c +++ b/reactos/dll/cpl/desk/screensaver.c @@ -147,33 +147,32 @@ static BOOL WaitForSettingsDialog(HWND hwndDlg, HANDLE hProcess) { + DWORD dwResult; + MSG msg; + while (TRUE) { - DWORD Ret; - MSG msg; - - while (PeekMessage(&msg, - NULL, - 0, - 0, - PM_REMOVE)) + dwResult = MsgWaitForMultipleObjects(1, + &hProcess, + FALSE, + INFINITE, + QS_ALLINPUT); + if (dwResult == WAIT_OBJECT_0 + 1) { - if (msg.message == WM_QUIT) - return FALSE; - - if (IsDialogMessage(hwndDlg, &msg)) + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + if (msg.message == WM_QUIT) + { + return FALSE; + } + if (IsDialogMessage(hwndDlg, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } } - - Ret = MsgWaitForMultipleObjects(1, - &hProcess, - FALSE, - INFINITE, - QS_ALLINPUT); - if (Ret == (WAIT_OBJECT_0)) + else { return TRUE; } From 4e381837a02b9069d2d7593933cc146df1d3400e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 19:35:05 +0000 Subject: [PATCH 204/292] [GDI32API] add IsHandleValid and use it SelectObject test svn path=/trunk/; revision=47549 --- rostests/apitests/gdi32api/gdi32api.c | 16 ++++++++++++++++ rostests/apitests/gdi32api/gdi32api.h | 1 + rostests/apitests/gdi32api/tests/SelectObject.c | 2 ++ 3 files changed, 19 insertions(+) diff --git a/rostests/apitests/gdi32api/gdi32api.c b/rostests/apitests/gdi32api/gdi32api.c index ab8889503a5..245c40112ff 100644 --- a/rostests/apitests/gdi32api/gdi32api.c +++ b/rostests/apitests/gdi32api/gdi32api.c @@ -18,6 +18,22 @@ MyGdiQueryTable() return pPeb->GdiSharedHandleTable; } +BOOL +IsHandleValid(HGDIOBJ hobj) +{ + USHORT Index = (ULONG_PTR)hobj; + PGDI_TABLE_ENTRY pentry = &GdiHandleTable[Index]; + + if (pentry->KernelData == NULL || + pentry->KernelData < (PVOID)0x80000000 || + (USHORT)pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16)) + { + return FALSE; + } + + return TRUE; +} + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, diff --git a/rostests/apitests/gdi32api/gdi32api.h b/rostests/apitests/gdi32api/gdi32api.h index 73ec2a95a5b..8811be18235 100644 --- a/rostests/apitests/gdi32api/gdi32api.h +++ b/rostests/apitests/gdi32api/gdi32api.h @@ -20,6 +20,7 @@ extern HINSTANCE g_hInstance; extern PGDI_TABLE_ENTRY GdiHandleTable; +BOOL IsHandleValid(HGDIOBJ hobj); #endif /* _GDITEST_H */ diff --git a/rostests/apitests/gdi32api/tests/SelectObject.c b/rostests/apitests/gdi32api/tests/SelectObject.c index 0df71e9837c..cb476f872b7 100644 --- a/rostests/apitests/gdi32api/tests/SelectObject.c +++ b/rostests/apitests/gdi32api/tests/SelectObject.c @@ -82,6 +82,8 @@ Test_SelectObject(PTESTINFO pti) DeleteObject(hOldObj); RTEST((UINT_PTR)SelectObject(hDC, hNewObj) == SIMPLEREGION); // ??? Why this? DeleteObject(hNewObj); + TEST(IsHandleValid(hNewObj) == TRUE); + RTEST(GetLastError() == ERROR_SUCCESS); /* Test BITMAP */ From 859c81ee74d894fb3e45b918b4077e4dcee7bf46 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 19:39:28 +0000 Subject: [PATCH 205/292] [W32KNAPI] Add few more tests for NtGdiCreateBitmap svn path=/trunk/; revision=47550 --- .../apitests/w32knapi/ntgdi/NtGdiCreateBitmap.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rostests/apitests/w32knapi/ntgdi/NtGdiCreateBitmap.c b/rostests/apitests/w32knapi/ntgdi/NtGdiCreateBitmap.c index 6018855ffca..8700a77be1b 100644 --- a/rostests/apitests/w32knapi/ntgdi/NtGdiCreateBitmap.c +++ b/rostests/apitests/w32knapi/ntgdi/NtGdiCreateBitmap.c @@ -36,16 +36,31 @@ Test_NtGdiCreateBitmap_Params(PTESTINFO pti) TEST(NtGdiCreateBitmap(1, -2, 1, 1, NULL) == NULL); TEST(GetLastError() == ERROR_INVALID_PARAMETER); - /* Test negative cy */ + /* Test negative cy and valid bits */ SetLastError(ERROR_SUCCESS); TEST(NtGdiCreateBitmap(1, -2, 1, 1, BitmapData) == NULL); TEST(GetLastError() == ERROR_SUCCESS); + /* Test negative cy and invalid bits */ + SetLastError(ERROR_SUCCESS); + TEST(NtGdiCreateBitmap(1, -2, 1, 1, (BYTE*)0x80001234) == NULL); + TEST(GetLastError() == ERROR_SUCCESS); + /* Test huge size */ SetLastError(ERROR_SUCCESS); TEST(NtGdiCreateBitmap(100000, 100000, 1, 1, NULL) == NULL); TEST(GetLastError() == ERROR_NOT_ENOUGH_MEMORY); + /* Test huge size and valid bits */ + SetLastError(ERROR_SUCCESS); + TEST(NtGdiCreateBitmap(1000, 1000, 1, 1, BitmapData) == NULL); + TEST(GetLastError() == ERROR_SUCCESS); + + /* Test huge size and invalid bits */ + SetLastError(ERROR_SUCCESS); + TEST(NtGdiCreateBitmap(100000, 100000, 1, 1, (BYTE*)0x80001234) == NULL); + TEST(GetLastError() == ERROR_SUCCESS); + /* Test cPlanes == 0 */ SetLastError(ERROR_SUCCESS); TEST((hBmp = NtGdiCreateBitmap(1, 1, 0, 1, NULL)) != NULL); From 5cede710e0c32a4ffc888be3e4e17820dc27350d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 20:08:26 +0000 Subject: [PATCH 206/292] [ROSTESTS] Fix 64 bit build of some modules (Samuel Serapion, modified by me) svn path=/trunk/; revision=47551 --- rostests/drivers/kmtest/ntos_io.c | 8 +-- rostests/drivers/kmtest/ntos_ob.c | 2 +- rostests/drivers/kmtest/reghelper.c | 2 +- rostests/dxtest/ddraw/helper.cpp | 2 +- rostests/tests/bench/bench-thread.c | 6 +-- rostests/tests/button2/buttontst2.c | 52 +++++++++---------- rostests/tests/capclock/capclock.c | 6 +-- rostests/tests/combotst/combotst.c | 4 +- rostests/tests/edit/edittest.c | 4 +- rostests/tests/global_mem/global_mem.c | 41 +++++++++------ rostests/tests/isotest/isotest.c | 4 +- .../tests/map_dup_inherit/map_dup_inherit.c | 2 +- rostests/tests/mdi/mdi.c | 2 +- rostests/tests/miditest/miditest.c | 2 +- rostests/tests/multithrdwin/multithrdwin.c | 2 +- rostests/tests/p_dup_handle/p_dup_handle.c | 4 +- rostests/win32/user32/kbdlayout/kbdlayout.c | 6 +-- 17 files changed, 78 insertions(+), 71 deletions(-) diff --git a/rostests/drivers/kmtest/ntos_io.c b/rostests/drivers/kmtest/ntos_io.c index d49955b95e6..f450ebfaef8 100644 --- a/rostests/drivers/kmtest/ntos_io.c +++ b/rostests/drivers/kmtest/ntos_io.c @@ -46,7 +46,7 @@ VOID NtoskrnlIoMdlTest(HANDLE KeyHandle) ok(Mdl == NULL, "IoAllocateMdl should fail allocation of 2Gb or more, but got Mdl=0x%X", - (UINT32)Mdl); + (UINT_PTR)Mdl); if (Mdl) IoFreeMdl(Mdl); @@ -57,10 +57,10 @@ VOID NtoskrnlIoMdlTest(HANDLE KeyHandle) ok(Mdl != NULL, "Mdl allocation failed"); // Check fields of the allocated struct ok(Mdl->Next == NULL, "Mdl->Next should be NULL, but is 0x%X", - (UINT32)Mdl->Next); + (UINT_PTR)Mdl->Next); ok(Mdl->ByteCount == MdlSize, "Mdl->ByteCount should be equal to MdlSize, but is 0x%X", - (UINT32)Mdl->ByteCount); + (UINT_PTR)Mdl->ByteCount); // TODO: Check other fields of MDL struct IoFreeMdl(Mdl); @@ -70,7 +70,7 @@ VOID NtoskrnlIoMdlTest(HANDLE KeyHandle) Mdl = IoAllocateMdl(VirtualAddress, MdlSize, FALSE, FALSE, Irp); ok(Mdl != NULL, "Mdl allocation failed"); ok(Irp->MdlAddress == Mdl, "Irp->MdlAddress should be 0x%X, but is 0x%X", - (UINT32)Mdl, (UINT32)Irp->MdlAddress); + (UINT_PTR)Mdl, (UINT_PTR)Irp->MdlAddress); IoFreeMdl(Mdl); diff --git a/rostests/drivers/kmtest/ntos_ob.c b/rostests/drivers/kmtest/ntos_ob.c index c8b4d35156a..9f5f71c9f26 100644 --- a/rostests/drivers/kmtest/ntos_ob.c +++ b/rostests/drivers/kmtest/ntos_ob.c @@ -324,7 +324,7 @@ ObtCreateObjects() "Object insertion should have failed, but got 0x%lX", Status); ok(ObBody[0] == ObBody1[1], "Object bodies doesn't match, 0x%p != 0x%p", ObBody[0], ObBody1[1]); - ok(ObHandle2[0] != NULL, "Bad handle returned 0x%lX", (ULONG)ObHandle2[0]); + ok(ObHandle2[0] != NULL, "Bad handle returned 0x%lX", (ULONG_PTR)ObHandle2[0]); DPRINT1("%d %d %d %d %d %d %d\n", DumpCount, OpenCount, // deletecount+1 CloseCount, DeleteCount, ParseCount, OkayToCloseCount, QueryNameCount); diff --git a/rostests/drivers/kmtest/reghelper.c b/rostests/drivers/kmtest/reghelper.c index c3a54d67ef3..a33e84a452c 100644 --- a/rostests/drivers/kmtest/reghelper.c +++ b/rostests/drivers/kmtest/reghelper.c @@ -75,7 +75,7 @@ PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriv /* Remove the current driver name from the string */ /* FIXME: Dont use hard coded driver name, determine it from the string returned from the above Query */ Length = (wcslen((PWCHAR)ValuePartialInfo->Data) * 2) - (wcslen(L"kmtest.sys") * 2); - RtlZeroMemory((PVOID)((ULONG)ValuePartialInfo->Data + Length), + RtlZeroMemory((PVOID)((ULONG_PTR)ValuePartialInfo->Data + Length), wcslen(L"drvtests.sys") * 2); ZwClose(ServiceKey); diff --git a/rostests/dxtest/ddraw/helper.cpp b/rostests/dxtest/ddraw/helper.cpp index 92bf3aa64d7..3d6e1fd105c 100644 --- a/rostests/dxtest/ddraw/helper.cpp +++ b/rostests/dxtest/ddraw/helper.cpp @@ -1,6 +1,6 @@ #include "ddrawtest.h" -LONG WINAPI BasicWindowProc (HWND hwnd, UINT message, UINT wParam, LONG lParam) +LRESULT WINAPI BasicWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { diff --git a/rostests/tests/bench/bench-thread.c b/rostests/tests/bench/bench-thread.c index 6a8e4b95956..a3aa9974f42 100644 --- a/rostests/tests/bench/bench-thread.c +++ b/rostests/tests/bench/bench-thread.c @@ -7,7 +7,7 @@ DWORD WINAPI thread_main1(LPVOID param) { - printf("Thread 1 running (Counter %lu)\n", (DWORD)param); + printf("Thread 1 running (Counter %lu)\n", PtrToUlong(param)); SleepEx(INFINITE, TRUE); return 0; } @@ -16,7 +16,7 @@ thread_main1(LPVOID param) DWORD WINAPI thread_main2(LPVOID param) { - printf("Thread 2 running (Counter %lu)\n", (DWORD)param); + printf("Thread 2 running (Counter %lu)\n", PtrToUlong(param)); Sleep(INFINITE); return 0; } @@ -34,7 +34,7 @@ int main (void) CreateThread(NULL, 0, thread_main1, - (LPVOID)i, + (LPVOID)(ULONG_PTR)i, 0, &id); diff --git a/rostests/tests/button2/buttontst2.c b/rostests/tests/button2/buttontst2.c index 0fa4ed74208..0564f7ec7b4 100644 --- a/rostests/tests/button2/buttontst2.c +++ b/rostests/tests/button2/buttontst2.c @@ -58,109 +58,109 @@ WinMain(HINSTANCE hInstance, hbtn[0] = CreateWindow( "BUTTON","BS_DEFPUSHBUTTON",WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, - 10, 10, 200, 40, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 10, 200, 40, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[1] = CreateWindow( "BUTTON","BS_3STATE",WS_VISIBLE | WS_CHILD | BS_3STATE, - 10, 60, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 60, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[2] = CreateWindow( "BUTTON","BS_AUTO3STATE",WS_VISIBLE | WS_CHILD | BS_AUTO3STATE, - 10, 90, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 90, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[3] = CreateWindow( "BUTTON","BS_AUTOCHECKBOX",WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - 10, 120, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 120, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[4] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - 10, 150, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 150, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[5] = CreateWindow( "BUTTON","BS_CHECKBOX",WS_VISIBLE | WS_CHILD | BS_CHECKBOX, - 10, 180, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 180, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[6] = CreateWindow( "BUTTON","BS_GROUPBOX",WS_VISIBLE | WS_CHILD | BS_GROUPBOX, - 10, 210, 200, 80, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 210, 200, 80, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[7] = CreateWindow( "BUTTON","BS_PUSHBUTTON",WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 20, 230, 180, 30, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 20, 230, 180, 30, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[8] = CreateWindow( "BUTTON","BS_RADIOBUTTON",WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON, - 10, 300, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 300, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[9] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - 220, 160, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 220, 160, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[10] = CreateWindow( "BUTTON","BS_DEFPUSHBUTTON|BS_BOTTOM",WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_BOTTOM, - 220, 10, 250, 40, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 220, 10, 250, 40, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[11] = CreateWindow( "BUTTON","BS_DEFPUSHBUTTON|BS_LEFT",WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_LEFT, - 480, 10, 250, 40, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 480, 10, 250, 40, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[12] = CreateWindow( "BUTTON","BS_DEFPUSHBUTTON|BS_RIGHT|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_RIGHT |BS_MULTILINE, - 740, 10, 150, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 740, 10, 150, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[13] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON|BS_TOP",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_TOP, - 220, 60, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 220, 60, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); // Other Combinations hbtn[14] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON|BS_BOTTOM|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_BOTTOM | BS_MULTILINE, - 480, 60, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 480, 60, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[15] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON|BS_LEFT",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_LEFT, - 740, 80, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 740, 80, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[16] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON|BS_RIGHT|BS_TOP",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_RIGHT | BS_TOP, - 220, 130, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 220, 130, 200, 20, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[17] = CreateWindow( "BUTTON","BS_AUTORADIOBUTTON|BS_TOP|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_TOP| BS_MULTILINE, - 480, 130, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 480, 130, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[18] = CreateWindow( "BUTTON","BS_AUTOCHECKBOX|BS_BOTTOM|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_BOTTOM | BS_MULTILINE, - 740, 130, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 740, 130, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[19] = CreateWindow( "BUTTON","BS_AUTOCHECKBOX|BS_TOP|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE, - 480, 190, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 480, 190, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[20] = CreateWindow( "BUTTON","BS_AUTOCHECKBOX|BS_LEFT|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_LEFT | BS_MULTILINE, - 220, 230, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 220, 230, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[21] = CreateWindow( "BUTTON","BS_AUTOCHECKBOX|BS_RIGHT|BS_MULTILINE",WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_RIGHT | BS_MULTILINE, - 480, 240, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 480, 240, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[22] = CreateWindow( "BUTTON","BS_GROUPBOX|BS_TOP",WS_VISIBLE | WS_CHILD | BS_GROUPBOX | BS_TOP, - 10, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[23] = CreateWindow( "BUTTON","BS_GROUPBOX|BS_BOTTOM",WS_VISIBLE | WS_CHILD | BS_GROUPBOX | BS_BOTTOM, - 10, 410, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 10, 410, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[24] = CreateWindow( "BUTTON","BS_GROUPBOXBOX|BS_LEFT",WS_VISIBLE | WS_CHILD | BS_GROUPBOX | BS_LEFT, - 520, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 520, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); hbtn[25] = CreateWindow( "BUTTON","BS_GROUPBOX|BS_RIGHT|BS_BOTTOM",WS_VISIBLE | WS_CHILD | BS_GROUPBOX | BS_BOTTOM | BS_RIGHT, - 300, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL); + 300, 340, 200, 60, hWnd, NULL, (HINSTANCE) GetWindowLongPtr(hWnd, GWL_HINSTANCE),NULL); while(GetMessage(&msg, NULL, 0, 0)) { diff --git a/rostests/tests/capclock/capclock.c b/rostests/tests/capclock/capclock.c index 4d69e3ec611..5ea9d33cf45 100644 --- a/rostests/tests/capclock/capclock.c +++ b/rostests/tests/capclock/capclock.c @@ -11,8 +11,8 @@ UINT Timer = 1; -static BOOL CALLBACK DialogFunc(HWND,UINT,WPARAM,LPARAM); -static VOID CALLBACK TimerProc(HWND,UINT,UINT,DWORD); +static INT_PTR CALLBACK DialogFunc(HWND,UINT,WPARAM,LPARAM); +static VOID CALLBACK TimerProc(HWND,UINT,UINT_PTR,DWORD); INT WINAPI WinMain (HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, INT nCmdShow) @@ -50,7 +50,7 @@ static INT_PTR CALLBACK DialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARA } return FALSE; } -static VOID CALLBACK TimerProc (HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) +static VOID CALLBACK TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { CHAR text [20]; SYSTEMTIME lt; diff --git a/rostests/tests/combotst/combotst.c b/rostests/tests/combotst/combotst.c index 561218d7176..aeed18d159a 100644 --- a/rostests/tests/combotst/combotst.c +++ b/rostests/tests/combotst/combotst.c @@ -282,7 +282,7 @@ CreateCheckButton(const char* lpWindowName, DWORD xSize, DWORD id) xSize, /* nWidth */ 20, /* nHeight */ g_hwnd, - (HMENU) id, + UlongToHandle(id), g_hInst, NULL ); @@ -302,7 +302,7 @@ CreatePushButton(const char* lpWindowName, DWORD xSize, DWORD id,DWORD Style) xSize, /* nWidth */ 20, /* nHeight */ g_hwnd, - (HMENU) id, + LongToHandle(id), g_hInst, NULL ); diff --git a/rostests/tests/edit/edittest.c b/rostests/tests/edit/edittest.c index 35ab9b5b4e4..75a2e676fdd 100644 --- a/rostests/tests/edit/edittest.c +++ b/rostests/tests/edit/edittest.c @@ -277,7 +277,7 @@ CreateCheckButton(const char* lpWindowName, DWORD xSize, DWORD id) xSize, /* nWidth */ 20, /* nHeight */ g_hwnd, - (HMENU) id, + UlongToHandle(id), g_hInst, NULL ); @@ -297,7 +297,7 @@ CreatePushButton(const char* lpWindowName, DWORD xSize, DWORD id,DWORD Style) xSize, // nWidth 20, // nHeight g_hwnd, - (HMENU) id, + (HMENU)(ULONG_PTR) id, g_hInst, NULL ); diff --git a/rostests/tests/global_mem/global_mem.c b/rostests/tests/global_mem/global_mem.c index c7804dda5ff..5e614a58a8a 100644 --- a/rostests/tests/global_mem/global_mem.c +++ b/rostests/tests/global_mem/global_mem.c @@ -146,6 +146,13 @@ void OUTPUT_HexDword(DWORD dw) OUTPUT_Line(buffer); } +void OUTPUT_Handle(HANDLE h) +{ + char buffer[32]; + sprintf(buffer, "0x%p", h); + OUTPUT_Line(buffer); +} + /*--------------------------------------------------------------------------- ** */ @@ -412,9 +419,9 @@ TEST_STATUS TestGlobalReAllocFixed() else { OUTPUT_Line("Alloced Handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("ReAlloced Handle: "); - OUTPUT_HexDword((DWORD)hReAlloced); + OUTPUT_Handle(hReAlloced); if (hMem == hReAlloced) { OUTPUT_Line("GlobalReAlloc returned the same pointer. The documentation states that this is wrong, but Windows NT works this way."); @@ -455,9 +462,9 @@ TEST_STATUS TestGlobalReAllocFixed() else { OUTPUT_Line("Alloced Handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("ReAlloced Handle: "); - OUTPUT_HexDword((DWORD)hReAlloced); + OUTPUT_Handle(hReAlloced); if (hMem != hReAlloced) { OUTPUT_Line("GlobalReAlloc returned a different."); @@ -516,9 +523,9 @@ TEST_STATUS TestGlobalReAllocMovable() else { OUTPUT_Line("Alloced Handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("ReAlloced Handle: "); - OUTPUT_HexDword((DWORD)hReAlloced); + OUTPUT_Handle(hReAlloced); pMem = GlobalLock(hReAlloced); hMem = hReAlloced; @@ -559,9 +566,9 @@ TEST_STATUS TestGlobalReAllocMovable() else { OUTPUT_Line("Alloced Handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("ReAlloced Handle: "); - OUTPUT_HexDword((DWORD)hReAlloced); + OUTPUT_Handle(hReAlloced); if (hMem != hReAlloced) { OUTPUT_Line("GlobalReAlloc returned a different block."); @@ -638,7 +645,7 @@ TEST_STATUS TestGlobalFlagsMoveable() OUTPUT_Result(result); OUTPUT_Line("Pointer from handle: "); - OUTPUT_HexDword((DWORD)GlobalLock(hMem)); + OUTPUT_Handle(GlobalLock(hMem)); OUTPUT_Line("Testing after a lock"); OUTPUT_Line("Testing for a lock of 1"); @@ -679,7 +686,7 @@ TEST_STATUS TestGlobalFlagsMoveable() if (0 != hMem) { OUTPUT_Line("Allocation handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("Testing for a discarded flag"); uFlags = GlobalFlags(hMem); if (0 != (uFlags & GMEM_DISCARDED)) /*discarded*/ @@ -720,7 +727,7 @@ TEST_STATUS TestGlobalFlagsFixed() { OUTPUT_Line("Allocation handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); OUTPUT_Line("Testing initial allocation"); OUTPUT_Line("Testing for non-discarded and lock of 0"); @@ -737,7 +744,7 @@ TEST_STATUS TestGlobalFlagsFixed() OUTPUT_Result(result); OUTPUT_Line("Pointer from handle: "); - OUTPUT_HexDword((DWORD)GlobalLock(hMem)); + OUTPUT_Handle(GlobalLock(hMem)); OUTPUT_Line("Testing after a lock"); OUTPUT_Line("Testing for non-discarded and lock of 0"); uFlags = GlobalFlags(hMem); @@ -796,7 +803,7 @@ TEST_STATUS TestGlobalHandle() { OUTPUT_Line("Allocation handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); hTest = GlobalHandle(hMem); if (hMem == hTest) @@ -806,7 +813,7 @@ TEST_STATUS TestGlobalHandle() else { OUTPUT_Line("GlobalHandle returned:"); - OUTPUT_HexDword((DWORD)hTest); + OUTPUT_Handle(hTest); subtest = TEST_CombineStatus(subtest, FAILED); } @@ -830,7 +837,7 @@ TEST_STATUS TestGlobalHandle() { OUTPUT_Line("Allocation handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); pMem = GlobalLock(hMem); hTest = GlobalHandle(pMem); if (hMem == hTest) @@ -840,7 +847,7 @@ TEST_STATUS TestGlobalHandle() else { OUTPUT_Line("GlobalHandle returned:"); - OUTPUT_HexDword((DWORD)hTest); + OUTPUT_Handle(hTest); subtest = TEST_CombineStatus(subtest, FAILED); } @@ -979,7 +986,7 @@ TEST_STATUS TestGlobalDiscard() if (0 != hMem) { OUTPUT_Line("Allocation handle: "); - OUTPUT_HexDword((DWORD)hMem); + OUTPUT_Handle(hMem); hTest = GlobalDiscard(hMem); if (0 == hTest) diff --git a/rostests/tests/isotest/isotest.c b/rostests/tests/isotest/isotest.c index a0c4921e5e3..d2f78513edf 100644 --- a/rostests/tests/isotest/isotest.c +++ b/rostests/tests/isotest/isotest.c @@ -21,7 +21,7 @@ void HexDump(char *buffer, ULONG size) while (offset < (size & ~15)) { - ptr = (unsigned char*)((ULONG)buffer + offset); + ptr = (unsigned char*)((ULONG_PTR)buffer + offset); printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx", offset, ptr[0], @@ -62,7 +62,7 @@ void HexDump(char *buffer, ULONG size) offset += 16; } - ptr = (unsigned char*)((ULONG)buffer + offset); + ptr = (unsigned char*)((ULONG_PTR)buffer + offset); if (offset < size) { printf("%08lx ", offset); diff --git a/rostests/tests/map_dup_inherit/map_dup_inherit.c b/rostests/tests/map_dup_inherit/map_dup_inherit.c index 59077fd19fc..3e78ad204f2 100644 --- a/rostests/tests/map_dup_inherit/map_dup_inherit.c +++ b/rostests/tests/map_dup_inherit/map_dup_inherit.c @@ -17,7 +17,7 @@ int main( int argc, char **argv ) { if( argc == 2 ) { #ifdef WIN64 - file_map = (void *)atoi64(argv[1]); + file_map = (void *)_atoi64(argv[1]); #else file_map = (void *)UlongToPtr(atoi(argv[1])); #endif diff --git a/rostests/tests/mdi/mdi.c b/rostests/tests/mdi/mdi.c index d3f2aaf7bea..67cf1a9e51b 100644 --- a/rostests/tests/mdi/mdi.c +++ b/rostests/tests/mdi/mdi.c @@ -160,7 +160,7 @@ HWND CreateNewMDIChild(HWND hMDIClient) mcs.y = mcs.cy = CW_USEDEFAULT; mcs.style = MDIS_ALLCHILDSTYLES; - hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs); + hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); if(!hChild) { MessageBox(hMDIClient, "MDI Child creation failed.", "Oh Oh...", diff --git a/rostests/tests/miditest/miditest.c b/rostests/tests/miditest/miditest.c index e58b4acdc09..695df008aca 100644 --- a/rostests/tests/miditest/miditest.c +++ b/rostests/tests/miditest/miditest.c @@ -36,7 +36,7 @@ int main() printf("Opening MIDI output #0\n"); Result = midiOutOpen(&Handle, 0, 0, 0, CALLBACK_NULL); - printf("Result == %d Handle == %d\n", Result, (int)Handle); + printf("Result == %d Handle == %p\n", Result, Handle); // play something: midiOutShortMsg(Handle, 0x007f3090); diff --git a/rostests/tests/multithrdwin/multithrdwin.c b/rostests/tests/multithrdwin/multithrdwin.c index e0f885355c5..0d4fc5e98f1 100644 --- a/rostests/tests/multithrdwin/multithrdwin.c +++ b/rostests/tests/multithrdwin/multithrdwin.c @@ -157,7 +157,7 @@ LRESULT CALLBACK MultiWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) HDC hDC; RECT Client; HBRUSH Brush; - DWORD Ret; + DWORD_PTR Ret; static COLORREF Colors[] = { diff --git a/rostests/tests/p_dup_handle/p_dup_handle.c b/rostests/tests/p_dup_handle/p_dup_handle.c index 6aa5f7d1c05..9be3fd860da 100644 --- a/rostests/tests/p_dup_handle/p_dup_handle.c +++ b/rostests/tests/p_dup_handle/p_dup_handle.c @@ -15,7 +15,7 @@ int main( int argc, char **argv ) { fprintf( stderr, "%lu: Starting\n", GetCurrentProcessId() ); if( argc == 2 ) { - h_process = (HANDLE)atoi(argv[1]); + h_process = (HANDLE)(ULONG_PTR)atoi(argv[1]); } else { if( !DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), @@ -38,7 +38,7 @@ int main( int argc, char **argv ) { memset( &si, 0, sizeof( si ) ); memset( &pi, 0, sizeof( pi ) ); - sprintf( cmdline, "%s %lu", argv[0], (DWORD)h_process ); + sprintf( cmdline, "%s %p", argv[0], h_process ); if( !CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ) ) { fprintf( stderr, "%lu: Could not create child process.\n", diff --git a/rostests/win32/user32/kbdlayout/kbdlayout.c b/rostests/win32/user32/kbdlayout/kbdlayout.c index 28dc32fe791..ade01ba1954 100644 --- a/rostests/win32/user32/kbdlayout/kbdlayout.c +++ b/rostests/win32/user32/kbdlayout/kbdlayout.c @@ -122,7 +122,7 @@ void FormatBox(HWND hWnd, DWORD Flags, WCHAR *Caption, WCHAR *Format, ...) LRESULT CALLBACK WndSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - WND_DATA *data = (WND_DATA*)GetWindowLong(hwnd, GWL_USERDATA); + WND_DATA *data = (WND_DATA*)GetWindowLongPtr(hwnd, GWL_USERDATA); if(uMsg == WM_INPUTLANGCHANGE) { @@ -143,9 +143,9 @@ LRESULT CALLBACK WndSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP void SubclassWnd(HWND hWnd, WCHAR* Name) { WND_DATA *data = HeapAlloc(GetProcessHeap(), 0, sizeof(WND_DATA)); - data->OrigProc = (WNDPROC)SetWindowLong( hWnd, GWL_WNDPROC, (LONG)WndSubclassProc); + data->OrigProc = (WNDPROC)SetWindowLongPtr( hWnd, GWL_WNDPROC, (LONG_PTR)WndSubclassProc); wcsncpy(data->WndName, Name, 25); - SetWindowLong(hWnd, GWL_USERDATA, (LONG)data); + SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)data); return; } From 9d059198bb3ae0f71a7b64a22a3214ffc03cc5f1 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 20:57:25 +0000 Subject: [PATCH 207/292] [ReactOS-amd64.rbuild] The old explorer won't compile for amd64 without massive hacking, so remove it from the build. svn path=/trunk/; revision=47552 --- reactos/ReactOS-amd64.rbuild | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/reactos/ReactOS-amd64.rbuild b/reactos/ReactOS-amd64.rbuild index 7a33724e4fc..b82bb361d0c 100644 --- a/reactos/ReactOS-amd64.rbuild +++ b/reactos/ReactOS-amd64.rbuild @@ -49,7 +49,26 @@ - + + + + + + + + + + + + + + + + + + + + From c3179d84ef857427fc5f990897ca758e0d6e3d7c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 21:55:57 +0000 Subject: [PATCH 208/292] [DDK} Add a number of PCI related types to ntddk.h svn path=/trunk/; revision=47553 --- reactos/include/ddk/ntddk.h | 777 +++++++++++++++++++++++++++++++++--- 1 file changed, 712 insertions(+), 65 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 4189edf733f..af08588183b 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -322,6 +322,718 @@ typedef struct _ARBITER_INTERFACE { ULONG Flags; } ARBITER_INTERFACE, *PARBITER_INTERFACE; +typedef enum _RESOURCE_TRANSLATION_DIRECTION { + TranslateChildToParent, + TranslateParentToChild +} RESOURCE_TRANSLATION_DIRECTION; + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( + IN OUT PVOID Context OPTIONAL, + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, + IN RESOURCE_TRANSLATION_DIRECTION Direction, + IN ULONG AlternativesCount OPTIONAL, + IN IO_RESOURCE_DESCRIPTOR Alternatives[], + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( + IN OUT PVOID Context OPTIONAL, + IN PIO_RESOURCE_DESCRIPTOR Source, + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PULONG TargetCount, + OUT PIO_RESOURCE_DESCRIPTOR *Target); + +typedef struct _TRANSLATOR_INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PTRANSLATE_RESOURCE_HANDLER TranslateResources; + PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; +} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; + +typedef struct _PCI_AGP_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + USHORT Minor:4; + USHORT Major:4; + USHORT Rsvd1:8; + struct _PCI_AGP_STATUS { + ULONG Rate:3; + ULONG Agp3Mode:1; + ULONG FastWrite:1; + ULONG FourGB:1; + ULONG HostTransDisable:1; + ULONG Gart64:1; + ULONG ITA_Coherent:1; + ULONG SideBandAddressing:1; + ULONG CalibrationCycle:3; + ULONG AsyncRequestSize:3; + ULONG Rsvd1:1; + ULONG Isoch:1; + ULONG Rsvd2:6; + ULONG RequestQueueDepthMaximum:8; + } AGPStatus; + struct _PCI_AGP_COMMAND { + ULONG Rate:3; + ULONG Rsvd1:1; + ULONG FastWriteEnable:1; + ULONG FourGBEnable:1; + ULONG Rsvd2:1; + ULONG Gart64:1; + ULONG AGPEnable:1; + ULONG SBAEnable:1; + ULONG CalibrationCycle:3; + ULONG AsyncReqSize:3; + ULONG Rsvd3:8; + ULONG RequestQueueDepth:8; + } AGPCommand; +} PCI_AGP_CAPABILITY, *PPCI_AGP_CAPABILITY; + +typedef enum _EXTENDED_AGP_REGISTER { + IsochStatus, + AgpControl, + ApertureSize, + AperturePageSize, + GartLow, + GartHigh, + IsochCommand +} EXTENDED_AGP_REGISTER, *PEXTENDED_AGP_REGISTER; + +typedef struct _PCI_AGP_ISOCH_STATUS { + ULONG ErrorCode:2; + ULONG Rsvd1:1; + ULONG Isoch_L:3; + ULONG Isoch_Y:2; + ULONG Isoch_N:8; + ULONG Rsvd2:16; +} PCI_AGP_ISOCH_STATUS, *PPCI_AGP_ISOCH_STATUS; + +typedef struct _PCI_AGP_CONTROL { + ULONG Rsvd1:7; + ULONG GTLB_Enable:1; + ULONG AP_Enable:1; + ULONG CAL_Disable:1; + ULONG Rsvd2:22; +} PCI_AGP_CONTROL, *PPCI_AGP_CONTROL; + +typedef struct _PCI_AGP_APERTURE_PAGE_SIZE { + USHORT PageSizeMask:11; + USHORT Rsvd1:1; + USHORT PageSizeSelect:4; +} PCI_AGP_APERTURE_PAGE_SIZE, *PPCI_AGP_APERTURE_PAGE_SIZE; + +typedef struct _PCI_AGP_ISOCH_COMMAND { + USHORT Rsvd1:6; + USHORT Isoch_Y:2; + USHORT Isoch_N:8; +} PCI_AGP_ISOCH_COMMAND, *PPCI_AGP_ISOCH_COMMAND; + +typedef struct PCI_AGP_EXTENDED_CAPABILITY { + PCI_AGP_ISOCH_STATUS IsochStatus; + PCI_AGP_CONTROL AgpControl; + USHORT ApertureSize; + PCI_AGP_APERTURE_PAGE_SIZE AperturePageSize; + ULONG GartLow; + ULONG GartHigh; + PCI_AGP_ISOCH_COMMAND IsochCommand; +} PCI_AGP_EXTENDED_CAPABILITY, *PPCI_AGP_EXTENDED_CAPABILITY; + +#define PCI_AGP_RATE_1X 0x1 +#define PCI_AGP_RATE_2X 0x2 +#define PCI_AGP_RATE_4X 0x4 + +#define PCIX_MODE_CONVENTIONAL_PCI 0x0 +#define PCIX_MODE1_66MHZ 0x1 +#define PCIX_MODE1_100MHZ 0x2 +#define PCIX_MODE1_133MHZ 0x3 +#define PCIX_MODE2_266_66MHZ 0x9 +#define PCIX_MODE2_266_100MHZ 0xA +#define PCIX_MODE2_266_133MHZ 0xB +#define PCIX_MODE2_533_66MHZ 0xD +#define PCIX_MODE2_533_100MHZ 0xE +#define PCIX_MODE2_533_133MHZ 0xF + +#define PCIX_VERSION_MODE1_ONLY 0x0 +#define PCIX_VERSION_MODE2_ECC 0x1 +#define PCIX_VERSION_DUAL_MODE_ECC 0x2 + +typedef struct _PCIX_BRIDGE_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + union { + struct { + USHORT Bus64Bit:1; + USHORT Bus133MHzCapable:1; + USHORT SplitCompletionDiscarded:1; + USHORT UnexpectedSplitCompletion:1; + USHORT SplitCompletionOverrun:1; + USHORT SplitRequestDelayed:1; + USHORT BusModeFrequency:4; + USHORT Rsvd:2; + USHORT Version:2; + USHORT Bus266MHzCapable:1; + USHORT Bus533MHzCapable:1; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; + } SecondaryStatus; + union { + struct { + ULONG FunctionNumber:3; + ULONG DeviceNumber:5; + ULONG BusNumber:8; + ULONG Device64Bit:1; + ULONG Device133MHzCapable:1; + ULONG SplitCompletionDiscarded:1; + ULONG UnexpectedSplitCompletion:1; + ULONG SplitCompletionOverrun:1; + ULONG SplitRequestDelayed:1; + ULONG Rsvd:7; + ULONG DIMCapable:1; + ULONG Device266MHzCapable:1; + ULONG Device533MHzCapable:1; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } BridgeStatus; + USHORT UpstreamSplitTransactionCapacity; + USHORT UpstreamSplitTransactionLimit; + USHORT DownstreamSplitTransactionCapacity; + USHORT DownstreamSplitTransactionLimit; + union { + struct { + ULONG SelectSecondaryRegisters:1; + ULONG ErrorPresentInOtherBank:1; + ULONG AdditionalCorrectableError:1; + ULONG AdditionalUncorrectableError:1; + ULONG ErrorPhase:3; + ULONG ErrorCorrected:1; + ULONG Syndrome:8; + ULONG ErrorFirstCommand:4; + ULONG ErrorSecondCommand:4; + ULONG ErrorUpperAttributes:4; + ULONG ControlUpdateEnable:1; + ULONG Rsvd:1; + ULONG DisableSingleBitCorrection:1; + ULONG EccMode:1; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } EccControlStatus; + ULONG EccFirstAddress; + ULONG EccSecondAddress; + ULONG EccAttribute; +} PCIX_BRIDGE_CAPABILITY, *PPCIX_BRIDGE_CAPABILITY; + +typedef struct _PCI_SUBSYSTEM_IDS_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + USHORT Reserved; + USHORT SubVendorID; + USHORT SubSystemID; +} PCI_SUBSYSTEM_IDS_CAPABILITY, *PPCI_SUBSYSTEM_IDS_CAPABILITY; + +#define OSC_FIRMWARE_FAILURE 0x02 +#define OSC_UNRECOGNIZED_UUID 0x04 +#define OSC_UNRECOGNIZED_REVISION 0x08 +#define OSC_CAPABILITIES_MASKED 0x10 + +#define PCI_ROOT_BUS_OSC_METHOD_CAPABILITY_REVISION 0x01 + +typedef struct _PCI_ROOT_BUS_OSC_SUPPORT_FIELD { + union { + struct { + ULONG ExtendedConfigOpRegions:1; + ULONG ActiveStatePowerManagement:1; + ULONG ClockPowerManagement:1; + ULONG SegmentGroups:1; + ULONG MessageSignaledInterrupts:1; + ULONG WindowsHardwareErrorArchitecture:1; + ULONG Reserved:26; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } u; +} PCI_ROOT_BUS_OSC_SUPPORT_FIELD, *PPCI_ROOT_BUS_OSC_SUPPORT_FIELD; + +typedef struct _PCI_ROOT_BUS_OSC_CONTROL_FIELD { + union { + struct { + ULONG ExpressNativeHotPlug:1; + ULONG ShpcNativeHotPlug:1; + ULONG ExpressNativePME:1; + ULONG ExpressAdvancedErrorReporting:1; + ULONG ExpressCapabilityStructure:1; + ULONG Reserved:27; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } u; +} PCI_ROOT_BUS_OSC_CONTROL_FIELD, *PPCI_ROOT_BUS_OSC_CONTROL_FIELD; + +typedef enum _PCI_HARDWARE_INTERFACE { + PciConventional, + PciXMode1, + PciXMode2, + PciExpress +} PCI_HARDWARE_INTERFACE, *PPCI_HARDWARE_INTERFACE; + +typedef enum { + BusWidth32Bits, + BusWidth64Bits +} PCI_BUS_WIDTH; + +typedef struct _PCI_ROOT_BUS_HARDWARE_CAPABILITY { + PCI_HARDWARE_INTERFACE SecondaryInterface; + struct { + BOOLEAN BusCapabilitiesFound; + ULONG CurrentSpeedAndMode; + ULONG SupportedSpeedsAndModes; + BOOLEAN DeviceIDMessagingCapable; + PCI_BUS_WIDTH SecondaryBusWidth; + } DUMMYSTRUCTNAME; + PCI_ROOT_BUS_OSC_SUPPORT_FIELD OscFeatureSupport; + PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlRequest; + PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlGranted; +} PCI_ROOT_BUS_HARDWARE_CAPABILITY, *PPCI_ROOT_BUS_HARDWARE_CAPABILITY; + +typedef union _PCI_EXPRESS_CAPABILITIES_REGISTER { + struct { + USHORT CapabilityVersion:4; + USHORT DeviceType:4; + USHORT SlotImplemented:1; + USHORT InterruptMessageNumber:5; + USHORT Rsvd:2; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_CAPABILITIES_REGISTER, *PPCI_EXPRESS_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER { + struct { + ULONG MaxPayloadSizeSupported:3; + ULONG PhantomFunctionsSupported:2; + ULONG ExtendedTagSupported:1; + ULONG L0sAcceptableLatency:3; + ULONG L1AcceptableLatency:3; + ULONG Undefined:3; + ULONG RoleBasedErrorReporting:1; + ULONG Rsvd1:2; + ULONG CapturedSlotPowerLimit:8; + ULONG CapturedSlotPowerLimitScale:2; + ULONG Rsvd2:4; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER, *PPCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER; + +#define PCI_EXPRESS_AER_DEVICE_CONTROL_MASK 0x07; + +typedef union _PCI_EXPRESS_DEVICE_CONTROL_REGISTER { + struct { + USHORT CorrectableErrorEnable:1; + USHORT NonFatalErrorEnable:1; + USHORT FatalErrorEnable:1; + USHORT UnsupportedRequestErrorEnable:1; + USHORT EnableRelaxedOrder:1; + USHORT MaxPayloadSize:3; + USHORT ExtendedTagEnable:1; + USHORT PhantomFunctionsEnable:1; + USHORT AuxPowerEnable:1; + USHORT NoSnoopEnable:1; + USHORT MaxReadRequestSize:3; + USHORT BridgeConfigRetryEnable:1; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_DEVICE_CONTROL_REGISTER, *PPCI_EXPRESS_DEVICE_CONTROL_REGISTER; + +#define PCI_EXPRESS_AER_DEVICE_STATUS_MASK 0x0F; + +typedef union _PCI_EXPRESS_DEVICE_STATUS_REGISTER { + struct { + USHORT CorrectableErrorDetected:1; + USHORT NonFatalErrorDetected:1; + USHORT FatalErrorDetected:1; + USHORT UnsupportedRequestDetected:1; + USHORT AuxPowerDetected:1; + USHORT TransactionsPending:1; + USHORT Rsvd:10; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_DEVICE_STATUS_REGISTER, *PPCI_EXPRESS_DEVICE_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_LINK_CAPABILITIES_REGISTER { + struct { + ULONG MaximumLinkSpeed:4; + ULONG MaximumLinkWidth:6; + ULONG ActiveStatePMSupport:2; + ULONG L0sExitLatency:3; + ULONG L1ExitLatency:3; + ULONG ClockPowerManagement:1; + ULONG SurpriseDownErrorReportingCapable:1; + ULONG DataLinkLayerActiveReportingCapable:1; + ULONG Rsvd:3; + ULONG PortNumber:8; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_LINK_CAPABILITIES_REGISTER, *PPCI_EXPRESS_LINK_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_LINK_CONTROL_REGISTER { + struct { + USHORT ActiveStatePMControl:2; + USHORT Rsvd1:1; + USHORT ReadCompletionBoundary:1; + USHORT LinkDisable:1; + USHORT RetrainLink:1; + USHORT CommonClockConfig:1; + USHORT ExtendedSynch:1; + USHORT EnableClockPowerManagement:1; + USHORT Rsvd2:7; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_LINK_CONTROL_REGISTER, *PPCI_EXPRESS_LINK_CONTROL_REGISTER; + +typedef union _PCI_EXPRESS_LINK_STATUS_REGISTER { + struct { + USHORT LinkSpeed:4; + USHORT LinkWidth:6; + USHORT Undefined:1; + USHORT LinkTraining:1; + USHORT SlotClockConfig:1; + USHORT DataLinkLayerActive:1; + USHORT Rsvd:2; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_LINK_STATUS_REGISTER, *PPCI_EXPRESS_LINK_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER { + struct { + ULONG AttentionButtonPresent:1; + ULONG PowerControllerPresent:1; + ULONG MRLSensorPresent:1; + ULONG AttentionIndicatorPresent:1; + ULONG PowerIndicatorPresent:1; + ULONG HotPlugSurprise:1; + ULONG HotPlugCapable:1; + ULONG SlotPowerLimit:8; + ULONG SlotPowerLimitScale:2; + ULONG ElectromechanicalLockPresent:1; + ULONG NoCommandCompletedSupport:1; + ULONG PhysicalSlotNumber:13; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_SLOT_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { + struct { + USHORT AttentionButtonEnable:1; + USHORT PowerFaultDetectEnable:1; + USHORT MRLSensorEnable:1; + USHORT PresenceDetectEnable:1; + USHORT CommandCompletedEnable:1; + USHORT HotPlugInterruptEnable:1; + USHORT AttentionIndicatorControl:2; + USHORT PowerIndicatorControl:2; + USHORT PowerControllerControl:1; + USHORT ElectromechanicalLockControl:1; + USHORT DataLinkStateChangeEnable:1; + USHORT Rsvd:3; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; + +typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { + struct { + USHORT AttentionButtonPressed:1; + USHORT PowerFaultDetected:1; + USHORT MRLSensorChanged:1; + USHORT PresenceDetectChanged:1; + USHORT CommandCompleted:1; + USHORT MRLSensorState:1; + USHORT PresenceDetectState:1; + USHORT ElectromechanicalLockEngaged:1; + USHORT DataLinkStateChanged:1; + USHORT Rsvd:7; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_SLOT_STATUS_REGISTER, *PPCI_EXPRESS_SLOT_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_CONTROL_REGISTER { + struct { + USHORT CorrectableSerrEnable:1; + USHORT NonFatalSerrEnable:1; + USHORT FatalSerrEnable:1; + USHORT PMEInterruptEnable:1; + USHORT CRSSoftwareVisibilityEnable:1; + USHORT Rsvd:11; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_ROOT_CONTROL_REGISTER, *PPCI_EXPRESS_ROOT_CONTROL_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER { + struct { + USHORT CRSSoftwareVisibility:1; + USHORT Rsvd:15; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_ROOT_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_STATUS_REGISTER { + struct { + ULONG PMERequestorId:16; + ULONG PMEStatus:1; + ULONG PMEPending:1; + ULONG Rsvd:14; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_ROOT_STATUS_REGISTER, *PPCI_EXPRESS_ROOT_STATUS_REGISTER; + +typedef struct _PCI_EXPRESS_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + PCI_EXPRESS_CAPABILITIES_REGISTER ExpressCapabilities; + PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER DeviceCapabilities; + PCI_EXPRESS_DEVICE_CONTROL_REGISTER DeviceControl; + PCI_EXPRESS_DEVICE_STATUS_REGISTER DeviceStatus; + PCI_EXPRESS_LINK_CAPABILITIES_REGISTER LinkCapabilities; + PCI_EXPRESS_LINK_CONTROL_REGISTER LinkControl; + PCI_EXPRESS_LINK_STATUS_REGISTER LinkStatus; + PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER SlotCapabilities; + PCI_EXPRESS_SLOT_CONTROL_REGISTER SlotControl; + PCI_EXPRESS_SLOT_STATUS_REGISTER SlotStatus; + PCI_EXPRESS_ROOT_CONTROL_REGISTER RootControl; + PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER RootCapabilities; + PCI_EXPRESS_ROOT_STATUS_REGISTER RootStatus; +} PCI_EXPRESS_CAPABILITY, *PPCI_EXPRESS_CAPABILITY; + +typedef enum { + MRLClosed = 0, + MRLOpen +} PCI_EXPRESS_MRL_STATE; + +typedef enum { + SlotEmpty = 0, + CardPresent +} PCI_EXPRESS_CARD_PRESENCE; + +typedef enum { + IndicatorOn = 1, + IndicatorBlink, + IndicatorOff +} PCI_EXPRESS_INDICATOR_STATE; + +typedef enum { + PowerOn = 0, + PowerOff +} PCI_EXPRESS_POWER_STATE; + +typedef enum { + L0sEntrySupport = 1, + L0sAndL1EntrySupport = 3 +} PCI_EXPRESS_ASPM_SUPPORT; + +typedef enum { + L0sAndL1EntryDisabled, + L0sEntryEnabled, + L1EntryEnabled, + L0sAndL1EntryEnabled +} PCI_EXPRESS_ASPM_CONTROL; + +typedef enum { + L0s_Below64ns = 0, + L0s_64ns_128ns, + L0s_128ns_256ns, + L0s_256ns_512ns, + L0s_512ns_1us, + L0s_1us_2us, + L0s_2us_4us, + L0s_Above4us +} PCI_EXPRESS_L0s_EXIT_LATENCY; + +typedef enum { + L1_Below1us = 0, + L1_1us_2us, + L1_2us_4us, + L1_4us_8us, + L1_8us_16us, + L1_16us_32us, + L1_32us_64us, + L1_Above64us +} PCI_EXPRESS_L1_EXIT_LATENCY; + +typedef enum { + PciExpressEndpoint = 0, + PciExpressLegacyEndpoint, + PciExpressRootPort = 4, + PciExpressUpstreamSwitchPort, + PciExpressDownstreamSwitchPort, + PciExpressToPciXBridge, + PciXToExpressBridge, + PciExpressRootComplexIntegratedEndpoint, + PciExpressRootComplexEventCollector +} PCI_EXPRESS_DEVICE_TYPE; + +typedef enum { + MaxPayload128Bytes = 0, + MaxPayload256Bytes, + MaxPayload512Bytes, + MaxPayload1024Bytes, + MaxPayload2048Bytes, + MaxPayload4096Bytes +} PCI_EXPRESS_MAX_PAYLOAD_SIZE; + +typedef union _PCI_EXPRESS_PME_REQUESTOR_ID { + struct { + USHORT FunctionNumber:3; + USHORT DeviceNumber:5; + USHORT BusNumber:8; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_PME_REQUESTOR_ID, *PPCI_EXPRESS_PME_REQUESTOR_ID; + +#if defined(_WIN64) + +#ifndef USE_DMA_MACROS +#define USE_DMA_MACROS +#endif + +#ifndef NO_LEGACY_DRIVERS +#define NO_LEGACY_DRIVERS +#endif + +#endif /* defined(_WIN64) */ + +typedef enum _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE { + ResourceTypeSingle = 0, + ResourceTypeRange, + ResourceTypeExtendedCounterConfiguration, + ResourceTypeOverflow, + ResourceTypeMax +} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE; + +typedef struct _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR { + PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE Type; + ULONG Flags; + union { + ULONG CounterIndex; + ULONG ExtendedRegisterAddress; + struct { + ULONG Begin; + ULONG End; + } Range; + } u; +} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR, *PPHYSICAL_COUNTER_RESOURCE_DESCRIPTOR; + +typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { + ULONG Count; + PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; +} PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; + +typedef VOID +(NTAPI *PciPin2Line)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); + +typedef VOID +(NTAPI *PciLine2Pin)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +typedef VOID +(NTAPI *PciReadWriteConfig)( + IN struct _BUS_HANDLER *BusHandler, + IN PCI_SLOT_NUMBER Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +#define PCI_DATA_TAG ' ICP' +#define PCI_DATA_VERSION 1 + +typedef struct _PCIBUSDATA { + ULONG Tag; + ULONG Version; + PciReadWriteConfig ReadConfig; + PciReadWriteConfig WriteConfig; + PciPin2Line Pin2Line; + PciLine2Pin Line2Pin; + PCI_SLOT_NUMBER ParentSlot; + PVOID Reserved[4]; +} PCIBUSDATA, *PPCIBUSDATA; + +#ifndef _PCIINTRF_X_ +#define _PCIINTRF_X_ + +typedef ULONG +(NTAPI *PCI_READ_WRITE_CONFIG)( + IN PVOID Context, + IN ULONG BusOffset, + IN ULONG Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef VOID +(NTAPI *PCI_PIN_TO_LINE)( + IN PVOID Context, + IN PPCI_COMMON_CONFIG PciData); + +typedef VOID +(NTAPI *PCI_LINE_TO_PIN)( + IN PVOID Context, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +typedef VOID +(NTAPI *PCI_ROOT_BUS_CAPABILITY)( + IN PVOID Context, + OUT PPCI_ROOT_BUS_HARDWARE_CAPABILITY HardwareCapability); + +typedef VOID +(NTAPI *PCI_EXPRESS_WAKE_CONTROL)( + IN PVOID Context, + IN BOOLEAN EnableWake); + +typedef struct _PCI_BUS_INTERFACE_STANDARD { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PCI_READ_WRITE_CONFIG ReadConfig; + PCI_READ_WRITE_CONFIG WriteConfig; + PCI_PIN_TO_LINE PinToLine; + PCI_LINE_TO_PIN LineToPin; + PCI_ROOT_BUS_CAPABILITY RootBusCapability; + PCI_EXPRESS_WAKE_CONTROL ExpressWakeControl; +} PCI_BUS_INTERFACE_STANDARD, *PPCI_BUS_INTERFACE_STANDARD; + +#define PCI_BUS_INTERFACE_STANDARD_VERSION 1 + +#endif /* _PCIINTRF_X_ */ + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX 0x00004000 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX 0x00008000 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX \ + (FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX | \ + FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX) + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_DEPRECATED 0x00000200 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_DEPRECATED 0x00000300 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_DEPRECATED 0x00000300 + +#else + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL 0x00000200 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL 0x00000300 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK 0x00000300 + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, @@ -422,39 +1134,6 @@ typedef struct _PM_DISPATCH_TABLE { PVOID Function[1]; } PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; -typedef enum _RESOURCE_TRANSLATION_DIRECTION { - TranslateChildToParent, - TranslateParentToChild -} RESOURCE_TRANSLATION_DIRECTION; - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( - IN OUT PVOID Context, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, - IN RESOURCE_TRANSLATION_DIRECTION Direction, - IN ULONG AlternativesCount OPTIONAL, - IN IO_RESOURCE_DESCRIPTOR Alternatives[], - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( - IN PVOID Context OPTIONAL, - IN PIO_RESOURCE_DESCRIPTOR Source, - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PULONG TargetCount, - OUT PIO_RESOURCE_DESCRIPTOR *Target); - -typedef struct _TRANSLATOR_INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PTRANSLATE_RESOURCE_HANDLER TranslateResources; - PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; -} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; - typedef VOID (FASTCALL *pHalExamineMBR)( IN PDEVICE_OBJECT DeviceObject, @@ -1867,42 +2546,10 @@ FsRtlIsTotalDeviceFailure( /* Hardware Abstraction Layer Types */ -typedef VOID -(NTAPI *PciPin2Line)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciData); -typedef VOID -(NTAPI *PciLine2Pin)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciNewData, - IN PPCI_COMMON_CONFIG PciOldData); -typedef VOID -(NTAPI *PciReadWriteConfig)( - IN struct _BUS_HANDLER *BusHandler, - IN PCI_SLOT_NUMBER Slot, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); -#define PCI_DATA_TAG ' ICP' -#define PCI_DATA_VERSION 1 -typedef struct _PCIBUSDATA { - ULONG Tag; - ULONG Version; - PciReadWriteConfig ReadConfig; - PciReadWriteConfig WriteConfig; - PciPin2Line Pin2Line; - PciLine2Pin Line2Pin; - PCI_SLOT_NUMBER ParentSlot; - PVOID Reserved[4]; -} PCIBUSDATA, *PPCIBUSDATA; /* Hardware Abstraction Layer Functions */ From da7f98efe806215dd7db65524da5f396b9faafd6 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 22:15:54 +0000 Subject: [PATCH 209/292] Revert r47553 because testbot doesn't like it svn path=/trunk/; revision=47554 --- reactos/include/ddk/ntddk.h | 777 +++--------------------------------- 1 file changed, 65 insertions(+), 712 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index af08588183b..4189edf733f 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -322,718 +322,6 @@ typedef struct _ARBITER_INTERFACE { ULONG Flags; } ARBITER_INTERFACE, *PARBITER_INTERFACE; -typedef enum _RESOURCE_TRANSLATION_DIRECTION { - TranslateChildToParent, - TranslateParentToChild -} RESOURCE_TRANSLATION_DIRECTION; - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( - IN OUT PVOID Context OPTIONAL, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, - IN RESOURCE_TRANSLATION_DIRECTION Direction, - IN ULONG AlternativesCount OPTIONAL, - IN IO_RESOURCE_DESCRIPTOR Alternatives[], - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( - IN OUT PVOID Context OPTIONAL, - IN PIO_RESOURCE_DESCRIPTOR Source, - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PULONG TargetCount, - OUT PIO_RESOURCE_DESCRIPTOR *Target); - -typedef struct _TRANSLATOR_INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PTRANSLATE_RESOURCE_HANDLER TranslateResources; - PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; -} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; - -typedef struct _PCI_AGP_CAPABILITY { - PCI_CAPABILITIES_HEADER Header; - USHORT Minor:4; - USHORT Major:4; - USHORT Rsvd1:8; - struct _PCI_AGP_STATUS { - ULONG Rate:3; - ULONG Agp3Mode:1; - ULONG FastWrite:1; - ULONG FourGB:1; - ULONG HostTransDisable:1; - ULONG Gart64:1; - ULONG ITA_Coherent:1; - ULONG SideBandAddressing:1; - ULONG CalibrationCycle:3; - ULONG AsyncRequestSize:3; - ULONG Rsvd1:1; - ULONG Isoch:1; - ULONG Rsvd2:6; - ULONG RequestQueueDepthMaximum:8; - } AGPStatus; - struct _PCI_AGP_COMMAND { - ULONG Rate:3; - ULONG Rsvd1:1; - ULONG FastWriteEnable:1; - ULONG FourGBEnable:1; - ULONG Rsvd2:1; - ULONG Gart64:1; - ULONG AGPEnable:1; - ULONG SBAEnable:1; - ULONG CalibrationCycle:3; - ULONG AsyncReqSize:3; - ULONG Rsvd3:8; - ULONG RequestQueueDepth:8; - } AGPCommand; -} PCI_AGP_CAPABILITY, *PPCI_AGP_CAPABILITY; - -typedef enum _EXTENDED_AGP_REGISTER { - IsochStatus, - AgpControl, - ApertureSize, - AperturePageSize, - GartLow, - GartHigh, - IsochCommand -} EXTENDED_AGP_REGISTER, *PEXTENDED_AGP_REGISTER; - -typedef struct _PCI_AGP_ISOCH_STATUS { - ULONG ErrorCode:2; - ULONG Rsvd1:1; - ULONG Isoch_L:3; - ULONG Isoch_Y:2; - ULONG Isoch_N:8; - ULONG Rsvd2:16; -} PCI_AGP_ISOCH_STATUS, *PPCI_AGP_ISOCH_STATUS; - -typedef struct _PCI_AGP_CONTROL { - ULONG Rsvd1:7; - ULONG GTLB_Enable:1; - ULONG AP_Enable:1; - ULONG CAL_Disable:1; - ULONG Rsvd2:22; -} PCI_AGP_CONTROL, *PPCI_AGP_CONTROL; - -typedef struct _PCI_AGP_APERTURE_PAGE_SIZE { - USHORT PageSizeMask:11; - USHORT Rsvd1:1; - USHORT PageSizeSelect:4; -} PCI_AGP_APERTURE_PAGE_SIZE, *PPCI_AGP_APERTURE_PAGE_SIZE; - -typedef struct _PCI_AGP_ISOCH_COMMAND { - USHORT Rsvd1:6; - USHORT Isoch_Y:2; - USHORT Isoch_N:8; -} PCI_AGP_ISOCH_COMMAND, *PPCI_AGP_ISOCH_COMMAND; - -typedef struct PCI_AGP_EXTENDED_CAPABILITY { - PCI_AGP_ISOCH_STATUS IsochStatus; - PCI_AGP_CONTROL AgpControl; - USHORT ApertureSize; - PCI_AGP_APERTURE_PAGE_SIZE AperturePageSize; - ULONG GartLow; - ULONG GartHigh; - PCI_AGP_ISOCH_COMMAND IsochCommand; -} PCI_AGP_EXTENDED_CAPABILITY, *PPCI_AGP_EXTENDED_CAPABILITY; - -#define PCI_AGP_RATE_1X 0x1 -#define PCI_AGP_RATE_2X 0x2 -#define PCI_AGP_RATE_4X 0x4 - -#define PCIX_MODE_CONVENTIONAL_PCI 0x0 -#define PCIX_MODE1_66MHZ 0x1 -#define PCIX_MODE1_100MHZ 0x2 -#define PCIX_MODE1_133MHZ 0x3 -#define PCIX_MODE2_266_66MHZ 0x9 -#define PCIX_MODE2_266_100MHZ 0xA -#define PCIX_MODE2_266_133MHZ 0xB -#define PCIX_MODE2_533_66MHZ 0xD -#define PCIX_MODE2_533_100MHZ 0xE -#define PCIX_MODE2_533_133MHZ 0xF - -#define PCIX_VERSION_MODE1_ONLY 0x0 -#define PCIX_VERSION_MODE2_ECC 0x1 -#define PCIX_VERSION_DUAL_MODE_ECC 0x2 - -typedef struct _PCIX_BRIDGE_CAPABILITY { - PCI_CAPABILITIES_HEADER Header; - union { - struct { - USHORT Bus64Bit:1; - USHORT Bus133MHzCapable:1; - USHORT SplitCompletionDiscarded:1; - USHORT UnexpectedSplitCompletion:1; - USHORT SplitCompletionOverrun:1; - USHORT SplitRequestDelayed:1; - USHORT BusModeFrequency:4; - USHORT Rsvd:2; - USHORT Version:2; - USHORT Bus266MHzCapable:1; - USHORT Bus533MHzCapable:1; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; - } SecondaryStatus; - union { - struct { - ULONG FunctionNumber:3; - ULONG DeviceNumber:5; - ULONG BusNumber:8; - ULONG Device64Bit:1; - ULONG Device133MHzCapable:1; - ULONG SplitCompletionDiscarded:1; - ULONG UnexpectedSplitCompletion:1; - ULONG SplitCompletionOverrun:1; - ULONG SplitRequestDelayed:1; - ULONG Rsvd:7; - ULONG DIMCapable:1; - ULONG Device266MHzCapable:1; - ULONG Device533MHzCapable:1; - } DUMMYSTRUCTNAME; - ULONG AsULONG; - } BridgeStatus; - USHORT UpstreamSplitTransactionCapacity; - USHORT UpstreamSplitTransactionLimit; - USHORT DownstreamSplitTransactionCapacity; - USHORT DownstreamSplitTransactionLimit; - union { - struct { - ULONG SelectSecondaryRegisters:1; - ULONG ErrorPresentInOtherBank:1; - ULONG AdditionalCorrectableError:1; - ULONG AdditionalUncorrectableError:1; - ULONG ErrorPhase:3; - ULONG ErrorCorrected:1; - ULONG Syndrome:8; - ULONG ErrorFirstCommand:4; - ULONG ErrorSecondCommand:4; - ULONG ErrorUpperAttributes:4; - ULONG ControlUpdateEnable:1; - ULONG Rsvd:1; - ULONG DisableSingleBitCorrection:1; - ULONG EccMode:1; - } DUMMYSTRUCTNAME; - ULONG AsULONG; - } EccControlStatus; - ULONG EccFirstAddress; - ULONG EccSecondAddress; - ULONG EccAttribute; -} PCIX_BRIDGE_CAPABILITY, *PPCIX_BRIDGE_CAPABILITY; - -typedef struct _PCI_SUBSYSTEM_IDS_CAPABILITY { - PCI_CAPABILITIES_HEADER Header; - USHORT Reserved; - USHORT SubVendorID; - USHORT SubSystemID; -} PCI_SUBSYSTEM_IDS_CAPABILITY, *PPCI_SUBSYSTEM_IDS_CAPABILITY; - -#define OSC_FIRMWARE_FAILURE 0x02 -#define OSC_UNRECOGNIZED_UUID 0x04 -#define OSC_UNRECOGNIZED_REVISION 0x08 -#define OSC_CAPABILITIES_MASKED 0x10 - -#define PCI_ROOT_BUS_OSC_METHOD_CAPABILITY_REVISION 0x01 - -typedef struct _PCI_ROOT_BUS_OSC_SUPPORT_FIELD { - union { - struct { - ULONG ExtendedConfigOpRegions:1; - ULONG ActiveStatePowerManagement:1; - ULONG ClockPowerManagement:1; - ULONG SegmentGroups:1; - ULONG MessageSignaledInterrupts:1; - ULONG WindowsHardwareErrorArchitecture:1; - ULONG Reserved:26; - } DUMMYSTRUCTNAME; - ULONG AsULONG; - } u; -} PCI_ROOT_BUS_OSC_SUPPORT_FIELD, *PPCI_ROOT_BUS_OSC_SUPPORT_FIELD; - -typedef struct _PCI_ROOT_BUS_OSC_CONTROL_FIELD { - union { - struct { - ULONG ExpressNativeHotPlug:1; - ULONG ShpcNativeHotPlug:1; - ULONG ExpressNativePME:1; - ULONG ExpressAdvancedErrorReporting:1; - ULONG ExpressCapabilityStructure:1; - ULONG Reserved:27; - } DUMMYSTRUCTNAME; - ULONG AsULONG; - } u; -} PCI_ROOT_BUS_OSC_CONTROL_FIELD, *PPCI_ROOT_BUS_OSC_CONTROL_FIELD; - -typedef enum _PCI_HARDWARE_INTERFACE { - PciConventional, - PciXMode1, - PciXMode2, - PciExpress -} PCI_HARDWARE_INTERFACE, *PPCI_HARDWARE_INTERFACE; - -typedef enum { - BusWidth32Bits, - BusWidth64Bits -} PCI_BUS_WIDTH; - -typedef struct _PCI_ROOT_BUS_HARDWARE_CAPABILITY { - PCI_HARDWARE_INTERFACE SecondaryInterface; - struct { - BOOLEAN BusCapabilitiesFound; - ULONG CurrentSpeedAndMode; - ULONG SupportedSpeedsAndModes; - BOOLEAN DeviceIDMessagingCapable; - PCI_BUS_WIDTH SecondaryBusWidth; - } DUMMYSTRUCTNAME; - PCI_ROOT_BUS_OSC_SUPPORT_FIELD OscFeatureSupport; - PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlRequest; - PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlGranted; -} PCI_ROOT_BUS_HARDWARE_CAPABILITY, *PPCI_ROOT_BUS_HARDWARE_CAPABILITY; - -typedef union _PCI_EXPRESS_CAPABILITIES_REGISTER { - struct { - USHORT CapabilityVersion:4; - USHORT DeviceType:4; - USHORT SlotImplemented:1; - USHORT InterruptMessageNumber:5; - USHORT Rsvd:2; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_CAPABILITIES_REGISTER, *PPCI_EXPRESS_CAPABILITIES_REGISTER; - -typedef union _PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER { - struct { - ULONG MaxPayloadSizeSupported:3; - ULONG PhantomFunctionsSupported:2; - ULONG ExtendedTagSupported:1; - ULONG L0sAcceptableLatency:3; - ULONG L1AcceptableLatency:3; - ULONG Undefined:3; - ULONG RoleBasedErrorReporting:1; - ULONG Rsvd1:2; - ULONG CapturedSlotPowerLimit:8; - ULONG CapturedSlotPowerLimitScale:2; - ULONG Rsvd2:4; - } DUMMYSTRUCTNAME; - ULONG AsULONG; -} PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER, *PPCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER; - -#define PCI_EXPRESS_AER_DEVICE_CONTROL_MASK 0x07; - -typedef union _PCI_EXPRESS_DEVICE_CONTROL_REGISTER { - struct { - USHORT CorrectableErrorEnable:1; - USHORT NonFatalErrorEnable:1; - USHORT FatalErrorEnable:1; - USHORT UnsupportedRequestErrorEnable:1; - USHORT EnableRelaxedOrder:1; - USHORT MaxPayloadSize:3; - USHORT ExtendedTagEnable:1; - USHORT PhantomFunctionsEnable:1; - USHORT AuxPowerEnable:1; - USHORT NoSnoopEnable:1; - USHORT MaxReadRequestSize:3; - USHORT BridgeConfigRetryEnable:1; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_DEVICE_CONTROL_REGISTER, *PPCI_EXPRESS_DEVICE_CONTROL_REGISTER; - -#define PCI_EXPRESS_AER_DEVICE_STATUS_MASK 0x0F; - -typedef union _PCI_EXPRESS_DEVICE_STATUS_REGISTER { - struct { - USHORT CorrectableErrorDetected:1; - USHORT NonFatalErrorDetected:1; - USHORT FatalErrorDetected:1; - USHORT UnsupportedRequestDetected:1; - USHORT AuxPowerDetected:1; - USHORT TransactionsPending:1; - USHORT Rsvd:10; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_DEVICE_STATUS_REGISTER, *PPCI_EXPRESS_DEVICE_STATUS_REGISTER; - -typedef union _PCI_EXPRESS_LINK_CAPABILITIES_REGISTER { - struct { - ULONG MaximumLinkSpeed:4; - ULONG MaximumLinkWidth:6; - ULONG ActiveStatePMSupport:2; - ULONG L0sExitLatency:3; - ULONG L1ExitLatency:3; - ULONG ClockPowerManagement:1; - ULONG SurpriseDownErrorReportingCapable:1; - ULONG DataLinkLayerActiveReportingCapable:1; - ULONG Rsvd:3; - ULONG PortNumber:8; - } DUMMYSTRUCTNAME; - ULONG AsULONG; -} PCI_EXPRESS_LINK_CAPABILITIES_REGISTER, *PPCI_EXPRESS_LINK_CAPABILITIES_REGISTER; - -typedef union _PCI_EXPRESS_LINK_CONTROL_REGISTER { - struct { - USHORT ActiveStatePMControl:2; - USHORT Rsvd1:1; - USHORT ReadCompletionBoundary:1; - USHORT LinkDisable:1; - USHORT RetrainLink:1; - USHORT CommonClockConfig:1; - USHORT ExtendedSynch:1; - USHORT EnableClockPowerManagement:1; - USHORT Rsvd2:7; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_LINK_CONTROL_REGISTER, *PPCI_EXPRESS_LINK_CONTROL_REGISTER; - -typedef union _PCI_EXPRESS_LINK_STATUS_REGISTER { - struct { - USHORT LinkSpeed:4; - USHORT LinkWidth:6; - USHORT Undefined:1; - USHORT LinkTraining:1; - USHORT SlotClockConfig:1; - USHORT DataLinkLayerActive:1; - USHORT Rsvd:2; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_LINK_STATUS_REGISTER, *PPCI_EXPRESS_LINK_STATUS_REGISTER; - -typedef union _PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER { - struct { - ULONG AttentionButtonPresent:1; - ULONG PowerControllerPresent:1; - ULONG MRLSensorPresent:1; - ULONG AttentionIndicatorPresent:1; - ULONG PowerIndicatorPresent:1; - ULONG HotPlugSurprise:1; - ULONG HotPlugCapable:1; - ULONG SlotPowerLimit:8; - ULONG SlotPowerLimitScale:2; - ULONG ElectromechanicalLockPresent:1; - ULONG NoCommandCompletedSupport:1; - ULONG PhysicalSlotNumber:13; - } DUMMYSTRUCTNAME; - ULONG AsULONG; -} PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_SLOT_CAPABILITIES_REGISTER; - -typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { - struct { - USHORT AttentionButtonEnable:1; - USHORT PowerFaultDetectEnable:1; - USHORT MRLSensorEnable:1; - USHORT PresenceDetectEnable:1; - USHORT CommandCompletedEnable:1; - USHORT HotPlugInterruptEnable:1; - USHORT AttentionIndicatorControl:2; - USHORT PowerIndicatorControl:2; - USHORT PowerControllerControl:1; - USHORT ElectromechanicalLockControl:1; - USHORT DataLinkStateChangeEnable:1; - USHORT Rsvd:3; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; - -typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { - struct { - USHORT AttentionButtonPressed:1; - USHORT PowerFaultDetected:1; - USHORT MRLSensorChanged:1; - USHORT PresenceDetectChanged:1; - USHORT CommandCompleted:1; - USHORT MRLSensorState:1; - USHORT PresenceDetectState:1; - USHORT ElectromechanicalLockEngaged:1; - USHORT DataLinkStateChanged:1; - USHORT Rsvd:7; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_SLOT_STATUS_REGISTER, *PPCI_EXPRESS_SLOT_STATUS_REGISTER; - -typedef union _PCI_EXPRESS_ROOT_CONTROL_REGISTER { - struct { - USHORT CorrectableSerrEnable:1; - USHORT NonFatalSerrEnable:1; - USHORT FatalSerrEnable:1; - USHORT PMEInterruptEnable:1; - USHORT CRSSoftwareVisibilityEnable:1; - USHORT Rsvd:11; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_ROOT_CONTROL_REGISTER, *PPCI_EXPRESS_ROOT_CONTROL_REGISTER; - -typedef union _PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER { - struct { - USHORT CRSSoftwareVisibility:1; - USHORT Rsvd:15; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_ROOT_CAPABILITIES_REGISTER; - -typedef union _PCI_EXPRESS_ROOT_STATUS_REGISTER { - struct { - ULONG PMERequestorId:16; - ULONG PMEStatus:1; - ULONG PMEPending:1; - ULONG Rsvd:14; - } DUMMYSTRUCTNAME; - ULONG AsULONG; -} PCI_EXPRESS_ROOT_STATUS_REGISTER, *PPCI_EXPRESS_ROOT_STATUS_REGISTER; - -typedef struct _PCI_EXPRESS_CAPABILITY { - PCI_CAPABILITIES_HEADER Header; - PCI_EXPRESS_CAPABILITIES_REGISTER ExpressCapabilities; - PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER DeviceCapabilities; - PCI_EXPRESS_DEVICE_CONTROL_REGISTER DeviceControl; - PCI_EXPRESS_DEVICE_STATUS_REGISTER DeviceStatus; - PCI_EXPRESS_LINK_CAPABILITIES_REGISTER LinkCapabilities; - PCI_EXPRESS_LINK_CONTROL_REGISTER LinkControl; - PCI_EXPRESS_LINK_STATUS_REGISTER LinkStatus; - PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER SlotCapabilities; - PCI_EXPRESS_SLOT_CONTROL_REGISTER SlotControl; - PCI_EXPRESS_SLOT_STATUS_REGISTER SlotStatus; - PCI_EXPRESS_ROOT_CONTROL_REGISTER RootControl; - PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER RootCapabilities; - PCI_EXPRESS_ROOT_STATUS_REGISTER RootStatus; -} PCI_EXPRESS_CAPABILITY, *PPCI_EXPRESS_CAPABILITY; - -typedef enum { - MRLClosed = 0, - MRLOpen -} PCI_EXPRESS_MRL_STATE; - -typedef enum { - SlotEmpty = 0, - CardPresent -} PCI_EXPRESS_CARD_PRESENCE; - -typedef enum { - IndicatorOn = 1, - IndicatorBlink, - IndicatorOff -} PCI_EXPRESS_INDICATOR_STATE; - -typedef enum { - PowerOn = 0, - PowerOff -} PCI_EXPRESS_POWER_STATE; - -typedef enum { - L0sEntrySupport = 1, - L0sAndL1EntrySupport = 3 -} PCI_EXPRESS_ASPM_SUPPORT; - -typedef enum { - L0sAndL1EntryDisabled, - L0sEntryEnabled, - L1EntryEnabled, - L0sAndL1EntryEnabled -} PCI_EXPRESS_ASPM_CONTROL; - -typedef enum { - L0s_Below64ns = 0, - L0s_64ns_128ns, - L0s_128ns_256ns, - L0s_256ns_512ns, - L0s_512ns_1us, - L0s_1us_2us, - L0s_2us_4us, - L0s_Above4us -} PCI_EXPRESS_L0s_EXIT_LATENCY; - -typedef enum { - L1_Below1us = 0, - L1_1us_2us, - L1_2us_4us, - L1_4us_8us, - L1_8us_16us, - L1_16us_32us, - L1_32us_64us, - L1_Above64us -} PCI_EXPRESS_L1_EXIT_LATENCY; - -typedef enum { - PciExpressEndpoint = 0, - PciExpressLegacyEndpoint, - PciExpressRootPort = 4, - PciExpressUpstreamSwitchPort, - PciExpressDownstreamSwitchPort, - PciExpressToPciXBridge, - PciXToExpressBridge, - PciExpressRootComplexIntegratedEndpoint, - PciExpressRootComplexEventCollector -} PCI_EXPRESS_DEVICE_TYPE; - -typedef enum { - MaxPayload128Bytes = 0, - MaxPayload256Bytes, - MaxPayload512Bytes, - MaxPayload1024Bytes, - MaxPayload2048Bytes, - MaxPayload4096Bytes -} PCI_EXPRESS_MAX_PAYLOAD_SIZE; - -typedef union _PCI_EXPRESS_PME_REQUESTOR_ID { - struct { - USHORT FunctionNumber:3; - USHORT DeviceNumber:5; - USHORT BusNumber:8; - } DUMMYSTRUCTNAME; - USHORT AsUSHORT; -} PCI_EXPRESS_PME_REQUESTOR_ID, *PPCI_EXPRESS_PME_REQUESTOR_ID; - -#if defined(_WIN64) - -#ifndef USE_DMA_MACROS -#define USE_DMA_MACROS -#endif - -#ifndef NO_LEGACY_DRIVERS -#define NO_LEGACY_DRIVERS -#endif - -#endif /* defined(_WIN64) */ - -typedef enum _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE { - ResourceTypeSingle = 0, - ResourceTypeRange, - ResourceTypeExtendedCounterConfiguration, - ResourceTypeOverflow, - ResourceTypeMax -} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE; - -typedef struct _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR { - PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE Type; - ULONG Flags; - union { - ULONG CounterIndex; - ULONG ExtendedRegisterAddress; - struct { - ULONG Begin; - ULONG End; - } Range; - } u; -} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR, *PPHYSICAL_COUNTER_RESOURCE_DESCRIPTOR; - -typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { - ULONG Count; - PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; -} PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; - -typedef VOID -(NTAPI *PciPin2Line)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciData); - -typedef VOID -(NTAPI *PciLine2Pin)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciNewData, - IN PPCI_COMMON_CONFIG PciOldData); - -typedef VOID -(NTAPI *PciReadWriteConfig)( - IN struct _BUS_HANDLER *BusHandler, - IN PCI_SLOT_NUMBER Slot, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -#define PCI_DATA_TAG ' ICP' -#define PCI_DATA_VERSION 1 - -typedef struct _PCIBUSDATA { - ULONG Tag; - ULONG Version; - PciReadWriteConfig ReadConfig; - PciReadWriteConfig WriteConfig; - PciPin2Line Pin2Line; - PciLine2Pin Line2Pin; - PCI_SLOT_NUMBER ParentSlot; - PVOID Reserved[4]; -} PCIBUSDATA, *PPCIBUSDATA; - -#ifndef _PCIINTRF_X_ -#define _PCIINTRF_X_ - -typedef ULONG -(NTAPI *PCI_READ_WRITE_CONFIG)( - IN PVOID Context, - IN ULONG BusOffset, - IN ULONG Slot, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -typedef VOID -(NTAPI *PCI_PIN_TO_LINE)( - IN PVOID Context, - IN PPCI_COMMON_CONFIG PciData); - -typedef VOID -(NTAPI *PCI_LINE_TO_PIN)( - IN PVOID Context, - IN PPCI_COMMON_CONFIG PciNewData, - IN PPCI_COMMON_CONFIG PciOldData); - -typedef VOID -(NTAPI *PCI_ROOT_BUS_CAPABILITY)( - IN PVOID Context, - OUT PPCI_ROOT_BUS_HARDWARE_CAPABILITY HardwareCapability); - -typedef VOID -(NTAPI *PCI_EXPRESS_WAKE_CONTROL)( - IN PVOID Context, - IN BOOLEAN EnableWake); - -typedef struct _PCI_BUS_INTERFACE_STANDARD { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PCI_READ_WRITE_CONFIG ReadConfig; - PCI_READ_WRITE_CONFIG WriteConfig; - PCI_PIN_TO_LINE PinToLine; - PCI_LINE_TO_PIN LineToPin; - PCI_ROOT_BUS_CAPABILITY RootBusCapability; - PCI_EXPRESS_WAKE_CONTROL ExpressWakeControl; -} PCI_BUS_INTERFACE_STANDARD, *PPCI_BUS_INTERFACE_STANDARD; - -#define PCI_BUS_INTERFACE_STANDARD_VERSION 1 - -#endif /* _PCIINTRF_X_ */ - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX 0x00004000 -#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX 0x00008000 -#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX \ - (FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX | \ - FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX) - -#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_DEPRECATED 0x00000200 -#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_DEPRECATED 0x00000300 -#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_DEPRECATED 0x00000300 - -#else - -#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL 0x00000200 -#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL 0x00000300 -#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK 0x00000300 - -#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL -#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL -#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, @@ -1134,6 +422,39 @@ typedef struct _PM_DISPATCH_TABLE { PVOID Function[1]; } PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; +typedef enum _RESOURCE_TRANSLATION_DIRECTION { + TranslateChildToParent, + TranslateParentToChild +} RESOURCE_TRANSLATION_DIRECTION; + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( + IN OUT PVOID Context, + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, + IN RESOURCE_TRANSLATION_DIRECTION Direction, + IN ULONG AlternativesCount OPTIONAL, + IN IO_RESOURCE_DESCRIPTOR Alternatives[], + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( + IN PVOID Context OPTIONAL, + IN PIO_RESOURCE_DESCRIPTOR Source, + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PULONG TargetCount, + OUT PIO_RESOURCE_DESCRIPTOR *Target); + +typedef struct _TRANSLATOR_INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PTRANSLATE_RESOURCE_HANDLER TranslateResources; + PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; +} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; + typedef VOID (FASTCALL *pHalExamineMBR)( IN PDEVICE_OBJECT DeviceObject, @@ -2546,10 +1867,42 @@ FsRtlIsTotalDeviceFailure( /* Hardware Abstraction Layer Types */ +typedef VOID +(NTAPI *PciPin2Line)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); +typedef VOID +(NTAPI *PciLine2Pin)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); +typedef VOID +(NTAPI *PciReadWriteConfig)( + IN struct _BUS_HANDLER *BusHandler, + IN PCI_SLOT_NUMBER Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); +#define PCI_DATA_TAG ' ICP' +#define PCI_DATA_VERSION 1 +typedef struct _PCIBUSDATA { + ULONG Tag; + ULONG Version; + PciReadWriteConfig ReadConfig; + PciReadWriteConfig WriteConfig; + PciPin2Line Pin2Line; + PciLine2Pin Line2Pin; + PCI_SLOT_NUMBER ParentSlot; + PVOID Reserved[4]; +} PCIBUSDATA, *PPCIBUSDATA; /* Hardware Abstraction Layer Functions */ From 3cbb0a3c40b54b940ccb2d411b37d91633e2b9aa Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 22:25:25 +0000 Subject: [PATCH 210/292] [DDK] 2nd try, this time adding half of the structures. svn path=/trunk/; revision=47555 --- reactos/include/ddk/ntddk.h | 381 ++++++++++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 4189edf733f..7e3e9bab789 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -322,6 +322,387 @@ typedef struct _ARBITER_INTERFACE { ULONG Flags; } ARBITER_INTERFACE, *PARBITER_INTERFACE; +typedef struct _PCI_AGP_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + USHORT Minor:4; + USHORT Major:4; + USHORT Rsvd1:8; + struct _PCI_AGP_STATUS { + ULONG Rate:3; + ULONG Agp3Mode:1; + ULONG FastWrite:1; + ULONG FourGB:1; + ULONG HostTransDisable:1; + ULONG Gart64:1; + ULONG ITA_Coherent:1; + ULONG SideBandAddressing:1; + ULONG CalibrationCycle:3; + ULONG AsyncRequestSize:3; + ULONG Rsvd1:1; + ULONG Isoch:1; + ULONG Rsvd2:6; + ULONG RequestQueueDepthMaximum:8; + } AGPStatus; + struct _PCI_AGP_COMMAND { + ULONG Rate:3; + ULONG Rsvd1:1; + ULONG FastWriteEnable:1; + ULONG FourGBEnable:1; + ULONG Rsvd2:1; + ULONG Gart64:1; + ULONG AGPEnable:1; + ULONG SBAEnable:1; + ULONG CalibrationCycle:3; + ULONG AsyncReqSize:3; + ULONG Rsvd3:8; + ULONG RequestQueueDepth:8; + } AGPCommand; +} PCI_AGP_CAPABILITY, *PPCI_AGP_CAPABILITY; + +typedef enum _EXTENDED_AGP_REGISTER { + IsochStatus, + AgpControl, + ApertureSize, + AperturePageSize, + GartLow, + GartHigh, + IsochCommand +} EXTENDED_AGP_REGISTER, *PEXTENDED_AGP_REGISTER; + +typedef struct _PCI_AGP_ISOCH_STATUS { + ULONG ErrorCode:2; + ULONG Rsvd1:1; + ULONG Isoch_L:3; + ULONG Isoch_Y:2; + ULONG Isoch_N:8; + ULONG Rsvd2:16; +} PCI_AGP_ISOCH_STATUS, *PPCI_AGP_ISOCH_STATUS; + +typedef struct _PCI_AGP_CONTROL { + ULONG Rsvd1:7; + ULONG GTLB_Enable:1; + ULONG AP_Enable:1; + ULONG CAL_Disable:1; + ULONG Rsvd2:22; +} PCI_AGP_CONTROL, *PPCI_AGP_CONTROL; + +typedef struct _PCI_AGP_APERTURE_PAGE_SIZE { + USHORT PageSizeMask:11; + USHORT Rsvd1:1; + USHORT PageSizeSelect:4; +} PCI_AGP_APERTURE_PAGE_SIZE, *PPCI_AGP_APERTURE_PAGE_SIZE; + +typedef struct _PCI_AGP_ISOCH_COMMAND { + USHORT Rsvd1:6; + USHORT Isoch_Y:2; + USHORT Isoch_N:8; +} PCI_AGP_ISOCH_COMMAND, *PPCI_AGP_ISOCH_COMMAND; + +typedef struct PCI_AGP_EXTENDED_CAPABILITY { + PCI_AGP_ISOCH_STATUS IsochStatus; + PCI_AGP_CONTROL AgpControl; + USHORT ApertureSize; + PCI_AGP_APERTURE_PAGE_SIZE AperturePageSize; + ULONG GartLow; + ULONG GartHigh; + PCI_AGP_ISOCH_COMMAND IsochCommand; +} PCI_AGP_EXTENDED_CAPABILITY, *PPCI_AGP_EXTENDED_CAPABILITY; + +#define PCI_AGP_RATE_1X 0x1 +#define PCI_AGP_RATE_2X 0x2 +#define PCI_AGP_RATE_4X 0x4 + +#define PCIX_MODE_CONVENTIONAL_PCI 0x0 +#define PCIX_MODE1_66MHZ 0x1 +#define PCIX_MODE1_100MHZ 0x2 +#define PCIX_MODE1_133MHZ 0x3 +#define PCIX_MODE2_266_66MHZ 0x9 +#define PCIX_MODE2_266_100MHZ 0xA +#define PCIX_MODE2_266_133MHZ 0xB +#define PCIX_MODE2_533_66MHZ 0xD +#define PCIX_MODE2_533_100MHZ 0xE +#define PCIX_MODE2_533_133MHZ 0xF + +#define PCIX_VERSION_MODE1_ONLY 0x0 +#define PCIX_VERSION_MODE2_ECC 0x1 +#define PCIX_VERSION_DUAL_MODE_ECC 0x2 + +typedef struct _PCIX_BRIDGE_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + union { + struct { + USHORT Bus64Bit:1; + USHORT Bus133MHzCapable:1; + USHORT SplitCompletionDiscarded:1; + USHORT UnexpectedSplitCompletion:1; + USHORT SplitCompletionOverrun:1; + USHORT SplitRequestDelayed:1; + USHORT BusModeFrequency:4; + USHORT Rsvd:2; + USHORT Version:2; + USHORT Bus266MHzCapable:1; + USHORT Bus533MHzCapable:1; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; + } SecondaryStatus; + union { + struct { + ULONG FunctionNumber:3; + ULONG DeviceNumber:5; + ULONG BusNumber:8; + ULONG Device64Bit:1; + ULONG Device133MHzCapable:1; + ULONG SplitCompletionDiscarded:1; + ULONG UnexpectedSplitCompletion:1; + ULONG SplitCompletionOverrun:1; + ULONG SplitRequestDelayed:1; + ULONG Rsvd:7; + ULONG DIMCapable:1; + ULONG Device266MHzCapable:1; + ULONG Device533MHzCapable:1; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } BridgeStatus; + USHORT UpstreamSplitTransactionCapacity; + USHORT UpstreamSplitTransactionLimit; + USHORT DownstreamSplitTransactionCapacity; + USHORT DownstreamSplitTransactionLimit; + union { + struct { + ULONG SelectSecondaryRegisters:1; + ULONG ErrorPresentInOtherBank:1; + ULONG AdditionalCorrectableError:1; + ULONG AdditionalUncorrectableError:1; + ULONG ErrorPhase:3; + ULONG ErrorCorrected:1; + ULONG Syndrome:8; + ULONG ErrorFirstCommand:4; + ULONG ErrorSecondCommand:4; + ULONG ErrorUpperAttributes:4; + ULONG ControlUpdateEnable:1; + ULONG Rsvd:1; + ULONG DisableSingleBitCorrection:1; + ULONG EccMode:1; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } EccControlStatus; + ULONG EccFirstAddress; + ULONG EccSecondAddress; + ULONG EccAttribute; +} PCIX_BRIDGE_CAPABILITY, *PPCIX_BRIDGE_CAPABILITY; + +typedef struct _PCI_SUBSYSTEM_IDS_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + USHORT Reserved; + USHORT SubVendorID; + USHORT SubSystemID; +} PCI_SUBSYSTEM_IDS_CAPABILITY, *PPCI_SUBSYSTEM_IDS_CAPABILITY; + +#define OSC_FIRMWARE_FAILURE 0x02 +#define OSC_UNRECOGNIZED_UUID 0x04 +#define OSC_UNRECOGNIZED_REVISION 0x08 +#define OSC_CAPABILITIES_MASKED 0x10 + +#define PCI_ROOT_BUS_OSC_METHOD_CAPABILITY_REVISION 0x01 + +typedef struct _PCI_ROOT_BUS_OSC_SUPPORT_FIELD { + union { + struct { + ULONG ExtendedConfigOpRegions:1; + ULONG ActiveStatePowerManagement:1; + ULONG ClockPowerManagement:1; + ULONG SegmentGroups:1; + ULONG MessageSignaledInterrupts:1; + ULONG WindowsHardwareErrorArchitecture:1; + ULONG Reserved:26; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } u; +} PCI_ROOT_BUS_OSC_SUPPORT_FIELD, *PPCI_ROOT_BUS_OSC_SUPPORT_FIELD; + +typedef struct _PCI_ROOT_BUS_OSC_CONTROL_FIELD { + union { + struct { + ULONG ExpressNativeHotPlug:1; + ULONG ShpcNativeHotPlug:1; + ULONG ExpressNativePME:1; + ULONG ExpressAdvancedErrorReporting:1; + ULONG ExpressCapabilityStructure:1; + ULONG Reserved:27; + } DUMMYSTRUCTNAME; + ULONG AsULONG; + } u; +} PCI_ROOT_BUS_OSC_CONTROL_FIELD, *PPCI_ROOT_BUS_OSC_CONTROL_FIELD; + +typedef enum _PCI_HARDWARE_INTERFACE { + PciConventional, + PciXMode1, + PciXMode2, + PciExpress +} PCI_HARDWARE_INTERFACE, *PPCI_HARDWARE_INTERFACE; + +typedef enum { + BusWidth32Bits, + BusWidth64Bits +} PCI_BUS_WIDTH; + +typedef struct _PCI_ROOT_BUS_HARDWARE_CAPABILITY { + PCI_HARDWARE_INTERFACE SecondaryInterface; + struct { + BOOLEAN BusCapabilitiesFound; + ULONG CurrentSpeedAndMode; + ULONG SupportedSpeedsAndModes; + BOOLEAN DeviceIDMessagingCapable; + PCI_BUS_WIDTH SecondaryBusWidth; + } DUMMYSTRUCTNAME; + PCI_ROOT_BUS_OSC_SUPPORT_FIELD OscFeatureSupport; + PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlRequest; + PCI_ROOT_BUS_OSC_CONTROL_FIELD OscControlGranted; +} PCI_ROOT_BUS_HARDWARE_CAPABILITY, *PPCI_ROOT_BUS_HARDWARE_CAPABILITY; + +typedef union _PCI_EXPRESS_CAPABILITIES_REGISTER { + struct { + USHORT CapabilityVersion:4; + USHORT DeviceType:4; + USHORT SlotImplemented:1; + USHORT InterruptMessageNumber:5; + USHORT Rsvd:2; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_CAPABILITIES_REGISTER, *PPCI_EXPRESS_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER { + struct { + ULONG MaxPayloadSizeSupported:3; + ULONG PhantomFunctionsSupported:2; + ULONG ExtendedTagSupported:1; + ULONG L0sAcceptableLatency:3; + ULONG L1AcceptableLatency:3; + ULONG Undefined:3; + ULONG RoleBasedErrorReporting:1; + ULONG Rsvd1:2; + ULONG CapturedSlotPowerLimit:8; + ULONG CapturedSlotPowerLimitScale:2; + ULONG Rsvd2:4; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER, *PPCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER; + +#define PCI_EXPRESS_AER_DEVICE_CONTROL_MASK 0x07; + +typedef union _PCI_EXPRESS_DEVICE_CONTROL_REGISTER { + struct { + USHORT CorrectableErrorEnable:1; + USHORT NonFatalErrorEnable:1; + USHORT FatalErrorEnable:1; + USHORT UnsupportedRequestErrorEnable:1; + USHORT EnableRelaxedOrder:1; + USHORT MaxPayloadSize:3; + USHORT ExtendedTagEnable:1; + USHORT PhantomFunctionsEnable:1; + USHORT AuxPowerEnable:1; + USHORT NoSnoopEnable:1; + USHORT MaxReadRequestSize:3; + USHORT BridgeConfigRetryEnable:1; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_DEVICE_CONTROL_REGISTER, *PPCI_EXPRESS_DEVICE_CONTROL_REGISTER; + +#define PCI_EXPRESS_AER_DEVICE_STATUS_MASK 0x0F; + +typedef union _PCI_EXPRESS_DEVICE_STATUS_REGISTER { + struct { + USHORT CorrectableErrorDetected:1; + USHORT NonFatalErrorDetected:1; + USHORT FatalErrorDetected:1; + USHORT UnsupportedRequestDetected:1; + USHORT AuxPowerDetected:1; + USHORT TransactionsPending:1; + USHORT Rsvd:10; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_DEVICE_STATUS_REGISTER, *PPCI_EXPRESS_DEVICE_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_LINK_CAPABILITIES_REGISTER { + struct { + ULONG MaximumLinkSpeed:4; + ULONG MaximumLinkWidth:6; + ULONG ActiveStatePMSupport:2; + ULONG L0sExitLatency:3; + ULONG L1ExitLatency:3; + ULONG ClockPowerManagement:1; + ULONG SurpriseDownErrorReportingCapable:1; + ULONG DataLinkLayerActiveReportingCapable:1; + ULONG Rsvd:3; + ULONG PortNumber:8; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_LINK_CAPABILITIES_REGISTER, *PPCI_EXPRESS_LINK_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_LINK_CONTROL_REGISTER { + struct { + USHORT ActiveStatePMControl:2; + USHORT Rsvd1:1; + USHORT ReadCompletionBoundary:1; + USHORT LinkDisable:1; + USHORT RetrainLink:1; + USHORT CommonClockConfig:1; + USHORT ExtendedSynch:1; + USHORT EnableClockPowerManagement:1; + USHORT Rsvd2:7; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_LINK_CONTROL_REGISTER, *PPCI_EXPRESS_LINK_CONTROL_REGISTER; + +typedef union _PCI_EXPRESS_LINK_STATUS_REGISTER { + struct { + USHORT LinkSpeed:4; + USHORT LinkWidth:6; + USHORT Undefined:1; + USHORT LinkTraining:1; + USHORT SlotClockConfig:1; + USHORT DataLinkLayerActive:1; + USHORT Rsvd:2; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_LINK_STATUS_REGISTER, *PPCI_EXPRESS_LINK_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER { + struct { + ULONG AttentionButtonPresent:1; + ULONG PowerControllerPresent:1; + ULONG MRLSensorPresent:1; + ULONG AttentionIndicatorPresent:1; + ULONG PowerIndicatorPresent:1; + ULONG HotPlugSurprise:1; + ULONG HotPlugCapable:1; + ULONG SlotPowerLimit:8; + ULONG SlotPowerLimitScale:2; + ULONG ElectromechanicalLockPresent:1; + ULONG NoCommandCompletedSupport:1; + ULONG PhysicalSlotNumber:13; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_SLOT_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { + struct { + USHORT AttentionButtonEnable:1; + USHORT PowerFaultDetectEnable:1; + USHORT MRLSensorEnable:1; + USHORT PresenceDetectEnable:1; + USHORT CommandCompletedEnable:1; + USHORT HotPlugInterruptEnable:1; + USHORT AttentionIndicatorControl:2; + USHORT PowerIndicatorControl:2; + USHORT PowerControllerControl:1; + USHORT ElectromechanicalLockControl:1; + USHORT DataLinkStateChangeEnable:1; + USHORT Rsvd:3; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; + typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, From 9bbc1250d2dd618878a8fc45651125cc036a246b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 23:08:40 +0000 Subject: [PATCH 211/292] [DDK] In an incredibly daring move, add even more types to ntddk.h svn path=/trunk/; revision=47556 --- reactos/include/ddk/ntddk.h | 261 ++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 7e3e9bab789..f8d1d3c1c29 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -703,6 +703,267 @@ typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { USHORT AsUSHORT; } PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; +typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { + struct { + USHORT AttentionButtonPressed:1; + USHORT PowerFaultDetected:1; + USHORT MRLSensorChanged:1; + USHORT PresenceDetectChanged:1; + USHORT CommandCompleted:1; + USHORT MRLSensorState:1; + USHORT PresenceDetectState:1; + USHORT ElectromechanicalLockEngaged:1; + USHORT DataLinkStateChanged:1; + USHORT Rsvd:7; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_SLOT_STATUS_REGISTER, *PPCI_EXPRESS_SLOT_STATUS_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_CONTROL_REGISTER { + struct { + USHORT CorrectableSerrEnable:1; + USHORT NonFatalSerrEnable:1; + USHORT FatalSerrEnable:1; + USHORT PMEInterruptEnable:1; + USHORT CRSSoftwareVisibilityEnable:1; + USHORT Rsvd:11; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_ROOT_CONTROL_REGISTER, *PPCI_EXPRESS_ROOT_CONTROL_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER { + struct { + USHORT CRSSoftwareVisibility:1; + USHORT Rsvd:15; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER, *PPCI_EXPRESS_ROOT_CAPABILITIES_REGISTER; + +typedef union _PCI_EXPRESS_ROOT_STATUS_REGISTER { + struct { + ULONG PMERequestorId:16; + ULONG PMEStatus:1; + ULONG PMEPending:1; + ULONG Rsvd:14; + } DUMMYSTRUCTNAME; + ULONG AsULONG; +} PCI_EXPRESS_ROOT_STATUS_REGISTER, *PPCI_EXPRESS_ROOT_STATUS_REGISTER; + +typedef struct _PCI_EXPRESS_CAPABILITY { + PCI_CAPABILITIES_HEADER Header; + PCI_EXPRESS_CAPABILITIES_REGISTER ExpressCapabilities; + PCI_EXPRESS_DEVICE_CAPABILITIES_REGISTER DeviceCapabilities; + PCI_EXPRESS_DEVICE_CONTROL_REGISTER DeviceControl; + PCI_EXPRESS_DEVICE_STATUS_REGISTER DeviceStatus; + PCI_EXPRESS_LINK_CAPABILITIES_REGISTER LinkCapabilities; + PCI_EXPRESS_LINK_CONTROL_REGISTER LinkControl; + PCI_EXPRESS_LINK_STATUS_REGISTER LinkStatus; + PCI_EXPRESS_SLOT_CAPABILITIES_REGISTER SlotCapabilities; + PCI_EXPRESS_SLOT_CONTROL_REGISTER SlotControl; + PCI_EXPRESS_SLOT_STATUS_REGISTER SlotStatus; + PCI_EXPRESS_ROOT_CONTROL_REGISTER RootControl; + PCI_EXPRESS_ROOT_CAPABILITIES_REGISTER RootCapabilities; + PCI_EXPRESS_ROOT_STATUS_REGISTER RootStatus; +} PCI_EXPRESS_CAPABILITY, *PPCI_EXPRESS_CAPABILITY; + +typedef enum { + MRLClosed = 0, + MRLOpen +} PCI_EXPRESS_MRL_STATE; + +typedef enum { + SlotEmpty = 0, + CardPresent +} PCI_EXPRESS_CARD_PRESENCE; + +typedef enum { + IndicatorOn = 1, + IndicatorBlink, + IndicatorOff +} PCI_EXPRESS_INDICATOR_STATE; + +typedef enum { + PowerOn = 0, + PowerOff +} PCI_EXPRESS_POWER_STATE; + +typedef enum { + L0sEntrySupport = 1, + L0sAndL1EntrySupport = 3 +} PCI_EXPRESS_ASPM_SUPPORT; + +typedef enum { + L0sAndL1EntryDisabled, + L0sEntryEnabled, + L1EntryEnabled, + L0sAndL1EntryEnabled +} PCI_EXPRESS_ASPM_CONTROL; + +typedef enum { + L0s_Below64ns = 0, + L0s_64ns_128ns, + L0s_128ns_256ns, + L0s_256ns_512ns, + L0s_512ns_1us, + L0s_1us_2us, + L0s_2us_4us, + L0s_Above4us +} PCI_EXPRESS_L0s_EXIT_LATENCY; + +typedef enum { + L1_Below1us = 0, + L1_1us_2us, + L1_2us_4us, + L1_4us_8us, + L1_8us_16us, + L1_16us_32us, + L1_32us_64us, + L1_Above64us +} PCI_EXPRESS_L1_EXIT_LATENCY; + +typedef enum { + PciExpressEndpoint = 0, + PciExpressLegacyEndpoint, + PciExpressRootPort = 4, + PciExpressUpstreamSwitchPort, + PciExpressDownstreamSwitchPort, + PciExpressToPciXBridge, + PciXToExpressBridge, + PciExpressRootComplexIntegratedEndpoint, + PciExpressRootComplexEventCollector +} PCI_EXPRESS_DEVICE_TYPE; + +typedef enum { + MaxPayload128Bytes = 0, + MaxPayload256Bytes, + MaxPayload512Bytes, + MaxPayload1024Bytes, + MaxPayload2048Bytes, + MaxPayload4096Bytes +} PCI_EXPRESS_MAX_PAYLOAD_SIZE; + +typedef union _PCI_EXPRESS_PME_REQUESTOR_ID { + struct { + USHORT FunctionNumber:3; + USHORT DeviceNumber:5; + USHORT BusNumber:8; + } DUMMYSTRUCTNAME; + USHORT AsUSHORT; +} PCI_EXPRESS_PME_REQUESTOR_ID, *PPCI_EXPRESS_PME_REQUESTOR_ID; + +#if defined(_WIN64) + +#ifndef USE_DMA_MACROS +#define USE_DMA_MACROS +#endif + +#ifndef NO_LEGACY_DRIVERS +#define NO_LEGACY_DRIVERS +#endif + +#endif /* defined(_WIN64) */ + +typedef enum _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE { + ResourceTypeSingle = 0, + ResourceTypeRange, + ResourceTypeExtendedCounterConfiguration, + ResourceTypeOverflow, + ResourceTypeMax +} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE; + +typedef struct _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR { + PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE Type; + ULONG Flags; + union { + ULONG CounterIndex; + ULONG ExtendedRegisterAddress; + struct { + ULONG Begin; + ULONG End; + } Range; + } u; +} PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR, *PPHYSICAL_COUNTER_RESOURCE_DESCRIPTOR; + +typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { + ULONG Count; + PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; +} PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; + +#ifndef _PCIINTRF_X_ +#define _PCIINTRF_X_ + +typedef ULONG +(NTAPI *PCI_READ_WRITE_CONFIG)( + IN PVOID Context, + IN ULONG BusOffset, + IN ULONG Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef VOID +(NTAPI *PCI_PIN_TO_LINE)( + IN PVOID Context, + IN PPCI_COMMON_CONFIG PciData); + +typedef VOID +(NTAPI *PCI_LINE_TO_PIN)( + IN PVOID Context, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +typedef VOID +(NTAPI *PCI_ROOT_BUS_CAPABILITY)( + IN PVOID Context, + OUT PPCI_ROOT_BUS_HARDWARE_CAPABILITY HardwareCapability); + +typedef VOID +(NTAPI *PCI_EXPRESS_WAKE_CONTROL)( + IN PVOID Context, + IN BOOLEAN EnableWake); + +typedef struct _PCI_BUS_INTERFACE_STANDARD { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PCI_READ_WRITE_CONFIG ReadConfig; + PCI_READ_WRITE_CONFIG WriteConfig; + PCI_PIN_TO_LINE PinToLine; + PCI_LINE_TO_PIN LineToPin; + PCI_ROOT_BUS_CAPABILITY RootBusCapability; + PCI_EXPRESS_WAKE_CONTROL ExpressWakeControl; +} PCI_BUS_INTERFACE_STANDARD, *PPCI_BUS_INTERFACE_STANDARD; + +#define PCI_BUS_INTERFACE_STANDARD_VERSION 1 + +#endif /* _PCIINTRF_X_ */ + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX 0x00004000 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX 0x00008000 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX \ + (FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX | \ + FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX) + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_DEPRECATED 0x00000200 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_DEPRECATED 0x00000300 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_DEPRECATED 0x00000300 + +#else + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL 0x00000200 +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL 0x00000300 +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK 0x00000300 + +#define FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_ORDERLY_REMOVAL +#define FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL_EX FILE_CHARACTERISTICS_EXPECT_SURPRISE_REMOVAL +#define FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK_EX FILE_CHARACTERISTICS_REMOVAL_POLICY_MASK + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, From a8d609e19d5c3343247504a6b525932ca778a3bd Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 23:18:20 +0000 Subject: [PATCH 212/292] [HAL] Include the correct headers for amd64 vs i386 svn path=/trunk/; revision=47557 --- reactos/hal/halx86/include/hal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/reactos/hal/halx86/include/hal.h b/reactos/hal/halx86/include/hal.h index 97e8f4a810e..0c3654f5ff8 100644 --- a/reactos/hal/halx86/include/hal.h +++ b/reactos/hal/halx86/include/hal.h @@ -32,11 +32,13 @@ /* Internal kernel headers */ #include "internal/pci.h" #define KeGetCurrentThread _KeGetCurrentThread -#include -#include #ifdef _M_AMD64 +#include +#include #include "internal/amd64/intrin_i.h" #else +#include +#include #include "internal/i386/intrin_i.h" #endif From a9cf165e5f5feb26a89b8f134e7a25bac881eb70 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 3 Jun 2010 23:40:33 +0000 Subject: [PATCH 213/292] [DDK] try to work around the testbot brokenness with an #if 0" svn path=/trunk/; revision=47558 --- reactos/include/ddk/ntddk.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index f8d1d3c1c29..0e02581425d 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -703,6 +703,7 @@ typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { USHORT AsUSHORT; } PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; +#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { struct { USHORT AttentionButtonPressed:1; @@ -964,6 +965,8 @@ typedef struct _PCI_BUS_INTERFACE_STANDARD { #endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ +#endif // 0 + typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, From babe335c713895b9309c2c5c8ce1318b8b58c6ea Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 00:19:39 +0000 Subject: [PATCH 214/292] [DDK] Merge the rest of the old header-branch version of ntddk.h, but with a large number of additional types #if 0'ed out svn path=/trunk/; revision=47559 --- reactos/include/ddk/ntddk.h | 6761 +++++++++++++++++++++++------------ 1 file changed, 4380 insertions(+), 2381 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 0e02581425d..1143aa4a545 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -1,12 +1,13 @@ /* * ntddk.h * - * Windows Device Driver Kit + * Windows NT Device Driver Kit * - * This file is part of the w32api package. + * This file is part of the ReactOS DDK package. * * Contributors: - * Created by Casper S. Hornstrup + * Amine Khaldi + * Timo Kreuzer (timo.kreuzer@reactos.org) * * THIS SOFTWARE IS NOT COPYRIGHTED * @@ -18,13 +19,10 @@ * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * DEFINES: - * DBG - Debugging enabled/disabled (0/1) - * POOL_TAGGING - Enable pool tagging - * _X86_ - X86 environment */ -#ifndef _NTDDK_ +#pragma once + #define _NTDDK_ #if !defined(_NTHAL_) && !defined(_NTIFS_) @@ -41,6 +39,7 @@ #include #include #include +#include /* FIXME #include @@ -55,21 +54,30 @@ extern "C" { #endif +/* GUID and UUID */ +#ifndef _NTLSA_IFS_ +#ifndef _NTLSA_AUDIT_ +#define _NTLSA_AUDIT_ + +#ifndef GUID_DEFINED +#include +#endif + +#endif /* _NTLSA_AUDIT_ */ +#endif /* _NTLSA_IFS_ */ + +typedef GUID UUID; + struct _LOADER_PARAMETER_BLOCK; struct _CREATE_DISK; struct _DRIVE_LAYOUT_INFORMATION_EX; struct _SET_PARTITION_INFORMATION_EX; -// -// GUID and UUID -// -#ifndef GUID_DEFINED -#include -#endif -typedef GUID UUID; - typedef struct _BUS_HANDLER *PBUS_HANDLER; - +typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT; +#if defined(_NTHAL_INCLUDED_) +typedef struct _KAFFINITY_EX *PKAFFINITY_EX; +#endif typedef struct _PEB *PPEB; #ifndef _NTIMAGE_ @@ -85,24 +93,89 @@ typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; #endif /* _NTIMAGE_ */ -#define EXCEPTION_READ_FAULT 0 -#define EXCEPTION_WRITE_FAULT 1 -#define EXCEPTION_EXECUTE_FAULT 8 +/****************************************************************************** + * Executive Types * + ******************************************************************************/ -#if (NTDDI_VERSION >= NTDDI_VISTA) -extern NTSYSAPI volatile CCHAR KeNumberProcessors; -#elif (NTDDI_VERSION >= NTDDI_WINXP) -extern NTSYSAPI CCHAR KeNumberProcessors; -#else -extern PCCHAR KeNumberProcessors; -#endif +typedef struct _ZONE_SEGMENT_HEADER { + SINGLE_LIST_ENTRY SegmentList; + PVOID Reserved; +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; -#define MAX_WOW64_SHARED_ENTRIES 16 +typedef struct _ZONE_HEADER { + SINGLE_LIST_ENTRY FreeList; + SINGLE_LIST_ENTRY SegmentList; + ULONG BlockSize; + ULONG TotalSegmentSize; +} ZONE_HEADER, *PZONE_HEADER; -#define NX_SUPPORT_POLICY_ALWAYSOFF 0 -#define NX_SUPPORT_POLICY_ALWAYSON 1 -#define NX_SUPPORT_POLICY_OPTIN 2 -#define NX_SUPPORT_POLICY_OPTOUT 3 +#define PROTECTED_POOL 0x80000000 + + +/****************************************************************************** + * I/O Manager Types * + ******************************************************************************/ + +/* DEVICE_OBJECT.Flags */ +#define DO_DEVICE_HAS_NAME 0x00000040 +#define DO_SYSTEM_BOOT_PARTITION 0x00000100 +#define DO_LONG_TERM_REQUESTS 0x00000200 +#define DO_NEVER_LAST_DEVICE 0x00000400 +#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 +#define DO_SUPPORTS_TRANSACTIONS 0x00040000 +#define DO_FORCE_NEITHER_IO 0x00080000 +#define DO_VOLUME_DEVICE_OBJECT 0x00100000 +#define DO_SYSTEM_SYSTEM_PARTITION 0x00200000 +#define DO_SYSTEM_CRITICAL_PARTITION 0x00400000 +#define DO_DISALLOW_EXECUTE 0x00800000 + +#ifndef _ARC_DDK_ +#define _ARC_DDK_ +typedef enum _CONFIGURATION_TYPE { + ArcSystem, + CentralProcessor, + FloatingPointProcessor, + PrimaryIcache, + PrimaryDcache, + SecondaryIcache, + SecondaryDcache, + SecondaryCache, + EisaAdapter, + TcAdapter, + ScsiAdapter, + DtiAdapter, + MultiFunctionAdapter, + DiskController, + TapeController, + CdromController, + WormController, + SerialController, + NetworkController, + DisplayController, + ParallelController, + PointerController, + KeyboardController, + AudioController, + OtherController, + DiskPeripheral, + FloppyDiskPeripheral, + TapePeripheral, + ModemPeripheral, + MonitorPeripheral, + PrinterPeripheral, + PointerPeripheral, + KeyboardPeripheral, + TerminalPeripheral, + OtherPeripheral, + LinePeripheral, + NetworkPeripheral, + SystemMemory, + DockingInformation, + RealModeIrqRoutingTable, + RealModePCIEnumeration, + MaximumType +} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; +#endif /* !_ARC_DDK_ */ /* ** IRP function codes @@ -137,102 +210,118 @@ extern PCCHAR KeNumberProcessors; #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 -typedef struct _IO_COUNTERS { - ULONGLONG ReadOperationCount; - ULONGLONG WriteOperationCount; - ULONGLONG OtherOperationCount; - ULONGLONG ReadTransferCount; - ULONGLONG WriteTransferCount; - ULONGLONG OtherTransferCount; -} IO_COUNTERS, *PIO_COUNTERS; +#define IO_CHECK_CREATE_PARAMETERS 0x0200 +#define IO_ATTACH_DEVICE 0x0400 +#define IO_IGNORE_SHARE_ACCESS_CHECK 0x0800 -typedef struct _VM_COUNTERS { - SIZE_T PeakVirtualSize; - SIZE_T VirtualSize; - ULONG PageFaultCount; - SIZE_T PeakWorkingSetSize; - SIZE_T WorkingSetSize; - SIZE_T QuotaPeakPagedPoolUsage; - SIZE_T QuotaPagedPoolUsage; - SIZE_T QuotaPeakNonPagedPoolUsage; - SIZE_T QuotaNonPagedPoolUsage; - SIZE_T PagefileUsage; - SIZE_T PeakPagefileUsage; -} VM_COUNTERS, *PVM_COUNTERS; +typedef +NTSTATUS +(NTAPI *PIO_QUERY_DEVICE_ROUTINE)( + IN PVOID Context, + IN PUNICODE_STRING PathName, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN PKEY_VALUE_FULL_INFORMATION *BusInformation, + IN CONFIGURATION_TYPE ControllerType, + IN ULONG ControllerNumber, + IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, + IN CONFIGURATION_TYPE PeripheralType, + IN ULONG PeripheralNumber, + IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); -typedef struct _VM_COUNTERS_EX -{ - SIZE_T PeakVirtualSize; - SIZE_T VirtualSize; - ULONG PageFaultCount; - SIZE_T PeakWorkingSetSize; - SIZE_T WorkingSetSize; - SIZE_T QuotaPeakPagedPoolUsage; - SIZE_T QuotaPagedPoolUsage; - SIZE_T QuotaPeakNonPagedPoolUsage; - SIZE_T QuotaNonPagedPoolUsage; - SIZE_T PagefileUsage; - SIZE_T PeakPagefileUsage; - SIZE_T PrivateUsage; -} VM_COUNTERS_EX, *PVM_COUNTERS_EX; +typedef enum _IO_QUERY_DEVICE_DATA_FORMAT { + IoQueryDeviceIdentifier = 0, + IoQueryDeviceConfigurationData, + IoQueryDeviceComponentInformation, + IoQueryDeviceMaxData +} IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT; -typedef struct _POOLED_USAGE_AND_LIMITS -{ - SIZE_T PeakPagedPoolUsage; - SIZE_T PagedPoolUsage; - SIZE_T PagedPoolLimit; - SIZE_T PeakNonPagedPoolUsage; - SIZE_T NonPagedPoolUsage; - SIZE_T NonPagedPoolLimit; - SIZE_T PeakPagefileUsage; - SIZE_T PagefileUsage; - SIZE_T PagefileLimit; -} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS; +typedef VOID +(NTAPI *PDRIVER_REINITIALIZE)( + IN struct _DRIVER_OBJECT *DriverObject, + IN PVOID Context OPTIONAL, + IN ULONG Count); -/* DEVICE_OBJECT.Flags */ - -#define DO_VERIFY_VOLUME 0x00000002 -#define DO_BUFFERED_IO 0x00000004 -#define DO_EXCLUSIVE 0x00000008 -#define DO_DIRECT_IO 0x00000010 -#define DO_MAP_IO_BUFFER 0x00000020 -#define DO_DEVICE_HAS_NAME 0x00000040 -#define DO_DEVICE_INITIALIZING 0x00000080 -#define DO_SYSTEM_BOOT_PARTITION 0x00000100 -#define DO_LONG_TERM_REQUESTS 0x00000200 -#define DO_NEVER_LAST_DEVICE 0x00000400 -#define DO_SHUTDOWN_REGISTERED 0x00000800 -#define DO_BUS_ENUMERATED_DEVICE 0x00001000 -#define DO_POWER_PAGABLE 0x00002000 -#define DO_POWER_INRUSH 0x00004000 -#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 -#define DO_SUPPORTS_TRANSACTIONS 0x00040000 -#define DO_FORCE_NEITHER_IO 0x00080000 -#define DO_VOLUME_DEVICE_OBJECT 0x00100000 -#define DO_SYSTEM_SYSTEM_PARTITION 0x00200000 -#define DO_SYSTEM_CRITICAL_PARTITION 0x00400000 -#define DO_DISALLOW_EXECUTE 0x00800000 +typedef struct _CONTROLLER_OBJECT { + CSHORT Type; + CSHORT Size; + PVOID ControllerExtension; + KDEVICE_QUEUE DeviceWaitQueue; + ULONG Spare1; + LARGE_INTEGER Spare2; +} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; #define DRVO_REINIT_REGISTERED 0x00000008 #define DRVO_INITIALIZED 0x00000010 #define DRVO_BOOTREINIT_REGISTERED 0x00000020 #define DRVO_LEGACY_RESOURCES 0x00000040 -typedef enum _ARBITER_REQUEST_SOURCE { - ArbiterRequestUndefined = -1, - ArbiterRequestLegacyReported, - ArbiterRequestHalReported, - ArbiterRequestLegacyAssigned, - ArbiterRequestPnpDetected, - ArbiterRequestPnpEnumerated -} ARBITER_REQUEST_SOURCE; +typedef struct _CONFIGURATION_INFORMATION { + ULONG DiskCount; + ULONG FloppyCount; + ULONG CdRomCount; + ULONG TapeCount; + ULONG ScsiPortCount; + ULONG SerialCount; + ULONG ParallelCount; + BOOLEAN AtDiskPrimaryAddressClaimed; + BOOLEAN AtDiskSecondaryAddressClaimed; + ULONG Version; + ULONG MediumChangerCount; +} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; -typedef enum _ARBITER_RESULT { - ArbiterResultUndefined = -1, - ArbiterResultSuccess, - ArbiterResultExternalConflict, - ArbiterResultNullRequest -} ARBITER_RESULT; +typedef struct _DISK_SIGNATURE { + ULONG PartitionStyle; + _ANONYMOUS_UNION union { + struct { + ULONG Signature; + ULONG CheckSum; + } Mbr; + struct { + GUID DiskId; + } Gpt; + } DUMMYUNIONNAME; +} DISK_SIGNATURE, *PDISK_SIGNATURE; + +typedef struct _TXN_PARAMETER_BLOCK { + USHORT Length; + USHORT TxFsContext; + PVOID TransactionObject; +} TXN_PARAMETER_BLOCK, *PTXN_PARAMETER_BLOCK; + +#define TXF_MINIVERSION_DEFAULT_VIEW (0xFFFE) + +typedef struct _IO_DRIVER_CREATE_CONTEXT { + CSHORT Size; + struct _ECP_LIST *ExtraCreateParameter; + PVOID DeviceObjectHint; + PTXN_PARAMETER_BLOCK TxnParameters; +} IO_DRIVER_CREATE_CONTEXT, *PIO_DRIVER_CREATE_CONTEXT; + +typedef struct _AGP_TARGET_BUS_INTERFACE_STANDARD { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PGET_SET_DEVICE_DATA SetBusData; + PGET_SET_DEVICE_DATA GetBusData; + UCHAR CapabilityID; +} AGP_TARGET_BUS_INTERFACE_STANDARD, *PAGP_TARGET_BUS_INTERFACE_STANDARD; + +typedef NTSTATUS +(NTAPI *PGET_LOCATION_STRING)( + IN OUT PVOID Context OPTIONAL, + OUT PWCHAR *LocationStrings); + +typedef struct _PNP_LOCATION_INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PGET_LOCATION_STRING GetLocationString; +} PNP_LOCATION_INTERFACE, *PPNP_LOCATION_INTERFACE; typedef enum _ARBITER_ACTION { ArbiterActionTestAllocation, @@ -253,39 +342,69 @@ typedef struct _ARBITER_CONFLICT_INFO { ULONGLONG End; } ARBITER_CONFLICT_INFO, *PARBITER_CONFLICT_INFO; -typedef struct _ARBITER_PARAMETERS { - union { - struct { +typedef struct _ARBITER_TEST_ALLOCATION_PARAMETERS { IN OUT PLIST_ENTRY ArbitrationList; IN ULONG AllocateFromCount; IN PCM_PARTIAL_RESOURCE_DESCRIPTOR AllocateFrom; - } TestAllocation; - struct { +} ARBITER_TEST_ALLOCATION_PARAMETERS, *PARBITER_TEST_ALLOCATION_PARAMETERS; + +typedef struct _ARBITER_RETEST_ALLOCATION_PARAMETERS { IN OUT PLIST_ENTRY ArbitrationList; IN ULONG AllocateFromCount; IN PCM_PARTIAL_RESOURCE_DESCRIPTOR AllocateFrom; - } RetestAllocation; - struct { +} ARBITER_RETEST_ALLOCATION_PARAMETERS, *PARBITER_RETEST_ALLOCATION_PARAMETERS; + +typedef struct _ARBITER_BOOT_ALLOCATION_PARAMETERS { IN OUT PLIST_ENTRY ArbitrationList; - } BootAllocation; - struct { +} ARBITER_BOOT_ALLOCATION_PARAMETERS, *PARBITER_BOOT_ALLOCATION_PARAMETERS; + +typedef struct _ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS { OUT PCM_PARTIAL_RESOURCE_LIST *AllocatedResources; - } QueryAllocatedResources; - struct { +} ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS, *PARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS; + +typedef struct _ARBITER_QUERY_CONFLICT_PARAMETERS { IN PDEVICE_OBJECT PhysicalDeviceObject; IN PIO_RESOURCE_DESCRIPTOR ConflictingResource; OUT PULONG ConflictCount; OUT PARBITER_CONFLICT_INFO *Conflicts; - } QueryConflict; - struct { +} ARBITER_QUERY_CONFLICT_PARAMETERS, *PARBITER_QUERY_CONFLICT_PARAMETERS; + +typedef struct _ARBITER_QUERY_ARBITRATE_PARAMETERS { IN PLIST_ENTRY ArbitrationList; - } QueryArbitrate; - struct { +} ARBITER_QUERY_ARBITRATE_PARAMETERS, *PARBITER_QUERY_ARBITRATE_PARAMETERS; + +typedef struct _ARBITER_ADD_RESERVED_PARAMETERS { IN PDEVICE_OBJECT ReserveDevice; - } AddReserved; +} ARBITER_ADD_RESERVED_PARAMETERS, *PARBITER_ADD_RESERVED_PARAMETERS; + +typedef struct _ARBITER_PARAMETERS { + union { + ARBITER_TEST_ALLOCATION_PARAMETERS TestAllocation; + ARBITER_RETEST_ALLOCATION_PARAMETERS RetestAllocation; + ARBITER_BOOT_ALLOCATION_PARAMETERS BootAllocation; + ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS QueryAllocatedResources; + ARBITER_QUERY_CONFLICT_PARAMETERS QueryConflict; + ARBITER_QUERY_ARBITRATE_PARAMETERS QueryArbitrate; + ARBITER_ADD_RESERVED_PARAMETERS AddReserved; } Parameters; } ARBITER_PARAMETERS, *PARBITER_PARAMETERS; +typedef enum _ARBITER_REQUEST_SOURCE { + ArbiterRequestUndefined = -1, + ArbiterRequestLegacyReported, + ArbiterRequestHalReported, + ArbiterRequestLegacyAssigned, + ArbiterRequestPnpDetected, + ArbiterRequestPnpEnumerated +} ARBITER_REQUEST_SOURCE; + +typedef enum _ARBITER_RESULT { + ArbiterResultUndefined = -1, + ArbiterResultSuccess, + ArbiterResultExternalConflict, + ArbiterResultNullRequest +} ARBITER_RESULT; + #define ARBITER_FLAG_BOOT_CONFIG 0x00000001 typedef struct _ARBITER_LIST_ENTRY { @@ -322,6 +441,41 @@ typedef struct _ARBITER_INTERFACE { ULONG Flags; } ARBITER_INTERFACE, *PARBITER_INTERFACE; +typedef enum _RESOURCE_TRANSLATION_DIRECTION { + TranslateChildToParent, + TranslateParentToChild +} RESOURCE_TRANSLATION_DIRECTION; + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( + IN OUT PVOID Context OPTIONAL, + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, + IN RESOURCE_TRANSLATION_DIRECTION Direction, + IN ULONG AlternativesCount OPTIONAL, + IN IO_RESOURCE_DESCRIPTOR Alternatives[], + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( + IN OUT PVOID Context OPTIONAL, + IN PIO_RESOURCE_DESCRIPTOR Source, + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PULONG TargetCount, + OUT PIO_RESOURCE_DESCRIPTOR *Target); + +typedef struct _TRANSLATOR_INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PTRANSLATE_RESOURCE_HANDLER TranslateResources; + PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; +} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; + +#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... + typedef struct _PCI_AGP_CAPABILITY { PCI_CAPABILITIES_HEADER Header; USHORT Minor:4; @@ -703,7 +857,6 @@ typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { USHORT AsUSHORT; } PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; -#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { struct { USHORT AttentionButtonPressed:1; @@ -890,6 +1043,43 @@ typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; } PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; +typedef VOID +(NTAPI *PciPin2Line)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); + +typedef VOID +(NTAPI *PciLine2Pin)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +typedef VOID +(NTAPI *PciReadWriteConfig)( + IN struct _BUS_HANDLER *BusHandler, + IN PCI_SLOT_NUMBER Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +#define PCI_DATA_TAG ' ICP' +#define PCI_DATA_VERSION 1 + +typedef struct _PCIBUSDATA { + ULONG Tag; + ULONG Version; + PciReadWriteConfig ReadConfig; + PciReadWriteConfig WriteConfig; + PciPin2Line Pin2Line; + PciLine2Pin Line2Pin; + PCI_SLOT_NUMBER ParentSlot; + PVOID Reserved[4]; +} PCIBUSDATA, *PPCIBUSDATA; + #ifndef _PCIINTRF_X_ #define _PCIINTRF_X_ @@ -967,6 +1157,114 @@ typedef struct _PCI_BUS_INTERFACE_STANDARD { #endif // 0 +#define FILE_CHARACTERISTICS_PROPAGATED ( FILE_REMOVABLE_MEDIA | \ + FILE_READ_ONLY_DEVICE | \ + FILE_FLOPPY_DISKETTE | \ + FILE_WRITE_ONCE_MEDIA | \ + FILE_DEVICE_SECURE_OPEN ) + +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + + +typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { + ULONG FileAttributes; + ULONG ReparseTag; +} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { + LARGE_INTEGER ValidDataLength; +} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; + +typedef struct _FILE_FS_LABEL_INFORMATION { + ULONG VolumeLabelLength; + WCHAR VolumeLabel[1]; +} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; + +typedef struct _FILE_FS_VOLUME_INFORMATION { + LARGE_INTEGER VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[1]; +} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; + +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +typedef struct _FILE_FS_FULL_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER CallerAvailableAllocationUnits; + LARGE_INTEGER ActualAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; + +typedef struct _FILE_FS_OBJECTID_INFORMATION { + UCHAR ObjectId[16]; + UCHAR ExtendedInfo[48]; +} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; + +typedef union _FILE_SEGMENT_ELEMENT { + PVOID64 Buffer; + ULONGLONG Alignment; +}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; + +#define IOCTL_AVIO_ALLOCATE_STREAM CTL_CODE(FILE_DEVICE_AVIO, 1, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define IOCTL_AVIO_FREE_STREAM CTL_CODE(FILE_DEVICE_AVIO, 2, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define IOCTL_AVIO_MODIFY_STREAM CTL_CODE(FILE_DEVICE_AVIO, 3, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) + +typedef enum _BUS_DATA_TYPE { + ConfigurationSpaceUndefined = -1, + Cmos, + EisaConfiguration, + Pos, + CbusConfiguration, + PCIConfiguration, + VMEConfiguration, + NuBusConfiguration, + PCMCIAConfiguration, + MPIConfiguration, + MPSAConfiguration, + PNPISAConfiguration, + SgiInternalConfiguration, + MaximumBusDataType +} BUS_DATA_TYPE, *PBUS_DATA_TYPE; + +/* Hardware Abstraction Layer Types */ + +typedef BOOLEAN +(NTAPI *PHAL_RESET_DISPLAY_PARAMETERS)( + IN ULONG Columns, + IN ULONG Rows); + +typedef PBUS_HANDLER +(FASTCALL *pHalHandlerForBus)( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber); + +typedef VOID +(FASTCALL *pHalReferenceBusHandler)( + IN PBUS_HANDLER BusHandler); + typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, @@ -1013,92 +1311,18 @@ typedef enum _HAL_SET_INFORMATION_CLASS { HalProfileDpgoSourceInterruptHandler } HAL_SET_INFORMATION_CLASS, *PHAL_SET_INFORMATION_CLASS; -typedef struct _HAL_PROFILE_SOURCE_INTERVAL { - KPROFILE_SOURCE Source; - ULONG_PTR Interval; -} HAL_PROFILE_SOURCE_INTERVAL, *PHAL_PROFILE_SOURCE_INTERVAL; - -typedef struct _HAL_PROFILE_SOURCE_INFORMATION { - KPROFILE_SOURCE Source; - BOOLEAN Supported; - ULONG Interval; -} HAL_PROFILE_SOURCE_INFORMATION, *PHAL_PROFILE_SOURCE_INFORMATION; - -typedef struct _MAP_REGISTER_ENTRY { - PVOID MapRegister; - BOOLEAN WriteToDevice; -} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; - -typedef struct _DEBUG_DEVICE_ADDRESS { - UCHAR Type; - BOOLEAN Valid; - UCHAR Reserved[2]; - PUCHAR TranslatedAddress; - ULONG Length; -} DEBUG_DEVICE_ADDRESS, *PDEBUG_DEVICE_ADDRESS; - -typedef struct _DEBUG_MEMORY_REQUIREMENTS { - PHYSICAL_ADDRESS Start; - PHYSICAL_ADDRESS MaxEnd; - PVOID VirtualAddress; - ULONG Length; - BOOLEAN Cached; - BOOLEAN Aligned; -} DEBUG_MEMORY_REQUIREMENTS, *PDEBUG_MEMORY_REQUIREMENTS; - -typedef struct _DEBUG_DEVICE_DESCRIPTOR { - ULONG Bus; - ULONG Slot; - USHORT Segment; - USHORT VendorID; - USHORT DeviceID; - UCHAR BaseClass; - UCHAR SubClass; - UCHAR ProgIf; - BOOLEAN Initialized; - BOOLEAN Configured; - DEBUG_DEVICE_ADDRESS BaseAddress[6]; - DEBUG_MEMORY_REQUIREMENTS Memory; -} DEBUG_DEVICE_DESCRIPTOR, *PDEBUG_DEVICE_DESCRIPTOR; - -typedef struct _PM_DISPATCH_TABLE { - ULONG Signature; - ULONG Version; - PVOID Function[1]; -} PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; - -typedef enum _RESOURCE_TRANSLATION_DIRECTION { - TranslateChildToParent, - TranslateParentToChild -} RESOURCE_TRANSLATION_DIRECTION; +typedef NTSTATUS +(NTAPI *pHalQuerySystemInformation)( + IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength); typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( - IN OUT PVOID Context, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, - IN RESOURCE_TRANSLATION_DIRECTION Direction, - IN ULONG AlternativesCount OPTIONAL, - IN IO_RESOURCE_DESCRIPTOR Alternatives[], - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( - IN PVOID Context OPTIONAL, - IN PIO_RESOURCE_DESCRIPTOR Source, - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PULONG TargetCount, - OUT PIO_RESOURCE_DESCRIPTOR *Target); - -typedef struct _TRANSLATOR_INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PTRANSLATE_RESOURCE_HANDLER TranslateResources; - PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; -} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; +(NTAPI *pHalSetSystemInformation)( + IN HAL_SET_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN PVOID Buffer); typedef VOID (FASTCALL *pHalExamineMBR)( @@ -1129,28 +1353,6 @@ typedef NTSTATUS IN ULONG NumberOfHeads, IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); -typedef PBUS_HANDLER -(FASTCALL *pHalHandlerForBus)( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber); - -typedef VOID -(FASTCALL *pHalReferenceBusHandler)( - IN PBUS_HANDLER BusHandler); - -typedef NTSTATUS -(NTAPI *pHalQuerySystemInformation)( - IN HAL_QUERY_INFORMATION_CLASS InformationClass, - IN ULONG BufferSize, - IN OUT PVOID Buffer, - OUT PULONG ReturnedLength); - -typedef NTSTATUS -(NTAPI *pHalSetSystemInformation)( - IN HAL_SET_INFORMATION_CLASS InformationClass, - IN ULONG BufferSize, - IN PVOID Buffer); - typedef NTSTATUS (NTAPI *pHalQueryBusSlots)( IN PBUS_HANDLER BusHandler, @@ -1162,6 +1364,12 @@ typedef NTSTATUS (NTAPI *pHalInitPnpDriver)( VOID); +typedef struct _PM_DISPATCH_TABLE { + ULONG Signature; + ULONG Version; + PVOID Function[1]; +} PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; + typedef NTSTATUS (NTAPI *pHalInitPowerManagement)( IN PPM_DISPATCH_TABLE PmDriverDispatchTable, @@ -1201,12 +1409,7 @@ typedef NTSTATUS IN PHYSICAL_ADDRESS PhysicalAddress, IN LARGE_INTEGER NumberOfBytes); -typedef VOID -(NTAPI *pHalEndOfBoot)( - VOID); - -typedef -BOOLEAN +typedef BOOLEAN (NTAPI *pHalTranslateBusAddress)( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, @@ -1214,8 +1417,7 @@ BOOLEAN IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress); -typedef -NTSTATUS +typedef NTSTATUS (NTAPI *pHalAssignSlotResources)( IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING DriverClassName OPTIONAL, @@ -1226,23 +1428,24 @@ NTSTATUS IN ULONG SlotNumber, IN OUT PCM_RESOURCE_LIST *AllocatedResources); -typedef -VOID +typedef VOID (NTAPI *pHalHaltSystem)( VOID); -typedef -BOOLEAN +typedef BOOLEAN (NTAPI *pHalResetDisplay)( VOID); -typedef -UCHAR +typedef struct _MAP_REGISTER_ENTRY { + PVOID MapRegister; + BOOLEAN WriteToDevice; +} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; + +typedef UCHAR (NTAPI *pHalVectorToIDTEntry)( ULONG Vector); -typedef -BOOLEAN +typedef BOOLEAN (NTAPI *pHalFindBusAddressTranslation)( IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, @@ -1250,94 +1453,33 @@ BOOLEAN IN OUT PULONG_PTR Context, IN BOOLEAN NextBus); -typedef -NTSTATUS -(NTAPI *pKdSetupPciDeviceForDebugging)( - IN PVOID LoaderBlock OPTIONAL, - IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); +typedef VOID +(NTAPI *pHalEndOfBoot)( + VOID); -typedef -NTSTATUS -(NTAPI *pKdReleasePciDeviceForDebugging)( - IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); - -typedef -PVOID -(NTAPI *pKdGetAcpiTablePhase0)( - IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, - IN ULONG Signature); - -typedef -PVOID +typedef PVOID (NTAPI *pHalGetAcpiTable)( IN ULONG Signature, IN PCSTR OemId OPTIONAL, IN PCSTR OemTableId OPTIONAL); -typedef -VOID -(NTAPI *pKdCheckPowerButton)( - VOID); +#if defined(_IA64_) +typedef NTSTATUS +(*pHalGetErrorCapList)( + IN OUT PULONG CapsListLength, + IN OUT PUCHAR ErrorCapList); -#if (NTDDI_VERSION >= NTDDI_VISTA) -typedef -PVOID -(NTAPI *pKdMapPhysicalMemory64)( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberPages, - IN BOOLEAN FlushCurrentTLB); - -typedef -VOID -(NTAPI *pKdUnmapVirtualAddress)( - IN PVOID VirtualAddress, - IN ULONG NumberPages, - IN BOOLEAN FlushCurrentTLB); -#else -typedef -PVOID -(NTAPI *pKdMapPhysicalMemory64)( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberPages); - -typedef -VOID -(NTAPI *pKdUnmapVirtualAddress)( - IN PVOID VirtualAddress, - IN ULONG NumberPages); +typedef NTSTATUS +(*pHalInjectError)( + IN ULONG BufferLength, + IN PUCHAR Buffer); #endif - -typedef -ULONG -(NTAPI *pKdGetPciDataByOffset)( - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -typedef -ULONG -(NTAPI *pKdSetPciDataByOffset)( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -typedef BOOLEAN -(NTAPI *PHAL_RESET_DISPLAY_PARAMETERS)( - IN ULONG Columns, - IN ULONG Rows); - -typedef -VOID +typedef VOID (NTAPI *PCI_ERROR_HANDLER_CALLBACK)( VOID); -typedef -VOID +typedef VOID (NTAPI *pHalSetPciErrorHandlerCallback)( IN PCI_ERROR_HANDLER_CALLBACK Callback); @@ -1411,78 +1553,706 @@ extern NTKERNELAPI HAL_DISPATCH HalDispatchTable; #define HalMirrorPhysicalMemory HALDISPATCH->HalMirrorPhysicalMemory #define HalEndOfBoot HALDISPATCH->HalEndOfBoot #define HalMirrorVerify HALDISPATCH->HalMirrorVerify - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - - -typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { - ULONG FileAttributes; - ULONG ReparseTag; -} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { - LARGE_INTEGER ValidDataLength; -} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; - -typedef union _FILE_SEGMENT_ELEMENT { - PVOID64 Buffer; - ULONGLONG Alignment; -}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; - -#define SE_UNSOLICITED_INPUT_PRIVILEGE 6 - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -ULONGLONG -NTAPI -VerSetConditionMask( - IN ULONGLONG ConditionMask, - IN ULONG TypeMask, - IN UCHAR Condition); +#define HalGetCachedAcpiTable HALDISPATCH->HalGetCachedAcpiTable +#define HalSetPciErrorHandlerCallback HALDISPATCH->HalSetPciErrorHandlerCallback +#if defined(_IA64_) +#define HalGetErrorCapList HALDISPATCH->HalGetErrorCapList +#define HalInjectError HALDISPATCH->HalInjectError #endif -#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ - ((ConditionMask) = VerSetConditionMask((ConditionMask), \ - (TypeBitMask), (ComparisonType))) +typedef struct _HAL_BUS_INFORMATION { + INTERFACE_TYPE BusType; + BUS_DATA_TYPE ConfigurationType; + ULONG BusNumber; + ULONG Reserved; +} HAL_BUS_INFORMATION, *PHAL_BUS_INFORMATION; -/* RtlVerifyVersionInfo() TypeMask */ +typedef struct _HAL_PROFILE_SOURCE_INFORMATION { + KPROFILE_SOURCE Source; + BOOLEAN Supported; + ULONG Interval; +} HAL_PROFILE_SOURCE_INFORMATION, *PHAL_PROFILE_SOURCE_INFORMATION; -#define VER_MINORVERSION 0x0000001 -#define VER_MAJORVERSION 0x0000002 -#define VER_BUILDNUMBER 0x0000004 -#define VER_PLATFORMID 0x0000008 -#define VER_SERVICEPACKMINOR 0x0000010 -#define VER_SERVICEPACKMAJOR 0x0000020 -#define VER_SUITENAME 0x0000040 -#define VER_PRODUCT_TYPE 0x0000080 +typedef struct _HAL_PROFILE_SOURCE_INFORMATION_EX { + KPROFILE_SOURCE Source; + BOOLEAN Supported; + ULONG_PTR Interval; + ULONG_PTR DefInterval; + ULONG_PTR MaxInterval; + ULONG_PTR MinInterval; +} HAL_PROFILE_SOURCE_INFORMATION_EX, *PHAL_PROFILE_SOURCE_INFORMATION_EX; -/* RtlVerifyVersionInfo() ComparisonType */ +typedef struct _HAL_PROFILE_SOURCE_INTERVAL { + KPROFILE_SOURCE Source; + ULONG_PTR Interval; +} HAL_PROFILE_SOURCE_INTERVAL, *PHAL_PROFILE_SOURCE_INTERVAL; -#define VER_EQUAL 1 -#define VER_GREATER 2 -#define VER_GREATER_EQUAL 3 -#define VER_LESS 4 -#define VER_LESS_EQUAL 5 -#define VER_AND 6 -#define VER_OR 7 +typedef struct _HAL_PROFILE_SOURCE_LIST { + KPROFILE_SOURCE Source; + PWSTR Description; +} HAL_PROFILE_SOURCE_LIST, *PHAL_PROFILE_SOURCE_LIST; -#define VER_CONDITION_MASK 7 -#define VER_NUM_BITS_PER_CONDITION_MASK 3 +typedef enum _HAL_DISPLAY_BIOS_INFORMATION { + HalDisplayInt10Bios, + HalDisplayEmulatedBios, + HalDisplayNoBios +} HAL_DISPLAY_BIOS_INFORMATION, *PHAL_DISPLAY_BIOS_INFORMATION; + +typedef struct _HAL_POWER_INFORMATION { + ULONG TBD; +} HAL_POWER_INFORMATION, *PHAL_POWER_INFORMATION; + +typedef struct _HAL_PROCESSOR_SPEED_INFO { + ULONG ProcessorSpeed; +} HAL_PROCESSOR_SPEED_INFORMATION, *PHAL_PROCESSOR_SPEED_INFORMATION; + +typedef struct _HAL_CALLBACKS { + PCALLBACK_OBJECT SetSystemInformation; + PCALLBACK_OBJECT BusCheck; +} HAL_CALLBACKS, *PHAL_CALLBACKS; + +typedef struct _HAL_PROCESSOR_FEATURE { + ULONG UsableFeatureBits; +} HAL_PROCESSOR_FEATURE; + +typedef NTSTATUS +(NTAPI *PHALIOREADWRITEHANDLER)( + IN BOOLEAN fRead, + IN ULONG dwAddr, + IN ULONG dwSize, + IN OUT PULONG pdwData); + +typedef struct _HAL_AMLI_BAD_IO_ADDRESS_LIST { + ULONG BadAddrBegin; + ULONG BadAddrSize; + ULONG OSVersionTrigger; + PHALIOREADWRITEHANDLER IOHandler; +} HAL_AMLI_BAD_IO_ADDRESS_LIST, *PHAL_AMLI_BAD_IO_ADDRESS_LIST; + +#if defined(_X86_) || defined(_IA64_) || defined(_AMD64_) + +typedef VOID +(NTAPI *PHALMCAINTERFACELOCK)( + VOID); + +typedef VOID +(NTAPI *PHALMCAINTERFACEUNLOCK)( + VOID); + +typedef NTSTATUS +(NTAPI *PHALMCAINTERFACEREADREGISTER)( + IN UCHAR BankNumber, + IN OUT PVOID Exception); + +typedef struct _HAL_MCA_INTERFACE { + PHALMCAINTERFACELOCK Lock; + PHALMCAINTERFACEUNLOCK Unlock; + PHALMCAINTERFACEREADREGISTER ReadRegister; +} HAL_MCA_INTERFACE; + +typedef enum { + ApicDestinationModePhysical = 1, + ApicDestinationModeLogicalFlat, + ApicDestinationModeLogicalClustered, + ApicDestinationModeUnknown +} HAL_APIC_DESTINATION_MODE, *PHAL_APIC_DESTINATION_MODE; + +#if defined(_AMD64_) + +struct _KTRAP_FRAME; +struct _KEXCEPTION_FRAME; + +typedef ERROR_SEVERITY +(NTAPI *PDRIVER_EXCPTN_CALLBACK)( + IN PVOID Context, + IN struct _KTRAP_FRAME *TrapFrame, + IN struct _KEXCEPTION_FRAME *ExceptionFrame, + IN PMCA_EXCEPTION Exception); + +#endif + +#if defined(_X86_) || defined(_IA64_) +typedef +#if defined(_IA64_) +ERROR_SEVERITY +#else +VOID +#endif +(NTAPI *PDRIVER_EXCPTN_CALLBACK)( + IN PVOID Context, + IN PMCA_EXCEPTION BankLog); +#endif + +typedef PDRIVER_EXCPTN_CALLBACK PDRIVER_MCA_EXCEPTION_CALLBACK; + +typedef struct _MCA_DRIVER_INFO { + PDRIVER_MCA_EXCEPTION_CALLBACK ExceptionCallback; + PKDEFERRED_ROUTINE DpcCallback; + PVOID DeviceContext; +} MCA_DRIVER_INFO, *PMCA_DRIVER_INFO; + +typedef struct _HAL_ERROR_INFO { + ULONG Version; + ULONG InitMaxSize; + ULONG McaMaxSize; + ULONG McaPreviousEventsCount; + ULONG McaCorrectedEventsCount; + ULONG McaKernelDeliveryFails; + ULONG McaDriverDpcQueueFails; + ULONG McaReserved; + ULONG CmcMaxSize; + ULONG CmcPollingInterval; + ULONG CmcInterruptsCount; + ULONG CmcKernelDeliveryFails; + ULONG CmcDriverDpcQueueFails; + ULONG CmcGetStateFails; + ULONG CmcClearStateFails; + ULONG CmcReserved; + ULONGLONG CmcLogId; + ULONG CpeMaxSize; + ULONG CpePollingInterval; + ULONG CpeInterruptsCount; + ULONG CpeKernelDeliveryFails; + ULONG CpeDriverDpcQueueFails; + ULONG CpeGetStateFails; + ULONG CpeClearStateFails; + ULONG CpeInterruptSources; + ULONGLONG CpeLogId; + ULONGLONG KernelReserved[4]; +} HAL_ERROR_INFO, *PHAL_ERROR_INFO; + +#define HAL_MCE_INTERRUPTS_BASED ((ULONG)-1) +#define HAL_MCE_DISABLED ((ULONG)0) + +#define HAL_CMC_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED +#define HAL_CMC_DISABLED HAL_MCE_DISABLED + +#define HAL_CPE_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED +#define HAL_CPE_DISABLED HAL_MCE_DISABLED + +#define HAL_MCA_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED +#define HAL_MCA_DISABLED HAL_MCE_DISABLED + +typedef VOID +(NTAPI *PDRIVER_CMC_EXCEPTION_CALLBACK)( + IN PVOID Context, + IN PCMC_EXCEPTION CmcLog); + +typedef VOID +(NTAPI *PDRIVER_CPE_EXCEPTION_CALLBACK)( + IN PVOID Context, + IN PCPE_EXCEPTION CmcLog); + +typedef struct _CMC_DRIVER_INFO { + PDRIVER_CMC_EXCEPTION_CALLBACK ExceptionCallback; + PKDEFERRED_ROUTINE DpcCallback; + PVOID DeviceContext; +} CMC_DRIVER_INFO, *PCMC_DRIVER_INFO; + +typedef struct _CPE_DRIVER_INFO { + PDRIVER_CPE_EXCEPTION_CALLBACK ExceptionCallback; + PKDEFERRED_ROUTINE DpcCallback; + PVOID DeviceContext; +} CPE_DRIVER_INFO, *PCPE_DRIVER_INFO; + +#endif // defined(_X86_) || defined(_IA64_) || defined(_AMD64_) + +#if defined(_IA64_) + +typedef NTSTATUS +(*HALSENDCROSSPARTITIONIPI)( + IN USHORT ProcessorID, + IN UCHAR HardwareVector); + +typedef NTSTATUS +(*HALRESERVECROSSPARTITIONINTERRUPTVECTOR)( + OUT PULONG Vector, + OUT PKIRQL Irql, + IN OUT PGROUP_AFFINITY Affinity, + OUT PUCHAR HardwareVector); + +typedef VOID +(*HALFREECROSSPARTITIONINTERRUPTVECTOR)( + IN ULONG Vector, + IN PGROUP_AFFINITY Affinity); + +typedef struct _HAL_CROSS_PARTITION_IPI_INTERFACE { + HALSENDCROSSPARTITIONIPI HalSendCrossPartitionIpi; + HALRESERVECROSSPARTITIONINTERRUPTVECTOR HalReserveCrossPartitionInterruptVector; + HALFREECROSSPARTITIONINTERRUPTVECTOR HalFreeCrossPartitionInterruptVector; +} HAL_CROSS_PARTITION_IPI_INTERFACE; + +#define HAL_CROSS_PARTITION_IPI_INTERFACE_MINIMUM_SIZE \ + FIELD_OFFSET(HAL_CROSS_PARTITION_IPI_INTERFACE, \ + HalFreeCrossPartitionInterruptVector) + +#endif /* defined(_IA64_) */ + +typedef struct _HAL_PLATFORM_INFORMATION { + ULONG PlatformFlags; +} HAL_PLATFORM_INFORMATION, *PHAL_PLATFORM_INFORMATION; + +#define HAL_PLATFORM_DISABLE_WRITE_COMBINING 0x01L +#define HAL_PLATFORM_DISABLE_PTCG 0x04L +#define HAL_PLATFORM_DISABLE_UC_MAIN_MEMORY 0x08L +#define HAL_PLATFORM_ENABLE_WRITE_COMBINING_MMIO 0x10L +#define HAL_PLATFORM_ACPI_TABLES_CACHED 0x20L + +/****************************************************************************** + * Kernel Types * + ******************************************************************************/ + +#define NX_SUPPORT_POLICY_ALWAYSOFF 0 +#define NX_SUPPORT_POLICY_ALWAYSON 1 +#define NX_SUPPORT_POLICY_OPTIN 2 +#define NX_SUPPORT_POLICY_OPTOUT 3 + +typedef VOID +(NTAPI *PEXPAND_STACK_CALLOUT)( + IN PVOID Parameter OPTIONAL); + +typedef VOID +(NTAPI *PTIMER_APC_ROUTINE)( + IN PVOID TimerContext, + IN ULONG TimerLowValue, + IN LONG TimerHighValue); + +typedef enum _TIMER_SET_INFORMATION_CLASS { + TimerSetCoalescableTimer, + MaxTimerInfoClass +} TIMER_SET_INFORMATION_CLASS; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +typedef struct _TIMER_SET_COALESCABLE_TIMER_INFO { + IN LARGE_INTEGER DueTime; + IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL; + IN PVOID TimerContext OPTIONAL; + IN struct _COUNTED_REASON_CONTEXT *WakeContext OPTIONAL; + IN ULONG Period OPTIONAL; + IN ULONG TolerableDelay; + OUT PBOOLEAN PreviousState OPTIONAL; +} TIMER_SET_COALESCABLE_TIMER_INFO, *PTIMER_SET_COALESCABLE_TIMER_INFO; +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + +#define XSTATE_LEGACY_FLOATING_POINT 0 +#define XSTATE_LEGACY_SSE 1 +#define XSTATE_GSSE 2 + +#define XSTATE_MASK_LEGACY_FLOATING_POINT (1i64 << (XSTATE_LEGACY_FLOATING_POINT)) +#define XSTATE_MASK_LEGACY_SSE (1i64 << (XSTATE_LEGACY_SSE)) +#define XSTATE_MASK_LEGACY (XSTATE_MASK_LEGACY_FLOATING_POINT | XSTATE_MASK_LEGACY_SSE) +#define XSTATE_MASK_GSSE (1i64 << (XSTATE_GSSE)) + +#define MAXIMUM_XSTATE_FEATURES 64 + +typedef struct _XSTATE_FEATURE { + ULONG Offset; + ULONG Size; +} XSTATE_FEATURE, *PXSTATE_FEATURE; + +typedef struct _XSTATE_CONFIGURATION { + ULONG64 EnabledFeatures; + ULONG Size; + ULONG OptimizedSave:1; + XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES]; +} XSTATE_CONFIGURATION, *PXSTATE_CONFIGURATION; + +#define MAX_WOW64_SHARED_ENTRIES 16 + +typedef struct _KUSER_SHARED_DATA { + ULONG TickCountLowDeprecated; + ULONG TickCountMultiplier; + volatile KSYSTEM_TIME InterruptTime; + volatile KSYSTEM_TIME SystemTime; + volatile KSYSTEM_TIME TimeZoneBias; + USHORT ImageNumberLow; + USHORT ImageNumberHigh; + WCHAR NtSystemRoot[260]; + ULONG MaxStackTraceDepth; + ULONG CryptoExponent; + ULONG TimeZoneId; + ULONG LargePageMinimum; + ULONG Reserved2[7]; + NT_PRODUCT_TYPE NtProductType; + BOOLEAN ProductTypeIsValid; + ULONG NtMajorVersion; + ULONG NtMinorVersion; + BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; + ULONG Reserved1; + ULONG Reserved3; + volatile ULONG TimeSlip; + ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; + ULONG AltArchitecturePad[1]; + LARGE_INTEGER SystemExpirationDate; + ULONG SuiteMask; + BOOLEAN KdDebuggerEnabled; +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) + UCHAR NXSupportPolicy; +#endif + volatile ULONG ActiveConsoleId; + volatile ULONG DismountCount; + ULONG ComPlusPackage; + ULONG LastSystemRITEventTickCount; + ULONG NumberOfPhysicalPages; + BOOLEAN SafeBootMode; +#if (NTDDI_VERSION >= NTDDI_WIN7) + union { + UCHAR TscQpcData; + struct { + UCHAR TscQpcEnabled:1; + UCHAR TscQpcSpareFlag:1; + UCHAR TscQpcShift:6; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + UCHAR TscQpcPad[2]; +#endif +#if (NTDDI_VERSION >= NTDDI_VISTA) + union { + ULONG SharedDataFlags; + struct { + ULONG DbgErrorPortPresent:1; + ULONG DbgElevationEnabled:1; + ULONG DbgVirtEnabled:1; + ULONG DbgInstallerDetectEnabled:1; + ULONG DbgSystemDllRelocated:1; + ULONG DbgDynProcessorEnabled:1; + ULONG DbgSEHValidationEnabled:1; + ULONG SpareBits:25; + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME2; +#else + ULONG TraceLogging; +#endif + ULONG DataFlagsPad[1]; + ULONGLONG TestRetInstruction; + ULONG SystemCall; + ULONG SystemCallReturn; + ULONGLONG SystemCallPad[3]; + _ANONYMOUS_UNION union { + volatile KSYSTEM_TIME TickCount; + volatile ULONG64 TickCountQuad; + _ANONYMOUS_STRUCT struct { + ULONG ReservedTickCountOverlay[3]; + ULONG TickCountPad[1]; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME3; + ULONG Cookie; + ULONG CookiePad[1]; +#if (NTDDI_VERSION >= NTDDI_WS03) + LONGLONG ConsoleSessionForegroundProcessId; + ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; +#endif +#if (NTDDI_VERSION >= NTDDI_VISTA) +#if (NTDDI_VERSION >= NTDDI_WIN7) + USHORT UserModeGlobalLogger[16]; +#else + USHORT UserModeGlobalLogger[8]; + ULONG HeapTracingPid[2]; + ULONG CritSecTracingPid[2]; +#endif + ULONG ImageFileExecutionOptions; +#if (NTDDI_VERSION >= NTDDI_VISTASP1) + ULONG LangGenerationCount; +#else + /* 4 bytes padding */ +#endif + ULONGLONG Reserved5; + volatile ULONG64 InterruptTimeBias; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN7) + volatile ULONG64 TscQpcBias; + volatile ULONG ActiveProcessorCount; + volatile USHORT ActiveGroupCount; + USHORT Reserved4; + volatile ULONG AitSamplingValue; + volatile ULONG AppCompatFlag; + ULONGLONG SystemDllNativeRelocation; + ULONG SystemDllWowRelocation; + ULONG XStatePad[1]; + XSTATE_CONFIGURATION XState; +#endif +} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +extern NTSYSAPI volatile CCHAR KeNumberProcessors; +#elif (NTDDI_VERSION >= NTDDI_WINXP) +extern NTSYSAPI CCHAR KeNumberProcessors; +#else +extern PCCHAR KeNumberProcessors; +#endif + + +/****************************************************************************** + * Kernel Debugger Types * + ******************************************************************************/ +typedef struct _DEBUG_DEVICE_ADDRESS { + UCHAR Type; + BOOLEAN Valid; + UCHAR Reserved[2]; + PUCHAR TranslatedAddress; + ULONG Length; +} DEBUG_DEVICE_ADDRESS, *PDEBUG_DEVICE_ADDRESS; + +typedef struct _DEBUG_MEMORY_REQUIREMENTS { + PHYSICAL_ADDRESS Start; + PHYSICAL_ADDRESS MaxEnd; + PVOID VirtualAddress; + ULONG Length; + BOOLEAN Cached; + BOOLEAN Aligned; +} DEBUG_MEMORY_REQUIREMENTS, *PDEBUG_MEMORY_REQUIREMENTS; + +typedef struct _DEBUG_DEVICE_DESCRIPTOR { + ULONG Bus; + ULONG Slot; + USHORT Segment; + USHORT VendorID; + USHORT DeviceID; + UCHAR BaseClass; + UCHAR SubClass; + UCHAR ProgIf; + BOOLEAN Initialized; + BOOLEAN Configured; + DEBUG_DEVICE_ADDRESS BaseAddress[6]; + DEBUG_MEMORY_REQUIREMENTS Memory; +} DEBUG_DEVICE_DESCRIPTOR, *PDEBUG_DEVICE_DESCRIPTOR; + +typedef NTSTATUS +(NTAPI *pKdSetupPciDeviceForDebugging)( + IN PVOID LoaderBlock OPTIONAL, + IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); + +typedef NTSTATUS +(NTAPI *pKdReleasePciDeviceForDebugging)( + IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); + +typedef PVOID +(NTAPI *pKdGetAcpiTablePhase0)( + IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, + IN ULONG Signature); + +typedef VOID +(NTAPI *pKdCheckPowerButton)( + VOID); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +typedef PVOID +(NTAPI *pKdMapPhysicalMemory64)( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberPages, + IN BOOLEAN FlushCurrentTLB); + +typedef VOID +(NTAPI *pKdUnmapVirtualAddress)( + IN PVOID VirtualAddress, + IN ULONG NumberPages, + IN BOOLEAN FlushCurrentTLB); +#else +typedef PVOID +(NTAPI *pKdMapPhysicalMemory64)( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberPages); + +typedef VOID +(NTAPI *pKdUnmapVirtualAddress)( + IN PVOID VirtualAddress, + IN ULONG NumberPages); +#endif + +typedef ULONG +(NTAPI *pKdGetPciDataByOffset)( + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef ULONG +(NTAPI *pKdSetPciDataByOffset)( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); +/****************************************************************************** + * Memory manager Types * + ******************************************************************************/ + +typedef struct _PHYSICAL_MEMORY_RANGE { + PHYSICAL_ADDRESS BaseAddress; + LARGE_INTEGER NumberOfBytes; +} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; + +typedef NTSTATUS +(NTAPI *PMM_ROTATE_COPY_CALLBACK_FUNCTION)( + IN PMDL DestinationMdl, + IN PMDL SourceMdl, + IN PVOID Context); + +typedef enum _MM_ROTATE_DIRECTION { + MmToFrameBuffer, + MmToFrameBufferNoCopy, + MmToRegularMemory, + MmToRegularMemoryNoCopy, + MmMaximumRotateDirection +} MM_ROTATE_DIRECTION, *PMM_ROTATE_DIRECTION; + + +/****************************************************************************** + * Process Manager Types * + ******************************************************************************/ + +#define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001 +#define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002 +#define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004 +#define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008 +#define QUOTA_LIMITS_USE_DEFAULT_LIMITS 0x00000010 + +typedef struct _QUOTA_LIMITS { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; +} QUOTA_LIMITS, *PQUOTA_LIMITS; + +typedef union _RATE_QUOTA_LIMIT { + ULONG RateData; + struct { + ULONG RatePercent:7; + ULONG Reserved0:25; + } DUMMYSTRUCTNAME; +} RATE_QUOTA_LIMIT, *PRATE_QUOTA_LIMIT; + +typedef struct _QUOTA_LIMITS_EX { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; + SIZE_T WorkingSetLimit; + SIZE_T Reserved2; + SIZE_T Reserved3; + SIZE_T Reserved4; + ULONG Flags; + RATE_QUOTA_LIMIT CpuRateLimit; +} QUOTA_LIMITS_EX, *PQUOTA_LIMITS_EX; + +typedef struct _IO_COUNTERS { + ULONGLONG ReadOperationCount; + ULONGLONG WriteOperationCount; + ULONGLONG OtherOperationCount; + ULONGLONG ReadTransferCount; + ULONGLONG WriteTransferCount; + ULONGLONG OtherTransferCount; +} IO_COUNTERS, *PIO_COUNTERS; + +typedef struct _VM_COUNTERS { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} VM_COUNTERS, *PVM_COUNTERS; + +typedef struct _VM_COUNTERS_EX { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; +} VM_COUNTERS_EX, *PVM_COUNTERS_EX; + +#define MAX_HW_COUNTERS 16 +#define THREAD_PROFILING_FLAG_DISPATCH 0x00000001 + +typedef enum _HARDWARE_COUNTER_TYPE { + PMCCounter, + MaxHardwareCounterType +} HARDWARE_COUNTER_TYPE, *PHARDWARE_COUNTER_TYPE; + +typedef struct _HARDWARE_COUNTER { + HARDWARE_COUNTER_TYPE Type; + ULONG Reserved; + ULONG64 Index; +} HARDWARE_COUNTER, *PHARDWARE_COUNTER; + +typedef struct _POOLED_USAGE_AND_LIMITS { + SIZE_T PeakPagedPoolUsage; + SIZE_T PagedPoolUsage; + SIZE_T PagedPoolLimit; + SIZE_T PeakNonPagedPoolUsage; + SIZE_T NonPagedPoolUsage; + SIZE_T NonPagedPoolLimit; + SIZE_T PeakPagefileUsage; + SIZE_T PagefileUsage; + SIZE_T PagefileLimit; +} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS; + +typedef struct _PROCESS_ACCESS_TOKEN { + HANDLE Token; + HANDLE Thread; +} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN; + +#define PROCESS_EXCEPTION_PORT_ALL_STATE_BITS 0x00000003UL +#define PROCESS_EXCEPTION_PORT_ALL_STATE_FLAGS ((ULONG_PTR)((1UL << PROCESS_EXCEPTION_PORT_ALL_STATE_BITS) - 1)) + +typedef struct _PROCESS_EXCEPTION_PORT { + IN HANDLE ExceptionPortHandle; + IN OUT ULONG StateFlags; +} PROCESS_EXCEPTION_PORT, *PPROCESS_EXCEPTION_PORT; + +typedef VOID +(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)( + IN HANDLE ParentId, + IN HANDLE ProcessId, + IN BOOLEAN Create); + +typedef struct _PS_CREATE_NOTIFY_INFO { + IN SIZE_T Size; + union { + IN ULONG Flags; + struct { + IN ULONG FileOpenNameAvailable:1; + IN ULONG Reserved:31; + }; + }; + IN HANDLE ParentProcessId; + IN CLIENT_ID CreatingThreadId; + IN OUT struct _FILE_OBJECT *FileObject; + IN PCUNICODE_STRING ImageFileName; + IN PCUNICODE_STRING CommandLine OPTIONAL; + IN OUT NTSTATUS CreationStatus; +} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO; + +typedef VOID +(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE_EX)( + IN OUT PEPROCESS Process, + IN HANDLE ProcessId, + IN PPS_CREATE_NOTIFY_INFO CreateInfo OPTIONAL); + +typedef VOID +(NTAPI *PCREATE_THREAD_NOTIFY_ROUTINE)( + IN HANDLE ProcessId, + IN HANDLE ThreadId, + IN BOOLEAN Create); + +#define IMAGE_ADDRESSING_MODE_32BIT 3 typedef struct _IMAGE_INFO { _ANONYMOUS_UNION union { @@ -1492,7 +2262,7 @@ typedef struct _IMAGE_INFO { ULONG SystemModeImage:1; ULONG ImageMappedToAllPids:1; ULONG ExtendedInfoPresent:1; - ULONG Reserved:22; + ULONG Reserved:21; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; PVOID ImageBase; @@ -1501,24 +2271,24 @@ typedef struct _IMAGE_INFO { ULONG ImageSectionNumber; } IMAGE_INFO, *PIMAGE_INFO; -#define IMAGE_ADDRESSING_MODE_32BIT 3 +typedef struct _IMAGE_INFO_EX { + SIZE_T Size; + IMAGE_INFO ImageInfo; + struct _FILE_OBJECT *FileObject; +} IMAGE_INFO_EX, *PIMAGE_INFO_EX; -typedef enum _BUS_DATA_TYPE { - ConfigurationSpaceUndefined = -1, - Cmos, - EisaConfiguration, - Pos, - CbusConfiguration, - PCIConfiguration, - VMEConfiguration, - NuBusConfiguration, - PCMCIAConfiguration, - MPIConfiguration, - MPSAConfiguration, - PNPISAConfiguration, - SgiInternalConfiguration, - MaximumBusDataType -} BUS_DATA_TYPE, *PBUS_DATA_TYPE; +typedef VOID +(NTAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)( + IN PUNICODE_STRING FullImageName, + IN HANDLE ProcessId, + IN PIMAGE_INFO ImageInfo); + +#define THREAD_CSWITCH_PMU_DISABLE FALSE +#define THREAD_CSWITCH_PMU_ENABLE TRUE + +#define PROCESS_LUID_DOSDEVICES_ONLY 0x00000001 + +#define PROCESS_HANDLE_TRACING_MAX_STACKS 16 typedef struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; @@ -1652,6 +2422,15 @@ typedef enum _THREADINFOCLASS { MaxThreadInfoClass } THREADINFOCLASS; +typedef struct _PAGE_PRIORITY_INFORMATION { + ULONG PagePriority; +} PAGE_PRIORITY_INFORMATION, *PPAGE_PRIORITY_INFORMATION; + +typedef struct _PROCESS_WS_WATCH_INFORMATION { + PVOID FaultingPc; + PVOID FaultingVa; +} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION; + typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; struct _PEB *PebBaseAddress; @@ -1661,10 +2440,20 @@ typedef struct _PROCESS_BASIC_INFORMATION { ULONG_PTR InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION; -typedef struct _PROCESS_WS_WATCH_INFORMATION { - PVOID FaultingPc; - PVOID FaultingVa; -} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION; +typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION { + SIZE_T Size; + PROCESS_BASIC_INFORMATION BasicInfo; + union { + ULONG Flags; + struct { + ULONG IsProtectedProcess:1; + ULONG IsWow64Process:1; + ULONG IsProcessDeleting:1; + ULONG IsCrossSessionCreate:1; + ULONG SpareBits:28; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION; typedef struct _PROCESS_DEVICEMAP_INFORMATION { __GNU_EXTENSION union { @@ -1678,1956 +2467,112 @@ typedef struct _PROCESS_DEVICEMAP_INFORMATION { }; } PROCESS_DEVICEMAP_INFORMATION, *PPROCESS_DEVICEMAP_INFORMATION; -typedef struct _KERNEL_USER_TIMES { - LARGE_INTEGER CreateTime; - LARGE_INTEGER ExitTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; -} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES; - -typedef struct _PROCESS_ACCESS_TOKEN { - HANDLE Token; - HANDLE Thread; -} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN; +typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX { + union { + struct { + HANDLE DirectoryHandle; + } Set; + struct { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + } DUMMYUNIONNAME; + ULONG Flags; +} PROCESS_DEVICEMAP_INFORMATION_EX, *PPROCESS_DEVICEMAP_INFORMATION_EX; typedef struct _PROCESS_SESSION_INFORMATION { ULONG SessionId; } PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION; -typedef enum _IO_QUERY_DEVICE_DATA_FORMAT { - IoQueryDeviceIdentifier = 0, - IoQueryDeviceConfigurationData, - IoQueryDeviceComponentInformation, - IoQueryDeviceMaxData -} IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT; - -typedef struct _DISK_SIGNATURE { - ULONG PartitionStyle; - _ANONYMOUS_UNION union { - struct { - ULONG Signature; - ULONG CheckSum; - } Mbr; - struct { - GUID DiskId; - } Gpt; - } DUMMYUNIONNAME; -} DISK_SIGNATURE, *PDISK_SIGNATURE; - -typedef ULONG_PTR -(NTAPI *PDRIVER_VERIFIER_THUNK_ROUTINE)( - IN PVOID Context); - -typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { - PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; - PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; -} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; - -#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 -#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 -#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 -#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 -#define DRIVER_VERIFIER_IO_CHECKING 0x0010 - -typedef VOID -(NTAPI *PTIMER_APC_ROUTINE)( - IN PVOID TimerContext, - IN ULONG TimerLowValue, - IN LONG TimerHighValue); - -typedef struct _KUSER_SHARED_DATA -{ - ULONG TickCountLowDeprecated; - ULONG TickCountMultiplier; - volatile KSYSTEM_TIME InterruptTime; - volatile KSYSTEM_TIME SystemTime; - volatile KSYSTEM_TIME TimeZoneBias; - USHORT ImageNumberLow; - USHORT ImageNumberHigh; - WCHAR NtSystemRoot[260]; - ULONG MaxStackTraceDepth; - ULONG CryptoExponent; - ULONG TimeZoneId; - ULONG LargePageMinimum; - ULONG Reserved2[7]; - NT_PRODUCT_TYPE NtProductType; - BOOLEAN ProductTypeIsValid; - ULONG NtMajorVersion; - ULONG NtMinorVersion; - BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; - ULONG Reserved1; - ULONG Reserved3; - volatile ULONG TimeSlip; - ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; - ULONG AltArchitecturePad[1]; - LARGE_INTEGER SystemExpirationDate; - ULONG SuiteMask; - BOOLEAN KdDebuggerEnabled; -#if (NTDDI_VERSION >= NTDDI_WINXPSP2) - UCHAR NXSupportPolicy; -#endif - volatile ULONG ActiveConsoleId; - volatile ULONG DismountCount; - ULONG ComPlusPackage; - ULONG LastSystemRITEventTickCount; - ULONG NumberOfPhysicalPages; - BOOLEAN SafeBootMode; -#if (NTDDI_VERSION >= NTDDI_WIN7) - union { - UCHAR TscQpcData; - struct { - UCHAR TscQpcEnabled:1; - UCHAR TscQpcSpareFlag:1; - UCHAR TscQpcShift:6; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - UCHAR TscQpcPad[2]; -#endif -#if (NTDDI_VERSION >= NTDDI_VISTA) - union { - ULONG SharedDataFlags; - struct { - ULONG DbgErrorPortPresent:1; - ULONG DbgElevationEnabled:1; - ULONG DbgVirtEnabled:1; - ULONG DbgInstallerDetectEnabled:1; - ULONG DbgSystemDllRelocated:1; - ULONG DbgDynProcessorEnabled:1; - ULONG DbgSEHValidationEnabled:1; - ULONG SpareBits:25; - } DUMMYSTRUCTNAME2; - } DUMMYUNIONNAME2; -#else - ULONG TraceLogging; -#endif - ULONG DataFlagsPad[1]; - ULONGLONG TestRetInstruction; - ULONG SystemCall; - ULONG SystemCallReturn; - ULONGLONG SystemCallPad[3]; - _ANONYMOUS_UNION union { - volatile KSYSTEM_TIME TickCount; - volatile ULONG64 TickCountQuad; - _ANONYMOUS_STRUCT struct { - ULONG ReservedTickCountOverlay[3]; - ULONG TickCountPad[1]; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME3; - ULONG Cookie; - ULONG CookiePad[1]; -#if (NTDDI_VERSION >= NTDDI_WS03) - LONGLONG ConsoleSessionForegroundProcessId; - ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; -#endif -#if (NTDDI_VERSION >= NTDDI_VISTA) -#if (NTDDI_VERSION >= NTDDI_WIN7) - USHORT UserModeGlobalLogger[16]; -#else - USHORT UserModeGlobalLogger[8]; - ULONG HeapTracingPid[2]; - ULONG CritSecTracingPid[2]; -#endif - ULONG ImageFileExecutionOptions; -#if (NTDDI_VERSION >= NTDDI_VISTASP1) - ULONG LangGenerationCount; -#else - /* 4 bytes padding */ -#endif - ULONGLONG Reserved5; - volatile ULONG64 InterruptTimeBias; -#endif -#if (NTDDI_VERSION >= NTDDI_WIN7) - volatile ULONG64 TscQpcBias; - volatile ULONG ActiveProcessorCount; - volatile USHORT ActiveGroupCount; - USHORT Reserved4; - volatile ULONG AitSamplingValue; - volatile ULONG AppCompatFlag; - ULONGLONG SystemDllNativeRelocation; - ULONG SystemDllWowRelocation; - ULONG XStatePad[1]; - XSTATE_CONFIGURATION XState; -#endif -} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; - -extern NTKERNELAPI PVOID MmHighestUserAddress; -extern NTKERNELAPI PVOID MmSystemRangeStart; -extern NTKERNELAPI ULONG MmUserProbeAddress; - - -#ifdef _X86_ - -#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress -#define MM_SYSTEM_RANGE_START MmSystemRangeStart -#if defined(_LOCAL_COPY_USER_PROBE_ADDRESS_) -#define MM_USER_PROBE_ADDRESS _LOCAL_COPY_USER_PROBE_ADDRESS_ -extern ULONG _LOCAL_COPY_USER_PROBE_ADDRESS_; -#else -#define MM_USER_PROBE_ADDRESS MmUserProbeAddress -#endif -#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 -#define MM_KSEG0_BASE MM_SYSTEM_RANGE_START -#define MM_SYSTEM_SPACE_END 0xFFFFFFFF -#if !defined (_X86PAE_) -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 -#else -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 -#endif - -#define KeGetPcr() PCR - -#define KERNEL_STACK_SIZE 12288 -#define KERNEL_LARGE_STACK_SIZE 61440 -#define KERNEL_LARGE_STACK_COMMIT 12288 - -#define SIZE_OF_80387_REGISTERS 80 - -#define PCR_MINOR_VERSION 1 -#define PCR_MAJOR_VERSION 1 - -#if !defined(RC_INVOKED) - -#define CONTEXT_i386 0x10000 -#define CONTEXT_i486 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) -#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) -#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) - -#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) - -#endif /* !defined(RC_INVOKED) */ - -typedef struct _KPCR { - union { - NT_TIB NtTib; - struct { - struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; - PVOID Used_StackBase; - PVOID Spare2; - PVOID TssCopy; - ULONG ContextSwitches; - KAFFINITY SetMemberCopy; - PVOID Used_Self; - }; - }; - struct _KPCR *SelfPcr; - struct _KPRCB *Prcb; - KIRQL Irql; - ULONG IRR; - ULONG IrrActive; - ULONG IDR; - PVOID KdVersionBlock; - struct _KIDTENTRY *IDT; - struct _KGDTENTRY *GDT; - struct _KTSS *TSS; - USHORT MajorVersion; - USHORT MinorVersion; - KAFFINITY SetMember; - ULONG StallScaleFactor; - UCHAR SpareUnused; - UCHAR Number; - UCHAR Spare0; - UCHAR SecondLevelCacheAssociativity; - ULONG VdmAlert; - ULONG KernelReserved[14]; - ULONG SecondLevelCacheSize; - ULONG HalReserved[16]; -} KPCR, *PKPCR; - -FORCEINLINE -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)__readfsbyte(FIELD_OFFSET(KPCR, Number)); -} - -typedef struct _FLOATING_SAVE_AREA { - ULONG ControlWord; - ULONG StatusWord; - ULONG TagWord; - ULONG ErrorOffset; - ULONG ErrorSelector; - ULONG DataOffset; - ULONG DataSelector; - UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; - ULONG Cr0NpxState; -} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; - -#include "pshpack4.h" -typedef struct _CONTEXT { - ULONG ContextFlags; - ULONG Dr0; - ULONG Dr1; - ULONG Dr2; - ULONG Dr3; - ULONG Dr6; - ULONG Dr7; - FLOATING_SAVE_AREA FloatSave; - ULONG SegGs; - ULONG SegFs; - ULONG SegEs; - ULONG SegDs; - ULONG Edi; - ULONG Esi; - ULONG Ebx; - ULONG Edx; - ULONG Ecx; - ULONG Eax; - ULONG Ebp; - ULONG Eip; - ULONG SegCs; - ULONG EFlags; - ULONG Esp; - ULONG SegSs; - UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; -} CONTEXT; -#include "poppack.h" - -#endif /* _X86_ */ - -#ifdef _AMD64_ - -#define PTI_SHIFT 12L -#define PDI_SHIFT 21L -#define PPI_SHIFT 30L -#define PXI_SHIFT 39L -#define PTE_PER_PAGE 512 -#define PDE_PER_PAGE 512 -#define PPE_PER_PAGE 512 -#define PXE_PER_PAGE 512 -#define PTI_MASK_AMD64 (PTE_PER_PAGE - 1) -#define PDI_MASK_AMD64 (PDE_PER_PAGE - 1) -#define PPI_MASK (PPE_PER_PAGE - 1) -#define PXI_MASK (PXE_PER_PAGE - 1) - -#define PXE_BASE 0xFFFFF6FB7DBED000ULL -#define PXE_SELFMAP 0xFFFFF6FB7DBEDF68ULL -#define PPE_BASE 0xFFFFF6FB7DA00000ULL -#define PDE_BASE 0xFFFFF6FB40000000ULL -#define PTE_BASE 0xFFFFF68000000000ULL -#define PXE_TOP 0xFFFFF6FB7DBEDFFFULL -#define PPE_TOP 0xFFFFF6FB7DBFFFFFULL -#define PDE_TOP 0xFFFFF6FB7FFFFFFFULL -#define PTE_TOP 0xFFFFF6FFFFFFFFFFULL - -#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress -#define MM_SYSTEM_RANGE_START MmSystemRangeStart -#define MM_USER_PROBE_ADDRESS MmUserProbeAddress -#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFF080000000000ULL -#define KI_USER_SHARED_DATA 0xFFFFF78000000000ULL - -typedef struct DECLSPEC_ALIGN(16) _CONTEXT { - ULONG64 P1Home; - ULONG64 P2Home; - ULONG64 P3Home; - ULONG64 P4Home; - ULONG64 P5Home; - ULONG64 P6Home; - - /* Control flags */ - ULONG ContextFlags; - ULONG MxCsr; - - /* Segment */ - USHORT SegCs; - USHORT SegDs; - USHORT SegEs; - USHORT SegFs; - USHORT SegGs; - USHORT SegSs; - ULONG EFlags; - - /* Debug */ - ULONG64 Dr0; - ULONG64 Dr1; - ULONG64 Dr2; - ULONG64 Dr3; - ULONG64 Dr6; - ULONG64 Dr7; - - /* Integer */ - ULONG64 Rax; - ULONG64 Rcx; - ULONG64 Rdx; - ULONG64 Rbx; - ULONG64 Rsp; - ULONG64 Rbp; - ULONG64 Rsi; - ULONG64 Rdi; - ULONG64 R8; - ULONG64 R9; - ULONG64 R10; - ULONG64 R11; - ULONG64 R12; - ULONG64 R13; - ULONG64 R14; - ULONG64 R15; - - /* Counter */ - ULONG64 Rip; - - /* Floating point */ - union { - XMM_SAVE_AREA32 FltSave; - struct { - M128A Header[2]; - M128A Legacy[8]; - M128A Xmm0; - M128A Xmm1; - M128A Xmm2; - M128A Xmm3; - M128A Xmm4; - M128A Xmm5; - M128A Xmm6; - M128A Xmm7; - M128A Xmm8; - M128A Xmm9; - M128A Xmm10; - M128A Xmm11; - M128A Xmm12; - M128A Xmm13; - M128A Xmm14; - M128A Xmm15; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - - /* Vector */ - M128A VectorRegister[26]; - ULONG64 VectorControl; - - /* Debug control */ - ULONG64 DebugControl; - ULONG64 LastBranchToRip; - ULONG64 LastBranchFromRip; - ULONG64 LastExceptionToRip; - ULONG64 LastExceptionFromRip; -} CONTEXT; - -typedef struct _KPCR -{ - _ANONYMOUS_UNION union - { - NT_TIB NtTib; - _ANONYMOUS_STRUCT struct - { - union _KGDTENTRY64 *GdtBase; - struct _KTSS64 *TssBase; - ULONG64 UserRsp; - struct _KPCR *Self; - struct _KPRCB *CurrentPrcb; - PKSPIN_LOCK_QUEUE LockArray; - PVOID Used_Self; - }; - }; - union _KIDTENTRY64 *IdtBase; - ULONG64 Unused[2]; - KIRQL Irql; - UCHAR SecondLevelCacheAssociativity; - UCHAR ObsoleteNumber; - UCHAR Fill0; - ULONG Unused0[3]; - USHORT MajorVersion; - USHORT MinorVersion; - ULONG StallScaleFactor; - PVOID Unused1[3]; - ULONG KernelReserved[15]; - ULONG SecondLevelCacheSize; - ULONG HalReserved[16]; - ULONG Unused2; - PVOID KdVersionBlock; - PVOID Unused3; - ULONG PcrAlign1[24]; -} KPCR, *PKPCR; - -FORCEINLINE -PKPCR -KeGetPcr(VOID) -{ - return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self)); -} - -FORCEINLINE -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)__readgsword(0x184); -} - -#if !defined(RC_INVOKED) - -#define CONTEXT_AMD64 0x100000 - -#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L) -#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L) -#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L) -#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) -#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) - -#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x20L) - -#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 -#define CONTEXT_SERVICE_ACTIVE 0x10000000 -#define CONTEXT_EXCEPTION_REQUEST 0x40000000 -#define CONTEXT_EXCEPTION_REPORTING 0x80000000 - -#endif /* RC_INVOKED */ - -#endif /* _AMD64_ */ - -typedef enum _INTERLOCKED_RESULT { - ResultNegative = RESULT_NEGATIVE, - ResultZero = RESULT_ZERO, - ResultPositive = RESULT_POSITIVE -} INTERLOCKED_RESULT; - -typedef struct _OSVERSIONINFOA { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - CHAR szCSDVersion[128]; -} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; - -typedef struct _OSVERSIONINFOW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; -} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; - -typedef struct _OSVERSIONINFOEXA { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - CHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; - -typedef struct _OSVERSIONINFOEXW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; - -#ifdef UNICODE -typedef OSVERSIONINFOEXW OSVERSIONINFOEX; -typedef POSVERSIONINFOEXW POSVERSIONINFOEX; -typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX; -typedef OSVERSIONINFOW OSVERSIONINFO; -typedef POSVERSIONINFOW POSVERSIONINFO; -typedef LPOSVERSIONINFOW LPOSVERSIONINFO; -#else -typedef OSVERSIONINFOEXA OSVERSIONINFOEX; -typedef POSVERSIONINFOEXA POSVERSIONINFOEX; -typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; -typedef OSVERSIONINFOA OSVERSIONINFO; -typedef POSVERSIONINFOA POSVERSIONINFO; -typedef LPOSVERSIONINFOA LPOSVERSIONINFO; -#endif /* UNICODE */ - -/* Executive Types */ - -#define PROTECTED_POOL 0x80000000 - -typedef struct _ZONE_SEGMENT_HEADER { - SINGLE_LIST_ENTRY SegmentList; - PVOID Reserved; -} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; - -typedef struct _ZONE_HEADER { - SINGLE_LIST_ENTRY FreeList; - SINGLE_LIST_ENTRY SegmentList; - ULONG BlockSize; - ULONG TotalSegmentSize; -} ZONE_HEADER, *PZONE_HEADER; - -/* Executive Functions */ - -static __inline PVOID -ExAllocateFromZone( - IN PZONE_HEADER Zone) -{ - if (Zone->FreeList.Next) - Zone->FreeList.Next = Zone->FreeList.Next->Next; - return (PVOID) Zone->FreeList.Next; -} - -static __inline PVOID -ExFreeToZone( - IN PZONE_HEADER Zone, - IN PVOID Block) -{ - ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; - Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); - return ((PSINGLE_LIST_ENTRY) Block)->Next; -} - -/* - * PVOID - * ExInterlockedAllocateFromZone( - * IN PZONE_HEADER Zone, - * IN PKSPIN_LOCK Lock) - */ -#define ExInterlockedAllocateFromZone(Zone, Lock) \ - ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) - -/* PVOID - * ExInterlockedFreeToZone( - * IN PZONE_HEADER Zone, - * IN PVOID Block, - * IN PKSPIN_LOCK Lock); - */ -#define ExInterlockedFreeToZone(Zone, Block, Lock) \ - ExInterlockedPushEntryList(&(Zone)->FreeList, (PSINGLE_LIST_ENTRY)(Block), Lock) - -/* - * BOOLEAN - * ExIsFullZone( - * IN PZONE_HEADER Zone) - */ -#define ExIsFullZone(Zone) \ - ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) - -/* BOOLEAN - * ExIsObjectInFirstZoneSegment( - * IN PZONE_HEADER Zone, - * IN PVOID Object); - */ -#define ExIsObjectInFirstZoneSegment(Zone,Object) \ - ((BOOLEAN)( ((PUCHAR)(Object) >= (PUCHAR)(Zone)->SegmentList.Next) && \ - ((PUCHAR)(Object) < (PUCHAR)(Zone)->SegmentList.Next + \ - (Zone)->TotalSegmentSize)) ) - -#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite -#define ExAcquireResourceShared ExAcquireResourceSharedLite -#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite -#define ExDeleteResource ExDeleteResourceLite -#define ExInitializeResource ExInitializeResourceLite -#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite -#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite -#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite -#define ExReleaseResourceForThread ExReleaseResourceForThreadLite - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTKERNELAPI -NTSTATUS -NTAPI -ExExtendZone( - IN OUT PZONE_HEADER Zone, - IN OUT PVOID Segment, - IN ULONG SegmentSize); - -NTKERNELAPI -NTSTATUS -NTAPI -ExInitializeZone( - OUT PZONE_HEADER Zone, - IN ULONG BlockSize, - IN OUT PVOID InitialSegment, - IN ULONG InitialSegmentSize); - -NTKERNELAPI -NTSTATUS -NTAPI -ExInterlockedExtendZone( - IN OUT PZONE_HEADER Zone, - IN OUT PVOID Segment, - IN ULONG SegmentSize, - IN OUT PKSPIN_LOCK Lock); - -NTKERNELAPI -NTSTATUS -NTAPI -ExUuidCreate( - OUT UUID *Uuid); - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -ExRaiseAccessViolation( - VOID); - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -ExRaiseDatatypeMisalignment( - VOID); - -#endif - -#ifdef _X86_ - -NTKERNELAPI -INTERLOCKED_RESULT -FASTCALL -Exfi386InterlockedIncrementLong( - IN OUT LONG volatile *Addend); - -NTKERNELAPI -INTERLOCKED_RESULT -FASTCALL -Exfi386InterlockedDecrementLong( - IN PLONG Addend); - -NTKERNELAPI -ULONG -FASTCALL -Exfi386InterlockedExchangeUlong( - IN PULONG Target, - IN ULONG Value); - -#endif /* _X86_ */ - -#ifndef _ARC_DDK_ -#define _ARC_DDK_ -typedef enum _CONFIGURATION_TYPE { - ArcSystem, - CentralProcessor, - FloatingPointProcessor, - PrimaryIcache, - PrimaryDcache, - SecondaryIcache, - SecondaryDcache, - SecondaryCache, - EisaAdapter, - TcAdapter, - ScsiAdapter, - DtiAdapter, - MultiFunctionAdapter, - DiskController, - TapeController, - CdromController, - WormController, - SerialController, - NetworkController, - DisplayController, - ParallelController, - PointerController, - KeyboardController, - AudioController, - OtherController, - DiskPeripheral, - FloppyDiskPeripheral, - TapePeripheral, - ModemPeripheral, - MonitorPeripheral, - PrinterPeripheral, - PointerPeripheral, - KeyboardPeripheral, - TerminalPeripheral, - OtherPeripheral, - LinePeripheral, - NetworkPeripheral, - SystemMemory, - DockingInformation, - RealModeIrqRoutingTable, - RealModePCIEnumeration, - MaximumType -} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; -#endif /* !_ARC_DDK_ */ - -typedef struct _CONTROLLER_OBJECT { - CSHORT Type; - CSHORT Size; - PVOID ControllerExtension; - KDEVICE_QUEUE DeviceWaitQueue; - ULONG Spare1; - LARGE_INTEGER Spare2; -} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; - -typedef struct _CONFIGURATION_INFORMATION { - ULONG DiskCount; - ULONG FloppyCount; - ULONG CdRomCount; - ULONG TapeCount; - ULONG ScsiPortCount; - ULONG SerialCount; - ULONG ParallelCount; - BOOLEAN AtDiskPrimaryAddressClaimed; - BOOLEAN AtDiskSecondaryAddressClaimed; - ULONG Version; - ULONG MediumChangerCount; -} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; - -typedef -NTSTATUS -(NTAPI *PIO_QUERY_DEVICE_ROUTINE)( - IN PVOID Context, - IN PUNICODE_STRING PathName, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN PKEY_VALUE_FULL_INFORMATION *BusInformation, - IN CONFIGURATION_TYPE ControllerType, - IN ULONG ControllerNumber, - IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, - IN CONFIGURATION_TYPE PeripheralType, - IN ULONG PeripheralNumber, - IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); - -typedef -VOID -(NTAPI DRIVER_REINITIALIZE)( - IN struct _DRIVER_OBJECT *DriverObject, - IN PVOID Context, - IN ULONG Count); - -typedef DRIVER_REINITIALIZE *PDRIVER_REINITIALIZE; - -/** Filesystem runtime library routines **/ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -BOOLEAN -NTAPI -FsRtlIsTotalDeviceFailure( - IN NTSTATUS Status); -#endif - -/* Hardware Abstraction Layer Types */ - -typedef VOID -(NTAPI *PciPin2Line)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciData); - -typedef VOID -(NTAPI *PciLine2Pin)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciNewData, - IN PPCI_COMMON_CONFIG PciOldData); - -typedef VOID -(NTAPI *PciReadWriteConfig)( - IN struct _BUS_HANDLER *BusHandler, - IN PCI_SLOT_NUMBER Slot, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -#define PCI_DATA_TAG ' ICP' -#define PCI_DATA_VERSION 1 - -typedef struct _PCIBUSDATA { - ULONG Tag; - ULONG Version; - PciReadWriteConfig ReadConfig; - PciReadWriteConfig WriteConfig; - PciPin2Line Pin2Line; - PciLine2Pin Line2Pin; - PCI_SLOT_NUMBER ParentSlot; - PVOID Reserved[4]; -} PCIBUSDATA, *PPCIBUSDATA; - -/* Hardware Abstraction Layer Functions */ - -#if !defined(NO_LEGACY_DRIVERS) - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTHALAPI -NTSTATUS -NTAPI -HalAssignSlotResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -NTHALAPI -ULONG -NTAPI -HalGetInterruptVector( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity); - -NTHALAPI -ULONG -NTAPI -HalSetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length); - -#endif - -#endif /* !defined(NO_LEGACY_DRIVERS) */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTHALAPI -PADAPTER_OBJECT -NTAPI -HalGetAdapter( - IN PDEVICE_DESCRIPTION DeviceDescription, - IN OUT PULONG NumberOfMapRegisters); - -NTHALAPI -BOOLEAN -NTAPI -HalMakeBeep( - IN ULONG Frequency); - -VOID -NTAPI -HalPutDmaAdapter( - IN PADAPTER_OBJECT DmaAdapter); - -NTHALAPI -VOID -NTAPI -HalAcquireDisplayOwnership( - IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); - -NTHALAPI -ULONG -NTAPI -HalGetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Length); - -NTHALAPI -ULONG -NTAPI -HalGetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTHALAPI -ULONG -NTAPI -HalSetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTHALAPI -BOOLEAN -NTAPI -HalTranslateBusAddress( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN PHYSICAL_ADDRESS BusAddress, - IN OUT PULONG AddressSpace, - OUT PPHYSICAL_ADDRESS TranslatedAddress); - -#endif - -#if (NTDDI_VERSION >= NTDDI_WINXP) -NTKERNELAPI -VOID -FASTCALL -HalExamineMBR( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, - OUT PVOID *Buffer); -#endif - -#if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) -// nothing here -#else - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -IoFreeAdapterChannel( - IN PADAPTER_OBJECT AdapterObject); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -BOOLEAN -NTAPI -IoFlushAdapterBuffers( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN ULONG Length, - IN BOOLEAN WriteToDevice); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -IoFreeMapRegisters( - IN PADAPTER_OBJECT AdapterObject, - IN PVOID MapRegisterBase, - IN ULONG NumberOfMapRegisters); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -PVOID -NTAPI -HalAllocateCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - OUT PPHYSICAL_ADDRESS LogicalAddress, - IN BOOLEAN CacheEnabled); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -HalFreeCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - IN PHYSICAL_ADDRESS LogicalAddress, - IN PVOID VirtualAddress, - IN BOOLEAN CacheEnabled); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -ULONG -NTAPI -HalReadDmaCounter( - IN PADAPTER_OBJECT AdapterObject); - -NTHALAPI -NTSTATUS -NTAPI -HalAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PWAIT_CONTEXT_BLOCK Wcb, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#endif /* defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) */ - -/* I/O Manager Functions */ - -/* - * VOID IoAssignArcName( - * IN PUNICODE_STRING ArcName, - * IN PUNICODE_STRING DeviceName); - */ -#define IoAssignArcName(_ArcName, _DeviceName) ( \ - IoCreateSymbolicLink((_ArcName), (_DeviceName))) - -/* - * VOID - * IoDeassignArcName( - * IN PUNICODE_STRING ArcName) - */ -#define IoDeassignArcName IoDeleteSymbolicLink - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -#if !(defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)) -NTKERNELAPI -NTSTATUS -NTAPI -IoAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); -#endif - -#if !defined(DMA_MACROS_DEFINED) -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -PHYSICAL_ADDRESS -NTAPI -IoMapTransfer( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN OUT PULONG Length, - IN BOOLEAN WriteToDevice); -#endif - -NTKERNELAPI -VOID -NTAPI -IoAllocateController( - IN PCONTROLLER_OBJECT ControllerObject, - IN PDEVICE_OBJECT DeviceObject, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -PCONTROLLER_OBJECT -NTAPI -IoCreateController( - IN ULONG Size); - -NTKERNELAPI -VOID -NTAPI -IoDeleteController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTKERNELAPI -VOID -NTAPI -IoFreeController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTKERNELAPI -PCONFIGURATION_INFORMATION -NTAPI -IoGetConfigurationInformation( - VOID); - -NTKERNELAPI -PDEVICE_OBJECT -NTAPI -IoGetDeviceToVerify( - IN PETHREAD Thread); - -NTKERNELAPI -VOID -NTAPI -IoCancelFileOpen( - IN PDEVICE_OBJECT DeviceObject, - IN PFILE_OBJECT FileObject); - -NTKERNELAPI -PGENERIC_MAPPING -NTAPI -IoGetFileObjectGenericMapping( - VOID); - -NTKERNELAPI -PIRP -NTAPI -IoMakeAssociatedIrp( - IN PIRP Irp, - IN CCHAR StackSize); - -NTKERNELAPI -NTSTATUS -NTAPI -IoQueryDeviceDescription( - IN PINTERFACE_TYPE BusType OPTIONAL, - IN PULONG BusNumber OPTIONAL, - IN PCONFIGURATION_TYPE ControllerType OPTIONAL, - IN PULONG ControllerNumber OPTIONAL, - IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, - IN PULONG PeripheralNumber OPTIONAL, - IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, - IN OUT PVOID Context OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRaiseHardError( - IN PIRP Irp, - IN PVPB Vpb OPTIONAL, - IN PDEVICE_OBJECT RealDeviceObject); - -NTKERNELAPI -BOOLEAN -NTAPI -IoRaiseInformationalHardError( - IN NTSTATUS ErrorStatus, - IN PUNICODE_STRING String OPTIONAL, - IN PKTHREAD Thread OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRegisterBootDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRegisterDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAttachDeviceByPointer( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportDetectedDevice( - IN PDRIVER_OBJECT DriverObject, - IN INTERFACE_TYPE LegacyBusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PCM_RESOURCE_LIST ResourceList OPTIONAL, - IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, - IN BOOLEAN ResourceAssigned, - IN OUT PDEVICE_OBJECT *DeviceObject); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportResourceForDetection( - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - OUT PBOOLEAN ConflictDetected); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportResourceUsage( - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - IN BOOLEAN OverrideConflict, - OUT PBOOLEAN ConflictDetected); - -NTKERNELAPI -VOID -NTAPI -IoSetHardErrorOrVerifyDevice( - IN PIRP Irp, - IN PDEVICE_OBJECT DeviceObject); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAssignResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources OPTIONAL, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) - -NTKERNELAPI -NTSTATUS -NTAPI -IoCreateDisk( - IN PDEVICE_OBJECT DeviceObject, - IN struct _CREATE_DISK* Disk OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReadDiskSignature( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG BytesPerSector, - OUT PDISK_SIGNATURE Signature); - -NTKERNELAPI -NTSTATUS -FASTCALL -IoReadPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN BOOLEAN ReturnRecognizedPartitions, - OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReadPartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); - -NTKERNELAPI -NTSTATUS -FASTCALL -IoSetPartitionInformation( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG PartitionNumber, - IN ULONG PartitionType); - -NTKERNELAPI -NTSTATUS -NTAPI -IoSetPartitionInformationEx( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG PartitionNumber, - IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); - -NTKERNELAPI -NTSTATUS -NTAPI -IoSetSystemPartition( - IN PUNICODE_STRING VolumeNameString); - -NTKERNELAPI -BOOLEAN -NTAPI -IoSetThreadHardErrorMode( - IN BOOLEAN EnableHardErrors); - -NTKERNELAPI -NTSTATUS -NTAPI -IoVerifyPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN FixErrors); - -NTKERNELAPI -NTSTATUS -NTAPI -IoVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTKERNELAPI -NTSTATUS -FASTCALL -IoWritePartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG SectorsPerTrack, - IN ULONG NumberOfHeads, - IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); - -NTKERNELAPI -NTSTATUS -NTAPI -IoWritePartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DRIVE_LAYOUT_INFORMATION_EX *DriveLayout); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAttachDeviceToDeviceStackSafe( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice, - OUT PDEVICE_OBJECT *AttachedToDeviceObject); - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - -/** Kernel debugger routines **/ - -NTSYSAPI -ULONG -NTAPI -DbgPrompt( - IN PCCH Prompt, - OUT PCH Response, - IN ULONG MaximumResponseLength); - -/* Kernel Functions */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -KeBugCheck( - IN ULONG BugCheckCode); - -NTKERNELAPI -LONG -NTAPI -KePulseEvent( - IN OUT PRKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait); - -NTKERNELAPI -LONG -NTAPI -KeSetBasePriorityThread( - IN OUT PRKTHREAD Thread, - IN LONG Increment); - -#endif - -/* Memory Manager Types */ - -typedef struct _PHYSICAL_MEMORY_RANGE { - PHYSICAL_ADDRESS BaseAddress; - LARGE_INTEGER NumberOfBytes; -} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; - -/* Memory Manager Functions */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTKERNELAPI -PPHYSICAL_MEMORY_RANGE -NTAPI -MmGetPhysicalMemoryRanges( - VOID); - -NTKERNELAPI -PHYSICAL_ADDRESS -NTAPI -MmGetPhysicalAddress( - IN PVOID BaseAddress); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsNonPagedSystemAddressValid( - IN PVOID VirtualAddress); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateNonCachedMemory( - IN SIZE_T NumberOfBytes); - -NTKERNELAPI -VOID -NTAPI -MmFreeNonCachedMemory( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -NTKERNELAPI -PVOID -NTAPI -MmGetVirtualForPhysical( - IN PHYSICAL_ADDRESS PhysicalAddress); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapUserAddressesToPage( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN PVOID PageAddress); - -NTKERNELAPI -PVOID -NTAPI -MmMapVideoDisplay( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN SIZE_T NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapViewInSessionSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapViewInSystemSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsAddressValid( - IN PVOID VirtualAddress); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsThisAnNtAsSystem( - VOID); - -NTKERNELAPI -VOID -NTAPI -MmLockPagableSectionByHandle( - IN PVOID ImageSectionHandle); - -NTKERNELAPI -NTSTATUS -NTAPI -MmUnmapViewInSessionSpace( - IN PVOID MappedBase); - -NTKERNELAPI -NTSTATUS -NTAPI -MmUnmapViewInSystemSpace( - IN PVOID MappedBase); - -NTKERNELAPI -VOID -NTAPI -MmUnsecureVirtualMemory( - IN HANDLE SecureHandle); - -NTKERNELAPI -NTSTATUS -NTAPI -MmRemovePhysicalMemory( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -NTKERNELAPI -HANDLE -NTAPI -MmSecureVirtualMemory( - IN PVOID Address, - IN SIZE_T Size, - IN ULONG ProbeMode); - -NTKERNELAPI -VOID -NTAPI -MmUnmapVideoDisplay( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -/* NtXxx Functions */ - -NTSYSCALLAPI -NTSTATUS -NTAPI -NtOpenProcess( - OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId OPTIONAL); - -NTSYSCALLAPI -NTSTATUS -NTAPI -NtQueryInformationProcess( - IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - OUT PVOID ProcessInformation OPTIONAL, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength OPTIONAL); - -/** Process manager types **/ - -typedef VOID -(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)( - IN HANDLE ParentId, - IN HANDLE ProcessId, - IN BOOLEAN Create); - -typedef VOID -(NTAPI *PCREATE_THREAD_NOTIFY_ROUTINE)( - IN HANDLE ProcessId, - IN HANDLE ThreadId, - IN BOOLEAN Create); - -typedef VOID -(NTAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)( - IN PUNICODE_STRING FullImageName, - IN HANDLE ProcessId, - IN PIMAGE_INFO ImageInfo); - -/** Process manager routines **/ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetCreateProcessNotifyRoutine( - IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, - IN BOOLEAN Remove); - -NTKERNELAPI -HANDLE -NTAPI -PsGetCurrentProcessId( - VOID); - -NTKERNELAPI -HANDLE -NTAPI -PsGetCurrentThreadId( - VOID); - -NTKERNELAPI -BOOLEAN -NTAPI -PsGetVersion( - OUT PULONG MajorVersion OPTIONAL, - OUT PULONG MinorVersion OPTIONAL, - OUT PULONG BuildNumber OPTIONAL, - OUT PUNICODE_STRING CSDVersion OPTIONAL); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) - -NTKERNELAPI -HANDLE -NTAPI -PsGetProcessId( - IN PEPROCESS Process); - -NTKERNELAPI -NTSTATUS -NTAPI -PsRemoveCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -NTSTATUS -NTAPI -PsRemoveLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ +typedef struct _PROCESS_HANDLE_TRACING_ENABLE { + ULONG Flags; +} PROCESS_HANDLE_TRACING_ENABLE, *PPROCESS_HANDLE_TRACING_ENABLE; + +typedef struct _PROCESS_HANDLE_TRACING_ENABLE_EX { + ULONG Flags; + ULONG TotalSlots; +} PROCESS_HANDLE_TRACING_ENABLE_EX, *PPROCESS_HANDLE_TRACING_ENABLE_EX; + +typedef struct _PROCESS_HANDLE_TRACING_ENTRY { + HANDLE Handle; + CLIENT_ID ClientId; + ULONG Type; + PVOID Stacks[PROCESS_HANDLE_TRACING_MAX_STACKS]; +} PROCESS_HANDLE_TRACING_ENTRY, *PPROCESS_HANDLE_TRACING_ENTRY; + +typedef struct _PROCESS_HANDLE_TRACING_QUERY { + HANDLE Handle; + ULONG TotalTraces; + PROCESS_HANDLE_TRACING_ENTRY HandleTrace[1]; +} PROCESS_HANDLE_TRACING_QUERY, *PPROCESS_HANDLE_TRACING_QUERY; extern NTKERNELAPI PEPROCESS PsInitialSystemProcess; -/* RTL Types */ -typedef struct _RTL_SPLAY_LINKS { - struct _RTL_SPLAY_LINKS *Parent; - struct _RTL_SPLAY_LINKS *LeftChild; - struct _RTL_SPLAY_LINKS *RightChild; -} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; +/****************************************************************************** + * Runtime Library Types * + ******************************************************************************/ -/* RTL Functions */ -#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_) -#define RtlGetCallersAddress(CallersAddress, CallersCaller) \ - *CallersAddress = (PVOID)_ReturnAddress(); \ - *CallersCaller = NULL; -#else +#ifndef _RTL_RUN_ONCE_DEF +#define _RTL_RUN_ONCE_DEF -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -VOID -NTAPI -RtlGetCallersAddress( - OUT PVOID *CallersAddress, - OUT PVOID *CallersCaller); -#endif +#define RTL_RUN_ONCE_INIT {0} -#endif +#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001UL +#define RTL_RUN_ONCE_ASYNC 0x00000002UL +#define RTL_RUN_ONCE_INIT_FAILED 0x00000004UL -#if !defined(MIDL_PASS) +#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2 -FORCEINLINE -LUID -NTAPI_INLINE -RtlConvertLongToLuid( - IN LONG Val) -{ - LUID Luid; - LARGE_INTEGER Temp; +#define RTL_HASH_ALLOCATED_HEADER 0x00000001 - Temp.QuadPart = Val; - Luid.LowPart = Temp.u.LowPart; - Luid.HighPart = Temp.u.HighPart; - return Luid; -} +#define RTL_HASH_RESERVED_SIGNATURE 0 -FORCEINLINE -LUID -NTAPI_INLINE -RtlConvertUlongToLuid( - IN ULONG Val) -{ - LUID Luid; +/* RtlVerifyVersionInfo() ComparisonType */ - Luid.LowPart = Val; - Luid.HighPart = 0; - return Luid; -} +#define VER_EQUAL 1 +#define VER_GREATER 2 +#define VER_GREATER_EQUAL 3 +#define VER_LESS 4 +#define VER_LESS_EQUAL 5 +#define VER_AND 6 +#define VER_OR 7 -#endif +#define VER_CONDITION_MASK 7 +#define VER_NUM_BITS_PER_CONDITION_MASK 3 -#if defined(_AMD64_) || defined(_IA64_) -//DECLSPEC_DEPRECATED_DDK_WINXP -FORCEINLINE -LARGE_INTEGER -NTAPI_INLINE -RtlLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER Divisor, - OUT PLARGE_INTEGER Remainder OPTIONAL) -{ - LARGE_INTEGER ret; - ret.QuadPart = Dividend.QuadPart / Divisor.QuadPart; - if (Remainder) - Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; - return ret; -} +/* RtlVerifyVersionInfo() TypeMask */ -#else +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_BUILDNUMBER 0x0000004 +#define VER_PLATFORMID 0x0000008 +#define VER_SERVICEPACKMINOR 0x0000010 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_SUITENAME 0x0000040 +#define VER_PRODUCT_TYPE 0x0000080 -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -LARGE_INTEGER -NTAPI -RtlLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER Divisor, - OUT PLARGE_INTEGER Remainder OPTIONAL); -#endif +#define VER_NT_WORKSTATION 0x0000001 +#define VER_NT_DOMAIN_CONTROLLER 0x0000002 +#define VER_NT_SERVER 0x0000003 -#endif /* defined(_AMD64_) || defined(_IA64_) */ +#define VER_PLATFORM_WIN32s 0 +#define VER_PLATFORM_WIN32_WINDOWS 1 +#define VER_PLATFORM_WIN32_NT 2 -#if (NTDDI_VERSION >= NTDDI_WIN2K) +typedef union _RTL_RUN_ONCE { + PVOID Ptr; +} RTL_RUN_ONCE, *PRTL_RUN_ONCE; -NTSYSAPI -BOOLEAN -NTAPI -RtlPrefixUnicodeString( - IN PCUNICODE_STRING String1, - IN PCUNICODE_STRING String2, - IN BOOLEAN CaseInSensitive); +typedef ULONG /* LOGICAL */ +(NTAPI *PRTL_RUN_ONCE_INIT_FN) ( + IN OUT PRTL_RUN_ONCE RunOnce, + IN OUT PVOID Parameter OPTIONAL, + IN OUT PVOID *Context OPTIONAL); -NTSYSAPI -VOID -NTAPI -RtlUpperString( - IN OUT PSTRING DestinationString, - IN const PSTRING SourceString); - -NTSYSAPI -NTSTATUS -NTAPI -RtlUpcaseUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PCUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -NTSYSAPI -VOID -NTAPI -RtlMapGenericMask( - IN OUT PACCESS_MASK AccessMask, - IN PGENERIC_MAPPING GenericMapping); - -NTSYSAPI -NTSTATUS -NTAPI -RtlVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTSYSAPI -NTSTATUS -NTAPI -RtlGetVersion( - IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); - -NTSYSAPI -NTSTATUS -NTAPI -RtlVerifyVersionInfo( - IN PRTL_OSVERSIONINFOEXW VersionInfo, - IN ULONG TypeMask, - IN ULONGLONG ConditionMask); - -NTSYSAPI -LONG -NTAPI -RtlCompareString( - IN const PSTRING String1, - IN const PSTRING String2, - BOOLEAN CaseInSensitive); - -NTSYSAPI -VOID -NTAPI -RtlCopyString( - OUT PSTRING DestinationString, - IN const PSTRING SourceString OPTIONAL); - -NTSYSAPI -BOOLEAN -NTAPI -RtlEqualString( - IN const PSTRING String1, - IN const PSTRING String2, - IN BOOLEAN CaseInSensitive); - -NTSYSAPI -NTSTATUS -NTAPI -RtlCharToInteger( - IN PCSZ String, - IN ULONG Base OPTIONAL, - OUT PULONG Value); - -NTSYSAPI -CHAR -NTAPI -RtlUpperChar( - IN CHAR Character); - -NTSYSAPI -ULONG -NTAPI -RtlWalkFrameChain( - OUT PVOID *Callers, - IN ULONG Count, - IN ULONG Flags); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -/* Security reference monitor routines */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -BOOLEAN -NTAPI -SeSinglePrivilegeCheck( - IN LUID PrivilegeValue, - IN KPROCESSOR_MODE PreviousMode); -#endif - -/* ZwXxx Functions */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTSTATUS -NTAPI -ZwCancelTimer( - IN HANDLE TimerHandle, - OUT PBOOLEAN CurrentState OPTIONAL); - -NTSTATUS -NTAPI -ZwCreateTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN TIMER_TYPE TimerType); - -NTSTATUS -NTAPI -ZwOpenTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTSYSAPI -NTSTATUS -NTAPI -ZwSetInformationThread( - IN HANDLE ThreadHandle, - IN THREADINFOCLASS ThreadInformationClass, - IN PVOID ThreadInformation, - IN ULONG ThreadInformationLength); - -NTSTATUS -NTAPI -ZwSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, - IN PVOID TimerContext OPTIONAL, - IN BOOLEAN ResumeTimer, - IN LONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL); - -#endif - -typedef struct _QUOTA_LIMITS { - SIZE_T PagedPoolLimit; - SIZE_T NonPagedPoolLimit; - SIZE_T MinimumWorkingSetSize; - SIZE_T MaximumWorkingSetSize; - SIZE_T PagefileLimit; - LARGE_INTEGER TimeLimit; -} QUOTA_LIMITS, *PQUOTA_LIMITS; - -struct _RTL_GENERIC_COMPARE_ROUTINE; -struct _RTL_GENERIC_ALLOCATE_ROUTINE; -struct _RTL_GENERIC_FREE_ROUTINE; - -typedef struct _RTL_GENERIC_TABLE { - PRTL_SPLAY_LINKS TableRoot; - LIST_ENTRY InsertOrderList; - PLIST_ENTRY OrderedPointer; - ULONG WhichOrderedElement; - ULONG NumberGenericTableElements; - struct _RTL_GENERIC_COMPARE_ROUTINE *CompareRoutine; - struct _RTL_GENERIC_ALLOCATE_ROUTINE *AllocateRoutine; - struct _RTL_GENERIC_FREE_ROUTINE *FreeRoutine; - PVOID TableContext; -} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE; +#endif /* _RTL_RUN_ONCE_DEF */ typedef enum _TABLE_SEARCH_RESULT { TableEmptyTree, @@ -3636,43 +2581,6 @@ typedef enum _TABLE_SEARCH_RESULT { TableInsertAsRight } TABLE_SEARCH_RESULT; -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -#define IO_CHECK_CREATE_PARAMETERS 0x0200 -#define IO_ATTACH_DEVICE 0x0400 -#define IO_IGNORE_SHARE_ACCESS_CHECK 0x0800 - -typedef struct _FILE_FS_VOLUME_INFORMATION { - LARGE_INTEGER VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[1]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; - -typedef struct _FILE_FS_FULL_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER CallerAvailableAllocationUnits; - LARGE_INTEGER ActualAvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; - -typedef struct _FILE_FS_OBJECTID_INFORMATION { - UCHAR ObjectId[16]; - UCHAR ExtendedInfo[48]; -} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; - -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[1]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; - typedef enum _RTL_GENERIC_COMPARE_RESULTS { GenericLessThan, GenericGreaterThan, @@ -3746,8 +2654,2344 @@ typedef VOID IN struct _RTL_GENERIC_TABLE *Table, IN PVOID Buffer); +typedef struct _RTL_SPLAY_LINKS { + struct _RTL_SPLAY_LINKS *Parent; + struct _RTL_SPLAY_LINKS *LeftChild; + struct _RTL_SPLAY_LINKS *RightChild; +} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; + +typedef struct _RTL_GENERIC_TABLE { + PRTL_SPLAY_LINKS TableRoot; + LIST_ENTRY InsertOrderList; + PLIST_ENTRY OrderedPointer; + ULONG WhichOrderedElement; + ULONG NumberGenericTableElements; + PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine; + PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine; + PRTL_GENERIC_FREE_ROUTINE FreeRoutine; + PVOID TableContext; +} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE; + #endif /* !RTL_USE_AVL_TABLES */ +#ifdef RTL_USE_AVL_TABLES + +#undef PRTL_GENERIC_COMPARE_ROUTINE +#undef RTL_GENERIC_COMPARE_ROUTINE +#undef PRTL_GENERIC_ALLOCATE_ROUTINE +#undef RTL_GENERIC_ALLOCATE_ROUTINE +#undef PRTL_GENERIC_FREE_ROUTINE +#undef RTL_GENERIC_FREE_ROUTINE +#undef RTL_GENERIC_TABLE +#undef PRTL_GENERIC_TABLE + +#define PRTL_GENERIC_COMPARE_ROUTINE PRTL_AVL_COMPARE_ROUTINE +#define RTL_GENERIC_COMPARE_ROUTINE RTL_AVL_COMPARE_ROUTINE +#define PRTL_GENERIC_ALLOCATE_ROUTINE PRTL_AVL_ALLOCATE_ROUTINE +#define RTL_GENERIC_ALLOCATE_ROUTINE RTL_AVL_ALLOCATE_ROUTINE +#define PRTL_GENERIC_FREE_ROUTINE PRTL_AVL_FREE_ROUTINE +#define RTL_GENERIC_FREE_ROUTINE RTL_AVL_FREE_ROUTINE +#define RTL_GENERIC_TABLE RTL_AVL_TABLE +#define PRTL_GENERIC_TABLE PRTL_AVL_TABLE + +#endif /* RTL_USE_AVL_TABLES */ + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENTRY { + LIST_ENTRY Linkage; + ULONG_PTR Signature; +} RTL_DYNAMIC_HASH_TABLE_ENTRY, *PRTL_DYNAMIC_HASH_TABLE_ENTRY; + +typedef struct _RTL_DYNAMIC_HASH_TABLE_CONTEXT { + PLIST_ENTRY ChainHead; + PLIST_ENTRY PrevLinkage; + ULONG_PTR Signature; +} RTL_DYNAMIC_HASH_TABLE_CONTEXT, *PRTL_DYNAMIC_HASH_TABLE_CONTEXT; + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENUMERATOR { + RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry; + PLIST_ENTRY ChainHead; + ULONG BucketIndex; +} RTL_DYNAMIC_HASH_TABLE_ENUMERATOR, *PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR; + +typedef struct _RTL_DYNAMIC_HASH_TABLE { + ULONG Flags; + ULONG Shift; + ULONG TableSize; + ULONG Pivot; + ULONG DivisorMask; + ULONG NumEntries; + ULONG NonEmptyBuckets; + ULONG NumEnumerators; + PVOID Directory; +} RTL_DYNAMIC_HASH_TABLE, *PRTL_DYNAMIC_HASH_TABLE; + +typedef struct _OSVERSIONINFOA { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + CHAR szCSDVersion[128]; +} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; + +typedef struct _OSVERSIONINFOW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; +} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; + +typedef struct _OSVERSIONINFOEXA { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + CHAR szCSDVersion[128]; + USHORT wServicePackMajor; + USHORT wServicePackMinor; + USHORT wSuiteMask; + UCHAR wProductType; + UCHAR wReserved; +} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; + +typedef struct _OSVERSIONINFOEXW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; + USHORT wServicePackMajor; + USHORT wServicePackMinor; + USHORT wSuiteMask; + UCHAR wProductType; + UCHAR wReserved; +} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; + +#ifdef UNICODE +typedef OSVERSIONINFOEXW OSVERSIONINFOEX; +typedef POSVERSIONINFOEXW POSVERSIONINFOEX; +typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX; +typedef OSVERSIONINFOW OSVERSIONINFO; +typedef POSVERSIONINFOW POSVERSIONINFO; +typedef LPOSVERSIONINFOW LPOSVERSIONINFO; +#else +typedef OSVERSIONINFOEXA OSVERSIONINFOEX; +typedef POSVERSIONINFOEXA POSVERSIONINFOEX; +typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; +typedef OSVERSIONINFOA OSVERSIONINFO; +typedef POSVERSIONINFOA POSVERSIONINFO; +typedef LPOSVERSIONINFOA LPOSVERSIONINFO; +#endif /* UNICODE */ + +#define HASH_ENTRY_KEY(x) ((x)->Signature) + +/****************************************************************************** + * Security Manager Types * + ******************************************************************************/ +#define SE_UNSOLICITED_INPUT_PRIVILEGE 6 + +typedef enum _WELL_KNOWN_SID_TYPE { + WinNullSid = 0, + WinWorldSid = 1, + WinLocalSid = 2, + WinCreatorOwnerSid = 3, + WinCreatorGroupSid = 4, + WinCreatorOwnerServerSid = 5, + WinCreatorGroupServerSid = 6, + WinNtAuthoritySid = 7, + WinDialupSid = 8, + WinNetworkSid = 9, + WinBatchSid = 10, + WinInteractiveSid = 11, + WinServiceSid = 12, + WinAnonymousSid = 13, + WinProxySid = 14, + WinEnterpriseControllersSid = 15, + WinSelfSid = 16, + WinAuthenticatedUserSid = 17, + WinRestrictedCodeSid = 18, + WinTerminalServerSid = 19, + WinRemoteLogonIdSid = 20, + WinLogonIdsSid = 21, + WinLocalSystemSid = 22, + WinLocalServiceSid = 23, + WinNetworkServiceSid = 24, + WinBuiltinDomainSid = 25, + WinBuiltinAdministratorsSid = 26, + WinBuiltinUsersSid = 27, + WinBuiltinGuestsSid = 28, + WinBuiltinPowerUsersSid = 29, + WinBuiltinAccountOperatorsSid = 30, + WinBuiltinSystemOperatorsSid = 31, + WinBuiltinPrintOperatorsSid = 32, + WinBuiltinBackupOperatorsSid = 33, + WinBuiltinReplicatorSid = 34, + WinBuiltinPreWindows2000CompatibleAccessSid = 35, + WinBuiltinRemoteDesktopUsersSid = 36, + WinBuiltinNetworkConfigurationOperatorsSid = 37, + WinAccountAdministratorSid = 38, + WinAccountGuestSid = 39, + WinAccountKrbtgtSid = 40, + WinAccountDomainAdminsSid = 41, + WinAccountDomainUsersSid = 42, + WinAccountDomainGuestsSid = 43, + WinAccountComputersSid = 44, + WinAccountControllersSid = 45, + WinAccountCertAdminsSid = 46, + WinAccountSchemaAdminsSid = 47, + WinAccountEnterpriseAdminsSid = 48, + WinAccountPolicyAdminsSid = 49, + WinAccountRasAndIasServersSid = 50, + WinNTLMAuthenticationSid = 51, + WinDigestAuthenticationSid = 52, + WinSChannelAuthenticationSid = 53, + WinThisOrganizationSid = 54, + WinOtherOrganizationSid = 55, + WinBuiltinIncomingForestTrustBuildersSid = 56, + WinBuiltinPerfMonitoringUsersSid = 57, + WinBuiltinPerfLoggingUsersSid = 58, + WinBuiltinAuthorizationAccessSid = 59, + WinBuiltinTerminalServerLicenseServersSid = 60, + WinBuiltinDCOMUsersSid = 61, + WinBuiltinIUsersSid = 62, + WinIUserSid = 63, + WinBuiltinCryptoOperatorsSid = 64, + WinUntrustedLabelSid = 65, + WinLowLabelSid = 66, + WinMediumLabelSid = 67, + WinHighLabelSid = 68, + WinSystemLabelSid = 69, + WinWriteRestrictedCodeSid = 70, + WinCreatorOwnerRightsSid = 71, + WinCacheablePrincipalsGroupSid = 72, + WinNonCacheablePrincipalsGroupSid = 73, + WinEnterpriseReadonlyControllersSid = 74, + WinAccountReadonlyControllersSid = 75, + WinBuiltinEventLogReadersGroup = 76, + WinNewEnterpriseReadonlyControllersSid = 77, + WinBuiltinCertSvcDComAccessGroup = 78, + WinMediumPlusLabelSid = 79, + WinLocalLogonSid = 80, + WinConsoleLogonSid = 81, + WinThisOrganizationCertificateSid = 82, +} WELL_KNOWN_SID_TYPE; + + + +#if defined(_M_IX86) + +#define PAUSE_PROCESSOR YieldProcessor(); + +#define KERNEL_STACK_SIZE 12288 +#define KERNEL_LARGE_STACK_SIZE 61440 +#define KERNEL_LARGE_STACK_COMMIT 12288 + +#define SIZE_OF_80387_REGISTERS 80 + +#if !defined(RC_INVOKED) + +#define CONTEXT_i386 0x10000 +#define CONTEXT_i486 0x10000 +#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) +#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) +#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) +#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) +#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) + +#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ + CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \ + CONTEXT_EXTENDED_REGISTERS) + +#define CONTEXT_XSTATE (CONTEXT_i386 | 0x00000040L) + +#endif /* !defined(RC_INVOKED) */ + +typedef struct _FLOATING_SAVE_AREA { + ULONG ControlWord; + ULONG StatusWord; + ULONG TagWord; + ULONG ErrorOffset; + ULONG ErrorSelector; + ULONG DataOffset; + ULONG DataSelector; + UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; + ULONG Cr0NpxState; +} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; + +#include "pshpack4.h" +typedef struct _CONTEXT { + ULONG ContextFlags; + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + FLOATING_SAVE_AREA FloatSave; + ULONG SegGs; + ULONG SegFs; + ULONG SegEs; + ULONG SegDs; + ULONG Edi; + ULONG Esi; + ULONG Ebx; + ULONG Edx; + ULONG Ecx; + ULONG Eax; + ULONG Ebp; + ULONG Eip; + ULONG SegCs; + ULONG EFlags; + ULONG Esp; + ULONG SegSs; + UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; +} CONTEXT; +#include "poppack.h" + +#define KeGetPcr() PCR + +#define PCR_MINOR_VERSION 1 +#define PCR_MAJOR_VERSION 1 + +typedef struct _KPCR { + union { + NT_TIB NtTib; + struct { + struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; + PVOID Used_StackBase; + PVOID Spare2; + PVOID TssCopy; + ULONG ContextSwitches; + KAFFINITY SetMemberCopy; + PVOID Used_Self; + }; + }; + struct _KPCR *SelfPcr; + struct _KPRCB *Prcb; + KIRQL Irql; + ULONG IRR; + ULONG IrrActive; + ULONG IDR; + PVOID KdVersionBlock; + struct _KIDTENTRY *IDT; + struct _KGDTENTRY *GDT; + struct _KTSS *TSS; + USHORT MajorVersion; + USHORT MinorVersion; + KAFFINITY SetMember; + ULONG StallScaleFactor; + UCHAR SpareUnused; + UCHAR Number; + UCHAR Spare0; + UCHAR SecondLevelCacheAssociativity; + ULONG VdmAlert; + ULONG KernelReserved[14]; + ULONG SecondLevelCacheSize; + ULONG HalReserved[16]; +} KPCR, *PKPCR; + +FORCEINLINE +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return (ULONG)__readfsbyte(FIELD_OFFSET(KPCR, Number)); +} + + + + + + +extern NTKERNELAPI PVOID MmHighestUserAddress; +extern NTKERNELAPI PVOID MmSystemRangeStart; +extern NTKERNELAPI ULONG MmUserProbeAddress; + +#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress +#define MM_SYSTEM_RANGE_START MmSystemRangeStart +#if defined(_LOCAL_COPY_USER_PROBE_ADDRESS_) +#define MM_USER_PROBE_ADDRESS _LOCAL_COPY_USER_PROBE_ADDRESS_ +extern ULONG _LOCAL_COPY_USER_PROBE_ADDRESS_; +#else +#define MM_USER_PROBE_ADDRESS MmUserProbeAddress +#endif +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_KSEG0_BASE MM_SYSTEM_RANGE_START +#define MM_SYSTEM_SPACE_END 0xFFFFFFFF +#if !defined (_X86PAE_) +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 +#else +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 +#endif + +#elif defined(_M_AMD64) + +#define PAUSE_PROCESSOR YieldProcessor(); + +#define KERNEL_STACK_SIZE 0x6000 +#define KERNEL_LARGE_STACK_SIZE 0x12000 +#define KERNEL_LARGE_STACK_COMMIT KERNEL_STACK_SIZE + +#define KERNEL_MCA_EXCEPTION_STACK_SIZE 0x2000 + +#define EXCEPTION_READ_FAULT 0 +#define EXCEPTION_WRITE_FAULT 1 +#define EXCEPTION_EXECUTE_FAULT 8 + +#if !defined(RC_INVOKED) + +#define CONTEXT_AMD64 0x100000 + +#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L) +#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L) +#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L) +#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) + +#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x20L) + +#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 +#define CONTEXT_SERVICE_ACTIVE 0x10000000 +#define CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define CONTEXT_EXCEPTION_REPORTING 0x80000000 + +#endif /* !defined(RC_INVOKED) */ + +#define INITIAL_MXCSR 0x1f80 +#define INITIAL_FPCSR 0x027f + +typedef struct DECLSPEC_ALIGN(16) _CONTEXT { + ULONG64 P1Home; + ULONG64 P2Home; + ULONG64 P3Home; + ULONG64 P4Home; + ULONG64 P5Home; + ULONG64 P6Home; + ULONG ContextFlags; + ULONG MxCsr; + USHORT SegCs; + USHORT SegDs; + USHORT SegEs; + USHORT SegFs; + USHORT SegGs; + USHORT SegSs; + ULONG EFlags; + ULONG64 Dr0; + ULONG64 Dr1; + ULONG64 Dr2; + ULONG64 Dr3; + ULONG64 Dr6; + ULONG64 Dr7; + ULONG64 Rax; + ULONG64 Rcx; + ULONG64 Rdx; + ULONG64 Rbx; + ULONG64 Rsp; + ULONG64 Rbp; + ULONG64 Rsi; + ULONG64 Rdi; + ULONG64 R8; + ULONG64 R9; + ULONG64 R10; + ULONG64 R11; + ULONG64 R12; + ULONG64 R13; + ULONG64 R14; + ULONG64 R15; + ULONG64 Rip; + union { + XMM_SAVE_AREA32 FltSave; + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + M128A VectorRegister[26]; + ULONG64 VectorControl; + ULONG64 DebugControl; + ULONG64 LastBranchToRip; + ULONG64 LastBranchFromRip; + ULONG64 LastExceptionToRip; + ULONG64 LastExceptionFromRip; +} CONTEXT; + +#define PCR_MINOR_VERSION 1 +#define PCR_MAJOR_VERSION 1 + +typedef struct _KPCR +{ + _ANONYMOUS_UNION union + { + NT_TIB NtTib; + _ANONYMOUS_STRUCT struct + { + union _KGDTENTRY64 *GdtBase; + struct _KTSS64 *TssBase; + ULONG64 UserRsp; + struct _KPCR *Self; + struct _KPRCB *CurrentPrcb; + PKSPIN_LOCK_QUEUE LockArray; + PVOID Used_Self; + }; + }; + union _KIDTENTRY64 *IdtBase; + ULONG64 Unused[2]; + KIRQL Irql; + UCHAR SecondLevelCacheAssociativity; + UCHAR ObsoleteNumber; + UCHAR Fill0; + ULONG Unused0[3]; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG StallScaleFactor; + PVOID Unused1[3]; + ULONG KernelReserved[15]; + ULONG SecondLevelCacheSize; + ULONG HalReserved[16]; + ULONG Unused2; + PVOID KdVersionBlock; + PVOID Unused3; + ULONG PcrAlign1[24]; +} KPCR, *PKPCR; + +FORCEINLINE +PKPCR +KeGetPcr(VOID) +{ + return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self)); +} + +FORCEINLINE +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return (ULONG)__readgsword(0x184); +} + + +#define PTI_SHIFT 12L +#define PDI_SHIFT 21L +#define PPI_SHIFT 30L +#define PXI_SHIFT 39L +#define PTE_PER_PAGE 512 +#define PDE_PER_PAGE 512 +#define PPE_PER_PAGE 512 +#define PXE_PER_PAGE 512 +#define PTI_MASK_AMD64 (PTE_PER_PAGE - 1) +#define PDI_MASK_AMD64 (PDE_PER_PAGE - 1) +#define PPI_MASK (PPE_PER_PAGE - 1) +#define PXI_MASK (PXE_PER_PAGE - 1) + +#define PXE_BASE 0xFFFFF6FB7DBED000ULL +#define PXE_SELFMAP 0xFFFFF6FB7DBEDF68ULL +#define PPE_BASE 0xFFFFF6FB7DA00000ULL +#define PDE_BASE 0xFFFFF6FB40000000ULL +#define PTE_BASE 0xFFFFF68000000000ULL +#define PXE_TOP 0xFFFFF6FB7DBEDFFFULL +#define PPE_TOP 0xFFFFF6FB7DBFFFFFULL +#define PDE_TOP 0xFFFFF6FB7FFFFFFFULL +#define PTE_TOP 0xFFFFF6FFFFFFFFFFULL + +extern NTKERNELAPI PVOID MmHighestUserAddress; +extern NTKERNELAPI PVOID MmSystemRangeStart; +extern NTKERNELAPI ULONG64 MmUserProbeAddress; + +#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress +#define MM_SYSTEM_RANGE_START MmSystemRangeStart +#define MM_USER_PROBE_ADDRESS MmUserProbeAddress +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFF080000000000ULL + + +#elif defined(_M_IA64) + +#elif defined(_M_PPC) + + +#elif defined(_M_MIPS) + +#elif defined(_M_ARM) +#else +#error Unknown Architecture +#endif + +/****************************************************************************** + * Executive Functions * + ******************************************************************************/ +static __inline PVOID +ExAllocateFromZone( + IN PZONE_HEADER Zone) +{ + if (Zone->FreeList.Next) + Zone->FreeList.Next = Zone->FreeList.Next->Next; + return (PVOID) Zone->FreeList.Next; +} + +static __inline PVOID +ExFreeToZone( + IN PZONE_HEADER Zone, + IN PVOID Block) +{ + ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; + Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); + return ((PSINGLE_LIST_ENTRY) Block)->Next; +} + +/* + * PVOID + * ExInterlockedAllocateFromZone( + * IN PZONE_HEADER Zone, + * IN PKSPIN_LOCK Lock) + */ +#define ExInterlockedAllocateFromZone(Zone, Lock) \ + ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) + +/* PVOID + * ExInterlockedFreeToZone( + * IN PZONE_HEADER Zone, + * IN PVOID Block, + * IN PKSPIN_LOCK Lock); + */ +#define ExInterlockedFreeToZone(Zone, Block, Lock) \ + ExInterlockedPushEntryList(&(Zone)->FreeList, (PSINGLE_LIST_ENTRY)(Block), Lock) + +/* + * BOOLEAN + * ExIsFullZone( + * IN PZONE_HEADER Zone) + */ +#define ExIsFullZone(Zone) \ + ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) + +/* BOOLEAN + * ExIsObjectInFirstZoneSegment( + * IN PZONE_HEADER Zone, + * IN PVOID Object); + */ +#define ExIsObjectInFirstZoneSegment(Zone,Object) \ + ((BOOLEAN)( ((PUCHAR)(Object) >= (PUCHAR)(Zone)->SegmentList.Next) && \ + ((PUCHAR)(Object) < (PUCHAR)(Zone)->SegmentList.Next + \ + (Zone)->TotalSegmentSize)) ) + +#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite +#define ExAcquireResourceShared ExAcquireResourceSharedLite +#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite +#define ExDeleteResource ExDeleteResourceLite +#define ExInitializeResource ExInitializeResourceLite +#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite +#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite +#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite +#define ExReleaseResourceForThread ExReleaseResourceForThreadLite + +#ifdef _X86_ + +typedef enum _INTERLOCKED_RESULT { + ResultNegative = RESULT_NEGATIVE, + ResultZero = RESULT_ZERO, + ResultPositive = RESULT_POSITIVE +} INTERLOCKED_RESULT; + +NTKERNELAPI +INTERLOCKED_RESULT +FASTCALL +Exfi386InterlockedIncrementLong( + IN OUT LONG volatile *Addend); + +NTKERNELAPI +INTERLOCKED_RESULT +FASTCALL +Exfi386InterlockedDecrementLong( + IN PLONG Addend); + +NTKERNELAPI +ULONG +FASTCALL +Exfi386InterlockedExchangeUlong( + IN PULONG Target, + IN ULONG Value); +#endif + + + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +NTSTATUS +NTAPI +ExExtendZone( + IN OUT PZONE_HEADER Zone, + IN OUT PVOID Segment, + IN ULONG SegmentSize); + +NTKERNELAPI +NTSTATUS +NTAPI +ExInitializeZone( + OUT PZONE_HEADER Zone, + IN ULONG BlockSize, + IN OUT PVOID InitialSegment, + IN ULONG InitialSegmentSize); + +NTKERNELAPI +NTSTATUS +NTAPI +ExInterlockedExtendZone( + IN OUT PZONE_HEADER Zone, + IN OUT PVOID Segment, + IN ULONG SegmentSize, + IN OUT PKSPIN_LOCK Lock); + +NTKERNELAPI +NTSTATUS +NTAPI +ExUuidCreate( + OUT UUID *Uuid); + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +ExRaiseAccessViolation(VOID); + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +ExRaiseDatatypeMisalignment(VOID); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + + +/* Hardware Abstraction Layer Functions */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +#if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) + +/* Nothing here */ + +#else /* USE_DMA_MACROS ... */ + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +IoFreeAdapterChannel( + IN PADAPTER_OBJECT AdapterObject); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +BOOLEAN +NTAPI +IoFlushAdapterBuffers( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN ULONG Length, + IN BOOLEAN WriteToDevice); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +IoFreeMapRegisters( + IN PADAPTER_OBJECT AdapterObject, + IN PVOID MapRegisterBase, + IN ULONG NumberOfMapRegisters); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +PVOID +NTAPI +HalAllocateCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + OUT PPHYSICAL_ADDRESS LogicalAddress, + IN BOOLEAN CacheEnabled); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +HalFreeCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + IN PHYSICAL_ADDRESS LogicalAddress, + IN PVOID VirtualAddress, + IN BOOLEAN CacheEnabled); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +ULONG +NTAPI +HalReadDmaCounter( + IN PADAPTER_OBJECT AdapterObject); + +NTHALAPI +NTSTATUS +NTAPI +HalAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PWAIT_CONTEXT_BLOCK Wcb, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine); + +#endif /* USE_DMA_MACROS ... */ + +#if !defined(NO_LEGACY_DRIVERS) +NTHALAPI +NTSTATUS +NTAPI +HalAssignSlotResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +NTHALAPI +ULONG +NTAPI +HalGetInterruptVector( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); + +NTHALAPI +ULONG +NTAPI +HalSetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length); + +NTHALAPI +ULONG +NTAPI +HalGetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Length); + +NTHALAPI +BOOLEAN +NTAPI +HalMakeBeep( + IN ULONG Frequency); +#endif /* !defined(NO_LEGACY_DRIVERS) */ + +NTHALAPI +PADAPTER_OBJECT +NTAPI +HalGetAdapter( + IN PDEVICE_DESCRIPTION DeviceDescription, + OUT PULONG NumberOfMapRegisters); + +VOID +NTAPI +HalPutDmaAdapter( + IN PADAPTER_OBJECT DmaAdapter); + +NTHALAPI +VOID +NTAPI +HalAcquireDisplayOwnership( + IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); + +NTHALAPI +ULONG +NTAPI +HalGetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTHALAPI +ULONG +NTAPI +HalSetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTHALAPI +BOOLEAN +NTAPI +HalTranslateBusAddress( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); + +NTHALAPI +PVOID +NTAPI +HalAllocateCrashDumpRegisters( + IN PADAPTER_OBJECT AdapterObject, + IN OUT PULONG NumberOfMapRegisters); + +NTSTATUS +NTAPI +HalGetScatterGatherList( + IN PADAPTER_OBJECT DmaAdapter, + IN PDEVICE_OBJECT DeviceObject, + IN PMDL Mdl, + IN PVOID CurrentVa, + IN ULONG Length, + IN PDRIVER_LIST_CONTROL ExecutionRoutine, + IN PVOID Context, + IN BOOLEAN WriteToDevice); + +VOID +NTAPI +HalPutScatterGatherList( + IN PADAPTER_OBJECT DmaAdapter, + IN PSCATTER_GATHER_LIST ScatterGather, + IN BOOLEAN WriteToDevice); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) +NTKERNELAPI +VOID +FASTCALL +HalExamineMBR( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG MBRTypeIdentifier, + OUT PVOID *Buffer); +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +NTSTATUS +NTAPI +HalAllocateHardwareCounters( + IN PGROUP_AFFINITY GroupAffinty, + IN ULONG GroupCount, + IN PPHYSICAL_COUNTER_RESOURCE_LIST ResourceList, + OUT PHANDLE CounterSetHandle); + +NTSTATUS +NTAPI +HalFreeHardwareCounters( + IN HANDLE CounterSetHandle); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + +#if defined(_IA64_) +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTHALAPI +ULONG +NTAPI +HalGetDmaAlignmentRequirement(VOID); +#endif +#endif /* defined(_IA64_) */ + +#if defined(_M_IX86) || defined(_M_AMD64) +#define HalGetDmaAlignmentRequirement() 1L +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +typedef struct _WHEA_ERROR_SOURCE_DESCRIPTOR *PWHEA_ERROR_SOURCE_DESCRIPTOR; +typedef struct _WHEA_ERROR_RECORD *PWHEA_ERROR_RECORD; + +NTHALAPI +VOID +NTAPI +HalBugCheckSystem( + IN PWHEA_ERROR_SOURCE_DESCRIPTOR ErrorSource, + IN PWHEA_ERROR_RECORD ErrorRecord); + +#else + +typedef struct _WHEA_ERROR_RECORD *PWHEA_ERROR_RECORD; + +NTHALAPI +VOID +NTAPI +HalBugCheckSystem( + IN PWHEA_ERROR_RECORD ErrorRecord); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + + +/****************************************************************************** + * I/O Manager Functions * + ******************************************************************************/ +/* + * VOID IoAssignArcName( + * IN PUNICODE_STRING ArcName, + * IN PUNICODE_STRING DeviceName); + */ +#define IoAssignArcName(_ArcName, _DeviceName) ( \ + IoCreateSymbolicLink((_ArcName), (_DeviceName))) + +/* + * VOID + * IoDeassignArcName( + * IN PUNICODE_STRING ArcName) + */ +#define IoDeassignArcName IoDeleteSymbolicLink + +VOID +FORCEINLINE +NTAPI +IoInitializeDriverCreateContext( + PIO_DRIVER_CREATE_CONTEXT DriverContext) +{ + RtlZeroMemory(DriverContext, sizeof(IO_DRIVER_CREATE_CONTEXT)); + DriverContext->Size = sizeof(IO_DRIVER_CREATE_CONTEXT); +} + + + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +#if !(defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)) +NTKERNELAPI +NTSTATUS +NTAPI +IoAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); +#endif + +#if !defined(DMA_MACROS_DEFINED) +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +PHYSICAL_ADDRESS +NTAPI +IoMapTransfer( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN OUT PULONG Length, + IN BOOLEAN WriteToDevice); +#endif + +NTKERNELAPI +VOID +NTAPI +IoAllocateController( + IN PCONTROLLER_OBJECT ControllerObject, + IN PDEVICE_OBJECT DeviceObject, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +PCONTROLLER_OBJECT +NTAPI +IoCreateController( + IN ULONG Size); + +NTKERNELAPI +VOID +NTAPI +IoDeleteController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTKERNELAPI +VOID +NTAPI +IoFreeController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTKERNELAPI +PCONFIGURATION_INFORMATION +NTAPI +IoGetConfigurationInformation(VOID); + +NTKERNELAPI +PDEVICE_OBJECT +NTAPI +IoGetDeviceToVerify( + IN PETHREAD Thread); + +NTKERNELAPI +VOID +NTAPI +IoCancelFileOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PFILE_OBJECT FileObject); + +NTKERNELAPI +PGENERIC_MAPPING +NTAPI +IoGetFileObjectGenericMapping(VOID); + +NTKERNELAPI +PIRP +NTAPI +IoMakeAssociatedIrp( + IN PIRP Irp, + IN CCHAR StackSize); + +NTKERNELAPI +NTSTATUS +NTAPI +IoQueryDeviceDescription( + IN PINTERFACE_TYPE BusType OPTIONAL, + IN PULONG BusNumber OPTIONAL, + IN PCONFIGURATION_TYPE ControllerType OPTIONAL, + IN PULONG ControllerNumber OPTIONAL, + IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, + IN PULONG PeripheralNumber OPTIONAL, + IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, + IN OUT PVOID Context OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRaiseHardError( + IN PIRP Irp, + IN PVPB Vpb OPTIONAL, + IN PDEVICE_OBJECT RealDeviceObject); + +NTKERNELAPI +BOOLEAN +NTAPI +IoRaiseInformationalHardError( + IN NTSTATUS ErrorStatus, + IN PUNICODE_STRING String OPTIONAL, + IN PKTHREAD Thread OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRegisterBootDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRegisterDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAttachDeviceByPointer( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportDetectedDevice( + IN PDRIVER_OBJECT DriverObject, + IN INTERFACE_TYPE LegacyBusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PCM_RESOURCE_LIST ResourceList OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, + IN BOOLEAN ResourceAssigned, + IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportResourceForDetection( + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + OUT PBOOLEAN ConflictDetected); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportResourceUsage( + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + IN BOOLEAN OverrideConflict, + OUT PBOOLEAN ConflictDetected); + +NTKERNELAPI +VOID +NTAPI +IoSetHardErrorOrVerifyDevice( + IN PIRP Irp, + IN PDEVICE_OBJECT DeviceObject); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAssignResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources OPTIONAL, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +NTKERNELAPI +BOOLEAN +NTAPI +IoSetThreadHardErrorMode( + IN BOOLEAN EnableHardErrors); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WIN2KSP3) + +NTKERNELAPI +BOOLEAN +NTAPI +IoIsFileOriginRemote( + IN PFILE_OBJECT FileObject); + +NTKERNELAPI +NTSTATUS +NTAPI +IoSetFileOrigin( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Remote); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2KSP3) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) +NTKERNELAPI +NTSTATUS +FASTCALL +IoReadPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN BOOLEAN ReturnRecognizedPartitions, + OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); + +NTKERNELAPI +NTSTATUS +FASTCALL +IoSetPartitionInformation( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG PartitionNumber, + IN ULONG PartitionType); + +NTKERNELAPI +NTSTATUS +FASTCALL +IoWritePartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG SectorsPerTrack, + IN ULONG NumberOfHeads, + IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); + +NTKERNELAPI +NTSTATUS +NTAPI +IoCreateDisk( + IN PDEVICE_OBJECT DeviceObject, + IN struct _CREATE_DISK* Disk OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReadDiskSignature( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG BytesPerSector, + OUT PDISK_SIGNATURE Signature); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReadPartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + OUT struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); + +NTKERNELAPI +NTSTATUS +NTAPI +IoSetPartitionInformationEx( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG PartitionNumber, + IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); + +NTKERNELAPI +NTSTATUS +NTAPI +IoSetSystemPartition( + IN PUNICODE_STRING VolumeNameString); + +NTKERNELAPI +NTSTATUS +NTAPI +IoVerifyPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN FixErrors); + +NTKERNELAPI +NTSTATUS +NTAPI +IoVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTKERNELAPI +NTSTATUS +NTAPI +IoWritePartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DRIVE_LAYOUT_INFORMATION_EX *DriveLayout); + +NTKERNELAPI +NTSTATUS +NTAPI +IoCreateFileSpecifyDeviceObjectHint( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG Disposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer OPTIONAL, + IN ULONG EaLength, + IN CREATE_FILE_TYPE CreateFileType, + IN PVOID InternalParameters OPTIONAL, + IN ULONG Options, + IN PVOID DeviceObject OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAttachDeviceToDeviceStackSafe( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice, + OUT PDEVICE_OBJECT *AttachedToDeviceObject); + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTKERNELAPI +IO_PAGING_PRIORITY +FASTCALL +IoGetPagingIoPriority( + IN PIRP Irp); + +#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ + +#if (NTDDI_VERSION >= NTDDI_WS03SP1) +BOOLEAN +NTAPI +IoTranslateBusAddress( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTKERNELAPI +NTSTATUS +NTAPI +IoUpdateDiskGeometry( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DISK_GEOMETRY_EX* OldDiskGeometry, + IN struct _DISK_GEOMETRY_EX* NewDiskGeometry); + +PTXN_PARAMETER_BLOCK +NTAPI +IoGetTransactionParameterBlock( + IN PFILE_OBJECT FileObject); + +NTKERNELAPI +NTSTATUS +NTAPI +IoCreateFileEx( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG Disposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer OPTIONAL, + IN ULONG EaLength, + IN CREATE_FILE_TYPE CreateFileType, + IN PVOID InternalParameters OPTIONAL, + IN ULONG Options, + IN PIO_DRIVER_CREATE_CONTEXT DriverContext OPTIONAL); + +NTSTATUS +NTAPI +IoSetIrpExtraCreateParameter( + IN OUT PIRP Irp, + IN struct _ECP_LIST *ExtraCreateParameter); + +VOID +NTAPI +IoClearIrpExtraCreateParameter( + IN OUT PIRP Irp); + +NTSTATUS +NTAPI +IoGetIrpExtraCreateParameter( + IN PIRP Irp, + OUT struct _ECP_LIST **ExtraCreateParameter OPTIONAL); + +BOOLEAN +NTAPI +IoIsFileObjectIgnoringSharing( + IN PFILE_OBJECT FileObject); + + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSTATUS +NTAPI +IoSetFileObjectIgnoreSharing( + IN PFILE_OBJECT FileObject); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + + +/****************************************************************************** + * Kernel Debugger Functions * + ******************************************************************************/ +NTSYSAPI +ULONG +NTAPI +DbgPrompt( + IN PCCH Prompt, + OUT PCH Response, + IN ULONG MaximumResponseLength); + +/****************************************************************************** + * Kernel Functions * + ******************************************************************************/ +NTKERNELAPI +VOID +FASTCALL +KeInvalidateRangeAllCaches( + IN PVOID BaseAddress, + IN ULONG Length); + + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTKERNELAPI +VOID +NTAPI +KeSetImportanceDpc( + IN OUT PRKDPC Dpc, + IN KDPC_IMPORTANCE Importance); + +NTKERNELAPI +LONG +NTAPI +KePulseEvent( + IN OUT PRKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + +NTKERNELAPI +LONG +NTAPI +KeSetBasePriorityThread( + IN OUT PRKTHREAD Thread, + IN LONG Increment); + +NTKERNELAPI +VOID +NTAPI +KeEnterCriticalRegion(VOID); + +NTKERNELAPI +VOID +NTAPI +KeLeaveCriticalRegion(VOID); + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +KeBugCheck( + IN ULONG BugCheckCode); + + +#if defined(SINGLE_GROUP_LEGACY_API) + + +NTKERNELAPI +VOID +NTAPI +KeSetTargetProcessorDpc( + IN OUT PRKDPC Dpc, + IN CCHAR Number); + +NTKERNELAPI +KAFFINITY +NTAPI +KeQueryActiveProcessors(VOID); + +#endif /* defined(SINGLE_GROUP_LEGACY_API) */ + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) +NTKERNELAPI +BOOLEAN +NTAPI +KeAreApcsDisabled(VOID); + + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + + +#if (NTDDI_VERSION >= NTDDI_WS03) + + +NTKERNELAPI +BOOLEAN +NTAPI +KeInvalidateAllCaches(VOID); + +#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ + +#if (NTDDI_VERSION >= NTDDI_WS03SP1) + +NTKERNELAPI +NTSTATUS +NTAPI +KeExpandKernelStackAndCallout( + IN PEXPAND_STACK_CALLOUT Callout, + IN PVOID Parameter OPTIONAL, + IN SIZE_T Size); + +NTKERNELAPI +VOID +NTAPI +KeEnterGuardedRegion(VOID); + +NTKERNELAPI +VOID +NTAPI +KeLeaveGuardedRegion(VOID); + + +#endif /* (NTDDI_VERSION >= NTDDI_WS03SP1) */ + +#if (NTDDI_VERSION >= NTDDI_VISTA) + + +#if defined(SINGLE_GROUP_LEGACY_API) +NTKERNELAPI +ULONG +NTAPI +KeQueryActiveProcessorCount( + OUT PKAFFINITY ActiveProcessors OPTIONAL); + +NTKERNELAPI +ULONG +NTAPI +KeQueryMaximumProcessorCount(VOID); + +#endif /* SINGLE_GROUP_LEGACY_API */ + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +NTKERNELAPI +ULONG +NTAPI +KeQueryActiveProcessorCountEx( + IN USHORT GroupNumber); + +NTKERNELAPI +ULONG +NTAPI +KeQueryMaximumProcessorCountEx( + IN USHORT GroupNumber); + +NTKERNELAPI +USHORT +NTAPI +KeQueryActiveGroupCount(VOID); + +NTKERNELAPI +USHORT +NTAPI +KeQueryMaximumGroupCount(VOID); + +NTKERNELAPI +KAFFINITY +NTAPI +KeQueryGroupAffinity( + IN USHORT GroupNumber); + +NTKERNELAPI +ULONG +NTAPI +KeGetCurrentProcessorNumberEx( + OUT PPROCESSOR_NUMBER ProcNumber OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +KeQueryNodeActiveAffinity( + IN USHORT NodeNumber, + OUT PGROUP_AFFINITY Affinity OPTIONAL, + OUT PUSHORT Count OPTIONAL); + +NTKERNELAPI +USHORT +NTAPI +KeQueryNodeMaximumProcessorCount( + IN USHORT NodeNumber); + +NTKERNELAPI +USHORT +NTAPI +KeQueryHighestNodeNumber(VOID); + +NTKERNELAPI +USHORT +NTAPI +KeGetCurrentNodeNumber(VOID); + +NTKERNELAPI +NTSTATUS +NTAPI +KeQueryLogicalProcessorRelationship( + IN PPROCESSOR_NUMBER ProcessorNumber OPTIONAL, + IN LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, + OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Information OPTIONAL, + IN OUT PULONG Length); + +NTKERNELAPI +NTSTATUS +NTAPI +KeSetHardwareCounterConfiguration( + IN PHARDWARE_COUNTER CounterArray, + IN ULONG Count); + +NTKERNELAPI +NTSTATUS +NTAPI +KeQueryHardwareCounterConfiguration( + OUT PHARDWARE_COUNTER CounterArray, + IN ULONG MaximumCount, + OUT PULONG Count); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + + +/****************************************************************************** + * Memory manager Functions * + ******************************************************************************/ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +PPHYSICAL_MEMORY_RANGE +NTAPI +MmGetPhysicalMemoryRanges(VOID); + +NTKERNELAPI +PHYSICAL_ADDRESS +NTAPI +MmGetPhysicalAddress( + IN PVOID BaseAddress); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsNonPagedSystemAddressValid( + IN PVOID VirtualAddress); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateNonCachedMemory( + IN SIZE_T NumberOfBytes); + +NTKERNELAPI +VOID +NTAPI +MmFreeNonCachedMemory( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +NTKERNELAPI +PVOID +NTAPI +MmGetVirtualForPhysical( + IN PHYSICAL_ADDRESS PhysicalAddress); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapUserAddressesToPage( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN PVOID PageAddress); + +NTKERNELAPI +PVOID +NTAPI +MmMapVideoDisplay( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN SIZE_T NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapViewInSessionSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapViewInSystemSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsAddressValid( + IN PVOID VirtualAddress); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsThisAnNtAsSystem(VOID); + +NTKERNELAPI +VOID +NTAPI +MmLockPagableSectionByHandle( + IN PVOID ImageSectionHandle); + +NTKERNELAPI +NTSTATUS +NTAPI +MmUnmapViewInSessionSpace( + IN PVOID MappedBase); + +NTKERNELAPI +NTSTATUS +NTAPI +MmUnmapViewInSystemSpace( + IN PVOID MappedBase); + +NTKERNELAPI +VOID +NTAPI +MmUnsecureVirtualMemory( + IN HANDLE SecureHandle); + +NTKERNELAPI +NTSTATUS +NTAPI +MmRemovePhysicalMemory( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +NTKERNELAPI +HANDLE +NTAPI +MmSecureVirtualMemory( + IN PVOID Address, + IN SIZE_T Size, + IN ULONG ProbeMode); + +NTKERNELAPI +VOID +NTAPI +MmUnmapVideoDisplay( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +NTKERNELAPI +NTSTATUS +NTAPI +MmAddPhysicalMemory( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateContiguousMemory( + IN SIZE_T NumberOfBytes, + IN PHYSICAL_ADDRESS HighestAcceptableAddress); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateContiguousMemorySpecifyCache( + IN SIZE_T NumberOfBytes, + IN PHYSICAL_ADDRESS LowestAcceptableAddress, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, + IN MEMORY_CACHING_TYPE CacheType); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateContiguousMemorySpecifyCacheNode( + IN SIZE_T NumberOfBytes, + IN PHYSICAL_ADDRESS LowestAcceptableAddress, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, + IN MEMORY_CACHING_TYPE CacheType, + IN NODE_REQUIREMENT PreferredNode); + +NTKERNELAPI +VOID +NTAPI +MmFreeContiguousMemory( + IN PVOID BaseAddress); + +NTKERNELAPI +VOID +NTAPI +MmFreeContiguousMemorySpecifyCache( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +NTKERNELAPI +NTSTATUS +NTAPI +MmAdvanceMdl( + IN OUT PMDL Mdl, + IN ULONG NumberOfBytes); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateMappingAddress( + IN SIZE_T NumberOfBytes, + IN ULONG PoolTag); + +NTKERNELAPI +VOID +NTAPI +MmFreeMappingAddress( + IN PVOID BaseAddress, + IN ULONG PoolTag); + +NTKERNELAPI +NTSTATUS +NTAPI +MmIsVerifierEnabled( + OUT PULONG VerifierFlags); + +NTKERNELAPI +PVOID +NTAPI +MmMapLockedPagesWithReservedMapping( + IN PVOID MappingAddress, + IN ULONG PoolTag, + IN PMDL MemoryDescriptorList, + IN MEMORY_CACHING_TYPE CacheType); + +NTKERNELAPI +NTSTATUS +NTAPI +MmProtectMdlSystemAddress( + IN PMDL MemoryDescriptorList, + IN ULONG NewProtect); + +NTKERNELAPI +VOID +NTAPI +MmUnmapReservedMapping( + IN PVOID BaseAddress, + IN ULONG PoolTag, + IN PMDL MemoryDescriptorList); + +NTKERNELAPI +NTSTATUS +NTAPI +MmAddVerifierThunks( + IN PVOID ThunkBuffer, + IN ULONG ThunkBufferSize); + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTKERNELAPI +NTSTATUS +NTAPI +MmCreateMirror(VOID); +#endif + + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSTATUS +NTAPI +MmRotatePhysicalView( + IN PVOID VirtualAddress, + IN OUT PSIZE_T NumberOfBytes, + IN PMDLX NewMdl OPTIONAL, + IN MM_ROTATE_DIRECTION Direction, + IN PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction, + IN PVOID Context OPTIONAL); + +#endif + +/****************************************************************************** + * Process Manager Functions * + ******************************************************************************/ + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL); + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation OPTIONAL, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetCreateProcessNotifyRoutine( + IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, + IN BOOLEAN Remove); + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +HANDLE +NTAPI +PsGetCurrentProcessId(VOID); + +NTKERNELAPI +HANDLE +NTAPI +PsGetCurrentThreadId(VOID); + +NTKERNELAPI +BOOLEAN +NTAPI +PsGetVersion( + OUT PULONG MajorVersion OPTIONAL, + OUT PULONG MinorVersion OPTIONAL, + OUT PULONG BuildNumber OPTIONAL, + OUT PUNICODE_STRING CSDVersion OPTIONAL); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +NTKERNELAPI +HANDLE +NTAPI +PsGetProcessId( + IN PEPROCESS Process); + +NTKERNELAPI +HANDLE +NTAPI +PsGetThreadId( + IN PETHREAD Thread); + +NTKERNELAPI +NTSTATUS +NTAPI +PsRemoveCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +NTSTATUS +NTAPI +PsRemoveLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +LONGLONG +NTAPI +PsGetProcessCreateTimeQuadPart( + IN PEPROCESS Process); + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTKERNELAPI +HANDLE +NTAPI +PsGetThreadProcessId( + IN PETHREAD Thread); +#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ + +#if (NTDDI_VERSION >= NTDDI_VISTA) + +NTKERNELAPI +BOOLEAN +NTAPI +PsSetCurrentThreadPrefetching( + IN BOOLEAN Prefetching); + +NTKERNELAPI +BOOLEAN +NTAPI +PsIsCurrentThreadPrefetching(VOID); + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + +#if (NTDDI_VERSION >= NTDDI_VISTASP1) +NTKERNELAPI +NTSTATUS +NTAPI +PsSetCreateProcessNotifyRoutineEx( + IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine, + IN BOOLEAN Remove); +#endif /* (NTDDI_VERSION >= NTDDI_VISTASP1) */ +/****************************************************************************** + * Runtime Library Functions * + ******************************************************************************/ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + + + +#ifndef RTL_USE_AVL_TABLES + +NTSYSAPI +VOID +NTAPI +RtlInitializeGenericTable( + OUT PRTL_GENERIC_TABLE Table, + IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, + IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, + IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, + IN PVOID TableContext OPTIONAL); + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTable( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer, + IN CLONG BufferSize, + OUT PBOOLEAN NewElement OPTIONAL); + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableFull( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer, + IN CLONG BufferSize, + OUT PBOOLEAN NewElement OPTIONAL, + IN PVOID NodeOrParent, + IN TABLE_SEARCH_RESULT SearchResult); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDeleteElementGenericTable( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer); + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTable( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer); + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableFull( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer, + OUT PVOID *NodeOrParent, + OUT TABLE_SEARCH_RESULT *SearchResult); + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTable( + IN PRTL_GENERIC_TABLE Table, + IN BOOLEAN Restart); + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableWithoutSplaying( + IN PRTL_GENERIC_TABLE Table, + IN OUT PVOID *RestartKey); + +NTSYSAPI +PVOID +NTAPI +RtlGetElementGenericTable( + IN PRTL_GENERIC_TABLE Table, + IN ULONG I); + +NTSYSAPI +ULONG +NTAPI +RtlNumberGenericTableElements( + IN PRTL_GENERIC_TABLE Table); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmpty( + IN PRTL_GENERIC_TABLE Table); + +#endif /* !RTL_USE_AVL_TABLES */ + +#define RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT 8 + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSplay( + IN OUT PRTL_SPLAY_LINKS Links); + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlDelete( + IN PRTL_SPLAY_LINKS Links); + +NTSYSAPI +VOID +NTAPI +RtlDeleteNoSplay( + IN PRTL_SPLAY_LINKS Links, + IN OUT PRTL_SPLAY_LINKS *Root); + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSubtreeSuccessor( + IN PRTL_SPLAY_LINKS Links); + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSubtreePredecessor( + IN PRTL_SPLAY_LINKS Links); + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlRealSuccessor( + IN PRTL_SPLAY_LINKS Links); + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlRealPredecessor( + IN PRTL_SPLAY_LINKS Links); + +NTSYSAPI +BOOLEAN +NTAPI +RtlPrefixUnicodeString( + IN PCUNICODE_STRING String1, + IN PCUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive); + +NTSYSAPI +VOID +NTAPI +RtlUpperString( + IN OUT PSTRING DestinationString, + IN const PSTRING SourceString); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI +VOID +NTAPI +RtlMapGenericMask( + IN OUT PACCESS_MASK AccessMask, + IN PGENERIC_MAPPING GenericMapping); + +NTSYSAPI +NTSTATUS +NTAPI +RtlVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetVersion( + IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); + +NTSYSAPI +NTSTATUS +NTAPI +RtlVerifyVersionInfo( + IN PRTL_OSVERSIONINFOEXW VersionInfo, + IN ULONG TypeMask, + IN ULONGLONG ConditionMask); + +NTSYSAPI +LONG +NTAPI +RtlCompareString( + IN const PSTRING String1, + IN const PSTRING String2, + IN BOOLEAN CaseInSensitive); + +NTSYSAPI +VOID +NTAPI +RtlCopyString( + OUT PSTRING DestinationString, + IN const PSTRING SourceString OPTIONAL); + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualString( + IN const PSTRING String1, + IN const PSTRING String2, + IN BOOLEAN CaseInSensitive); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCharToInteger( + IN PCSZ String, + IN ULONG Base OPTIONAL, + OUT PULONG Value); + +NTSYSAPI +CHAR +NTAPI +RtlUpperChar( + IN CHAR Character); + +NTSYSAPI +ULONG +NTAPI +RtlWalkFrameChain( + OUT PVOID *Callers, + IN ULONG Count, + IN ULONG Flags); + + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + + +#if (NTDDI_VERSION >= NTDDI_WINXP) + + NTSYSAPI VOID NTAPI @@ -3758,9 +5002,764 @@ RtlInitializeGenericTableAvl( IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext OPTIONAL); -#ifdef __cplusplus +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer, + IN CLONG BufferSize, + OUT PBOOLEAN NewElement OPTIONAL); + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableFullAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer, + IN CLONG BufferSize, + OUT PBOOLEAN NewElement OPTIONAL, + IN PVOID NodeOrParent, + IN TABLE_SEARCH_RESULT SearchResult); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDeleteElementGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer); + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer); + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableFullAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer, + OUT PVOID *NodeOrParent, + OUT TABLE_SEARCH_RESULT *SearchResult); + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN BOOLEAN Restart); + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableWithoutSplayingAvl( + IN PRTL_AVL_TABLE Table, + IN OUT PVOID *RestartKey); + +NTSYSAPI +PVOID +NTAPI +RtlLookupFirstMatchingElementGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN PVOID Buffer, + OUT PVOID *RestartKey); + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableLikeADirectory( + IN PRTL_AVL_TABLE Table, + IN PRTL_AVL_MATCH_FUNCTION MatchFunction OPTIONAL, + IN PVOID MatchData OPTIONAL, + IN ULONG NextFlag, + IN OUT PVOID *RestartKey, + IN OUT PULONG DeleteCount, + IN PVOID Buffer); + +NTSYSAPI +PVOID +NTAPI +RtlGetElementGenericTableAvl( + IN PRTL_AVL_TABLE Table, + IN ULONG I); + +NTSYSAPI +ULONG +NTAPI +RtlNumberGenericTableElementsAvl( + IN PRTL_AVL_TABLE Table); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmptyAvl( + IN PRTL_AVL_TABLE Table); + + + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + +#if (NTDDI_VERSION >= NTDDI_VISTA) + + +NTSYSAPI +VOID +NTAPI +RtlRunOnceInitialize( + OUT PRTL_RUN_ONCE RunOnce); + +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceExecuteOnce( + IN OUT PRTL_RUN_ONCE RunOnce, + IN PRTL_RUN_ONCE_INIT_FN InitFn, + IN OUT PVOID Parameter OPTIONAL, + OUT PVOID *Context OPTIONAL); + +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceBeginInitialize( + IN OUT PRTL_RUN_ONCE RunOnce, + IN ULONG Flags, + OUT PVOID *Context OPTIONAL); + +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceComplete( + IN OUT PRTL_RUN_ONCE RunOnce, + IN ULONG Flags, + IN PVOID Context OPTIONAL); + +NTSYSAPI +BOOLEAN +NTAPI +RtlGetProductInfo( + IN ULONG OSMajorVersion, + IN ULONG OSMinorVersion, + IN ULONG SpMajorVersion, + IN ULONG SpMinorVersion, + OUT PULONG ReturnedProductType); + + + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + +#if (NTDDI_VERSION >= NTDDI_WIN7) + + +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateHashTable( + IN OUT PRTL_DYNAMIC_HASH_TABLE *HashTable OPTIONAL, + IN ULONG Shift, + IN ULONG Flags); + +NTSYSAPI +VOID +NTAPI +RtlDeleteHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + +NTSYSAPI +BOOLEAN +NTAPI +RtlInsertEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + IN ULONG_PTR Signature, + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI +BOOLEAN +NTAPI +RtlRemoveEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlLookupEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN ULONG_PTR Signature, + OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlGetNextEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context); + +NTSYSAPI +BOOLEAN +NTAPI +RtlInitEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlEnumerateEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +VOID +NTAPI +RtlEndEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +BOOLEAN +NTAPI +RtlInitWeakEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlWeaklyEnumerateEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +VOID +NTAPI +RtlEndWeakEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI +BOOLEAN +NTAPI +RtlExpandHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + +NTSYSAPI +BOOLEAN +NTAPI +RtlContractHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + + +#if defined(_AMD64_) || defined(_IA64_) + + + +//DECLSPEC_DEPRECATED_DDK_WINXP +FORCEINLINE +LARGE_INTEGER +NTAPI_INLINE +RtlLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER Divisor, + OUT PLARGE_INTEGER Remainder OPTIONAL) +{ + LARGE_INTEGER ret; + ret.QuadPart = Dividend.QuadPart / Divisor.QuadPart; + if (Remainder) + Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; + return ret; } + +#else + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +LARGE_INTEGER +NTAPI +RtlLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER Divisor, + OUT PLARGE_INTEGER Remainder OPTIONAL); #endif -#endif /* _NTDDK_ */ +#endif /* defined(_AMD64_) || defined(_IA64_) */ + + + +#ifdef RTL_USE_AVL_TABLES + +#define RtlInitializeGenericTable RtlInitializeGenericTableAvl +#define RtlInsertElementGenericTable RtlInsertElementGenericTableAvl +#define RtlInsertElementGenericTableFull RtlInsertElementGenericTableFullAvl +#define RtlDeleteElementGenericTable RtlDeleteElementGenericTableAvl +#define RtlLookupElementGenericTable RtlLookupElementGenericTableAvl +#define RtlLookupElementGenericTableFull RtlLookupElementGenericTableFullAvl +#define RtlEnumerateGenericTable RtlEnumerateGenericTableAvl +#define RtlEnumerateGenericTableWithoutSplaying RtlEnumerateGenericTableWithoutSplayingAvl +#define RtlGetElementGenericTable RtlGetElementGenericTableAvl +#define RtlNumberGenericTableElements RtlNumberGenericTableElementsAvl +#define RtlIsGenericTableEmpty RtlIsGenericTableEmptyAvl + +#endif /* RTL_USE_AVL_TABLES */ + +#define RtlInitializeSplayLinks(Links) { \ + PRTL_SPLAY_LINKS _SplayLinks; \ + _SplayLinks = (PRTL_SPLAY_LINKS)(Links); \ + _SplayLinks->Parent = _SplayLinks; \ + _SplayLinks->LeftChild = NULL; \ + _SplayLinks->RightChild = NULL; \ +} + +#define RtlIsLeftChild(Links) \ + (RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) + +#define RtlIsRightChild(Links) \ + (RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) + +#define RtlRightChild(Links) \ + ((PRTL_SPLAY_LINKS)(Links))->RightChild + +#define RtlIsRoot(Links) \ + (RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)) + +#define RtlLeftChild(Links) \ + ((PRTL_SPLAY_LINKS)(Links))->LeftChild + +#define RtlParent(Links) \ + ((PRTL_SPLAY_LINKS)(Links))->Parent + +#define RtlInsertAsLeftChild(ParentLinks,ChildLinks) \ + { \ + PRTL_SPLAY_LINKS _SplayParent; \ + PRTL_SPLAY_LINKS _SplayChild; \ + _SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \ + _SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \ + _SplayParent->LeftChild = _SplayChild; \ + _SplayChild->Parent = _SplayParent; \ + } + +#define RtlInsertAsRightChild(ParentLinks,ChildLinks) \ + { \ + PRTL_SPLAY_LINKS _SplayParent; \ + PRTL_SPLAY_LINKS _SplayChild; \ + _SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \ + _SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \ + _SplayParent->RightChild = _SplayChild; \ + _SplayChild->Parent = _SplayParent; \ + } + +#if !defined(MIDL_PASS) + +FORCEINLINE +LUID +NTAPI_INLINE +RtlConvertLongToLuid( + IN LONG Val) +{ + LUID Luid; + LARGE_INTEGER Temp; + + Temp.QuadPart = Val; + Luid.LowPart = Temp.u.LowPart; + Luid.HighPart = Temp.u.HighPart; + return Luid; +} + +FORCEINLINE +LUID +NTAPI_INLINE +RtlConvertUlongToLuid( + IN ULONG Val) +{ + LUID Luid; + + Luid.LowPart = Val; + Luid.HighPart = 0; + return Luid; +} + +#endif /* !defined(MIDL_PASS) */ + +#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_) +#define RtlGetCallersAddress(CallersAddress, CallersCaller) \ + *CallersAddress = (PVOID)_ReturnAddress(); \ + *CallersCaller = NULL; +#else +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +VOID +NTAPI +RtlGetCallersAddress( + OUT PVOID *CallersAddress, + OUT PVOID *CallersCaller); +#endif +#endif + +#if !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +FORCEINLINE +VOID +NTAPI +RtlInitHashTableContext( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) +{ + Context->ChainHead = NULL; + Context->PrevLinkage = NULL; +} + +FORCEINLINE +VOID +NTAPI +RtlInitHashTableContextFromEnumerator( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context, + IN PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator) +{ + Context->ChainHead = Enumerator->ChainHead; + Context->PrevLinkage = Enumerator->HashEntry.Linkage.Blink; +} + +FORCEINLINE +VOID +NTAPI +RtlReleaseHashTableContext( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) +{ + UNREFERENCED_PARAMETER(Context); + return; +} + +FORCEINLINE +ULONG +NTAPI +RtlTotalBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->TableSize; +} + +FORCEINLINE +ULONG +NTAPI +RtlNonEmptyBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NonEmptyBuckets; +} + +FORCEINLINE +ULONG +NTAPI +RtlEmptyBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->TableSize - HashTable->NonEmptyBuckets; +} + +FORCEINLINE +ULONG +NTAPI +RtlTotalEntriesHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NumEntries; +} + +FORCEINLINE +ULONG +NTAPI +RtlActiveEnumeratorsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NumEnumerators; +} + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + +#endif /* !defined(MIDL_PASS) && !defined(SORTPP_PASS) */ + +/****************************************************************************** + * Security Manager Functions * + ******************************************************************************/ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +BOOLEAN +NTAPI +SeSinglePrivilegeCheck( + IN LUID PrivilegeValue, + IN KPROCESSOR_MODE PreviousMode); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +/****************************************************************************** + * ZwXxx Functions * + ******************************************************************************/ + + + +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateLocallyUniqueId( + OUT PLUID Luid); + +NTSYSAPI +NTSTATUS +NTAPI +ZwTerminateProcess( + IN HANDLE ProcessHandle OPTIONAL, + IN NTSTATUS ExitStatus); + +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL); + + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + + +NTSTATUS +NTAPI +ZwCancelTimer( + IN HANDLE TimerHandle, + OUT PBOOLEAN CurrentState OPTIONAL); + +NTSTATUS +NTAPI +ZwCreateTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN TIMER_TYPE TimerType); + +NTSTATUS +NTAPI +ZwOpenTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +NTSTATUS +NTAPI +ZwSetTimer( + IN HANDLE TimerHandle, + IN PLARGE_INTEGER DueTime, + IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, + IN PVOID TimerContext OPTIONAL, + IN BOOLEAN ResumeTimer, + IN LONG Period OPTIONAL, + OUT PBOOLEAN PreviousState OPTIONAL); + +NTSYSAPI +NTSTATUS +NTAPI +ZwDisplayString( + IN PUNICODE_STRING String); + +NTSYSAPI +NTSTATUS +NTAPI +ZwPowerInformation( + IN POWER_INFORMATION_LEVEL PowerInformationLevel, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength); + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryVolumeInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FsInformation, + IN ULONG Length, + IN FS_INFORMATION_CLASS FsInformationClass); + +NTSYSAPI +NTSTATUS +NTAPI +ZwDeviceIoControlFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength); + + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +NTSTATUS +NTAPI +ZwSetTimerEx( + IN HANDLE TimerHandle, + IN TIMER_SET_INFORMATION_CLASS TimerSetInformationClass, + IN OUT PVOID TimerSetInformation, + IN ULONG TimerSetInformationLength); + + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + + + +/* UNSORTED */ + +#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ + ((ConditionMask) = VerSetConditionMask((ConditionMask), \ + (TypeBitMask), (ComparisonType))) + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +ULONGLONG +NTAPI +VerSetConditionMask( + IN ULONGLONG ConditionMask, + IN ULONG TypeMask, + IN UCHAR Condition); +#endif + +typedef struct _KERNEL_USER_TIMES { + LARGE_INTEGER CreateTime; + LARGE_INTEGER ExitTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; +} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES; + +/* NtXxx Functions */ + +typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION { + SystemFirmwareTable_Enumerate, + SystemFirmwareTable_Get +} SYSTEM_FIRMWARE_TABLE_ACTION; + +typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION { + ULONG ProviderSignature; + SYSTEM_FIRMWARE_TABLE_ACTION Action; + ULONG TableID; + ULONG TableBufferLength; + UCHAR TableBuffer[ANYSIZE_ARRAY]; +} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION; + +typedef NTSTATUS +(__cdecl *PFNFTH)( + IN OUT PSYSTEM_FIRMWARE_TABLE_INFORMATION SystemFirmwareTableInfo); + +typedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER { + ULONG ProviderSignature; + BOOLEAN Register; + PFNFTH FirmwareTableHandler; + PVOID DriverObject; +} SYSTEM_FIRMWARE_TABLE_HANDLER, *PSYSTEM_FIRMWARE_TABLE_HANDLER; + +typedef ULONG_PTR +(NTAPI *PDRIVER_VERIFIER_THUNK_ROUTINE)( + IN PVOID Context); + +typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { + PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; + PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; +} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; + +#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 +#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 +#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 +#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 +#define DRIVER_VERIFIER_IO_CHECKING 0x0010 + +#define SHARED_GLOBAL_FLAGS_ERROR_PORT_V 0x0 +#define SHARED_GLOBAL_FLAGS_ERROR_PORT (1UL << SHARED_GLOBAL_FLAGS_ERROR_PORT_V) + +#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V 0x1 +#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED (1UL << SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V 0x2 +#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED (1UL << SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V 0x3 +#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_SPARE_V 0x4 +#define SHARED_GLOBAL_FLAGS_SPARE \ + (1UL << SHARED_GLOBAL_FLAGS_SPARE_V) + +#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V 0x5 +#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED_V 0x6 +#define SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED_V) + +#define EX_INIT_BITS(Flags, Bit) \ + *((Flags)) |= (Bit) // Safe to use before concurrently accessible + +#define EX_TEST_SET_BIT(Flags, Bit) \ + InterlockedBitTestAndSet ((PLONG)(Flags), (Bit)) + +#define EX_TEST_CLEAR_BIT(Flags, Bit) \ + InterlockedBitTestAndReset ((PLONG)(Flags), (Bit)) + +#define PCCARD_MAP_ERROR 0x01 +#define PCCARD_DEVICE_PCI 0x10 + +#define PCCARD_SCAN_DISABLED 0x01 +#define PCCARD_MAP_ZERO 0x02 +#define PCCARD_NO_TIMER 0x03 +#define PCCARD_NO_PIC 0x04 +#define PCCARD_NO_LEGACY_BASE 0x05 +#define PCCARD_DUP_LEGACY_BASE 0x06 +#define PCCARD_NO_CONTROLLERS 0x07 + +#define MAXIMUM_EXPANSION_SIZE (KERNEL_LARGE_STACK_SIZE - (PAGE_SIZE / 2)) + +/* Filesystem runtime library routines */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +BOOLEAN +NTAPI +FsRtlIsTotalDeviceFailure( + IN NTSTATUS Status); +#endif + +/* FIXME : These definitions below doesn't belong to NTDDK */ + +#ifdef __cplusplus +} +#endif From 38717f6840b5aef36a2521bf4ae92f1d6bdc747e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 00:26:49 +0000 Subject: [PATCH 215/292] try to fix build svn path=/trunk/; revision=47560 --- reactos/include/ddk/ntddk.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 1143aa4a545..a74e448e885 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -1043,6 +1043,8 @@ typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; } PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; +#endif // 0 + typedef VOID (NTAPI *PciPin2Line)( IN struct _BUS_HANDLER *BusHandler, @@ -1080,6 +1082,8 @@ typedef struct _PCIBUSDATA { PVOID Reserved[4]; } PCIBUSDATA, *PPCIBUSDATA; +#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... + #ifndef _PCIINTRF_X_ #define _PCIINTRF_X_ From 591e5017e9f412b3b550081c779f5f3296a524a6 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 00:49:33 +0000 Subject: [PATCH 216/292] revert 47559 and 47560 (once again... sigh) svn path=/trunk/; revision=47561 --- reactos/include/ddk/ntddk.h | 6771 ++++++++++++----------------------- 1 file changed, 2384 insertions(+), 4387 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index a74e448e885..0e02581425d 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -1,13 +1,12 @@ /* * ntddk.h * - * Windows NT Device Driver Kit + * Windows Device Driver Kit * - * This file is part of the ReactOS DDK package. + * This file is part of the w32api package. * * Contributors: - * Amine Khaldi - * Timo Kreuzer (timo.kreuzer@reactos.org) + * Created by Casper S. Hornstrup * * THIS SOFTWARE IS NOT COPYRIGHTED * @@ -19,10 +18,13 @@ * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * DEFINES: + * DBG - Debugging enabled/disabled (0/1) + * POOL_TAGGING - Enable pool tagging + * _X86_ - X86 environment */ -#pragma once - +#ifndef _NTDDK_ #define _NTDDK_ #if !defined(_NTHAL_) && !defined(_NTIFS_) @@ -39,7 +41,6 @@ #include #include #include -#include /* FIXME #include @@ -54,30 +55,21 @@ extern "C" { #endif -/* GUID and UUID */ -#ifndef _NTLSA_IFS_ -#ifndef _NTLSA_AUDIT_ -#define _NTLSA_AUDIT_ - -#ifndef GUID_DEFINED -#include -#endif - -#endif /* _NTLSA_AUDIT_ */ -#endif /* _NTLSA_IFS_ */ - -typedef GUID UUID; - struct _LOADER_PARAMETER_BLOCK; struct _CREATE_DISK; struct _DRIVE_LAYOUT_INFORMATION_EX; struct _SET_PARTITION_INFORMATION_EX; -typedef struct _BUS_HANDLER *PBUS_HANDLER; -typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT; -#if defined(_NTHAL_INCLUDED_) -typedef struct _KAFFINITY_EX *PKAFFINITY_EX; +// +// GUID and UUID +// +#ifndef GUID_DEFINED +#include #endif +typedef GUID UUID; + +typedef struct _BUS_HANDLER *PBUS_HANDLER; + typedef struct _PEB *PPEB; #ifndef _NTIMAGE_ @@ -93,89 +85,24 @@ typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; #endif /* _NTIMAGE_ */ -/****************************************************************************** - * Executive Types * - ******************************************************************************/ +#define EXCEPTION_READ_FAULT 0 +#define EXCEPTION_WRITE_FAULT 1 +#define EXCEPTION_EXECUTE_FAULT 8 -typedef struct _ZONE_SEGMENT_HEADER { - SINGLE_LIST_ENTRY SegmentList; - PVOID Reserved; -} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; +#if (NTDDI_VERSION >= NTDDI_VISTA) +extern NTSYSAPI volatile CCHAR KeNumberProcessors; +#elif (NTDDI_VERSION >= NTDDI_WINXP) +extern NTSYSAPI CCHAR KeNumberProcessors; +#else +extern PCCHAR KeNumberProcessors; +#endif -typedef struct _ZONE_HEADER { - SINGLE_LIST_ENTRY FreeList; - SINGLE_LIST_ENTRY SegmentList; - ULONG BlockSize; - ULONG TotalSegmentSize; -} ZONE_HEADER, *PZONE_HEADER; +#define MAX_WOW64_SHARED_ENTRIES 16 -#define PROTECTED_POOL 0x80000000 - - -/****************************************************************************** - * I/O Manager Types * - ******************************************************************************/ - -/* DEVICE_OBJECT.Flags */ -#define DO_DEVICE_HAS_NAME 0x00000040 -#define DO_SYSTEM_BOOT_PARTITION 0x00000100 -#define DO_LONG_TERM_REQUESTS 0x00000200 -#define DO_NEVER_LAST_DEVICE 0x00000400 -#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 -#define DO_SUPPORTS_TRANSACTIONS 0x00040000 -#define DO_FORCE_NEITHER_IO 0x00080000 -#define DO_VOLUME_DEVICE_OBJECT 0x00100000 -#define DO_SYSTEM_SYSTEM_PARTITION 0x00200000 -#define DO_SYSTEM_CRITICAL_PARTITION 0x00400000 -#define DO_DISALLOW_EXECUTE 0x00800000 - -#ifndef _ARC_DDK_ -#define _ARC_DDK_ -typedef enum _CONFIGURATION_TYPE { - ArcSystem, - CentralProcessor, - FloatingPointProcessor, - PrimaryIcache, - PrimaryDcache, - SecondaryIcache, - SecondaryDcache, - SecondaryCache, - EisaAdapter, - TcAdapter, - ScsiAdapter, - DtiAdapter, - MultiFunctionAdapter, - DiskController, - TapeController, - CdromController, - WormController, - SerialController, - NetworkController, - DisplayController, - ParallelController, - PointerController, - KeyboardController, - AudioController, - OtherController, - DiskPeripheral, - FloppyDiskPeripheral, - TapePeripheral, - ModemPeripheral, - MonitorPeripheral, - PrinterPeripheral, - PointerPeripheral, - KeyboardPeripheral, - TerminalPeripheral, - OtherPeripheral, - LinePeripheral, - NetworkPeripheral, - SystemMemory, - DockingInformation, - RealModeIrqRoutingTable, - RealModePCIEnumeration, - MaximumType -} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; -#endif /* !_ARC_DDK_ */ +#define NX_SUPPORT_POLICY_ALWAYSOFF 0 +#define NX_SUPPORT_POLICY_ALWAYSON 1 +#define NX_SUPPORT_POLICY_OPTIN 2 +#define NX_SUPPORT_POLICY_OPTOUT 3 /* ** IRP function codes @@ -210,118 +137,102 @@ typedef enum _CONFIGURATION_TYPE { #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 -#define IO_CHECK_CREATE_PARAMETERS 0x0200 -#define IO_ATTACH_DEVICE 0x0400 -#define IO_IGNORE_SHARE_ACCESS_CHECK 0x0800 +typedef struct _IO_COUNTERS { + ULONGLONG ReadOperationCount; + ULONGLONG WriteOperationCount; + ULONGLONG OtherOperationCount; + ULONGLONG ReadTransferCount; + ULONGLONG WriteTransferCount; + ULONGLONG OtherTransferCount; +} IO_COUNTERS, *PIO_COUNTERS; -typedef -NTSTATUS -(NTAPI *PIO_QUERY_DEVICE_ROUTINE)( - IN PVOID Context, - IN PUNICODE_STRING PathName, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN PKEY_VALUE_FULL_INFORMATION *BusInformation, - IN CONFIGURATION_TYPE ControllerType, - IN ULONG ControllerNumber, - IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, - IN CONFIGURATION_TYPE PeripheralType, - IN ULONG PeripheralNumber, - IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); +typedef struct _VM_COUNTERS { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} VM_COUNTERS, *PVM_COUNTERS; -typedef enum _IO_QUERY_DEVICE_DATA_FORMAT { - IoQueryDeviceIdentifier = 0, - IoQueryDeviceConfigurationData, - IoQueryDeviceComponentInformation, - IoQueryDeviceMaxData -} IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT; +typedef struct _VM_COUNTERS_EX +{ + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; +} VM_COUNTERS_EX, *PVM_COUNTERS_EX; -typedef VOID -(NTAPI *PDRIVER_REINITIALIZE)( - IN struct _DRIVER_OBJECT *DriverObject, - IN PVOID Context OPTIONAL, - IN ULONG Count); +typedef struct _POOLED_USAGE_AND_LIMITS +{ + SIZE_T PeakPagedPoolUsage; + SIZE_T PagedPoolUsage; + SIZE_T PagedPoolLimit; + SIZE_T PeakNonPagedPoolUsage; + SIZE_T NonPagedPoolUsage; + SIZE_T NonPagedPoolLimit; + SIZE_T PeakPagefileUsage; + SIZE_T PagefileUsage; + SIZE_T PagefileLimit; +} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS; -typedef struct _CONTROLLER_OBJECT { - CSHORT Type; - CSHORT Size; - PVOID ControllerExtension; - KDEVICE_QUEUE DeviceWaitQueue; - ULONG Spare1; - LARGE_INTEGER Spare2; -} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; +/* DEVICE_OBJECT.Flags */ + +#define DO_VERIFY_VOLUME 0x00000002 +#define DO_BUFFERED_IO 0x00000004 +#define DO_EXCLUSIVE 0x00000008 +#define DO_DIRECT_IO 0x00000010 +#define DO_MAP_IO_BUFFER 0x00000020 +#define DO_DEVICE_HAS_NAME 0x00000040 +#define DO_DEVICE_INITIALIZING 0x00000080 +#define DO_SYSTEM_BOOT_PARTITION 0x00000100 +#define DO_LONG_TERM_REQUESTS 0x00000200 +#define DO_NEVER_LAST_DEVICE 0x00000400 +#define DO_SHUTDOWN_REGISTERED 0x00000800 +#define DO_BUS_ENUMERATED_DEVICE 0x00001000 +#define DO_POWER_PAGABLE 0x00002000 +#define DO_POWER_INRUSH 0x00004000 +#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 +#define DO_SUPPORTS_TRANSACTIONS 0x00040000 +#define DO_FORCE_NEITHER_IO 0x00080000 +#define DO_VOLUME_DEVICE_OBJECT 0x00100000 +#define DO_SYSTEM_SYSTEM_PARTITION 0x00200000 +#define DO_SYSTEM_CRITICAL_PARTITION 0x00400000 +#define DO_DISALLOW_EXECUTE 0x00800000 #define DRVO_REINIT_REGISTERED 0x00000008 #define DRVO_INITIALIZED 0x00000010 #define DRVO_BOOTREINIT_REGISTERED 0x00000020 #define DRVO_LEGACY_RESOURCES 0x00000040 -typedef struct _CONFIGURATION_INFORMATION { - ULONG DiskCount; - ULONG FloppyCount; - ULONG CdRomCount; - ULONG TapeCount; - ULONG ScsiPortCount; - ULONG SerialCount; - ULONG ParallelCount; - BOOLEAN AtDiskPrimaryAddressClaimed; - BOOLEAN AtDiskSecondaryAddressClaimed; - ULONG Version; - ULONG MediumChangerCount; -} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; +typedef enum _ARBITER_REQUEST_SOURCE { + ArbiterRequestUndefined = -1, + ArbiterRequestLegacyReported, + ArbiterRequestHalReported, + ArbiterRequestLegacyAssigned, + ArbiterRequestPnpDetected, + ArbiterRequestPnpEnumerated +} ARBITER_REQUEST_SOURCE; -typedef struct _DISK_SIGNATURE { - ULONG PartitionStyle; - _ANONYMOUS_UNION union { - struct { - ULONG Signature; - ULONG CheckSum; - } Mbr; - struct { - GUID DiskId; - } Gpt; - } DUMMYUNIONNAME; -} DISK_SIGNATURE, *PDISK_SIGNATURE; - -typedef struct _TXN_PARAMETER_BLOCK { - USHORT Length; - USHORT TxFsContext; - PVOID TransactionObject; -} TXN_PARAMETER_BLOCK, *PTXN_PARAMETER_BLOCK; - -#define TXF_MINIVERSION_DEFAULT_VIEW (0xFFFE) - -typedef struct _IO_DRIVER_CREATE_CONTEXT { - CSHORT Size; - struct _ECP_LIST *ExtraCreateParameter; - PVOID DeviceObjectHint; - PTXN_PARAMETER_BLOCK TxnParameters; -} IO_DRIVER_CREATE_CONTEXT, *PIO_DRIVER_CREATE_CONTEXT; - -typedef struct _AGP_TARGET_BUS_INTERFACE_STANDARD { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PGET_SET_DEVICE_DATA SetBusData; - PGET_SET_DEVICE_DATA GetBusData; - UCHAR CapabilityID; -} AGP_TARGET_BUS_INTERFACE_STANDARD, *PAGP_TARGET_BUS_INTERFACE_STANDARD; - -typedef NTSTATUS -(NTAPI *PGET_LOCATION_STRING)( - IN OUT PVOID Context OPTIONAL, - OUT PWCHAR *LocationStrings); - -typedef struct _PNP_LOCATION_INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PGET_LOCATION_STRING GetLocationString; -} PNP_LOCATION_INTERFACE, *PPNP_LOCATION_INTERFACE; +typedef enum _ARBITER_RESULT { + ArbiterResultUndefined = -1, + ArbiterResultSuccess, + ArbiterResultExternalConflict, + ArbiterResultNullRequest +} ARBITER_RESULT; typedef enum _ARBITER_ACTION { ArbiterActionTestAllocation, @@ -342,69 +253,39 @@ typedef struct _ARBITER_CONFLICT_INFO { ULONGLONG End; } ARBITER_CONFLICT_INFO, *PARBITER_CONFLICT_INFO; -typedef struct _ARBITER_TEST_ALLOCATION_PARAMETERS { +typedef struct _ARBITER_PARAMETERS { + union { + struct { IN OUT PLIST_ENTRY ArbitrationList; IN ULONG AllocateFromCount; IN PCM_PARTIAL_RESOURCE_DESCRIPTOR AllocateFrom; -} ARBITER_TEST_ALLOCATION_PARAMETERS, *PARBITER_TEST_ALLOCATION_PARAMETERS; - -typedef struct _ARBITER_RETEST_ALLOCATION_PARAMETERS { + } TestAllocation; + struct { IN OUT PLIST_ENTRY ArbitrationList; IN ULONG AllocateFromCount; IN PCM_PARTIAL_RESOURCE_DESCRIPTOR AllocateFrom; -} ARBITER_RETEST_ALLOCATION_PARAMETERS, *PARBITER_RETEST_ALLOCATION_PARAMETERS; - -typedef struct _ARBITER_BOOT_ALLOCATION_PARAMETERS { + } RetestAllocation; + struct { IN OUT PLIST_ENTRY ArbitrationList; -} ARBITER_BOOT_ALLOCATION_PARAMETERS, *PARBITER_BOOT_ALLOCATION_PARAMETERS; - -typedef struct _ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS { + } BootAllocation; + struct { OUT PCM_PARTIAL_RESOURCE_LIST *AllocatedResources; -} ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS, *PARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS; - -typedef struct _ARBITER_QUERY_CONFLICT_PARAMETERS { + } QueryAllocatedResources; + struct { IN PDEVICE_OBJECT PhysicalDeviceObject; IN PIO_RESOURCE_DESCRIPTOR ConflictingResource; OUT PULONG ConflictCount; OUT PARBITER_CONFLICT_INFO *Conflicts; -} ARBITER_QUERY_CONFLICT_PARAMETERS, *PARBITER_QUERY_CONFLICT_PARAMETERS; - -typedef struct _ARBITER_QUERY_ARBITRATE_PARAMETERS { + } QueryConflict; + struct { IN PLIST_ENTRY ArbitrationList; -} ARBITER_QUERY_ARBITRATE_PARAMETERS, *PARBITER_QUERY_ARBITRATE_PARAMETERS; - -typedef struct _ARBITER_ADD_RESERVED_PARAMETERS { + } QueryArbitrate; + struct { IN PDEVICE_OBJECT ReserveDevice; -} ARBITER_ADD_RESERVED_PARAMETERS, *PARBITER_ADD_RESERVED_PARAMETERS; - -typedef struct _ARBITER_PARAMETERS { - union { - ARBITER_TEST_ALLOCATION_PARAMETERS TestAllocation; - ARBITER_RETEST_ALLOCATION_PARAMETERS RetestAllocation; - ARBITER_BOOT_ALLOCATION_PARAMETERS BootAllocation; - ARBITER_QUERY_ALLOCATED_RESOURCES_PARAMETERS QueryAllocatedResources; - ARBITER_QUERY_CONFLICT_PARAMETERS QueryConflict; - ARBITER_QUERY_ARBITRATE_PARAMETERS QueryArbitrate; - ARBITER_ADD_RESERVED_PARAMETERS AddReserved; + } AddReserved; } Parameters; } ARBITER_PARAMETERS, *PARBITER_PARAMETERS; -typedef enum _ARBITER_REQUEST_SOURCE { - ArbiterRequestUndefined = -1, - ArbiterRequestLegacyReported, - ArbiterRequestHalReported, - ArbiterRequestLegacyAssigned, - ArbiterRequestPnpDetected, - ArbiterRequestPnpEnumerated -} ARBITER_REQUEST_SOURCE; - -typedef enum _ARBITER_RESULT { - ArbiterResultUndefined = -1, - ArbiterResultSuccess, - ArbiterResultExternalConflict, - ArbiterResultNullRequest -} ARBITER_RESULT; - #define ARBITER_FLAG_BOOT_CONFIG 0x00000001 typedef struct _ARBITER_LIST_ENTRY { @@ -441,41 +322,6 @@ typedef struct _ARBITER_INTERFACE { ULONG Flags; } ARBITER_INTERFACE, *PARBITER_INTERFACE; -typedef enum _RESOURCE_TRANSLATION_DIRECTION { - TranslateChildToParent, - TranslateParentToChild -} RESOURCE_TRANSLATION_DIRECTION; - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( - IN OUT PVOID Context OPTIONAL, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, - IN RESOURCE_TRANSLATION_DIRECTION Direction, - IN ULONG AlternativesCount OPTIONAL, - IN IO_RESOURCE_DESCRIPTOR Alternatives[], - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); - -typedef NTSTATUS -(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( - IN OUT PVOID Context OPTIONAL, - IN PIO_RESOURCE_DESCRIPTOR Source, - IN PDEVICE_OBJECT PhysicalDeviceObject, - OUT PULONG TargetCount, - OUT PIO_RESOURCE_DESCRIPTOR *Target); - -typedef struct _TRANSLATOR_INTERFACE { - USHORT Size; - USHORT Version; - PVOID Context; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - PTRANSLATE_RESOURCE_HANDLER TranslateResources; - PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; -} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; - -#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... - typedef struct _PCI_AGP_CAPABILITY { PCI_CAPABILITIES_HEADER Header; USHORT Minor:4; @@ -857,6 +703,7 @@ typedef union _PCI_EXPRESS_SLOT_CONTROL_REGISTER { USHORT AsUSHORT; } PCI_EXPRESS_SLOT_CONTROL_REGISTER, *PPCI_EXPRESS_SLOT_CONTROL_REGISTER; +#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... typedef union _PCI_EXPRESS_SLOT_STATUS_REGISTER { struct { USHORT AttentionButtonPressed:1; @@ -1043,47 +890,6 @@ typedef struct _PHYSICAL_COUNTER_RESOURCE_LIST { PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR Descriptors[ANYSIZE_ARRAY]; } PHYSICAL_COUNTER_RESOURCE_LIST, *PPHYSICAL_COUNTER_RESOURCE_LIST; -#endif // 0 - -typedef VOID -(NTAPI *PciPin2Line)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciData); - -typedef VOID -(NTAPI *PciLine2Pin)( - IN struct _BUS_HANDLER *BusHandler, - IN struct _BUS_HANDLER *RootHandler, - IN PCI_SLOT_NUMBER SlotNumber, - IN PPCI_COMMON_CONFIG PciNewData, - IN PPCI_COMMON_CONFIG PciOldData); - -typedef VOID -(NTAPI *PciReadWriteConfig)( - IN struct _BUS_HANDLER *BusHandler, - IN PCI_SLOT_NUMBER Slot, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -#define PCI_DATA_TAG ' ICP' -#define PCI_DATA_VERSION 1 - -typedef struct _PCIBUSDATA { - ULONG Tag; - ULONG Version; - PciReadWriteConfig ReadConfig; - PciReadWriteConfig WriteConfig; - PciPin2Line Pin2Line; - PciLine2Pin Line2Pin; - PCI_SLOT_NUMBER ParentSlot; - PVOID Reserved[4]; -} PCIBUSDATA, *PPCIBUSDATA; - -#if 0 // Someone (testbot? RosBE for linux?) doesn't like too many types it seems... - #ifndef _PCIINTRF_X_ #define _PCIINTRF_X_ @@ -1161,114 +967,6 @@ typedef struct _PCI_BUS_INTERFACE_STANDARD { #endif // 0 -#define FILE_CHARACTERISTICS_PROPAGATED ( FILE_REMOVABLE_MEDIA | \ - FILE_READ_ONLY_DEVICE | \ - FILE_FLOPPY_DISKETTE | \ - FILE_WRITE_ONCE_MEDIA | \ - FILE_DEVICE_SECURE_OPEN ) - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - - -typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { - ULONG FileAttributes; - ULONG ReparseTag; -} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { - LARGE_INTEGER ValidDataLength; -} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; - -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[1]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; - -typedef struct _FILE_FS_VOLUME_INFORMATION { - LARGE_INTEGER VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[1]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; - -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -typedef struct _FILE_FS_FULL_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER CallerAvailableAllocationUnits; - LARGE_INTEGER ActualAvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; - -typedef struct _FILE_FS_OBJECTID_INFORMATION { - UCHAR ObjectId[16]; - UCHAR ExtendedInfo[48]; -} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; - -typedef union _FILE_SEGMENT_ELEMENT { - PVOID64 Buffer; - ULONGLONG Alignment; -}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; - -#define IOCTL_AVIO_ALLOCATE_STREAM CTL_CODE(FILE_DEVICE_AVIO, 1, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) -#define IOCTL_AVIO_FREE_STREAM CTL_CODE(FILE_DEVICE_AVIO, 2, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) -#define IOCTL_AVIO_MODIFY_STREAM CTL_CODE(FILE_DEVICE_AVIO, 3, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) - -typedef enum _BUS_DATA_TYPE { - ConfigurationSpaceUndefined = -1, - Cmos, - EisaConfiguration, - Pos, - CbusConfiguration, - PCIConfiguration, - VMEConfiguration, - NuBusConfiguration, - PCMCIAConfiguration, - MPIConfiguration, - MPSAConfiguration, - PNPISAConfiguration, - SgiInternalConfiguration, - MaximumBusDataType -} BUS_DATA_TYPE, *PBUS_DATA_TYPE; - -/* Hardware Abstraction Layer Types */ - -typedef BOOLEAN -(NTAPI *PHAL_RESET_DISPLAY_PARAMETERS)( - IN ULONG Columns, - IN ULONG Rows); - -typedef PBUS_HANDLER -(FASTCALL *pHalHandlerForBus)( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber); - -typedef VOID -(FASTCALL *pHalReferenceBusHandler)( - IN PBUS_HANDLER BusHandler); - typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, @@ -1315,18 +1013,92 @@ typedef enum _HAL_SET_INFORMATION_CLASS { HalProfileDpgoSourceInterruptHandler } HAL_SET_INFORMATION_CLASS, *PHAL_SET_INFORMATION_CLASS; -typedef NTSTATUS -(NTAPI *pHalQuerySystemInformation)( - IN HAL_QUERY_INFORMATION_CLASS InformationClass, - IN ULONG BufferSize, - IN OUT PVOID Buffer, - OUT PULONG ReturnedLength); +typedef struct _HAL_PROFILE_SOURCE_INTERVAL { + KPROFILE_SOURCE Source; + ULONG_PTR Interval; +} HAL_PROFILE_SOURCE_INTERVAL, *PHAL_PROFILE_SOURCE_INTERVAL; + +typedef struct _HAL_PROFILE_SOURCE_INFORMATION { + KPROFILE_SOURCE Source; + BOOLEAN Supported; + ULONG Interval; +} HAL_PROFILE_SOURCE_INFORMATION, *PHAL_PROFILE_SOURCE_INFORMATION; + +typedef struct _MAP_REGISTER_ENTRY { + PVOID MapRegister; + BOOLEAN WriteToDevice; +} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; + +typedef struct _DEBUG_DEVICE_ADDRESS { + UCHAR Type; + BOOLEAN Valid; + UCHAR Reserved[2]; + PUCHAR TranslatedAddress; + ULONG Length; +} DEBUG_DEVICE_ADDRESS, *PDEBUG_DEVICE_ADDRESS; + +typedef struct _DEBUG_MEMORY_REQUIREMENTS { + PHYSICAL_ADDRESS Start; + PHYSICAL_ADDRESS MaxEnd; + PVOID VirtualAddress; + ULONG Length; + BOOLEAN Cached; + BOOLEAN Aligned; +} DEBUG_MEMORY_REQUIREMENTS, *PDEBUG_MEMORY_REQUIREMENTS; + +typedef struct _DEBUG_DEVICE_DESCRIPTOR { + ULONG Bus; + ULONG Slot; + USHORT Segment; + USHORT VendorID; + USHORT DeviceID; + UCHAR BaseClass; + UCHAR SubClass; + UCHAR ProgIf; + BOOLEAN Initialized; + BOOLEAN Configured; + DEBUG_DEVICE_ADDRESS BaseAddress[6]; + DEBUG_MEMORY_REQUIREMENTS Memory; +} DEBUG_DEVICE_DESCRIPTOR, *PDEBUG_DEVICE_DESCRIPTOR; + +typedef struct _PM_DISPATCH_TABLE { + ULONG Signature; + ULONG Version; + PVOID Function[1]; +} PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; + +typedef enum _RESOURCE_TRANSLATION_DIRECTION { + TranslateChildToParent, + TranslateParentToChild +} RESOURCE_TRANSLATION_DIRECTION; typedef NTSTATUS -(NTAPI *pHalSetSystemInformation)( - IN HAL_SET_INFORMATION_CLASS InformationClass, - IN ULONG BufferSize, - IN PVOID Buffer); +(NTAPI *PTRANSLATE_RESOURCE_HANDLER)( + IN OUT PVOID Context, + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, + IN RESOURCE_TRANSLATION_DIRECTION Direction, + IN ULONG AlternativesCount OPTIONAL, + IN IO_RESOURCE_DESCRIPTOR Alternatives[], + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target); + +typedef NTSTATUS +(NTAPI *PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( + IN PVOID Context OPTIONAL, + IN PIO_RESOURCE_DESCRIPTOR Source, + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PULONG TargetCount, + OUT PIO_RESOURCE_DESCRIPTOR *Target); + +typedef struct _TRANSLATOR_INTERFACE { + USHORT Size; + USHORT Version; + PVOID Context; + PINTERFACE_REFERENCE InterfaceReference; + PINTERFACE_DEREFERENCE InterfaceDereference; + PTRANSLATE_RESOURCE_HANDLER TranslateResources; + PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; +} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; typedef VOID (FASTCALL *pHalExamineMBR)( @@ -1357,6 +1129,28 @@ typedef NTSTATUS IN ULONG NumberOfHeads, IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); +typedef PBUS_HANDLER +(FASTCALL *pHalHandlerForBus)( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber); + +typedef VOID +(FASTCALL *pHalReferenceBusHandler)( + IN PBUS_HANDLER BusHandler); + +typedef NTSTATUS +(NTAPI *pHalQuerySystemInformation)( + IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength); + +typedef NTSTATUS +(NTAPI *pHalSetSystemInformation)( + IN HAL_SET_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN PVOID Buffer); + typedef NTSTATUS (NTAPI *pHalQueryBusSlots)( IN PBUS_HANDLER BusHandler, @@ -1368,12 +1162,6 @@ typedef NTSTATUS (NTAPI *pHalInitPnpDriver)( VOID); -typedef struct _PM_DISPATCH_TABLE { - ULONG Signature; - ULONG Version; - PVOID Function[1]; -} PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; - typedef NTSTATUS (NTAPI *pHalInitPowerManagement)( IN PPM_DISPATCH_TABLE PmDriverDispatchTable, @@ -1413,7 +1201,12 @@ typedef NTSTATUS IN PHYSICAL_ADDRESS PhysicalAddress, IN LARGE_INTEGER NumberOfBytes); -typedef BOOLEAN +typedef VOID +(NTAPI *pHalEndOfBoot)( + VOID); + +typedef +BOOLEAN (NTAPI *pHalTranslateBusAddress)( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, @@ -1421,7 +1214,8 @@ typedef BOOLEAN IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress); -typedef NTSTATUS +typedef +NTSTATUS (NTAPI *pHalAssignSlotResources)( IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING DriverClassName OPTIONAL, @@ -1432,24 +1226,23 @@ typedef NTSTATUS IN ULONG SlotNumber, IN OUT PCM_RESOURCE_LIST *AllocatedResources); -typedef VOID +typedef +VOID (NTAPI *pHalHaltSystem)( VOID); -typedef BOOLEAN +typedef +BOOLEAN (NTAPI *pHalResetDisplay)( VOID); -typedef struct _MAP_REGISTER_ENTRY { - PVOID MapRegister; - BOOLEAN WriteToDevice; -} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; - -typedef UCHAR +typedef +UCHAR (NTAPI *pHalVectorToIDTEntry)( ULONG Vector); -typedef BOOLEAN +typedef +BOOLEAN (NTAPI *pHalFindBusAddressTranslation)( IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, @@ -1457,33 +1250,94 @@ typedef BOOLEAN IN OUT PULONG_PTR Context, IN BOOLEAN NextBus); -typedef VOID -(NTAPI *pHalEndOfBoot)( - VOID); +typedef +NTSTATUS +(NTAPI *pKdSetupPciDeviceForDebugging)( + IN PVOID LoaderBlock OPTIONAL, + IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); -typedef PVOID +typedef +NTSTATUS +(NTAPI *pKdReleasePciDeviceForDebugging)( + IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); + +typedef +PVOID +(NTAPI *pKdGetAcpiTablePhase0)( + IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, + IN ULONG Signature); + +typedef +PVOID (NTAPI *pHalGetAcpiTable)( IN ULONG Signature, IN PCSTR OemId OPTIONAL, IN PCSTR OemTableId OPTIONAL); -#if defined(_IA64_) -typedef NTSTATUS -(*pHalGetErrorCapList)( - IN OUT PULONG CapsListLength, - IN OUT PUCHAR ErrorCapList); +typedef +VOID +(NTAPI *pKdCheckPowerButton)( + VOID); -typedef NTSTATUS -(*pHalInjectError)( - IN ULONG BufferLength, - IN PUCHAR Buffer); +#if (NTDDI_VERSION >= NTDDI_VISTA) +typedef +PVOID +(NTAPI *pKdMapPhysicalMemory64)( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberPages, + IN BOOLEAN FlushCurrentTLB); + +typedef +VOID +(NTAPI *pKdUnmapVirtualAddress)( + IN PVOID VirtualAddress, + IN ULONG NumberPages, + IN BOOLEAN FlushCurrentTLB); +#else +typedef +PVOID +(NTAPI *pKdMapPhysicalMemory64)( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberPages); + +typedef +VOID +(NTAPI *pKdUnmapVirtualAddress)( + IN PVOID VirtualAddress, + IN ULONG NumberPages); #endif -typedef VOID + +typedef +ULONG +(NTAPI *pKdGetPciDataByOffset)( + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef +ULONG +(NTAPI *pKdSetPciDataByOffset)( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef BOOLEAN +(NTAPI *PHAL_RESET_DISPLAY_PARAMETERS)( + IN ULONG Columns, + IN ULONG Rows); + +typedef +VOID (NTAPI *PCI_ERROR_HANDLER_CALLBACK)( VOID); -typedef VOID +typedef +VOID (NTAPI *pHalSetPciErrorHandlerCallback)( IN PCI_ERROR_HANDLER_CALLBACK Callback); @@ -1557,706 +1411,78 @@ extern NTKERNELAPI HAL_DISPATCH HalDispatchTable; #define HalMirrorPhysicalMemory HALDISPATCH->HalMirrorPhysicalMemory #define HalEndOfBoot HALDISPATCH->HalEndOfBoot #define HalMirrorVerify HALDISPATCH->HalMirrorVerify -#define HalGetCachedAcpiTable HALDISPATCH->HalGetCachedAcpiTable -#define HalSetPciErrorHandlerCallback HALDISPATCH->HalSetPciErrorHandlerCallback -#if defined(_IA64_) -#define HalGetErrorCapList HALDISPATCH->HalGetErrorCapList -#define HalInjectError HALDISPATCH->HalInjectError + +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + + +typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION { + ULONG FileAttributes; + ULONG ReparseTag; +} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION { + LARGE_INTEGER ValidDataLength; +} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; + +typedef union _FILE_SEGMENT_ELEMENT { + PVOID64 Buffer; + ULONGLONG Alignment; +}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; + +#define SE_UNSOLICITED_INPUT_PRIVILEGE 6 + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +ULONGLONG +NTAPI +VerSetConditionMask( + IN ULONGLONG ConditionMask, + IN ULONG TypeMask, + IN UCHAR Condition); #endif -typedef struct _HAL_BUS_INFORMATION { - INTERFACE_TYPE BusType; - BUS_DATA_TYPE ConfigurationType; - ULONG BusNumber; - ULONG Reserved; -} HAL_BUS_INFORMATION, *PHAL_BUS_INFORMATION; - -typedef struct _HAL_PROFILE_SOURCE_INFORMATION { - KPROFILE_SOURCE Source; - BOOLEAN Supported; - ULONG Interval; -} HAL_PROFILE_SOURCE_INFORMATION, *PHAL_PROFILE_SOURCE_INFORMATION; - -typedef struct _HAL_PROFILE_SOURCE_INFORMATION_EX { - KPROFILE_SOURCE Source; - BOOLEAN Supported; - ULONG_PTR Interval; - ULONG_PTR DefInterval; - ULONG_PTR MaxInterval; - ULONG_PTR MinInterval; -} HAL_PROFILE_SOURCE_INFORMATION_EX, *PHAL_PROFILE_SOURCE_INFORMATION_EX; - -typedef struct _HAL_PROFILE_SOURCE_INTERVAL { - KPROFILE_SOURCE Source; - ULONG_PTR Interval; -} HAL_PROFILE_SOURCE_INTERVAL, *PHAL_PROFILE_SOURCE_INTERVAL; - -typedef struct _HAL_PROFILE_SOURCE_LIST { - KPROFILE_SOURCE Source; - PWSTR Description; -} HAL_PROFILE_SOURCE_LIST, *PHAL_PROFILE_SOURCE_LIST; - -typedef enum _HAL_DISPLAY_BIOS_INFORMATION { - HalDisplayInt10Bios, - HalDisplayEmulatedBios, - HalDisplayNoBios -} HAL_DISPLAY_BIOS_INFORMATION, *PHAL_DISPLAY_BIOS_INFORMATION; - -typedef struct _HAL_POWER_INFORMATION { - ULONG TBD; -} HAL_POWER_INFORMATION, *PHAL_POWER_INFORMATION; - -typedef struct _HAL_PROCESSOR_SPEED_INFO { - ULONG ProcessorSpeed; -} HAL_PROCESSOR_SPEED_INFORMATION, *PHAL_PROCESSOR_SPEED_INFORMATION; - -typedef struct _HAL_CALLBACKS { - PCALLBACK_OBJECT SetSystemInformation; - PCALLBACK_OBJECT BusCheck; -} HAL_CALLBACKS, *PHAL_CALLBACKS; - -typedef struct _HAL_PROCESSOR_FEATURE { - ULONG UsableFeatureBits; -} HAL_PROCESSOR_FEATURE; - -typedef NTSTATUS -(NTAPI *PHALIOREADWRITEHANDLER)( - IN BOOLEAN fRead, - IN ULONG dwAddr, - IN ULONG dwSize, - IN OUT PULONG pdwData); - -typedef struct _HAL_AMLI_BAD_IO_ADDRESS_LIST { - ULONG BadAddrBegin; - ULONG BadAddrSize; - ULONG OSVersionTrigger; - PHALIOREADWRITEHANDLER IOHandler; -} HAL_AMLI_BAD_IO_ADDRESS_LIST, *PHAL_AMLI_BAD_IO_ADDRESS_LIST; - -#if defined(_X86_) || defined(_IA64_) || defined(_AMD64_) - -typedef VOID -(NTAPI *PHALMCAINTERFACELOCK)( - VOID); - -typedef VOID -(NTAPI *PHALMCAINTERFACEUNLOCK)( - VOID); - -typedef NTSTATUS -(NTAPI *PHALMCAINTERFACEREADREGISTER)( - IN UCHAR BankNumber, - IN OUT PVOID Exception); - -typedef struct _HAL_MCA_INTERFACE { - PHALMCAINTERFACELOCK Lock; - PHALMCAINTERFACEUNLOCK Unlock; - PHALMCAINTERFACEREADREGISTER ReadRegister; -} HAL_MCA_INTERFACE; - -typedef enum { - ApicDestinationModePhysical = 1, - ApicDestinationModeLogicalFlat, - ApicDestinationModeLogicalClustered, - ApicDestinationModeUnknown -} HAL_APIC_DESTINATION_MODE, *PHAL_APIC_DESTINATION_MODE; - -#if defined(_AMD64_) - -struct _KTRAP_FRAME; -struct _KEXCEPTION_FRAME; - -typedef ERROR_SEVERITY -(NTAPI *PDRIVER_EXCPTN_CALLBACK)( - IN PVOID Context, - IN struct _KTRAP_FRAME *TrapFrame, - IN struct _KEXCEPTION_FRAME *ExceptionFrame, - IN PMCA_EXCEPTION Exception); - -#endif - -#if defined(_X86_) || defined(_IA64_) -typedef -#if defined(_IA64_) -ERROR_SEVERITY -#else -VOID -#endif -(NTAPI *PDRIVER_EXCPTN_CALLBACK)( - IN PVOID Context, - IN PMCA_EXCEPTION BankLog); -#endif - -typedef PDRIVER_EXCPTN_CALLBACK PDRIVER_MCA_EXCEPTION_CALLBACK; - -typedef struct _MCA_DRIVER_INFO { - PDRIVER_MCA_EXCEPTION_CALLBACK ExceptionCallback; - PKDEFERRED_ROUTINE DpcCallback; - PVOID DeviceContext; -} MCA_DRIVER_INFO, *PMCA_DRIVER_INFO; - -typedef struct _HAL_ERROR_INFO { - ULONG Version; - ULONG InitMaxSize; - ULONG McaMaxSize; - ULONG McaPreviousEventsCount; - ULONG McaCorrectedEventsCount; - ULONG McaKernelDeliveryFails; - ULONG McaDriverDpcQueueFails; - ULONG McaReserved; - ULONG CmcMaxSize; - ULONG CmcPollingInterval; - ULONG CmcInterruptsCount; - ULONG CmcKernelDeliveryFails; - ULONG CmcDriverDpcQueueFails; - ULONG CmcGetStateFails; - ULONG CmcClearStateFails; - ULONG CmcReserved; - ULONGLONG CmcLogId; - ULONG CpeMaxSize; - ULONG CpePollingInterval; - ULONG CpeInterruptsCount; - ULONG CpeKernelDeliveryFails; - ULONG CpeDriverDpcQueueFails; - ULONG CpeGetStateFails; - ULONG CpeClearStateFails; - ULONG CpeInterruptSources; - ULONGLONG CpeLogId; - ULONGLONG KernelReserved[4]; -} HAL_ERROR_INFO, *PHAL_ERROR_INFO; - -#define HAL_MCE_INTERRUPTS_BASED ((ULONG)-1) -#define HAL_MCE_DISABLED ((ULONG)0) - -#define HAL_CMC_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED -#define HAL_CMC_DISABLED HAL_MCE_DISABLED - -#define HAL_CPE_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED -#define HAL_CPE_DISABLED HAL_MCE_DISABLED - -#define HAL_MCA_INTERRUPTS_BASED HAL_MCE_INTERRUPTS_BASED -#define HAL_MCA_DISABLED HAL_MCE_DISABLED - -typedef VOID -(NTAPI *PDRIVER_CMC_EXCEPTION_CALLBACK)( - IN PVOID Context, - IN PCMC_EXCEPTION CmcLog); - -typedef VOID -(NTAPI *PDRIVER_CPE_EXCEPTION_CALLBACK)( - IN PVOID Context, - IN PCPE_EXCEPTION CmcLog); - -typedef struct _CMC_DRIVER_INFO { - PDRIVER_CMC_EXCEPTION_CALLBACK ExceptionCallback; - PKDEFERRED_ROUTINE DpcCallback; - PVOID DeviceContext; -} CMC_DRIVER_INFO, *PCMC_DRIVER_INFO; - -typedef struct _CPE_DRIVER_INFO { - PDRIVER_CPE_EXCEPTION_CALLBACK ExceptionCallback; - PKDEFERRED_ROUTINE DpcCallback; - PVOID DeviceContext; -} CPE_DRIVER_INFO, *PCPE_DRIVER_INFO; - -#endif // defined(_X86_) || defined(_IA64_) || defined(_AMD64_) - -#if defined(_IA64_) - -typedef NTSTATUS -(*HALSENDCROSSPARTITIONIPI)( - IN USHORT ProcessorID, - IN UCHAR HardwareVector); - -typedef NTSTATUS -(*HALRESERVECROSSPARTITIONINTERRUPTVECTOR)( - OUT PULONG Vector, - OUT PKIRQL Irql, - IN OUT PGROUP_AFFINITY Affinity, - OUT PUCHAR HardwareVector); - -typedef VOID -(*HALFREECROSSPARTITIONINTERRUPTVECTOR)( - IN ULONG Vector, - IN PGROUP_AFFINITY Affinity); - -typedef struct _HAL_CROSS_PARTITION_IPI_INTERFACE { - HALSENDCROSSPARTITIONIPI HalSendCrossPartitionIpi; - HALRESERVECROSSPARTITIONINTERRUPTVECTOR HalReserveCrossPartitionInterruptVector; - HALFREECROSSPARTITIONINTERRUPTVECTOR HalFreeCrossPartitionInterruptVector; -} HAL_CROSS_PARTITION_IPI_INTERFACE; - -#define HAL_CROSS_PARTITION_IPI_INTERFACE_MINIMUM_SIZE \ - FIELD_OFFSET(HAL_CROSS_PARTITION_IPI_INTERFACE, \ - HalFreeCrossPartitionInterruptVector) - -#endif /* defined(_IA64_) */ - -typedef struct _HAL_PLATFORM_INFORMATION { - ULONG PlatformFlags; -} HAL_PLATFORM_INFORMATION, *PHAL_PLATFORM_INFORMATION; - -#define HAL_PLATFORM_DISABLE_WRITE_COMBINING 0x01L -#define HAL_PLATFORM_DISABLE_PTCG 0x04L -#define HAL_PLATFORM_DISABLE_UC_MAIN_MEMORY 0x08L -#define HAL_PLATFORM_ENABLE_WRITE_COMBINING_MMIO 0x10L -#define HAL_PLATFORM_ACPI_TABLES_CACHED 0x20L - -/****************************************************************************** - * Kernel Types * - ******************************************************************************/ - -#define NX_SUPPORT_POLICY_ALWAYSOFF 0 -#define NX_SUPPORT_POLICY_ALWAYSON 1 -#define NX_SUPPORT_POLICY_OPTIN 2 -#define NX_SUPPORT_POLICY_OPTOUT 3 - -typedef VOID -(NTAPI *PEXPAND_STACK_CALLOUT)( - IN PVOID Parameter OPTIONAL); - -typedef VOID -(NTAPI *PTIMER_APC_ROUTINE)( - IN PVOID TimerContext, - IN ULONG TimerLowValue, - IN LONG TimerHighValue); - -typedef enum _TIMER_SET_INFORMATION_CLASS { - TimerSetCoalescableTimer, - MaxTimerInfoClass -} TIMER_SET_INFORMATION_CLASS; - -#if (NTDDI_VERSION >= NTDDI_WIN7) -typedef struct _TIMER_SET_COALESCABLE_TIMER_INFO { - IN LARGE_INTEGER DueTime; - IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL; - IN PVOID TimerContext OPTIONAL; - IN struct _COUNTED_REASON_CONTEXT *WakeContext OPTIONAL; - IN ULONG Period OPTIONAL; - IN ULONG TolerableDelay; - OUT PBOOLEAN PreviousState OPTIONAL; -} TIMER_SET_COALESCABLE_TIMER_INFO, *PTIMER_SET_COALESCABLE_TIMER_INFO; -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - -#define XSTATE_LEGACY_FLOATING_POINT 0 -#define XSTATE_LEGACY_SSE 1 -#define XSTATE_GSSE 2 - -#define XSTATE_MASK_LEGACY_FLOATING_POINT (1i64 << (XSTATE_LEGACY_FLOATING_POINT)) -#define XSTATE_MASK_LEGACY_SSE (1i64 << (XSTATE_LEGACY_SSE)) -#define XSTATE_MASK_LEGACY (XSTATE_MASK_LEGACY_FLOATING_POINT | XSTATE_MASK_LEGACY_SSE) -#define XSTATE_MASK_GSSE (1i64 << (XSTATE_GSSE)) - -#define MAXIMUM_XSTATE_FEATURES 64 - -typedef struct _XSTATE_FEATURE { - ULONG Offset; - ULONG Size; -} XSTATE_FEATURE, *PXSTATE_FEATURE; - -typedef struct _XSTATE_CONFIGURATION { - ULONG64 EnabledFeatures; - ULONG Size; - ULONG OptimizedSave:1; - XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES]; -} XSTATE_CONFIGURATION, *PXSTATE_CONFIGURATION; - -#define MAX_WOW64_SHARED_ENTRIES 16 - -typedef struct _KUSER_SHARED_DATA { - ULONG TickCountLowDeprecated; - ULONG TickCountMultiplier; - volatile KSYSTEM_TIME InterruptTime; - volatile KSYSTEM_TIME SystemTime; - volatile KSYSTEM_TIME TimeZoneBias; - USHORT ImageNumberLow; - USHORT ImageNumberHigh; - WCHAR NtSystemRoot[260]; - ULONG MaxStackTraceDepth; - ULONG CryptoExponent; - ULONG TimeZoneId; - ULONG LargePageMinimum; - ULONG Reserved2[7]; - NT_PRODUCT_TYPE NtProductType; - BOOLEAN ProductTypeIsValid; - ULONG NtMajorVersion; - ULONG NtMinorVersion; - BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; - ULONG Reserved1; - ULONG Reserved3; - volatile ULONG TimeSlip; - ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; - ULONG AltArchitecturePad[1]; - LARGE_INTEGER SystemExpirationDate; - ULONG SuiteMask; - BOOLEAN KdDebuggerEnabled; -#if (NTDDI_VERSION >= NTDDI_WINXPSP2) - UCHAR NXSupportPolicy; -#endif - volatile ULONG ActiveConsoleId; - volatile ULONG DismountCount; - ULONG ComPlusPackage; - ULONG LastSystemRITEventTickCount; - ULONG NumberOfPhysicalPages; - BOOLEAN SafeBootMode; -#if (NTDDI_VERSION >= NTDDI_WIN7) - union { - UCHAR TscQpcData; - struct { - UCHAR TscQpcEnabled:1; - UCHAR TscQpcSpareFlag:1; - UCHAR TscQpcShift:6; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - UCHAR TscQpcPad[2]; -#endif -#if (NTDDI_VERSION >= NTDDI_VISTA) - union { - ULONG SharedDataFlags; - struct { - ULONG DbgErrorPortPresent:1; - ULONG DbgElevationEnabled:1; - ULONG DbgVirtEnabled:1; - ULONG DbgInstallerDetectEnabled:1; - ULONG DbgSystemDllRelocated:1; - ULONG DbgDynProcessorEnabled:1; - ULONG DbgSEHValidationEnabled:1; - ULONG SpareBits:25; - } DUMMYSTRUCTNAME2; - } DUMMYUNIONNAME2; -#else - ULONG TraceLogging; -#endif - ULONG DataFlagsPad[1]; - ULONGLONG TestRetInstruction; - ULONG SystemCall; - ULONG SystemCallReturn; - ULONGLONG SystemCallPad[3]; - _ANONYMOUS_UNION union { - volatile KSYSTEM_TIME TickCount; - volatile ULONG64 TickCountQuad; - _ANONYMOUS_STRUCT struct { - ULONG ReservedTickCountOverlay[3]; - ULONG TickCountPad[1]; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME3; - ULONG Cookie; - ULONG CookiePad[1]; -#if (NTDDI_VERSION >= NTDDI_WS03) - LONGLONG ConsoleSessionForegroundProcessId; - ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; -#endif -#if (NTDDI_VERSION >= NTDDI_VISTA) -#if (NTDDI_VERSION >= NTDDI_WIN7) - USHORT UserModeGlobalLogger[16]; -#else - USHORT UserModeGlobalLogger[8]; - ULONG HeapTracingPid[2]; - ULONG CritSecTracingPid[2]; -#endif - ULONG ImageFileExecutionOptions; -#if (NTDDI_VERSION >= NTDDI_VISTASP1) - ULONG LangGenerationCount; -#else - /* 4 bytes padding */ -#endif - ULONGLONG Reserved5; - volatile ULONG64 InterruptTimeBias; -#endif -#if (NTDDI_VERSION >= NTDDI_WIN7) - volatile ULONG64 TscQpcBias; - volatile ULONG ActiveProcessorCount; - volatile USHORT ActiveGroupCount; - USHORT Reserved4; - volatile ULONG AitSamplingValue; - volatile ULONG AppCompatFlag; - ULONGLONG SystemDllNativeRelocation; - ULONG SystemDllWowRelocation; - ULONG XStatePad[1]; - XSTATE_CONFIGURATION XState; -#endif -} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; - -#if (NTDDI_VERSION >= NTDDI_VISTA) -extern NTSYSAPI volatile CCHAR KeNumberProcessors; -#elif (NTDDI_VERSION >= NTDDI_WINXP) -extern NTSYSAPI CCHAR KeNumberProcessors; -#else -extern PCCHAR KeNumberProcessors; -#endif - - -/****************************************************************************** - * Kernel Debugger Types * - ******************************************************************************/ -typedef struct _DEBUG_DEVICE_ADDRESS { - UCHAR Type; - BOOLEAN Valid; - UCHAR Reserved[2]; - PUCHAR TranslatedAddress; - ULONG Length; -} DEBUG_DEVICE_ADDRESS, *PDEBUG_DEVICE_ADDRESS; - -typedef struct _DEBUG_MEMORY_REQUIREMENTS { - PHYSICAL_ADDRESS Start; - PHYSICAL_ADDRESS MaxEnd; - PVOID VirtualAddress; - ULONG Length; - BOOLEAN Cached; - BOOLEAN Aligned; -} DEBUG_MEMORY_REQUIREMENTS, *PDEBUG_MEMORY_REQUIREMENTS; - -typedef struct _DEBUG_DEVICE_DESCRIPTOR { - ULONG Bus; - ULONG Slot; - USHORT Segment; - USHORT VendorID; - USHORT DeviceID; - UCHAR BaseClass; - UCHAR SubClass; - UCHAR ProgIf; - BOOLEAN Initialized; - BOOLEAN Configured; - DEBUG_DEVICE_ADDRESS BaseAddress[6]; - DEBUG_MEMORY_REQUIREMENTS Memory; -} DEBUG_DEVICE_DESCRIPTOR, *PDEBUG_DEVICE_DESCRIPTOR; - -typedef NTSTATUS -(NTAPI *pKdSetupPciDeviceForDebugging)( - IN PVOID LoaderBlock OPTIONAL, - IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); - -typedef NTSTATUS -(NTAPI *pKdReleasePciDeviceForDebugging)( - IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice); - -typedef PVOID -(NTAPI *pKdGetAcpiTablePhase0)( - IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, - IN ULONG Signature); - -typedef VOID -(NTAPI *pKdCheckPowerButton)( - VOID); - -#if (NTDDI_VERSION >= NTDDI_VISTA) -typedef PVOID -(NTAPI *pKdMapPhysicalMemory64)( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberPages, - IN BOOLEAN FlushCurrentTLB); - -typedef VOID -(NTAPI *pKdUnmapVirtualAddress)( - IN PVOID VirtualAddress, - IN ULONG NumberPages, - IN BOOLEAN FlushCurrentTLB); -#else -typedef PVOID -(NTAPI *pKdMapPhysicalMemory64)( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberPages); - -typedef VOID -(NTAPI *pKdUnmapVirtualAddress)( - IN PVOID VirtualAddress, - IN ULONG NumberPages); -#endif - -typedef ULONG -(NTAPI *pKdGetPciDataByOffset)( - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -typedef ULONG -(NTAPI *pKdSetPciDataByOffset)( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); -/****************************************************************************** - * Memory manager Types * - ******************************************************************************/ - -typedef struct _PHYSICAL_MEMORY_RANGE { - PHYSICAL_ADDRESS BaseAddress; - LARGE_INTEGER NumberOfBytes; -} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; - -typedef NTSTATUS -(NTAPI *PMM_ROTATE_COPY_CALLBACK_FUNCTION)( - IN PMDL DestinationMdl, - IN PMDL SourceMdl, - IN PVOID Context); - -typedef enum _MM_ROTATE_DIRECTION { - MmToFrameBuffer, - MmToFrameBufferNoCopy, - MmToRegularMemory, - MmToRegularMemoryNoCopy, - MmMaximumRotateDirection -} MM_ROTATE_DIRECTION, *PMM_ROTATE_DIRECTION; - - -/****************************************************************************** - * Process Manager Types * - ******************************************************************************/ - -#define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001 -#define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002 -#define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004 -#define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008 -#define QUOTA_LIMITS_USE_DEFAULT_LIMITS 0x00000010 - -typedef struct _QUOTA_LIMITS { - SIZE_T PagedPoolLimit; - SIZE_T NonPagedPoolLimit; - SIZE_T MinimumWorkingSetSize; - SIZE_T MaximumWorkingSetSize; - SIZE_T PagefileLimit; - LARGE_INTEGER TimeLimit; -} QUOTA_LIMITS, *PQUOTA_LIMITS; - -typedef union _RATE_QUOTA_LIMIT { - ULONG RateData; - struct { - ULONG RatePercent:7; - ULONG Reserved0:25; - } DUMMYSTRUCTNAME; -} RATE_QUOTA_LIMIT, *PRATE_QUOTA_LIMIT; - -typedef struct _QUOTA_LIMITS_EX { - SIZE_T PagedPoolLimit; - SIZE_T NonPagedPoolLimit; - SIZE_T MinimumWorkingSetSize; - SIZE_T MaximumWorkingSetSize; - SIZE_T PagefileLimit; - LARGE_INTEGER TimeLimit; - SIZE_T WorkingSetLimit; - SIZE_T Reserved2; - SIZE_T Reserved3; - SIZE_T Reserved4; - ULONG Flags; - RATE_QUOTA_LIMIT CpuRateLimit; -} QUOTA_LIMITS_EX, *PQUOTA_LIMITS_EX; - -typedef struct _IO_COUNTERS { - ULONGLONG ReadOperationCount; - ULONGLONG WriteOperationCount; - ULONGLONG OtherOperationCount; - ULONGLONG ReadTransferCount; - ULONGLONG WriteTransferCount; - ULONGLONG OtherTransferCount; -} IO_COUNTERS, *PIO_COUNTERS; - -typedef struct _VM_COUNTERS { - SIZE_T PeakVirtualSize; - SIZE_T VirtualSize; - ULONG PageFaultCount; - SIZE_T PeakWorkingSetSize; - SIZE_T WorkingSetSize; - SIZE_T QuotaPeakPagedPoolUsage; - SIZE_T QuotaPagedPoolUsage; - SIZE_T QuotaPeakNonPagedPoolUsage; - SIZE_T QuotaNonPagedPoolUsage; - SIZE_T PagefileUsage; - SIZE_T PeakPagefileUsage; -} VM_COUNTERS, *PVM_COUNTERS; - -typedef struct _VM_COUNTERS_EX { - SIZE_T PeakVirtualSize; - SIZE_T VirtualSize; - ULONG PageFaultCount; - SIZE_T PeakWorkingSetSize; - SIZE_T WorkingSetSize; - SIZE_T QuotaPeakPagedPoolUsage; - SIZE_T QuotaPagedPoolUsage; - SIZE_T QuotaPeakNonPagedPoolUsage; - SIZE_T QuotaNonPagedPoolUsage; - SIZE_T PagefileUsage; - SIZE_T PeakPagefileUsage; - SIZE_T PrivateUsage; -} VM_COUNTERS_EX, *PVM_COUNTERS_EX; - -#define MAX_HW_COUNTERS 16 -#define THREAD_PROFILING_FLAG_DISPATCH 0x00000001 - -typedef enum _HARDWARE_COUNTER_TYPE { - PMCCounter, - MaxHardwareCounterType -} HARDWARE_COUNTER_TYPE, *PHARDWARE_COUNTER_TYPE; - -typedef struct _HARDWARE_COUNTER { - HARDWARE_COUNTER_TYPE Type; - ULONG Reserved; - ULONG64 Index; -} HARDWARE_COUNTER, *PHARDWARE_COUNTER; - -typedef struct _POOLED_USAGE_AND_LIMITS { - SIZE_T PeakPagedPoolUsage; - SIZE_T PagedPoolUsage; - SIZE_T PagedPoolLimit; - SIZE_T PeakNonPagedPoolUsage; - SIZE_T NonPagedPoolUsage; - SIZE_T NonPagedPoolLimit; - SIZE_T PeakPagefileUsage; - SIZE_T PagefileUsage; - SIZE_T PagefileLimit; -} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS; - -typedef struct _PROCESS_ACCESS_TOKEN { - HANDLE Token; - HANDLE Thread; -} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN; - -#define PROCESS_EXCEPTION_PORT_ALL_STATE_BITS 0x00000003UL -#define PROCESS_EXCEPTION_PORT_ALL_STATE_FLAGS ((ULONG_PTR)((1UL << PROCESS_EXCEPTION_PORT_ALL_STATE_BITS) - 1)) - -typedef struct _PROCESS_EXCEPTION_PORT { - IN HANDLE ExceptionPortHandle; - IN OUT ULONG StateFlags; -} PROCESS_EXCEPTION_PORT, *PPROCESS_EXCEPTION_PORT; - -typedef VOID -(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)( - IN HANDLE ParentId, - IN HANDLE ProcessId, - IN BOOLEAN Create); - -typedef struct _PS_CREATE_NOTIFY_INFO { - IN SIZE_T Size; - union { - IN ULONG Flags; - struct { - IN ULONG FileOpenNameAvailable:1; - IN ULONG Reserved:31; - }; - }; - IN HANDLE ParentProcessId; - IN CLIENT_ID CreatingThreadId; - IN OUT struct _FILE_OBJECT *FileObject; - IN PCUNICODE_STRING ImageFileName; - IN PCUNICODE_STRING CommandLine OPTIONAL; - IN OUT NTSTATUS CreationStatus; -} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO; - -typedef VOID -(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE_EX)( - IN OUT PEPROCESS Process, - IN HANDLE ProcessId, - IN PPS_CREATE_NOTIFY_INFO CreateInfo OPTIONAL); - -typedef VOID -(NTAPI *PCREATE_THREAD_NOTIFY_ROUTINE)( - IN HANDLE ProcessId, - IN HANDLE ThreadId, - IN BOOLEAN Create); - -#define IMAGE_ADDRESSING_MODE_32BIT 3 +#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ + ((ConditionMask) = VerSetConditionMask((ConditionMask), \ + (TypeBitMask), (ComparisonType))) + +/* RtlVerifyVersionInfo() TypeMask */ + +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_BUILDNUMBER 0x0000004 +#define VER_PLATFORMID 0x0000008 +#define VER_SERVICEPACKMINOR 0x0000010 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_SUITENAME 0x0000040 +#define VER_PRODUCT_TYPE 0x0000080 + +/* RtlVerifyVersionInfo() ComparisonType */ + +#define VER_EQUAL 1 +#define VER_GREATER 2 +#define VER_GREATER_EQUAL 3 +#define VER_LESS 4 +#define VER_LESS_EQUAL 5 +#define VER_AND 6 +#define VER_OR 7 + +#define VER_CONDITION_MASK 7 +#define VER_NUM_BITS_PER_CONDITION_MASK 3 typedef struct _IMAGE_INFO { _ANONYMOUS_UNION union { @@ -2266,7 +1492,7 @@ typedef struct _IMAGE_INFO { ULONG SystemModeImage:1; ULONG ImageMappedToAllPids:1; ULONG ExtendedInfoPresent:1; - ULONG Reserved:21; + ULONG Reserved:22; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; PVOID ImageBase; @@ -2275,24 +1501,24 @@ typedef struct _IMAGE_INFO { ULONG ImageSectionNumber; } IMAGE_INFO, *PIMAGE_INFO; -typedef struct _IMAGE_INFO_EX { - SIZE_T Size; - IMAGE_INFO ImageInfo; - struct _FILE_OBJECT *FileObject; -} IMAGE_INFO_EX, *PIMAGE_INFO_EX; +#define IMAGE_ADDRESSING_MODE_32BIT 3 -typedef VOID -(NTAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)( - IN PUNICODE_STRING FullImageName, - IN HANDLE ProcessId, - IN PIMAGE_INFO ImageInfo); - -#define THREAD_CSWITCH_PMU_DISABLE FALSE -#define THREAD_CSWITCH_PMU_ENABLE TRUE - -#define PROCESS_LUID_DOSDEVICES_ONLY 0x00000001 - -#define PROCESS_HANDLE_TRACING_MAX_STACKS 16 +typedef enum _BUS_DATA_TYPE { + ConfigurationSpaceUndefined = -1, + Cmos, + EisaConfiguration, + Pos, + CbusConfiguration, + PCIConfiguration, + VMEConfiguration, + NuBusConfiguration, + PCMCIAConfiguration, + MPIConfiguration, + MPSAConfiguration, + PNPISAConfiguration, + SgiInternalConfiguration, + MaximumBusDataType +} BUS_DATA_TYPE, *PBUS_DATA_TYPE; typedef struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; @@ -2426,15 +1652,6 @@ typedef enum _THREADINFOCLASS { MaxThreadInfoClass } THREADINFOCLASS; -typedef struct _PAGE_PRIORITY_INFORMATION { - ULONG PagePriority; -} PAGE_PRIORITY_INFORMATION, *PPAGE_PRIORITY_INFORMATION; - -typedef struct _PROCESS_WS_WATCH_INFORMATION { - PVOID FaultingPc; - PVOID FaultingVa; -} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION; - typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; struct _PEB *PebBaseAddress; @@ -2444,20 +1661,10 @@ typedef struct _PROCESS_BASIC_INFORMATION { ULONG_PTR InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION; -typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION { - SIZE_T Size; - PROCESS_BASIC_INFORMATION BasicInfo; - union { - ULONG Flags; - struct { - ULONG IsProtectedProcess:1; - ULONG IsWow64Process:1; - ULONG IsProcessDeleting:1; - ULONG IsCrossSessionCreate:1; - ULONG SpareBits:28; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; -} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION; +typedef struct _PROCESS_WS_WATCH_INFORMATION { + PVOID FaultingPc; + PVOID FaultingVa; +} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION; typedef struct _PROCESS_DEVICEMAP_INFORMATION { __GNU_EXTENSION union { @@ -2471,112 +1678,1956 @@ typedef struct _PROCESS_DEVICEMAP_INFORMATION { }; } PROCESS_DEVICEMAP_INFORMATION, *PPROCESS_DEVICEMAP_INFORMATION; -typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX { - union { - struct { - HANDLE DirectoryHandle; - } Set; - struct { - ULONG DriveMap; - UCHAR DriveType[32]; - } Query; - } DUMMYUNIONNAME; - ULONG Flags; -} PROCESS_DEVICEMAP_INFORMATION_EX, *PPROCESS_DEVICEMAP_INFORMATION_EX; +typedef struct _KERNEL_USER_TIMES { + LARGE_INTEGER CreateTime; + LARGE_INTEGER ExitTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; +} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES; + +typedef struct _PROCESS_ACCESS_TOKEN { + HANDLE Token; + HANDLE Thread; +} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN; typedef struct _PROCESS_SESSION_INFORMATION { ULONG SessionId; } PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION; -typedef struct _PROCESS_HANDLE_TRACING_ENABLE { - ULONG Flags; -} PROCESS_HANDLE_TRACING_ENABLE, *PPROCESS_HANDLE_TRACING_ENABLE; +typedef enum _IO_QUERY_DEVICE_DATA_FORMAT { + IoQueryDeviceIdentifier = 0, + IoQueryDeviceConfigurationData, + IoQueryDeviceComponentInformation, + IoQueryDeviceMaxData +} IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT; -typedef struct _PROCESS_HANDLE_TRACING_ENABLE_EX { - ULONG Flags; - ULONG TotalSlots; -} PROCESS_HANDLE_TRACING_ENABLE_EX, *PPROCESS_HANDLE_TRACING_ENABLE_EX; +typedef struct _DISK_SIGNATURE { + ULONG PartitionStyle; + _ANONYMOUS_UNION union { + struct { + ULONG Signature; + ULONG CheckSum; + } Mbr; + struct { + GUID DiskId; + } Gpt; + } DUMMYUNIONNAME; +} DISK_SIGNATURE, *PDISK_SIGNATURE; -typedef struct _PROCESS_HANDLE_TRACING_ENTRY { - HANDLE Handle; - CLIENT_ID ClientId; - ULONG Type; - PVOID Stacks[PROCESS_HANDLE_TRACING_MAX_STACKS]; -} PROCESS_HANDLE_TRACING_ENTRY, *PPROCESS_HANDLE_TRACING_ENTRY; +typedef ULONG_PTR +(NTAPI *PDRIVER_VERIFIER_THUNK_ROUTINE)( + IN PVOID Context); -typedef struct _PROCESS_HANDLE_TRACING_QUERY { - HANDLE Handle; - ULONG TotalTraces; - PROCESS_HANDLE_TRACING_ENTRY HandleTrace[1]; -} PROCESS_HANDLE_TRACING_QUERY, *PPROCESS_HANDLE_TRACING_QUERY; +typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { + PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; + PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; +} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; + +#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 +#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 +#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 +#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 +#define DRIVER_VERIFIER_IO_CHECKING 0x0010 + +typedef VOID +(NTAPI *PTIMER_APC_ROUTINE)( + IN PVOID TimerContext, + IN ULONG TimerLowValue, + IN LONG TimerHighValue); + +typedef struct _KUSER_SHARED_DATA +{ + ULONG TickCountLowDeprecated; + ULONG TickCountMultiplier; + volatile KSYSTEM_TIME InterruptTime; + volatile KSYSTEM_TIME SystemTime; + volatile KSYSTEM_TIME TimeZoneBias; + USHORT ImageNumberLow; + USHORT ImageNumberHigh; + WCHAR NtSystemRoot[260]; + ULONG MaxStackTraceDepth; + ULONG CryptoExponent; + ULONG TimeZoneId; + ULONG LargePageMinimum; + ULONG Reserved2[7]; + NT_PRODUCT_TYPE NtProductType; + BOOLEAN ProductTypeIsValid; + ULONG NtMajorVersion; + ULONG NtMinorVersion; + BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; + ULONG Reserved1; + ULONG Reserved3; + volatile ULONG TimeSlip; + ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; + ULONG AltArchitecturePad[1]; + LARGE_INTEGER SystemExpirationDate; + ULONG SuiteMask; + BOOLEAN KdDebuggerEnabled; +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) + UCHAR NXSupportPolicy; +#endif + volatile ULONG ActiveConsoleId; + volatile ULONG DismountCount; + ULONG ComPlusPackage; + ULONG LastSystemRITEventTickCount; + ULONG NumberOfPhysicalPages; + BOOLEAN SafeBootMode; +#if (NTDDI_VERSION >= NTDDI_WIN7) + union { + UCHAR TscQpcData; + struct { + UCHAR TscQpcEnabled:1; + UCHAR TscQpcSpareFlag:1; + UCHAR TscQpcShift:6; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + UCHAR TscQpcPad[2]; +#endif +#if (NTDDI_VERSION >= NTDDI_VISTA) + union { + ULONG SharedDataFlags; + struct { + ULONG DbgErrorPortPresent:1; + ULONG DbgElevationEnabled:1; + ULONG DbgVirtEnabled:1; + ULONG DbgInstallerDetectEnabled:1; + ULONG DbgSystemDllRelocated:1; + ULONG DbgDynProcessorEnabled:1; + ULONG DbgSEHValidationEnabled:1; + ULONG SpareBits:25; + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME2; +#else + ULONG TraceLogging; +#endif + ULONG DataFlagsPad[1]; + ULONGLONG TestRetInstruction; + ULONG SystemCall; + ULONG SystemCallReturn; + ULONGLONG SystemCallPad[3]; + _ANONYMOUS_UNION union { + volatile KSYSTEM_TIME TickCount; + volatile ULONG64 TickCountQuad; + _ANONYMOUS_STRUCT struct { + ULONG ReservedTickCountOverlay[3]; + ULONG TickCountPad[1]; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME3; + ULONG Cookie; + ULONG CookiePad[1]; +#if (NTDDI_VERSION >= NTDDI_WS03) + LONGLONG ConsoleSessionForegroundProcessId; + ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; +#endif +#if (NTDDI_VERSION >= NTDDI_VISTA) +#if (NTDDI_VERSION >= NTDDI_WIN7) + USHORT UserModeGlobalLogger[16]; +#else + USHORT UserModeGlobalLogger[8]; + ULONG HeapTracingPid[2]; + ULONG CritSecTracingPid[2]; +#endif + ULONG ImageFileExecutionOptions; +#if (NTDDI_VERSION >= NTDDI_VISTASP1) + ULONG LangGenerationCount; +#else + /* 4 bytes padding */ +#endif + ULONGLONG Reserved5; + volatile ULONG64 InterruptTimeBias; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN7) + volatile ULONG64 TscQpcBias; + volatile ULONG ActiveProcessorCount; + volatile USHORT ActiveGroupCount; + USHORT Reserved4; + volatile ULONG AitSamplingValue; + volatile ULONG AppCompatFlag; + ULONGLONG SystemDllNativeRelocation; + ULONG SystemDllWowRelocation; + ULONG XStatePad[1]; + XSTATE_CONFIGURATION XState; +#endif +} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; + +extern NTKERNELAPI PVOID MmHighestUserAddress; +extern NTKERNELAPI PVOID MmSystemRangeStart; +extern NTKERNELAPI ULONG MmUserProbeAddress; + + +#ifdef _X86_ + +#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress +#define MM_SYSTEM_RANGE_START MmSystemRangeStart +#if defined(_LOCAL_COPY_USER_PROBE_ADDRESS_) +#define MM_USER_PROBE_ADDRESS _LOCAL_COPY_USER_PROBE_ADDRESS_ +extern ULONG _LOCAL_COPY_USER_PROBE_ADDRESS_; +#else +#define MM_USER_PROBE_ADDRESS MmUserProbeAddress +#endif +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_KSEG0_BASE MM_SYSTEM_RANGE_START +#define MM_SYSTEM_SPACE_END 0xFFFFFFFF +#if !defined (_X86PAE_) +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 +#else +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 +#endif + +#define KeGetPcr() PCR + +#define KERNEL_STACK_SIZE 12288 +#define KERNEL_LARGE_STACK_SIZE 61440 +#define KERNEL_LARGE_STACK_COMMIT 12288 + +#define SIZE_OF_80387_REGISTERS 80 + +#define PCR_MINOR_VERSION 1 +#define PCR_MAJOR_VERSION 1 + +#if !defined(RC_INVOKED) + +#define CONTEXT_i386 0x10000 +#define CONTEXT_i486 0x10000 +#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) +#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) +#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) +#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) +#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) + +#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) + +#endif /* !defined(RC_INVOKED) */ + +typedef struct _KPCR { + union { + NT_TIB NtTib; + struct { + struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; + PVOID Used_StackBase; + PVOID Spare2; + PVOID TssCopy; + ULONG ContextSwitches; + KAFFINITY SetMemberCopy; + PVOID Used_Self; + }; + }; + struct _KPCR *SelfPcr; + struct _KPRCB *Prcb; + KIRQL Irql; + ULONG IRR; + ULONG IrrActive; + ULONG IDR; + PVOID KdVersionBlock; + struct _KIDTENTRY *IDT; + struct _KGDTENTRY *GDT; + struct _KTSS *TSS; + USHORT MajorVersion; + USHORT MinorVersion; + KAFFINITY SetMember; + ULONG StallScaleFactor; + UCHAR SpareUnused; + UCHAR Number; + UCHAR Spare0; + UCHAR SecondLevelCacheAssociativity; + ULONG VdmAlert; + ULONG KernelReserved[14]; + ULONG SecondLevelCacheSize; + ULONG HalReserved[16]; +} KPCR, *PKPCR; + +FORCEINLINE +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return (ULONG)__readfsbyte(FIELD_OFFSET(KPCR, Number)); +} + +typedef struct _FLOATING_SAVE_AREA { + ULONG ControlWord; + ULONG StatusWord; + ULONG TagWord; + ULONG ErrorOffset; + ULONG ErrorSelector; + ULONG DataOffset; + ULONG DataSelector; + UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; + ULONG Cr0NpxState; +} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; + +#include "pshpack4.h" +typedef struct _CONTEXT { + ULONG ContextFlags; + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + FLOATING_SAVE_AREA FloatSave; + ULONG SegGs; + ULONG SegFs; + ULONG SegEs; + ULONG SegDs; + ULONG Edi; + ULONG Esi; + ULONG Ebx; + ULONG Edx; + ULONG Ecx; + ULONG Eax; + ULONG Ebp; + ULONG Eip; + ULONG SegCs; + ULONG EFlags; + ULONG Esp; + ULONG SegSs; + UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; +} CONTEXT; +#include "poppack.h" + +#endif /* _X86_ */ + +#ifdef _AMD64_ + +#define PTI_SHIFT 12L +#define PDI_SHIFT 21L +#define PPI_SHIFT 30L +#define PXI_SHIFT 39L +#define PTE_PER_PAGE 512 +#define PDE_PER_PAGE 512 +#define PPE_PER_PAGE 512 +#define PXE_PER_PAGE 512 +#define PTI_MASK_AMD64 (PTE_PER_PAGE - 1) +#define PDI_MASK_AMD64 (PDE_PER_PAGE - 1) +#define PPI_MASK (PPE_PER_PAGE - 1) +#define PXI_MASK (PXE_PER_PAGE - 1) + +#define PXE_BASE 0xFFFFF6FB7DBED000ULL +#define PXE_SELFMAP 0xFFFFF6FB7DBEDF68ULL +#define PPE_BASE 0xFFFFF6FB7DA00000ULL +#define PDE_BASE 0xFFFFF6FB40000000ULL +#define PTE_BASE 0xFFFFF68000000000ULL +#define PXE_TOP 0xFFFFF6FB7DBEDFFFULL +#define PPE_TOP 0xFFFFF6FB7DBFFFFFULL +#define PDE_TOP 0xFFFFF6FB7FFFFFFFULL +#define PTE_TOP 0xFFFFF6FFFFFFFFFFULL + +#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress +#define MM_SYSTEM_RANGE_START MmSystemRangeStart +#define MM_USER_PROBE_ADDRESS MmUserProbeAddress +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFF080000000000ULL +#define KI_USER_SHARED_DATA 0xFFFFF78000000000ULL + +typedef struct DECLSPEC_ALIGN(16) _CONTEXT { + ULONG64 P1Home; + ULONG64 P2Home; + ULONG64 P3Home; + ULONG64 P4Home; + ULONG64 P5Home; + ULONG64 P6Home; + + /* Control flags */ + ULONG ContextFlags; + ULONG MxCsr; + + /* Segment */ + USHORT SegCs; + USHORT SegDs; + USHORT SegEs; + USHORT SegFs; + USHORT SegGs; + USHORT SegSs; + ULONG EFlags; + + /* Debug */ + ULONG64 Dr0; + ULONG64 Dr1; + ULONG64 Dr2; + ULONG64 Dr3; + ULONG64 Dr6; + ULONG64 Dr7; + + /* Integer */ + ULONG64 Rax; + ULONG64 Rcx; + ULONG64 Rdx; + ULONG64 Rbx; + ULONG64 Rsp; + ULONG64 Rbp; + ULONG64 Rsi; + ULONG64 Rdi; + ULONG64 R8; + ULONG64 R9; + ULONG64 R10; + ULONG64 R11; + ULONG64 R12; + ULONG64 R13; + ULONG64 R14; + ULONG64 R15; + + /* Counter */ + ULONG64 Rip; + + /* Floating point */ + union { + XMM_SAVE_AREA32 FltSave; + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + /* Vector */ + M128A VectorRegister[26]; + ULONG64 VectorControl; + + /* Debug control */ + ULONG64 DebugControl; + ULONG64 LastBranchToRip; + ULONG64 LastBranchFromRip; + ULONG64 LastExceptionToRip; + ULONG64 LastExceptionFromRip; +} CONTEXT; + +typedef struct _KPCR +{ + _ANONYMOUS_UNION union + { + NT_TIB NtTib; + _ANONYMOUS_STRUCT struct + { + union _KGDTENTRY64 *GdtBase; + struct _KTSS64 *TssBase; + ULONG64 UserRsp; + struct _KPCR *Self; + struct _KPRCB *CurrentPrcb; + PKSPIN_LOCK_QUEUE LockArray; + PVOID Used_Self; + }; + }; + union _KIDTENTRY64 *IdtBase; + ULONG64 Unused[2]; + KIRQL Irql; + UCHAR SecondLevelCacheAssociativity; + UCHAR ObsoleteNumber; + UCHAR Fill0; + ULONG Unused0[3]; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG StallScaleFactor; + PVOID Unused1[3]; + ULONG KernelReserved[15]; + ULONG SecondLevelCacheSize; + ULONG HalReserved[16]; + ULONG Unused2; + PVOID KdVersionBlock; + PVOID Unused3; + ULONG PcrAlign1[24]; +} KPCR, *PKPCR; + +FORCEINLINE +PKPCR +KeGetPcr(VOID) +{ + return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self)); +} + +FORCEINLINE +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return (ULONG)__readgsword(0x184); +} + +#if !defined(RC_INVOKED) + +#define CONTEXT_AMD64 0x100000 + +#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L) +#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L) +#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L) +#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) + +#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x20L) + +#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 +#define CONTEXT_SERVICE_ACTIVE 0x10000000 +#define CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define CONTEXT_EXCEPTION_REPORTING 0x80000000 + +#endif /* RC_INVOKED */ + +#endif /* _AMD64_ */ + +typedef enum _INTERLOCKED_RESULT { + ResultNegative = RESULT_NEGATIVE, + ResultZero = RESULT_ZERO, + ResultPositive = RESULT_POSITIVE +} INTERLOCKED_RESULT; + +typedef struct _OSVERSIONINFOA { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + CHAR szCSDVersion[128]; +} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; + +typedef struct _OSVERSIONINFOW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; +} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; + +typedef struct _OSVERSIONINFOEXA { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + CHAR szCSDVersion[128]; + USHORT wServicePackMajor; + USHORT wServicePackMinor; + USHORT wSuiteMask; + UCHAR wProductType; + UCHAR wReserved; +} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; + +typedef struct _OSVERSIONINFOEXW { + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; + USHORT wServicePackMajor; + USHORT wServicePackMinor; + USHORT wSuiteMask; + UCHAR wProductType; + UCHAR wReserved; +} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; + +#ifdef UNICODE +typedef OSVERSIONINFOEXW OSVERSIONINFOEX; +typedef POSVERSIONINFOEXW POSVERSIONINFOEX; +typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX; +typedef OSVERSIONINFOW OSVERSIONINFO; +typedef POSVERSIONINFOW POSVERSIONINFO; +typedef LPOSVERSIONINFOW LPOSVERSIONINFO; +#else +typedef OSVERSIONINFOEXA OSVERSIONINFOEX; +typedef POSVERSIONINFOEXA POSVERSIONINFOEX; +typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; +typedef OSVERSIONINFOA OSVERSIONINFO; +typedef POSVERSIONINFOA POSVERSIONINFO; +typedef LPOSVERSIONINFOA LPOSVERSIONINFO; +#endif /* UNICODE */ + +/* Executive Types */ + +#define PROTECTED_POOL 0x80000000 + +typedef struct _ZONE_SEGMENT_HEADER { + SINGLE_LIST_ENTRY SegmentList; + PVOID Reserved; +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; + +typedef struct _ZONE_HEADER { + SINGLE_LIST_ENTRY FreeList; + SINGLE_LIST_ENTRY SegmentList; + ULONG BlockSize; + ULONG TotalSegmentSize; +} ZONE_HEADER, *PZONE_HEADER; + +/* Executive Functions */ + +static __inline PVOID +ExAllocateFromZone( + IN PZONE_HEADER Zone) +{ + if (Zone->FreeList.Next) + Zone->FreeList.Next = Zone->FreeList.Next->Next; + return (PVOID) Zone->FreeList.Next; +} + +static __inline PVOID +ExFreeToZone( + IN PZONE_HEADER Zone, + IN PVOID Block) +{ + ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; + Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); + return ((PSINGLE_LIST_ENTRY) Block)->Next; +} + +/* + * PVOID + * ExInterlockedAllocateFromZone( + * IN PZONE_HEADER Zone, + * IN PKSPIN_LOCK Lock) + */ +#define ExInterlockedAllocateFromZone(Zone, Lock) \ + ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) + +/* PVOID + * ExInterlockedFreeToZone( + * IN PZONE_HEADER Zone, + * IN PVOID Block, + * IN PKSPIN_LOCK Lock); + */ +#define ExInterlockedFreeToZone(Zone, Block, Lock) \ + ExInterlockedPushEntryList(&(Zone)->FreeList, (PSINGLE_LIST_ENTRY)(Block), Lock) + +/* + * BOOLEAN + * ExIsFullZone( + * IN PZONE_HEADER Zone) + */ +#define ExIsFullZone(Zone) \ + ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) + +/* BOOLEAN + * ExIsObjectInFirstZoneSegment( + * IN PZONE_HEADER Zone, + * IN PVOID Object); + */ +#define ExIsObjectInFirstZoneSegment(Zone,Object) \ + ((BOOLEAN)( ((PUCHAR)(Object) >= (PUCHAR)(Zone)->SegmentList.Next) && \ + ((PUCHAR)(Object) < (PUCHAR)(Zone)->SegmentList.Next + \ + (Zone)->TotalSegmentSize)) ) + +#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite +#define ExAcquireResourceShared ExAcquireResourceSharedLite +#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite +#define ExDeleteResource ExDeleteResourceLite +#define ExInitializeResource ExInitializeResourceLite +#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite +#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite +#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite +#define ExReleaseResourceForThread ExReleaseResourceForThreadLite + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTKERNELAPI +NTSTATUS +NTAPI +ExExtendZone( + IN OUT PZONE_HEADER Zone, + IN OUT PVOID Segment, + IN ULONG SegmentSize); + +NTKERNELAPI +NTSTATUS +NTAPI +ExInitializeZone( + OUT PZONE_HEADER Zone, + IN ULONG BlockSize, + IN OUT PVOID InitialSegment, + IN ULONG InitialSegmentSize); + +NTKERNELAPI +NTSTATUS +NTAPI +ExInterlockedExtendZone( + IN OUT PZONE_HEADER Zone, + IN OUT PVOID Segment, + IN ULONG SegmentSize, + IN OUT PKSPIN_LOCK Lock); + +NTKERNELAPI +NTSTATUS +NTAPI +ExUuidCreate( + OUT UUID *Uuid); + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +ExRaiseAccessViolation( + VOID); + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +ExRaiseDatatypeMisalignment( + VOID); + +#endif + +#ifdef _X86_ + +NTKERNELAPI +INTERLOCKED_RESULT +FASTCALL +Exfi386InterlockedIncrementLong( + IN OUT LONG volatile *Addend); + +NTKERNELAPI +INTERLOCKED_RESULT +FASTCALL +Exfi386InterlockedDecrementLong( + IN PLONG Addend); + +NTKERNELAPI +ULONG +FASTCALL +Exfi386InterlockedExchangeUlong( + IN PULONG Target, + IN ULONG Value); + +#endif /* _X86_ */ + +#ifndef _ARC_DDK_ +#define _ARC_DDK_ +typedef enum _CONFIGURATION_TYPE { + ArcSystem, + CentralProcessor, + FloatingPointProcessor, + PrimaryIcache, + PrimaryDcache, + SecondaryIcache, + SecondaryDcache, + SecondaryCache, + EisaAdapter, + TcAdapter, + ScsiAdapter, + DtiAdapter, + MultiFunctionAdapter, + DiskController, + TapeController, + CdromController, + WormController, + SerialController, + NetworkController, + DisplayController, + ParallelController, + PointerController, + KeyboardController, + AudioController, + OtherController, + DiskPeripheral, + FloppyDiskPeripheral, + TapePeripheral, + ModemPeripheral, + MonitorPeripheral, + PrinterPeripheral, + PointerPeripheral, + KeyboardPeripheral, + TerminalPeripheral, + OtherPeripheral, + LinePeripheral, + NetworkPeripheral, + SystemMemory, + DockingInformation, + RealModeIrqRoutingTable, + RealModePCIEnumeration, + MaximumType +} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE; +#endif /* !_ARC_DDK_ */ + +typedef struct _CONTROLLER_OBJECT { + CSHORT Type; + CSHORT Size; + PVOID ControllerExtension; + KDEVICE_QUEUE DeviceWaitQueue; + ULONG Spare1; + LARGE_INTEGER Spare2; +} CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; + +typedef struct _CONFIGURATION_INFORMATION { + ULONG DiskCount; + ULONG FloppyCount; + ULONG CdRomCount; + ULONG TapeCount; + ULONG ScsiPortCount; + ULONG SerialCount; + ULONG ParallelCount; + BOOLEAN AtDiskPrimaryAddressClaimed; + BOOLEAN AtDiskSecondaryAddressClaimed; + ULONG Version; + ULONG MediumChangerCount; +} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; + +typedef +NTSTATUS +(NTAPI *PIO_QUERY_DEVICE_ROUTINE)( + IN PVOID Context, + IN PUNICODE_STRING PathName, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN PKEY_VALUE_FULL_INFORMATION *BusInformation, + IN CONFIGURATION_TYPE ControllerType, + IN ULONG ControllerNumber, + IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, + IN CONFIGURATION_TYPE PeripheralType, + IN ULONG PeripheralNumber, + IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation); + +typedef +VOID +(NTAPI DRIVER_REINITIALIZE)( + IN struct _DRIVER_OBJECT *DriverObject, + IN PVOID Context, + IN ULONG Count); + +typedef DRIVER_REINITIALIZE *PDRIVER_REINITIALIZE; + +/** Filesystem runtime library routines **/ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +BOOLEAN +NTAPI +FsRtlIsTotalDeviceFailure( + IN NTSTATUS Status); +#endif + +/* Hardware Abstraction Layer Types */ + +typedef VOID +(NTAPI *PciPin2Line)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); + +typedef VOID +(NTAPI *PciLine2Pin)( + IN struct _BUS_HANDLER *BusHandler, + IN struct _BUS_HANDLER *RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +typedef VOID +(NTAPI *PciReadWriteConfig)( + IN struct _BUS_HANDLER *BusHandler, + IN PCI_SLOT_NUMBER Slot, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +#define PCI_DATA_TAG ' ICP' +#define PCI_DATA_VERSION 1 + +typedef struct _PCIBUSDATA { + ULONG Tag; + ULONG Version; + PciReadWriteConfig ReadConfig; + PciReadWriteConfig WriteConfig; + PciPin2Line Pin2Line; + PciLine2Pin Line2Pin; + PCI_SLOT_NUMBER ParentSlot; + PVOID Reserved[4]; +} PCIBUSDATA, *PPCIBUSDATA; + +/* Hardware Abstraction Layer Functions */ + +#if !defined(NO_LEGACY_DRIVERS) + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTHALAPI +NTSTATUS +NTAPI +HalAssignSlotResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +NTHALAPI +ULONG +NTAPI +HalGetInterruptVector( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); + +NTHALAPI +ULONG +NTAPI +HalSetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length); + +#endif + +#endif /* !defined(NO_LEGACY_DRIVERS) */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTHALAPI +PADAPTER_OBJECT +NTAPI +HalGetAdapter( + IN PDEVICE_DESCRIPTION DeviceDescription, + IN OUT PULONG NumberOfMapRegisters); + +NTHALAPI +BOOLEAN +NTAPI +HalMakeBeep( + IN ULONG Frequency); + +VOID +NTAPI +HalPutDmaAdapter( + IN PADAPTER_OBJECT DmaAdapter); + +NTHALAPI +VOID +NTAPI +HalAcquireDisplayOwnership( + IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); + +NTHALAPI +ULONG +NTAPI +HalGetBusData( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Length); + +NTHALAPI +ULONG +NTAPI +HalGetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTHALAPI +ULONG +NTAPI +HalSetBusDataByOffset( + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +NTHALAPI +BOOLEAN +NTAPI +HalTranslateBusAddress( + IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); + +#endif + +#if (NTDDI_VERSION >= NTDDI_WINXP) +NTKERNELAPI +VOID +FASTCALL +HalExamineMBR( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG MBRTypeIdentifier, + OUT PVOID *Buffer); +#endif + +#if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) +// nothing here +#else + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +IoFreeAdapterChannel( + IN PADAPTER_OBJECT AdapterObject); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +BOOLEAN +NTAPI +IoFlushAdapterBuffers( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN ULONG Length, + IN BOOLEAN WriteToDevice); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +IoFreeMapRegisters( + IN PADAPTER_OBJECT AdapterObject, + IN PVOID MapRegisterBase, + IN ULONG NumberOfMapRegisters); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +PVOID +NTAPI +HalAllocateCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + OUT PPHYSICAL_ADDRESS LogicalAddress, + IN BOOLEAN CacheEnabled); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +VOID +NTAPI +HalFreeCommonBuffer( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG Length, + IN PHYSICAL_ADDRESS LogicalAddress, + IN PVOID VirtualAddress, + IN BOOLEAN CacheEnabled); + +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +ULONG +NTAPI +HalReadDmaCounter( + IN PADAPTER_OBJECT AdapterObject); + +NTHALAPI +NTSTATUS +NTAPI +HalAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PWAIT_CONTEXT_BLOCK Wcb, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#endif /* defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) */ + +/* I/O Manager Functions */ + +/* + * VOID IoAssignArcName( + * IN PUNICODE_STRING ArcName, + * IN PUNICODE_STRING DeviceName); + */ +#define IoAssignArcName(_ArcName, _DeviceName) ( \ + IoCreateSymbolicLink((_ArcName), (_DeviceName))) + +/* + * VOID + * IoDeassignArcName( + * IN PUNICODE_STRING ArcName) + */ +#define IoDeassignArcName IoDeleteSymbolicLink + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +#if !(defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)) +NTKERNELAPI +NTSTATUS +NTAPI +IoAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); +#endif + +#if !defined(DMA_MACROS_DEFINED) +//DECLSPEC_DEPRECATED_DDK +NTHALAPI +PHYSICAL_ADDRESS +NTAPI +IoMapTransfer( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN OUT PULONG Length, + IN BOOLEAN WriteToDevice); +#endif + +NTKERNELAPI +VOID +NTAPI +IoAllocateController( + IN PCONTROLLER_OBJECT ControllerObject, + IN PDEVICE_OBJECT DeviceObject, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +PCONTROLLER_OBJECT +NTAPI +IoCreateController( + IN ULONG Size); + +NTKERNELAPI +VOID +NTAPI +IoDeleteController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTKERNELAPI +VOID +NTAPI +IoFreeController( + IN PCONTROLLER_OBJECT ControllerObject); + +NTKERNELAPI +PCONFIGURATION_INFORMATION +NTAPI +IoGetConfigurationInformation( + VOID); + +NTKERNELAPI +PDEVICE_OBJECT +NTAPI +IoGetDeviceToVerify( + IN PETHREAD Thread); + +NTKERNELAPI +VOID +NTAPI +IoCancelFileOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PFILE_OBJECT FileObject); + +NTKERNELAPI +PGENERIC_MAPPING +NTAPI +IoGetFileObjectGenericMapping( + VOID); + +NTKERNELAPI +PIRP +NTAPI +IoMakeAssociatedIrp( + IN PIRP Irp, + IN CCHAR StackSize); + +NTKERNELAPI +NTSTATUS +NTAPI +IoQueryDeviceDescription( + IN PINTERFACE_TYPE BusType OPTIONAL, + IN PULONG BusNumber OPTIONAL, + IN PCONFIGURATION_TYPE ControllerType OPTIONAL, + IN PULONG ControllerNumber OPTIONAL, + IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, + IN PULONG PeripheralNumber OPTIONAL, + IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, + IN OUT PVOID Context OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRaiseHardError( + IN PIRP Irp, + IN PVPB Vpb OPTIONAL, + IN PDEVICE_OBJECT RealDeviceObject); + +NTKERNELAPI +BOOLEAN +NTAPI +IoRaiseInformationalHardError( + IN NTSTATUS ErrorStatus, + IN PUNICODE_STRING String OPTIONAL, + IN PKTHREAD Thread OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRegisterBootDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +VOID +NTAPI +IoRegisterDriverReinitialization( + IN PDRIVER_OBJECT DriverObject, + IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, + IN PVOID Context OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAttachDeviceByPointer( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportDetectedDevice( + IN PDRIVER_OBJECT DriverObject, + IN INTERFACE_TYPE LegacyBusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PCM_RESOURCE_LIST ResourceList OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, + IN BOOLEAN ResourceAssigned, + IN OUT PDEVICE_OBJECT *DeviceObject); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportResourceForDetection( + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + OUT PBOOLEAN ConflictDetected); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReportResourceUsage( + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PCM_RESOURCE_LIST DriverList OPTIONAL, + IN ULONG DriverListSize OPTIONAL, + IN PDEVICE_OBJECT DeviceObject, + IN PCM_RESOURCE_LIST DeviceList OPTIONAL, + IN ULONG DeviceListSize OPTIONAL, + IN BOOLEAN OverrideConflict, + OUT PBOOLEAN ConflictDetected); + +NTKERNELAPI +VOID +NTAPI +IoSetHardErrorOrVerifyDevice( + IN PIRP Irp, + IN PDEVICE_OBJECT DeviceObject); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAssignResources( + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources OPTIONAL, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +NTKERNELAPI +NTSTATUS +NTAPI +IoCreateDisk( + IN PDEVICE_OBJECT DeviceObject, + IN struct _CREATE_DISK* Disk OPTIONAL); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReadDiskSignature( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG BytesPerSector, + OUT PDISK_SIGNATURE Signature); + +NTKERNELAPI +NTSTATUS +FASTCALL +IoReadPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN BOOLEAN ReturnRecognizedPartitions, + OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); + +NTKERNELAPI +NTSTATUS +NTAPI +IoReadPartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); + +NTKERNELAPI +NTSTATUS +FASTCALL +IoSetPartitionInformation( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG PartitionNumber, + IN ULONG PartitionType); + +NTKERNELAPI +NTSTATUS +NTAPI +IoSetPartitionInformationEx( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG PartitionNumber, + IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); + +NTKERNELAPI +NTSTATUS +NTAPI +IoSetSystemPartition( + IN PUNICODE_STRING VolumeNameString); + +NTKERNELAPI +BOOLEAN +NTAPI +IoSetThreadHardErrorMode( + IN BOOLEAN EnableHardErrors); + +NTKERNELAPI +NTSTATUS +NTAPI +IoVerifyPartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN BOOLEAN FixErrors); + +NTKERNELAPI +NTSTATUS +NTAPI +IoVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTKERNELAPI +NTSTATUS +FASTCALL +IoWritePartitionTable( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG SectorsPerTrack, + IN ULONG NumberOfHeads, + IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); + +NTKERNELAPI +NTSTATUS +NTAPI +IoWritePartitionTableEx( + IN PDEVICE_OBJECT DeviceObject, + IN struct _DRIVE_LAYOUT_INFORMATION_EX *DriveLayout); + +NTKERNELAPI +NTSTATUS +NTAPI +IoAttachDeviceToDeviceStackSafe( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice, + OUT PDEVICE_OBJECT *AttachedToDeviceObject); + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ + +/** Kernel debugger routines **/ + +NTSYSAPI +ULONG +NTAPI +DbgPrompt( + IN PCCH Prompt, + OUT PCH Response, + IN ULONG MaximumResponseLength); + +/* Kernel Functions */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTKERNELAPI +DECLSPEC_NORETURN +VOID +NTAPI +KeBugCheck( + IN ULONG BugCheckCode); + +NTKERNELAPI +LONG +NTAPI +KePulseEvent( + IN OUT PRKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + +NTKERNELAPI +LONG +NTAPI +KeSetBasePriorityThread( + IN OUT PRKTHREAD Thread, + IN LONG Increment); + +#endif + +/* Memory Manager Types */ + +typedef struct _PHYSICAL_MEMORY_RANGE { + PHYSICAL_ADDRESS BaseAddress; + LARGE_INTEGER NumberOfBytes; +} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; + +/* Memory Manager Functions */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTKERNELAPI +PPHYSICAL_MEMORY_RANGE +NTAPI +MmGetPhysicalMemoryRanges( + VOID); + +NTKERNELAPI +PHYSICAL_ADDRESS +NTAPI +MmGetPhysicalAddress( + IN PVOID BaseAddress); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsNonPagedSystemAddressValid( + IN PVOID VirtualAddress); + +NTKERNELAPI +PVOID +NTAPI +MmAllocateNonCachedMemory( + IN SIZE_T NumberOfBytes); + +NTKERNELAPI +VOID +NTAPI +MmFreeNonCachedMemory( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +NTKERNELAPI +PVOID +NTAPI +MmGetVirtualForPhysical( + IN PHYSICAL_ADDRESS PhysicalAddress); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapUserAddressesToPage( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN PVOID PageAddress); + +NTKERNELAPI +PVOID +NTAPI +MmMapVideoDisplay( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN SIZE_T NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapViewInSessionSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); + +NTKERNELAPI +NTSTATUS +NTAPI +MmMapViewInSystemSpace( + IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsAddressValid( + IN PVOID VirtualAddress); + +NTKERNELAPI +BOOLEAN +NTAPI +MmIsThisAnNtAsSystem( + VOID); + +NTKERNELAPI +VOID +NTAPI +MmLockPagableSectionByHandle( + IN PVOID ImageSectionHandle); + +NTKERNELAPI +NTSTATUS +NTAPI +MmUnmapViewInSessionSpace( + IN PVOID MappedBase); + +NTKERNELAPI +NTSTATUS +NTAPI +MmUnmapViewInSystemSpace( + IN PVOID MappedBase); + +NTKERNELAPI +VOID +NTAPI +MmUnsecureVirtualMemory( + IN HANDLE SecureHandle); + +NTKERNELAPI +NTSTATUS +NTAPI +MmRemovePhysicalMemory( + IN PPHYSICAL_ADDRESS StartAddress, + IN OUT PLARGE_INTEGER NumberOfBytes); + +NTKERNELAPI +HANDLE +NTAPI +MmSecureVirtualMemory( + IN PVOID Address, + IN SIZE_T Size, + IN ULONG ProbeMode); + +NTKERNELAPI +VOID +NTAPI +MmUnmapVideoDisplay( + IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +/* NtXxx Functions */ + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL); + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation OPTIONAL, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +/** Process manager types **/ + +typedef VOID +(NTAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)( + IN HANDLE ParentId, + IN HANDLE ProcessId, + IN BOOLEAN Create); + +typedef VOID +(NTAPI *PCREATE_THREAD_NOTIFY_ROUTINE)( + IN HANDLE ProcessId, + IN HANDLE ThreadId, + IN BOOLEAN Create); + +typedef VOID +(NTAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)( + IN PUNICODE_STRING FullImageName, + IN HANDLE ProcessId, + IN PIMAGE_INFO ImageInfo); + +/** Process manager routines **/ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetCreateProcessNotifyRoutine( + IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, + IN BOOLEAN Remove); + +NTKERNELAPI +HANDLE +NTAPI +PsGetCurrentProcessId( + VOID); + +NTKERNELAPI +HANDLE +NTAPI +PsGetCurrentThreadId( + VOID); + +NTKERNELAPI +BOOLEAN +NTAPI +PsGetVersion( + OUT PULONG MajorVersion OPTIONAL, + OUT PULONG MinorVersion OPTIONAL, + OUT PULONG BuildNumber OPTIONAL, + OUT PUNICODE_STRING CSDVersion OPTIONAL); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +NTKERNELAPI +HANDLE +NTAPI +PsGetProcessId( + IN PEPROCESS Process); + +NTKERNELAPI +NTSTATUS +NTAPI +PsRemoveCreateThreadNotifyRoutine( + IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); + +NTKERNELAPI +NTSTATUS +NTAPI +PsRemoveLoadImageNotifyRoutine( + IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); + +#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ extern NTKERNELAPI PEPROCESS PsInitialSystemProcess; +/* RTL Types */ -/****************************************************************************** - * Runtime Library Types * - ******************************************************************************/ +typedef struct _RTL_SPLAY_LINKS { + struct _RTL_SPLAY_LINKS *Parent; + struct _RTL_SPLAY_LINKS *LeftChild; + struct _RTL_SPLAY_LINKS *RightChild; +} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; +/* RTL Functions */ +#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_) -#ifndef _RTL_RUN_ONCE_DEF -#define _RTL_RUN_ONCE_DEF +#define RtlGetCallersAddress(CallersAddress, CallersCaller) \ + *CallersAddress = (PVOID)_ReturnAddress(); \ + *CallersCaller = NULL; +#else -#define RTL_RUN_ONCE_INIT {0} +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +VOID +NTAPI +RtlGetCallersAddress( + OUT PVOID *CallersAddress, + OUT PVOID *CallersCaller); +#endif -#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001UL -#define RTL_RUN_ONCE_ASYNC 0x00000002UL -#define RTL_RUN_ONCE_INIT_FAILED 0x00000004UL +#endif -#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2 +#if !defined(MIDL_PASS) -#define RTL_HASH_ALLOCATED_HEADER 0x00000001 +FORCEINLINE +LUID +NTAPI_INLINE +RtlConvertLongToLuid( + IN LONG Val) +{ + LUID Luid; + LARGE_INTEGER Temp; -#define RTL_HASH_RESERVED_SIGNATURE 0 + Temp.QuadPart = Val; + Luid.LowPart = Temp.u.LowPart; + Luid.HighPart = Temp.u.HighPart; + return Luid; +} -/* RtlVerifyVersionInfo() ComparisonType */ +FORCEINLINE +LUID +NTAPI_INLINE +RtlConvertUlongToLuid( + IN ULONG Val) +{ + LUID Luid; -#define VER_EQUAL 1 -#define VER_GREATER 2 -#define VER_GREATER_EQUAL 3 -#define VER_LESS 4 -#define VER_LESS_EQUAL 5 -#define VER_AND 6 -#define VER_OR 7 + Luid.LowPart = Val; + Luid.HighPart = 0; + return Luid; +} -#define VER_CONDITION_MASK 7 -#define VER_NUM_BITS_PER_CONDITION_MASK 3 +#endif -/* RtlVerifyVersionInfo() TypeMask */ +#if defined(_AMD64_) || defined(_IA64_) +//DECLSPEC_DEPRECATED_DDK_WINXP +FORCEINLINE +LARGE_INTEGER +NTAPI_INLINE +RtlLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER Divisor, + OUT PLARGE_INTEGER Remainder OPTIONAL) +{ + LARGE_INTEGER ret; + ret.QuadPart = Dividend.QuadPart / Divisor.QuadPart; + if (Remainder) + Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; + return ret; +} -#define VER_MINORVERSION 0x0000001 -#define VER_MAJORVERSION 0x0000002 -#define VER_BUILDNUMBER 0x0000004 -#define VER_PLATFORMID 0x0000008 -#define VER_SERVICEPACKMINOR 0x0000010 -#define VER_SERVICEPACKMAJOR 0x0000020 -#define VER_SUITENAME 0x0000040 -#define VER_PRODUCT_TYPE 0x0000080 +#else -#define VER_NT_WORKSTATION 0x0000001 -#define VER_NT_DOMAIN_CONTROLLER 0x0000002 -#define VER_NT_SERVER 0x0000003 +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTSYSAPI +LARGE_INTEGER +NTAPI +RtlLargeIntegerDivide( + IN LARGE_INTEGER Dividend, + IN LARGE_INTEGER Divisor, + OUT PLARGE_INTEGER Remainder OPTIONAL); +#endif -#define VER_PLATFORM_WIN32s 0 -#define VER_PLATFORM_WIN32_WINDOWS 1 -#define VER_PLATFORM_WIN32_NT 2 +#endif /* defined(_AMD64_) || defined(_IA64_) */ -typedef union _RTL_RUN_ONCE { - PVOID Ptr; -} RTL_RUN_ONCE, *PRTL_RUN_ONCE; +#if (NTDDI_VERSION >= NTDDI_WIN2K) -typedef ULONG /* LOGICAL */ -(NTAPI *PRTL_RUN_ONCE_INIT_FN) ( - IN OUT PRTL_RUN_ONCE RunOnce, - IN OUT PVOID Parameter OPTIONAL, - IN OUT PVOID *Context OPTIONAL); +NTSYSAPI +BOOLEAN +NTAPI +RtlPrefixUnicodeString( + IN PCUNICODE_STRING String1, + IN PCUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive); -#endif /* _RTL_RUN_ONCE_DEF */ +NTSYSAPI +VOID +NTAPI +RtlUpperString( + IN OUT PSTRING DestinationString, + IN const PSTRING SourceString); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI +VOID +NTAPI +RtlMapGenericMask( + IN OUT PACCESS_MASK AccessMask, + IN PGENERIC_MAPPING GenericMapping); + +NTSYSAPI +NTSTATUS +NTAPI +RtlVolumeDeviceToDosName( + IN PVOID VolumeDeviceObject, + OUT PUNICODE_STRING DosName); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetVersion( + IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); + +NTSYSAPI +NTSTATUS +NTAPI +RtlVerifyVersionInfo( + IN PRTL_OSVERSIONINFOEXW VersionInfo, + IN ULONG TypeMask, + IN ULONGLONG ConditionMask); + +NTSYSAPI +LONG +NTAPI +RtlCompareString( + IN const PSTRING String1, + IN const PSTRING String2, + BOOLEAN CaseInSensitive); + +NTSYSAPI +VOID +NTAPI +RtlCopyString( + OUT PSTRING DestinationString, + IN const PSTRING SourceString OPTIONAL); + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualString( + IN const PSTRING String1, + IN const PSTRING String2, + IN BOOLEAN CaseInSensitive); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCharToInteger( + IN PCSZ String, + IN ULONG Base OPTIONAL, + OUT PULONG Value); + +NTSYSAPI +CHAR +NTAPI +RtlUpperChar( + IN CHAR Character); + +NTSYSAPI +ULONG +NTAPI +RtlWalkFrameChain( + OUT PVOID *Callers, + IN ULONG Count, + IN ULONG Flags); + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +/* Security reference monitor routines */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) +NTKERNELAPI +BOOLEAN +NTAPI +SeSinglePrivilegeCheck( + IN LUID PrivilegeValue, + IN KPROCESSOR_MODE PreviousMode); +#endif + +/* ZwXxx Functions */ + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +NTSTATUS +NTAPI +ZwCancelTimer( + IN HANDLE TimerHandle, + OUT PBOOLEAN CurrentState OPTIONAL); + +NTSTATUS +NTAPI +ZwCreateTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN TIMER_TYPE TimerType); + +NTSTATUS +NTAPI +ZwOpenTimer( + OUT PHANDLE TimerHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +NTSTATUS +NTAPI +ZwSetTimer( + IN HANDLE TimerHandle, + IN PLARGE_INTEGER DueTime, + IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, + IN PVOID TimerContext OPTIONAL, + IN BOOLEAN ResumeTimer, + IN LONG Period OPTIONAL, + OUT PBOOLEAN PreviousState OPTIONAL); + +#endif + +typedef struct _QUOTA_LIMITS { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; +} QUOTA_LIMITS, *PQUOTA_LIMITS; + +struct _RTL_GENERIC_COMPARE_ROUTINE; +struct _RTL_GENERIC_ALLOCATE_ROUTINE; +struct _RTL_GENERIC_FREE_ROUTINE; + +typedef struct _RTL_GENERIC_TABLE { + PRTL_SPLAY_LINKS TableRoot; + LIST_ENTRY InsertOrderList; + PLIST_ENTRY OrderedPointer; + ULONG WhichOrderedElement; + ULONG NumberGenericTableElements; + struct _RTL_GENERIC_COMPARE_ROUTINE *CompareRoutine; + struct _RTL_GENERIC_ALLOCATE_ROUTINE *AllocateRoutine; + struct _RTL_GENERIC_FREE_ROUTINE *FreeRoutine; + PVOID TableContext; +} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE; typedef enum _TABLE_SEARCH_RESULT { TableEmptyTree, @@ -2585,6 +3636,43 @@ typedef enum _TABLE_SEARCH_RESULT { TableInsertAsRight } TABLE_SEARCH_RESULT; +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +#define IO_CHECK_CREATE_PARAMETERS 0x0200 +#define IO_ATTACH_DEVICE 0x0400 +#define IO_IGNORE_SHARE_ACCESS_CHECK 0x0800 + +typedef struct _FILE_FS_VOLUME_INFORMATION { + LARGE_INTEGER VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[1]; +} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; + +typedef struct _FILE_FS_FULL_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER CallerAvailableAllocationUnits; + LARGE_INTEGER ActualAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; + +typedef struct _FILE_FS_OBJECTID_INFORMATION { + UCHAR ObjectId[16]; + UCHAR ExtendedInfo[48]; +} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; + +typedef struct _FILE_FS_LABEL_INFORMATION { + ULONG VolumeLabelLength; + WCHAR VolumeLabel[1]; +} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; + typedef enum _RTL_GENERIC_COMPARE_RESULTS { GenericLessThan, GenericGreaterThan, @@ -2658,2344 +3746,8 @@ typedef VOID IN struct _RTL_GENERIC_TABLE *Table, IN PVOID Buffer); -typedef struct _RTL_SPLAY_LINKS { - struct _RTL_SPLAY_LINKS *Parent; - struct _RTL_SPLAY_LINKS *LeftChild; - struct _RTL_SPLAY_LINKS *RightChild; -} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; - -typedef struct _RTL_GENERIC_TABLE { - PRTL_SPLAY_LINKS TableRoot; - LIST_ENTRY InsertOrderList; - PLIST_ENTRY OrderedPointer; - ULONG WhichOrderedElement; - ULONG NumberGenericTableElements; - PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine; - PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine; - PRTL_GENERIC_FREE_ROUTINE FreeRoutine; - PVOID TableContext; -} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE; - #endif /* !RTL_USE_AVL_TABLES */ -#ifdef RTL_USE_AVL_TABLES - -#undef PRTL_GENERIC_COMPARE_ROUTINE -#undef RTL_GENERIC_COMPARE_ROUTINE -#undef PRTL_GENERIC_ALLOCATE_ROUTINE -#undef RTL_GENERIC_ALLOCATE_ROUTINE -#undef PRTL_GENERIC_FREE_ROUTINE -#undef RTL_GENERIC_FREE_ROUTINE -#undef RTL_GENERIC_TABLE -#undef PRTL_GENERIC_TABLE - -#define PRTL_GENERIC_COMPARE_ROUTINE PRTL_AVL_COMPARE_ROUTINE -#define RTL_GENERIC_COMPARE_ROUTINE RTL_AVL_COMPARE_ROUTINE -#define PRTL_GENERIC_ALLOCATE_ROUTINE PRTL_AVL_ALLOCATE_ROUTINE -#define RTL_GENERIC_ALLOCATE_ROUTINE RTL_AVL_ALLOCATE_ROUTINE -#define PRTL_GENERIC_FREE_ROUTINE PRTL_AVL_FREE_ROUTINE -#define RTL_GENERIC_FREE_ROUTINE RTL_AVL_FREE_ROUTINE -#define RTL_GENERIC_TABLE RTL_AVL_TABLE -#define PRTL_GENERIC_TABLE PRTL_AVL_TABLE - -#endif /* RTL_USE_AVL_TABLES */ - -typedef struct _RTL_DYNAMIC_HASH_TABLE_ENTRY { - LIST_ENTRY Linkage; - ULONG_PTR Signature; -} RTL_DYNAMIC_HASH_TABLE_ENTRY, *PRTL_DYNAMIC_HASH_TABLE_ENTRY; - -typedef struct _RTL_DYNAMIC_HASH_TABLE_CONTEXT { - PLIST_ENTRY ChainHead; - PLIST_ENTRY PrevLinkage; - ULONG_PTR Signature; -} RTL_DYNAMIC_HASH_TABLE_CONTEXT, *PRTL_DYNAMIC_HASH_TABLE_CONTEXT; - -typedef struct _RTL_DYNAMIC_HASH_TABLE_ENUMERATOR { - RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry; - PLIST_ENTRY ChainHead; - ULONG BucketIndex; -} RTL_DYNAMIC_HASH_TABLE_ENUMERATOR, *PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR; - -typedef struct _RTL_DYNAMIC_HASH_TABLE { - ULONG Flags; - ULONG Shift; - ULONG TableSize; - ULONG Pivot; - ULONG DivisorMask; - ULONG NumEntries; - ULONG NonEmptyBuckets; - ULONG NumEnumerators; - PVOID Directory; -} RTL_DYNAMIC_HASH_TABLE, *PRTL_DYNAMIC_HASH_TABLE; - -typedef struct _OSVERSIONINFOA { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - CHAR szCSDVersion[128]; -} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; - -typedef struct _OSVERSIONINFOW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; -} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; - -typedef struct _OSVERSIONINFOEXA { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - CHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; - -typedef struct _OSVERSIONINFOEXW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; - -#ifdef UNICODE -typedef OSVERSIONINFOEXW OSVERSIONINFOEX; -typedef POSVERSIONINFOEXW POSVERSIONINFOEX; -typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX; -typedef OSVERSIONINFOW OSVERSIONINFO; -typedef POSVERSIONINFOW POSVERSIONINFO; -typedef LPOSVERSIONINFOW LPOSVERSIONINFO; -#else -typedef OSVERSIONINFOEXA OSVERSIONINFOEX; -typedef POSVERSIONINFOEXA POSVERSIONINFOEX; -typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; -typedef OSVERSIONINFOA OSVERSIONINFO; -typedef POSVERSIONINFOA POSVERSIONINFO; -typedef LPOSVERSIONINFOA LPOSVERSIONINFO; -#endif /* UNICODE */ - -#define HASH_ENTRY_KEY(x) ((x)->Signature) - -/****************************************************************************** - * Security Manager Types * - ******************************************************************************/ -#define SE_UNSOLICITED_INPUT_PRIVILEGE 6 - -typedef enum _WELL_KNOWN_SID_TYPE { - WinNullSid = 0, - WinWorldSid = 1, - WinLocalSid = 2, - WinCreatorOwnerSid = 3, - WinCreatorGroupSid = 4, - WinCreatorOwnerServerSid = 5, - WinCreatorGroupServerSid = 6, - WinNtAuthoritySid = 7, - WinDialupSid = 8, - WinNetworkSid = 9, - WinBatchSid = 10, - WinInteractiveSid = 11, - WinServiceSid = 12, - WinAnonymousSid = 13, - WinProxySid = 14, - WinEnterpriseControllersSid = 15, - WinSelfSid = 16, - WinAuthenticatedUserSid = 17, - WinRestrictedCodeSid = 18, - WinTerminalServerSid = 19, - WinRemoteLogonIdSid = 20, - WinLogonIdsSid = 21, - WinLocalSystemSid = 22, - WinLocalServiceSid = 23, - WinNetworkServiceSid = 24, - WinBuiltinDomainSid = 25, - WinBuiltinAdministratorsSid = 26, - WinBuiltinUsersSid = 27, - WinBuiltinGuestsSid = 28, - WinBuiltinPowerUsersSid = 29, - WinBuiltinAccountOperatorsSid = 30, - WinBuiltinSystemOperatorsSid = 31, - WinBuiltinPrintOperatorsSid = 32, - WinBuiltinBackupOperatorsSid = 33, - WinBuiltinReplicatorSid = 34, - WinBuiltinPreWindows2000CompatibleAccessSid = 35, - WinBuiltinRemoteDesktopUsersSid = 36, - WinBuiltinNetworkConfigurationOperatorsSid = 37, - WinAccountAdministratorSid = 38, - WinAccountGuestSid = 39, - WinAccountKrbtgtSid = 40, - WinAccountDomainAdminsSid = 41, - WinAccountDomainUsersSid = 42, - WinAccountDomainGuestsSid = 43, - WinAccountComputersSid = 44, - WinAccountControllersSid = 45, - WinAccountCertAdminsSid = 46, - WinAccountSchemaAdminsSid = 47, - WinAccountEnterpriseAdminsSid = 48, - WinAccountPolicyAdminsSid = 49, - WinAccountRasAndIasServersSid = 50, - WinNTLMAuthenticationSid = 51, - WinDigestAuthenticationSid = 52, - WinSChannelAuthenticationSid = 53, - WinThisOrganizationSid = 54, - WinOtherOrganizationSid = 55, - WinBuiltinIncomingForestTrustBuildersSid = 56, - WinBuiltinPerfMonitoringUsersSid = 57, - WinBuiltinPerfLoggingUsersSid = 58, - WinBuiltinAuthorizationAccessSid = 59, - WinBuiltinTerminalServerLicenseServersSid = 60, - WinBuiltinDCOMUsersSid = 61, - WinBuiltinIUsersSid = 62, - WinIUserSid = 63, - WinBuiltinCryptoOperatorsSid = 64, - WinUntrustedLabelSid = 65, - WinLowLabelSid = 66, - WinMediumLabelSid = 67, - WinHighLabelSid = 68, - WinSystemLabelSid = 69, - WinWriteRestrictedCodeSid = 70, - WinCreatorOwnerRightsSid = 71, - WinCacheablePrincipalsGroupSid = 72, - WinNonCacheablePrincipalsGroupSid = 73, - WinEnterpriseReadonlyControllersSid = 74, - WinAccountReadonlyControllersSid = 75, - WinBuiltinEventLogReadersGroup = 76, - WinNewEnterpriseReadonlyControllersSid = 77, - WinBuiltinCertSvcDComAccessGroup = 78, - WinMediumPlusLabelSid = 79, - WinLocalLogonSid = 80, - WinConsoleLogonSid = 81, - WinThisOrganizationCertificateSid = 82, -} WELL_KNOWN_SID_TYPE; - - - -#if defined(_M_IX86) - -#define PAUSE_PROCESSOR YieldProcessor(); - -#define KERNEL_STACK_SIZE 12288 -#define KERNEL_LARGE_STACK_SIZE 61440 -#define KERNEL_LARGE_STACK_COMMIT 12288 - -#define SIZE_OF_80387_REGISTERS 80 - -#if !defined(RC_INVOKED) - -#define CONTEXT_i386 0x10000 -#define CONTEXT_i486 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) -#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) -#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) - -#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) -#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ - CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \ - CONTEXT_EXTENDED_REGISTERS) - -#define CONTEXT_XSTATE (CONTEXT_i386 | 0x00000040L) - -#endif /* !defined(RC_INVOKED) */ - -typedef struct _FLOATING_SAVE_AREA { - ULONG ControlWord; - ULONG StatusWord; - ULONG TagWord; - ULONG ErrorOffset; - ULONG ErrorSelector; - ULONG DataOffset; - ULONG DataSelector; - UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; - ULONG Cr0NpxState; -} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; - -#include "pshpack4.h" -typedef struct _CONTEXT { - ULONG ContextFlags; - ULONG Dr0; - ULONG Dr1; - ULONG Dr2; - ULONG Dr3; - ULONG Dr6; - ULONG Dr7; - FLOATING_SAVE_AREA FloatSave; - ULONG SegGs; - ULONG SegFs; - ULONG SegEs; - ULONG SegDs; - ULONG Edi; - ULONG Esi; - ULONG Ebx; - ULONG Edx; - ULONG Ecx; - ULONG Eax; - ULONG Ebp; - ULONG Eip; - ULONG SegCs; - ULONG EFlags; - ULONG Esp; - ULONG SegSs; - UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; -} CONTEXT; -#include "poppack.h" - -#define KeGetPcr() PCR - -#define PCR_MINOR_VERSION 1 -#define PCR_MAJOR_VERSION 1 - -typedef struct _KPCR { - union { - NT_TIB NtTib; - struct { - struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; - PVOID Used_StackBase; - PVOID Spare2; - PVOID TssCopy; - ULONG ContextSwitches; - KAFFINITY SetMemberCopy; - PVOID Used_Self; - }; - }; - struct _KPCR *SelfPcr; - struct _KPRCB *Prcb; - KIRQL Irql; - ULONG IRR; - ULONG IrrActive; - ULONG IDR; - PVOID KdVersionBlock; - struct _KIDTENTRY *IDT; - struct _KGDTENTRY *GDT; - struct _KTSS *TSS; - USHORT MajorVersion; - USHORT MinorVersion; - KAFFINITY SetMember; - ULONG StallScaleFactor; - UCHAR SpareUnused; - UCHAR Number; - UCHAR Spare0; - UCHAR SecondLevelCacheAssociativity; - ULONG VdmAlert; - ULONG KernelReserved[14]; - ULONG SecondLevelCacheSize; - ULONG HalReserved[16]; -} KPCR, *PKPCR; - -FORCEINLINE -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)__readfsbyte(FIELD_OFFSET(KPCR, Number)); -} - - - - - - -extern NTKERNELAPI PVOID MmHighestUserAddress; -extern NTKERNELAPI PVOID MmSystemRangeStart; -extern NTKERNELAPI ULONG MmUserProbeAddress; - -#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress -#define MM_SYSTEM_RANGE_START MmSystemRangeStart -#if defined(_LOCAL_COPY_USER_PROBE_ADDRESS_) -#define MM_USER_PROBE_ADDRESS _LOCAL_COPY_USER_PROBE_ADDRESS_ -extern ULONG _LOCAL_COPY_USER_PROBE_ADDRESS_; -#else -#define MM_USER_PROBE_ADDRESS MmUserProbeAddress -#endif -#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 -#define MM_KSEG0_BASE MM_SYSTEM_RANGE_START -#define MM_SYSTEM_SPACE_END 0xFFFFFFFF -#if !defined (_X86PAE_) -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 -#else -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 -#endif - -#elif defined(_M_AMD64) - -#define PAUSE_PROCESSOR YieldProcessor(); - -#define KERNEL_STACK_SIZE 0x6000 -#define KERNEL_LARGE_STACK_SIZE 0x12000 -#define KERNEL_LARGE_STACK_COMMIT KERNEL_STACK_SIZE - -#define KERNEL_MCA_EXCEPTION_STACK_SIZE 0x2000 - -#define EXCEPTION_READ_FAULT 0 -#define EXCEPTION_WRITE_FAULT 1 -#define EXCEPTION_EXECUTE_FAULT 8 - -#if !defined(RC_INVOKED) - -#define CONTEXT_AMD64 0x100000 - -#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L) -#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L) -#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L) -#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) -#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) - -#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x20L) - -#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 -#define CONTEXT_SERVICE_ACTIVE 0x10000000 -#define CONTEXT_EXCEPTION_REQUEST 0x40000000 -#define CONTEXT_EXCEPTION_REPORTING 0x80000000 - -#endif /* !defined(RC_INVOKED) */ - -#define INITIAL_MXCSR 0x1f80 -#define INITIAL_FPCSR 0x027f - -typedef struct DECLSPEC_ALIGN(16) _CONTEXT { - ULONG64 P1Home; - ULONG64 P2Home; - ULONG64 P3Home; - ULONG64 P4Home; - ULONG64 P5Home; - ULONG64 P6Home; - ULONG ContextFlags; - ULONG MxCsr; - USHORT SegCs; - USHORT SegDs; - USHORT SegEs; - USHORT SegFs; - USHORT SegGs; - USHORT SegSs; - ULONG EFlags; - ULONG64 Dr0; - ULONG64 Dr1; - ULONG64 Dr2; - ULONG64 Dr3; - ULONG64 Dr6; - ULONG64 Dr7; - ULONG64 Rax; - ULONG64 Rcx; - ULONG64 Rdx; - ULONG64 Rbx; - ULONG64 Rsp; - ULONG64 Rbp; - ULONG64 Rsi; - ULONG64 Rdi; - ULONG64 R8; - ULONG64 R9; - ULONG64 R10; - ULONG64 R11; - ULONG64 R12; - ULONG64 R13; - ULONG64 R14; - ULONG64 R15; - ULONG64 Rip; - union { - XMM_SAVE_AREA32 FltSave; - struct { - M128A Header[2]; - M128A Legacy[8]; - M128A Xmm0; - M128A Xmm1; - M128A Xmm2; - M128A Xmm3; - M128A Xmm4; - M128A Xmm5; - M128A Xmm6; - M128A Xmm7; - M128A Xmm8; - M128A Xmm9; - M128A Xmm10; - M128A Xmm11; - M128A Xmm12; - M128A Xmm13; - M128A Xmm14; - M128A Xmm15; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - M128A VectorRegister[26]; - ULONG64 VectorControl; - ULONG64 DebugControl; - ULONG64 LastBranchToRip; - ULONG64 LastBranchFromRip; - ULONG64 LastExceptionToRip; - ULONG64 LastExceptionFromRip; -} CONTEXT; - -#define PCR_MINOR_VERSION 1 -#define PCR_MAJOR_VERSION 1 - -typedef struct _KPCR -{ - _ANONYMOUS_UNION union - { - NT_TIB NtTib; - _ANONYMOUS_STRUCT struct - { - union _KGDTENTRY64 *GdtBase; - struct _KTSS64 *TssBase; - ULONG64 UserRsp; - struct _KPCR *Self; - struct _KPRCB *CurrentPrcb; - PKSPIN_LOCK_QUEUE LockArray; - PVOID Used_Self; - }; - }; - union _KIDTENTRY64 *IdtBase; - ULONG64 Unused[2]; - KIRQL Irql; - UCHAR SecondLevelCacheAssociativity; - UCHAR ObsoleteNumber; - UCHAR Fill0; - ULONG Unused0[3]; - USHORT MajorVersion; - USHORT MinorVersion; - ULONG StallScaleFactor; - PVOID Unused1[3]; - ULONG KernelReserved[15]; - ULONG SecondLevelCacheSize; - ULONG HalReserved[16]; - ULONG Unused2; - PVOID KdVersionBlock; - PVOID Unused3; - ULONG PcrAlign1[24]; -} KPCR, *PKPCR; - -FORCEINLINE -PKPCR -KeGetPcr(VOID) -{ - return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self)); -} - -FORCEINLINE -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)__readgsword(0x184); -} - - -#define PTI_SHIFT 12L -#define PDI_SHIFT 21L -#define PPI_SHIFT 30L -#define PXI_SHIFT 39L -#define PTE_PER_PAGE 512 -#define PDE_PER_PAGE 512 -#define PPE_PER_PAGE 512 -#define PXE_PER_PAGE 512 -#define PTI_MASK_AMD64 (PTE_PER_PAGE - 1) -#define PDI_MASK_AMD64 (PDE_PER_PAGE - 1) -#define PPI_MASK (PPE_PER_PAGE - 1) -#define PXI_MASK (PXE_PER_PAGE - 1) - -#define PXE_BASE 0xFFFFF6FB7DBED000ULL -#define PXE_SELFMAP 0xFFFFF6FB7DBEDF68ULL -#define PPE_BASE 0xFFFFF6FB7DA00000ULL -#define PDE_BASE 0xFFFFF6FB40000000ULL -#define PTE_BASE 0xFFFFF68000000000ULL -#define PXE_TOP 0xFFFFF6FB7DBEDFFFULL -#define PPE_TOP 0xFFFFF6FB7DBFFFFFULL -#define PDE_TOP 0xFFFFF6FB7FFFFFFFULL -#define PTE_TOP 0xFFFFF6FFFFFFFFFFULL - -extern NTKERNELAPI PVOID MmHighestUserAddress; -extern NTKERNELAPI PVOID MmSystemRangeStart; -extern NTKERNELAPI ULONG64 MmUserProbeAddress; - -#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress -#define MM_SYSTEM_RANGE_START MmSystemRangeStart -#define MM_USER_PROBE_ADDRESS MmUserProbeAddress -#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 -#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFF080000000000ULL - - -#elif defined(_M_IA64) - -#elif defined(_M_PPC) - - -#elif defined(_M_MIPS) - -#elif defined(_M_ARM) -#else -#error Unknown Architecture -#endif - -/****************************************************************************** - * Executive Functions * - ******************************************************************************/ -static __inline PVOID -ExAllocateFromZone( - IN PZONE_HEADER Zone) -{ - if (Zone->FreeList.Next) - Zone->FreeList.Next = Zone->FreeList.Next->Next; - return (PVOID) Zone->FreeList.Next; -} - -static __inline PVOID -ExFreeToZone( - IN PZONE_HEADER Zone, - IN PVOID Block) -{ - ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next; - Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block); - return ((PSINGLE_LIST_ENTRY) Block)->Next; -} - -/* - * PVOID - * ExInterlockedAllocateFromZone( - * IN PZONE_HEADER Zone, - * IN PKSPIN_LOCK Lock) - */ -#define ExInterlockedAllocateFromZone(Zone, Lock) \ - ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock)) - -/* PVOID - * ExInterlockedFreeToZone( - * IN PZONE_HEADER Zone, - * IN PVOID Block, - * IN PKSPIN_LOCK Lock); - */ -#define ExInterlockedFreeToZone(Zone, Block, Lock) \ - ExInterlockedPushEntryList(&(Zone)->FreeList, (PSINGLE_LIST_ENTRY)(Block), Lock) - -/* - * BOOLEAN - * ExIsFullZone( - * IN PZONE_HEADER Zone) - */ -#define ExIsFullZone(Zone) \ - ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL) - -/* BOOLEAN - * ExIsObjectInFirstZoneSegment( - * IN PZONE_HEADER Zone, - * IN PVOID Object); - */ -#define ExIsObjectInFirstZoneSegment(Zone,Object) \ - ((BOOLEAN)( ((PUCHAR)(Object) >= (PUCHAR)(Zone)->SegmentList.Next) && \ - ((PUCHAR)(Object) < (PUCHAR)(Zone)->SegmentList.Next + \ - (Zone)->TotalSegmentSize)) ) - -#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite -#define ExAcquireResourceShared ExAcquireResourceSharedLite -#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite -#define ExDeleteResource ExDeleteResourceLite -#define ExInitializeResource ExInitializeResourceLite -#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite -#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite -#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite -#define ExReleaseResourceForThread ExReleaseResourceForThreadLite - -#ifdef _X86_ - -typedef enum _INTERLOCKED_RESULT { - ResultNegative = RESULT_NEGATIVE, - ResultZero = RESULT_ZERO, - ResultPositive = RESULT_POSITIVE -} INTERLOCKED_RESULT; - -NTKERNELAPI -INTERLOCKED_RESULT -FASTCALL -Exfi386InterlockedIncrementLong( - IN OUT LONG volatile *Addend); - -NTKERNELAPI -INTERLOCKED_RESULT -FASTCALL -Exfi386InterlockedDecrementLong( - IN PLONG Addend); - -NTKERNELAPI -ULONG -FASTCALL -Exfi386InterlockedExchangeUlong( - IN PULONG Target, - IN ULONG Value); -#endif - - - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -NTSTATUS -NTAPI -ExExtendZone( - IN OUT PZONE_HEADER Zone, - IN OUT PVOID Segment, - IN ULONG SegmentSize); - -NTKERNELAPI -NTSTATUS -NTAPI -ExInitializeZone( - OUT PZONE_HEADER Zone, - IN ULONG BlockSize, - IN OUT PVOID InitialSegment, - IN ULONG InitialSegmentSize); - -NTKERNELAPI -NTSTATUS -NTAPI -ExInterlockedExtendZone( - IN OUT PZONE_HEADER Zone, - IN OUT PVOID Segment, - IN ULONG SegmentSize, - IN OUT PKSPIN_LOCK Lock); - -NTKERNELAPI -NTSTATUS -NTAPI -ExUuidCreate( - OUT UUID *Uuid); - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -ExRaiseAccessViolation(VOID); - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -ExRaiseDatatypeMisalignment(VOID); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - - -/* Hardware Abstraction Layer Functions */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -#if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_) - -/* Nothing here */ - -#else /* USE_DMA_MACROS ... */ - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -IoFreeAdapterChannel( - IN PADAPTER_OBJECT AdapterObject); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -BOOLEAN -NTAPI -IoFlushAdapterBuffers( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN ULONG Length, - IN BOOLEAN WriteToDevice); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -IoFreeMapRegisters( - IN PADAPTER_OBJECT AdapterObject, - IN PVOID MapRegisterBase, - IN ULONG NumberOfMapRegisters); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -PVOID -NTAPI -HalAllocateCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - OUT PPHYSICAL_ADDRESS LogicalAddress, - IN BOOLEAN CacheEnabled); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -VOID -NTAPI -HalFreeCommonBuffer( - IN PADAPTER_OBJECT AdapterObject, - IN ULONG Length, - IN PHYSICAL_ADDRESS LogicalAddress, - IN PVOID VirtualAddress, - IN BOOLEAN CacheEnabled); - -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -ULONG -NTAPI -HalReadDmaCounter( - IN PADAPTER_OBJECT AdapterObject); - -NTHALAPI -NTSTATUS -NTAPI -HalAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PWAIT_CONTEXT_BLOCK Wcb, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine); - -#endif /* USE_DMA_MACROS ... */ - -#if !defined(NO_LEGACY_DRIVERS) -NTHALAPI -NTSTATUS -NTAPI -HalAssignSlotResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject, - IN INTERFACE_TYPE BusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -NTHALAPI -ULONG -NTAPI -HalGetInterruptVector( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity); - -NTHALAPI -ULONG -NTAPI -HalSetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length); - -NTHALAPI -ULONG -NTAPI -HalGetBusData( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Length); - -NTHALAPI -BOOLEAN -NTAPI -HalMakeBeep( - IN ULONG Frequency); -#endif /* !defined(NO_LEGACY_DRIVERS) */ - -NTHALAPI -PADAPTER_OBJECT -NTAPI -HalGetAdapter( - IN PDEVICE_DESCRIPTION DeviceDescription, - OUT PULONG NumberOfMapRegisters); - -VOID -NTAPI -HalPutDmaAdapter( - IN PADAPTER_OBJECT DmaAdapter); - -NTHALAPI -VOID -NTAPI -HalAcquireDisplayOwnership( - IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); - -NTHALAPI -ULONG -NTAPI -HalGetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTHALAPI -ULONG -NTAPI -HalSetBusDataByOffset( - IN BUS_DATA_TYPE BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length); - -NTHALAPI -BOOLEAN -NTAPI -HalTranslateBusAddress( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN PHYSICAL_ADDRESS BusAddress, - IN OUT PULONG AddressSpace, - OUT PPHYSICAL_ADDRESS TranslatedAddress); - -NTHALAPI -PVOID -NTAPI -HalAllocateCrashDumpRegisters( - IN PADAPTER_OBJECT AdapterObject, - IN OUT PULONG NumberOfMapRegisters); - -NTSTATUS -NTAPI -HalGetScatterGatherList( - IN PADAPTER_OBJECT DmaAdapter, - IN PDEVICE_OBJECT DeviceObject, - IN PMDL Mdl, - IN PVOID CurrentVa, - IN ULONG Length, - IN PDRIVER_LIST_CONTROL ExecutionRoutine, - IN PVOID Context, - IN BOOLEAN WriteToDevice); - -VOID -NTAPI -HalPutScatterGatherList( - IN PADAPTER_OBJECT DmaAdapter, - IN PSCATTER_GATHER_LIST ScatterGather, - IN BOOLEAN WriteToDevice); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) -NTKERNELAPI -VOID -FASTCALL -HalExamineMBR( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, - OUT PVOID *Buffer); -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -NTSTATUS -NTAPI -HalAllocateHardwareCounters( - IN PGROUP_AFFINITY GroupAffinty, - IN ULONG GroupCount, - IN PPHYSICAL_COUNTER_RESOURCE_LIST ResourceList, - OUT PHANDLE CounterSetHandle); - -NTSTATUS -NTAPI -HalFreeHardwareCounters( - IN HANDLE CounterSetHandle); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - -#if defined(_IA64_) -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTHALAPI -ULONG -NTAPI -HalGetDmaAlignmentRequirement(VOID); -#endif -#endif /* defined(_IA64_) */ - -#if defined(_M_IX86) || defined(_M_AMD64) -#define HalGetDmaAlignmentRequirement() 1L -#endif - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -typedef struct _WHEA_ERROR_SOURCE_DESCRIPTOR *PWHEA_ERROR_SOURCE_DESCRIPTOR; -typedef struct _WHEA_ERROR_RECORD *PWHEA_ERROR_RECORD; - -NTHALAPI -VOID -NTAPI -HalBugCheckSystem( - IN PWHEA_ERROR_SOURCE_DESCRIPTOR ErrorSource, - IN PWHEA_ERROR_RECORD ErrorRecord); - -#else - -typedef struct _WHEA_ERROR_RECORD *PWHEA_ERROR_RECORD; - -NTHALAPI -VOID -NTAPI -HalBugCheckSystem( - IN PWHEA_ERROR_RECORD ErrorRecord); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - - -/****************************************************************************** - * I/O Manager Functions * - ******************************************************************************/ -/* - * VOID IoAssignArcName( - * IN PUNICODE_STRING ArcName, - * IN PUNICODE_STRING DeviceName); - */ -#define IoAssignArcName(_ArcName, _DeviceName) ( \ - IoCreateSymbolicLink((_ArcName), (_DeviceName))) - -/* - * VOID - * IoDeassignArcName( - * IN PUNICODE_STRING ArcName) - */ -#define IoDeassignArcName IoDeleteSymbolicLink - -VOID -FORCEINLINE -NTAPI -IoInitializeDriverCreateContext( - PIO_DRIVER_CREATE_CONTEXT DriverContext) -{ - RtlZeroMemory(DriverContext, sizeof(IO_DRIVER_CREATE_CONTEXT)); - DriverContext->Size = sizeof(IO_DRIVER_CREATE_CONTEXT); -} - - - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -#if !(defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)) -NTKERNELAPI -NTSTATUS -NTAPI -IoAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); -#endif - -#if !defined(DMA_MACROS_DEFINED) -//DECLSPEC_DEPRECATED_DDK -NTHALAPI -PHYSICAL_ADDRESS -NTAPI -IoMapTransfer( - IN PADAPTER_OBJECT AdapterObject, - IN PMDL Mdl, - IN PVOID MapRegisterBase, - IN PVOID CurrentVa, - IN OUT PULONG Length, - IN BOOLEAN WriteToDevice); -#endif - -NTKERNELAPI -VOID -NTAPI -IoAllocateController( - IN PCONTROLLER_OBJECT ControllerObject, - IN PDEVICE_OBJECT DeviceObject, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -PCONTROLLER_OBJECT -NTAPI -IoCreateController( - IN ULONG Size); - -NTKERNELAPI -VOID -NTAPI -IoDeleteController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTKERNELAPI -VOID -NTAPI -IoFreeController( - IN PCONTROLLER_OBJECT ControllerObject); - -NTKERNELAPI -PCONFIGURATION_INFORMATION -NTAPI -IoGetConfigurationInformation(VOID); - -NTKERNELAPI -PDEVICE_OBJECT -NTAPI -IoGetDeviceToVerify( - IN PETHREAD Thread); - -NTKERNELAPI -VOID -NTAPI -IoCancelFileOpen( - IN PDEVICE_OBJECT DeviceObject, - IN PFILE_OBJECT FileObject); - -NTKERNELAPI -PGENERIC_MAPPING -NTAPI -IoGetFileObjectGenericMapping(VOID); - -NTKERNELAPI -PIRP -NTAPI -IoMakeAssociatedIrp( - IN PIRP Irp, - IN CCHAR StackSize); - -NTKERNELAPI -NTSTATUS -NTAPI -IoQueryDeviceDescription( - IN PINTERFACE_TYPE BusType OPTIONAL, - IN PULONG BusNumber OPTIONAL, - IN PCONFIGURATION_TYPE ControllerType OPTIONAL, - IN PULONG ControllerNumber OPTIONAL, - IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, - IN PULONG PeripheralNumber OPTIONAL, - IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, - IN OUT PVOID Context OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRaiseHardError( - IN PIRP Irp, - IN PVPB Vpb OPTIONAL, - IN PDEVICE_OBJECT RealDeviceObject); - -NTKERNELAPI -BOOLEAN -NTAPI -IoRaiseInformationalHardError( - IN NTSTATUS ErrorStatus, - IN PUNICODE_STRING String OPTIONAL, - IN PKTHREAD Thread OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRegisterBootDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -IoRegisterDriverReinitialization( - IN PDRIVER_OBJECT DriverObject, - IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, - IN PVOID Context OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAttachDeviceByPointer( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportDetectedDevice( - IN PDRIVER_OBJECT DriverObject, - IN INTERFACE_TYPE LegacyBusType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PCM_RESOURCE_LIST ResourceList OPTIONAL, - IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, - IN BOOLEAN ResourceAssigned, - IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportResourceForDetection( - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - OUT PBOOLEAN ConflictDetected); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReportResourceUsage( - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PCM_RESOURCE_LIST DriverList OPTIONAL, - IN ULONG DriverListSize OPTIONAL, - IN PDEVICE_OBJECT DeviceObject, - IN PCM_RESOURCE_LIST DeviceList OPTIONAL, - IN ULONG DeviceListSize OPTIONAL, - IN BOOLEAN OverrideConflict, - OUT PBOOLEAN ConflictDetected); - -NTKERNELAPI -VOID -NTAPI -IoSetHardErrorOrVerifyDevice( - IN PIRP Irp, - IN PDEVICE_OBJECT DeviceObject); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAssignResources( - IN PUNICODE_STRING RegistryPath, - IN PUNICODE_STRING DriverClassName OPTIONAL, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT DeviceObject OPTIONAL, - IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources OPTIONAL, - IN OUT PCM_RESOURCE_LIST *AllocatedResources); - -NTKERNELAPI -BOOLEAN -NTAPI -IoSetThreadHardErrorMode( - IN BOOLEAN EnableHardErrors); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WIN2KSP3) - -NTKERNELAPI -BOOLEAN -NTAPI -IoIsFileOriginRemote( - IN PFILE_OBJECT FileObject); - -NTKERNELAPI -NTSTATUS -NTAPI -IoSetFileOrigin( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Remote); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2KSP3) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) -NTKERNELAPI -NTSTATUS -FASTCALL -IoReadPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN BOOLEAN ReturnRecognizedPartitions, - OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); - -NTKERNELAPI -NTSTATUS -FASTCALL -IoSetPartitionInformation( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG PartitionNumber, - IN ULONG PartitionType); - -NTKERNELAPI -NTSTATUS -FASTCALL -IoWritePartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG SectorsPerTrack, - IN ULONG NumberOfHeads, - IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); - -NTKERNELAPI -NTSTATUS -NTAPI -IoCreateDisk( - IN PDEVICE_OBJECT DeviceObject, - IN struct _CREATE_DISK* Disk OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReadDiskSignature( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG BytesPerSector, - OUT PDISK_SIGNATURE Signature); - -NTKERNELAPI -NTSTATUS -NTAPI -IoReadPartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - OUT struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); - -NTKERNELAPI -NTSTATUS -NTAPI -IoSetPartitionInformationEx( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG PartitionNumber, - IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); - -NTKERNELAPI -NTSTATUS -NTAPI -IoSetSystemPartition( - IN PUNICODE_STRING VolumeNameString); - -NTKERNELAPI -NTSTATUS -NTAPI -IoVerifyPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN BOOLEAN FixErrors); - -NTKERNELAPI -NTSTATUS -NTAPI -IoVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTKERNELAPI -NTSTATUS -NTAPI -IoWritePartitionTableEx( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DRIVE_LAYOUT_INFORMATION_EX *DriveLayout); - -NTKERNELAPI -NTSTATUS -NTAPI -IoCreateFileSpecifyDeviceObjectHint( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG Disposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength, - IN CREATE_FILE_TYPE CreateFileType, - IN PVOID InternalParameters OPTIONAL, - IN ULONG Options, - IN PVOID DeviceObject OPTIONAL); - -NTKERNELAPI -NTSTATUS -NTAPI -IoAttachDeviceToDeviceStackSafe( - IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice, - OUT PDEVICE_OBJECT *AttachedToDeviceObject); - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - - -#if (NTDDI_VERSION >= NTDDI_WS03) -NTKERNELAPI -IO_PAGING_PRIORITY -FASTCALL -IoGetPagingIoPriority( - IN PIRP Irp); - -#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ - -#if (NTDDI_VERSION >= NTDDI_WS03SP1) -BOOLEAN -NTAPI -IoTranslateBusAddress( - IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber, - IN PHYSICAL_ADDRESS BusAddress, - IN OUT PULONG AddressSpace, - OUT PPHYSICAL_ADDRESS TranslatedAddress); -#endif - -#if (NTDDI_VERSION >= NTDDI_VISTA) -NTKERNELAPI -NTSTATUS -NTAPI -IoUpdateDiskGeometry( - IN PDEVICE_OBJECT DeviceObject, - IN struct _DISK_GEOMETRY_EX* OldDiskGeometry, - IN struct _DISK_GEOMETRY_EX* NewDiskGeometry); - -PTXN_PARAMETER_BLOCK -NTAPI -IoGetTransactionParameterBlock( - IN PFILE_OBJECT FileObject); - -NTKERNELAPI -NTSTATUS -NTAPI -IoCreateFileEx( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG Disposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength, - IN CREATE_FILE_TYPE CreateFileType, - IN PVOID InternalParameters OPTIONAL, - IN ULONG Options, - IN PIO_DRIVER_CREATE_CONTEXT DriverContext OPTIONAL); - -NTSTATUS -NTAPI -IoSetIrpExtraCreateParameter( - IN OUT PIRP Irp, - IN struct _ECP_LIST *ExtraCreateParameter); - -VOID -NTAPI -IoClearIrpExtraCreateParameter( - IN OUT PIRP Irp); - -NTSTATUS -NTAPI -IoGetIrpExtraCreateParameter( - IN PIRP Irp, - OUT struct _ECP_LIST **ExtraCreateParameter OPTIONAL); - -BOOLEAN -NTAPI -IoIsFileObjectIgnoringSharing( - IN PFILE_OBJECT FileObject); - - -#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ - - -#if (NTDDI_VERSION >= NTDDI_WIN7) -NTSTATUS -NTAPI -IoSetFileObjectIgnoreSharing( - IN PFILE_OBJECT FileObject); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - - -/****************************************************************************** - * Kernel Debugger Functions * - ******************************************************************************/ -NTSYSAPI -ULONG -NTAPI -DbgPrompt( - IN PCCH Prompt, - OUT PCH Response, - IN ULONG MaximumResponseLength); - -/****************************************************************************** - * Kernel Functions * - ******************************************************************************/ -NTKERNELAPI -VOID -FASTCALL -KeInvalidateRangeAllCaches( - IN PVOID BaseAddress, - IN ULONG Length); - - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -NTKERNELAPI -VOID -NTAPI -KeSetImportanceDpc( - IN OUT PRKDPC Dpc, - IN KDPC_IMPORTANCE Importance); - -NTKERNELAPI -LONG -NTAPI -KePulseEvent( - IN OUT PRKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait); - -NTKERNELAPI -LONG -NTAPI -KeSetBasePriorityThread( - IN OUT PRKTHREAD Thread, - IN LONG Increment); - -NTKERNELAPI -VOID -NTAPI -KeEnterCriticalRegion(VOID); - -NTKERNELAPI -VOID -NTAPI -KeLeaveCriticalRegion(VOID); - -NTKERNELAPI -DECLSPEC_NORETURN -VOID -NTAPI -KeBugCheck( - IN ULONG BugCheckCode); - - -#if defined(SINGLE_GROUP_LEGACY_API) - - -NTKERNELAPI -VOID -NTAPI -KeSetTargetProcessorDpc( - IN OUT PRKDPC Dpc, - IN CCHAR Number); - -NTKERNELAPI -KAFFINITY -NTAPI -KeQueryActiveProcessors(VOID); - -#endif /* defined(SINGLE_GROUP_LEGACY_API) */ - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) -NTKERNELAPI -BOOLEAN -NTAPI -KeAreApcsDisabled(VOID); - - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - - -#if (NTDDI_VERSION >= NTDDI_WS03) - - -NTKERNELAPI -BOOLEAN -NTAPI -KeInvalidateAllCaches(VOID); - -#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ - -#if (NTDDI_VERSION >= NTDDI_WS03SP1) - -NTKERNELAPI -NTSTATUS -NTAPI -KeExpandKernelStackAndCallout( - IN PEXPAND_STACK_CALLOUT Callout, - IN PVOID Parameter OPTIONAL, - IN SIZE_T Size); - -NTKERNELAPI -VOID -NTAPI -KeEnterGuardedRegion(VOID); - -NTKERNELAPI -VOID -NTAPI -KeLeaveGuardedRegion(VOID); - - -#endif /* (NTDDI_VERSION >= NTDDI_WS03SP1) */ - -#if (NTDDI_VERSION >= NTDDI_VISTA) - - -#if defined(SINGLE_GROUP_LEGACY_API) -NTKERNELAPI -ULONG -NTAPI -KeQueryActiveProcessorCount( - OUT PKAFFINITY ActiveProcessors OPTIONAL); - -NTKERNELAPI -ULONG -NTAPI -KeQueryMaximumProcessorCount(VOID); - -#endif /* SINGLE_GROUP_LEGACY_API */ - -#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ - - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -NTKERNELAPI -ULONG -NTAPI -KeQueryActiveProcessorCountEx( - IN USHORT GroupNumber); - -NTKERNELAPI -ULONG -NTAPI -KeQueryMaximumProcessorCountEx( - IN USHORT GroupNumber); - -NTKERNELAPI -USHORT -NTAPI -KeQueryActiveGroupCount(VOID); - -NTKERNELAPI -USHORT -NTAPI -KeQueryMaximumGroupCount(VOID); - -NTKERNELAPI -KAFFINITY -NTAPI -KeQueryGroupAffinity( - IN USHORT GroupNumber); - -NTKERNELAPI -ULONG -NTAPI -KeGetCurrentProcessorNumberEx( - OUT PPROCESSOR_NUMBER ProcNumber OPTIONAL); - -NTKERNELAPI -VOID -NTAPI -KeQueryNodeActiveAffinity( - IN USHORT NodeNumber, - OUT PGROUP_AFFINITY Affinity OPTIONAL, - OUT PUSHORT Count OPTIONAL); - -NTKERNELAPI -USHORT -NTAPI -KeQueryNodeMaximumProcessorCount( - IN USHORT NodeNumber); - -NTKERNELAPI -USHORT -NTAPI -KeQueryHighestNodeNumber(VOID); - -NTKERNELAPI -USHORT -NTAPI -KeGetCurrentNodeNumber(VOID); - -NTKERNELAPI -NTSTATUS -NTAPI -KeQueryLogicalProcessorRelationship( - IN PPROCESSOR_NUMBER ProcessorNumber OPTIONAL, - IN LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, - OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Information OPTIONAL, - IN OUT PULONG Length); - -NTKERNELAPI -NTSTATUS -NTAPI -KeSetHardwareCounterConfiguration( - IN PHARDWARE_COUNTER CounterArray, - IN ULONG Count); - -NTKERNELAPI -NTSTATUS -NTAPI -KeQueryHardwareCounterConfiguration( - OUT PHARDWARE_COUNTER CounterArray, - IN ULONG MaximumCount, - OUT PULONG Count); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - - -/****************************************************************************** - * Memory manager Functions * - ******************************************************************************/ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -PPHYSICAL_MEMORY_RANGE -NTAPI -MmGetPhysicalMemoryRanges(VOID); - -NTKERNELAPI -PHYSICAL_ADDRESS -NTAPI -MmGetPhysicalAddress( - IN PVOID BaseAddress); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsNonPagedSystemAddressValid( - IN PVOID VirtualAddress); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateNonCachedMemory( - IN SIZE_T NumberOfBytes); - -NTKERNELAPI -VOID -NTAPI -MmFreeNonCachedMemory( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -NTKERNELAPI -PVOID -NTAPI -MmGetVirtualForPhysical( - IN PHYSICAL_ADDRESS PhysicalAddress); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapUserAddressesToPage( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN PVOID PageAddress); - -NTKERNELAPI -PVOID -NTAPI -MmMapVideoDisplay( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN SIZE_T NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapViewInSessionSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); - -NTKERNELAPI -NTSTATUS -NTAPI -MmMapViewInSystemSpace( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsAddressValid( - IN PVOID VirtualAddress); - -NTKERNELAPI -BOOLEAN -NTAPI -MmIsThisAnNtAsSystem(VOID); - -NTKERNELAPI -VOID -NTAPI -MmLockPagableSectionByHandle( - IN PVOID ImageSectionHandle); - -NTKERNELAPI -NTSTATUS -NTAPI -MmUnmapViewInSessionSpace( - IN PVOID MappedBase); - -NTKERNELAPI -NTSTATUS -NTAPI -MmUnmapViewInSystemSpace( - IN PVOID MappedBase); - -NTKERNELAPI -VOID -NTAPI -MmUnsecureVirtualMemory( - IN HANDLE SecureHandle); - -NTKERNELAPI -NTSTATUS -NTAPI -MmRemovePhysicalMemory( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -NTKERNELAPI -HANDLE -NTAPI -MmSecureVirtualMemory( - IN PVOID Address, - IN SIZE_T Size, - IN ULONG ProbeMode); - -NTKERNELAPI -VOID -NTAPI -MmUnmapVideoDisplay( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes); - -NTKERNELAPI -NTSTATUS -NTAPI -MmAddPhysicalMemory( - IN PPHYSICAL_ADDRESS StartAddress, - IN OUT PLARGE_INTEGER NumberOfBytes); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateContiguousMemory( - IN SIZE_T NumberOfBytes, - IN PHYSICAL_ADDRESS HighestAcceptableAddress); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateContiguousMemorySpecifyCache( - IN SIZE_T NumberOfBytes, - IN PHYSICAL_ADDRESS LowestAcceptableAddress, - IN PHYSICAL_ADDRESS HighestAcceptableAddress, - IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, - IN MEMORY_CACHING_TYPE CacheType); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateContiguousMemorySpecifyCacheNode( - IN SIZE_T NumberOfBytes, - IN PHYSICAL_ADDRESS LowestAcceptableAddress, - IN PHYSICAL_ADDRESS HighestAcceptableAddress, - IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, - IN MEMORY_CACHING_TYPE CacheType, - IN NODE_REQUIREMENT PreferredNode); - -NTKERNELAPI -VOID -NTAPI -MmFreeContiguousMemory( - IN PVOID BaseAddress); - -NTKERNELAPI -VOID -NTAPI -MmFreeContiguousMemorySpecifyCache( - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) - -NTKERNELAPI -NTSTATUS -NTAPI -MmAdvanceMdl( - IN OUT PMDL Mdl, - IN ULONG NumberOfBytes); - -NTKERNELAPI -PVOID -NTAPI -MmAllocateMappingAddress( - IN SIZE_T NumberOfBytes, - IN ULONG PoolTag); - -NTKERNELAPI -VOID -NTAPI -MmFreeMappingAddress( - IN PVOID BaseAddress, - IN ULONG PoolTag); - -NTKERNELAPI -NTSTATUS -NTAPI -MmIsVerifierEnabled( - OUT PULONG VerifierFlags); - -NTKERNELAPI -PVOID -NTAPI -MmMapLockedPagesWithReservedMapping( - IN PVOID MappingAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList, - IN MEMORY_CACHING_TYPE CacheType); - -NTKERNELAPI -NTSTATUS -NTAPI -MmProtectMdlSystemAddress( - IN PMDL MemoryDescriptorList, - IN ULONG NewProtect); - -NTKERNELAPI -VOID -NTAPI -MmUnmapReservedMapping( - IN PVOID BaseAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList); - -NTKERNELAPI -NTSTATUS -NTAPI -MmAddVerifierThunks( - IN PVOID ThunkBuffer, - IN ULONG ThunkBufferSize); - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - -#if (NTDDI_VERSION >= NTDDI_WS03) -NTKERNELAPI -NTSTATUS -NTAPI -MmCreateMirror(VOID); -#endif - - -#if (NTDDI_VERSION >= NTDDI_VISTA) -NTSTATUS -NTAPI -MmRotatePhysicalView( - IN PVOID VirtualAddress, - IN OUT PSIZE_T NumberOfBytes, - IN PMDLX NewMdl OPTIONAL, - IN MM_ROTATE_DIRECTION Direction, - IN PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction, - IN PVOID Context OPTIONAL); - -#endif - -/****************************************************************************** - * Process Manager Functions * - ******************************************************************************/ - -NTSYSCALLAPI -NTSTATUS -NTAPI -NtOpenProcess( - OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId OPTIONAL); - -NTSYSCALLAPI -NTSTATUS -NTAPI -NtQueryInformationProcess( - IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - OUT PVOID ProcessInformation OPTIONAL, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength OPTIONAL); - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetCreateProcessNotifyRoutine( - IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, - IN BOOLEAN Remove); - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -NTSTATUS -NTAPI -PsSetLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -HANDLE -NTAPI -PsGetCurrentProcessId(VOID); - -NTKERNELAPI -HANDLE -NTAPI -PsGetCurrentThreadId(VOID); - -NTKERNELAPI -BOOLEAN -NTAPI -PsGetVersion( - OUT PULONG MajorVersion OPTIONAL, - OUT PULONG MinorVersion OPTIONAL, - OUT PULONG BuildNumber OPTIONAL, - OUT PUNICODE_STRING CSDVersion OPTIONAL); - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -#if (NTDDI_VERSION >= NTDDI_WINXP) - -NTKERNELAPI -HANDLE -NTAPI -PsGetProcessId( - IN PEPROCESS Process); - -NTKERNELAPI -HANDLE -NTAPI -PsGetThreadId( - IN PETHREAD Thread); - -NTKERNELAPI -NTSTATUS -NTAPI -PsRemoveCreateThreadNotifyRoutine( - IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -NTSTATUS -NTAPI -PsRemoveLoadImageNotifyRoutine( - IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); - -NTKERNELAPI -LONGLONG -NTAPI -PsGetProcessCreateTimeQuadPart( - IN PEPROCESS Process); - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - -#if (NTDDI_VERSION >= NTDDI_WS03) -NTKERNELAPI -HANDLE -NTAPI -PsGetThreadProcessId( - IN PETHREAD Thread); -#endif /* (NTDDI_VERSION >= NTDDI_WS03) */ - -#if (NTDDI_VERSION >= NTDDI_VISTA) - -NTKERNELAPI -BOOLEAN -NTAPI -PsSetCurrentThreadPrefetching( - IN BOOLEAN Prefetching); - -NTKERNELAPI -BOOLEAN -NTAPI -PsIsCurrentThreadPrefetching(VOID); - -#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ - -#if (NTDDI_VERSION >= NTDDI_VISTASP1) -NTKERNELAPI -NTSTATUS -NTAPI -PsSetCreateProcessNotifyRoutineEx( - IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine, - IN BOOLEAN Remove); -#endif /* (NTDDI_VERSION >= NTDDI_VISTASP1) */ -/****************************************************************************** - * Runtime Library Functions * - ******************************************************************************/ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - - - -#ifndef RTL_USE_AVL_TABLES - -NTSYSAPI -VOID -NTAPI -RtlInitializeGenericTable( - OUT PRTL_GENERIC_TABLE Table, - IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, - IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, - IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, - IN PVOID TableContext OPTIONAL); - -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTable( - IN PRTL_GENERIC_TABLE Table, - IN PVOID Buffer, - IN CLONG BufferSize, - OUT PBOOLEAN NewElement OPTIONAL); - -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTableFull( - IN PRTL_GENERIC_TABLE Table, - IN PVOID Buffer, - IN CLONG BufferSize, - OUT PBOOLEAN NewElement OPTIONAL, - IN PVOID NodeOrParent, - IN TABLE_SEARCH_RESULT SearchResult); - -NTSYSAPI -BOOLEAN -NTAPI -RtlDeleteElementGenericTable( - IN PRTL_GENERIC_TABLE Table, - IN PVOID Buffer); - -NTSYSAPI -PVOID -NTAPI -RtlLookupElementGenericTable( - IN PRTL_GENERIC_TABLE Table, - IN PVOID Buffer); - -NTSYSAPI -PVOID -NTAPI -RtlLookupElementGenericTableFull( - IN PRTL_GENERIC_TABLE Table, - IN PVOID Buffer, - OUT PVOID *NodeOrParent, - OUT TABLE_SEARCH_RESULT *SearchResult); - -NTSYSAPI -PVOID -NTAPI -RtlEnumerateGenericTable( - IN PRTL_GENERIC_TABLE Table, - IN BOOLEAN Restart); - -NTSYSAPI -PVOID -NTAPI -RtlEnumerateGenericTableWithoutSplaying( - IN PRTL_GENERIC_TABLE Table, - IN OUT PVOID *RestartKey); - -NTSYSAPI -PVOID -NTAPI -RtlGetElementGenericTable( - IN PRTL_GENERIC_TABLE Table, - IN ULONG I); - -NTSYSAPI -ULONG -NTAPI -RtlNumberGenericTableElements( - IN PRTL_GENERIC_TABLE Table); - -NTSYSAPI -BOOLEAN -NTAPI -RtlIsGenericTableEmpty( - IN PRTL_GENERIC_TABLE Table); - -#endif /* !RTL_USE_AVL_TABLES */ - -#define RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT 8 - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlSplay( - IN OUT PRTL_SPLAY_LINKS Links); - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlDelete( - IN PRTL_SPLAY_LINKS Links); - -NTSYSAPI -VOID -NTAPI -RtlDeleteNoSplay( - IN PRTL_SPLAY_LINKS Links, - IN OUT PRTL_SPLAY_LINKS *Root); - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlSubtreeSuccessor( - IN PRTL_SPLAY_LINKS Links); - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlSubtreePredecessor( - IN PRTL_SPLAY_LINKS Links); - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlRealSuccessor( - IN PRTL_SPLAY_LINKS Links); - -NTSYSAPI -PRTL_SPLAY_LINKS -NTAPI -RtlRealPredecessor( - IN PRTL_SPLAY_LINKS Links); - -NTSYSAPI -BOOLEAN -NTAPI -RtlPrefixUnicodeString( - IN PCUNICODE_STRING String1, - IN PCUNICODE_STRING String2, - IN BOOLEAN CaseInSensitive); - -NTSYSAPI -VOID -NTAPI -RtlUpperString( - IN OUT PSTRING DestinationString, - IN const PSTRING SourceString); - -NTSYSAPI -NTSTATUS -NTAPI -RtlUpcaseUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PCUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -NTSYSAPI -VOID -NTAPI -RtlMapGenericMask( - IN OUT PACCESS_MASK AccessMask, - IN PGENERIC_MAPPING GenericMapping); - -NTSYSAPI -NTSTATUS -NTAPI -RtlVolumeDeviceToDosName( - IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName); - -NTSYSAPI -NTSTATUS -NTAPI -RtlGetVersion( - IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); - -NTSYSAPI -NTSTATUS -NTAPI -RtlVerifyVersionInfo( - IN PRTL_OSVERSIONINFOEXW VersionInfo, - IN ULONG TypeMask, - IN ULONGLONG ConditionMask); - -NTSYSAPI -LONG -NTAPI -RtlCompareString( - IN const PSTRING String1, - IN const PSTRING String2, - IN BOOLEAN CaseInSensitive); - -NTSYSAPI -VOID -NTAPI -RtlCopyString( - OUT PSTRING DestinationString, - IN const PSTRING SourceString OPTIONAL); - -NTSYSAPI -BOOLEAN -NTAPI -RtlEqualString( - IN const PSTRING String1, - IN const PSTRING String2, - IN BOOLEAN CaseInSensitive); - -NTSYSAPI -NTSTATUS -NTAPI -RtlCharToInteger( - IN PCSZ String, - IN ULONG Base OPTIONAL, - OUT PULONG Value); - -NTSYSAPI -CHAR -NTAPI -RtlUpperChar( - IN CHAR Character); - -NTSYSAPI -ULONG -NTAPI -RtlWalkFrameChain( - OUT PVOID *Callers, - IN ULONG Count, - IN ULONG Flags); - - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - - -#if (NTDDI_VERSION >= NTDDI_WINXP) - - NTSYSAPI VOID NTAPI @@ -5006,764 +3758,9 @@ RtlInitializeGenericTableAvl( IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext OPTIONAL); -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer, - IN CLONG BufferSize, - OUT PBOOLEAN NewElement OPTIONAL); - -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTableFullAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer, - IN CLONG BufferSize, - OUT PBOOLEAN NewElement OPTIONAL, - IN PVOID NodeOrParent, - IN TABLE_SEARCH_RESULT SearchResult); - -NTSYSAPI -BOOLEAN -NTAPI -RtlDeleteElementGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer); - -NTSYSAPI -PVOID -NTAPI -RtlLookupElementGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer); - -NTSYSAPI -PVOID -NTAPI -RtlLookupElementGenericTableFullAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer, - OUT PVOID *NodeOrParent, - OUT TABLE_SEARCH_RESULT *SearchResult); - -NTSYSAPI -PVOID -NTAPI -RtlEnumerateGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN BOOLEAN Restart); - -NTSYSAPI -PVOID -NTAPI -RtlEnumerateGenericTableWithoutSplayingAvl( - IN PRTL_AVL_TABLE Table, - IN OUT PVOID *RestartKey); - -NTSYSAPI -PVOID -NTAPI -RtlLookupFirstMatchingElementGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN PVOID Buffer, - OUT PVOID *RestartKey); - -NTSYSAPI -PVOID -NTAPI -RtlEnumerateGenericTableLikeADirectory( - IN PRTL_AVL_TABLE Table, - IN PRTL_AVL_MATCH_FUNCTION MatchFunction OPTIONAL, - IN PVOID MatchData OPTIONAL, - IN ULONG NextFlag, - IN OUT PVOID *RestartKey, - IN OUT PULONG DeleteCount, - IN PVOID Buffer); - -NTSYSAPI -PVOID -NTAPI -RtlGetElementGenericTableAvl( - IN PRTL_AVL_TABLE Table, - IN ULONG I); - -NTSYSAPI -ULONG -NTAPI -RtlNumberGenericTableElementsAvl( - IN PRTL_AVL_TABLE Table); - -NTSYSAPI -BOOLEAN -NTAPI -RtlIsGenericTableEmptyAvl( - IN PRTL_AVL_TABLE Table); - - - -#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */ - -#if (NTDDI_VERSION >= NTDDI_VISTA) - - -NTSYSAPI -VOID -NTAPI -RtlRunOnceInitialize( - OUT PRTL_RUN_ONCE RunOnce); - -NTSYSAPI -NTSTATUS -NTAPI -RtlRunOnceExecuteOnce( - IN OUT PRTL_RUN_ONCE RunOnce, - IN PRTL_RUN_ONCE_INIT_FN InitFn, - IN OUT PVOID Parameter OPTIONAL, - OUT PVOID *Context OPTIONAL); - -NTSYSAPI -NTSTATUS -NTAPI -RtlRunOnceBeginInitialize( - IN OUT PRTL_RUN_ONCE RunOnce, - IN ULONG Flags, - OUT PVOID *Context OPTIONAL); - -NTSYSAPI -NTSTATUS -NTAPI -RtlRunOnceComplete( - IN OUT PRTL_RUN_ONCE RunOnce, - IN ULONG Flags, - IN PVOID Context OPTIONAL); - -NTSYSAPI -BOOLEAN -NTAPI -RtlGetProductInfo( - IN ULONG OSMajorVersion, - IN ULONG OSMinorVersion, - IN ULONG SpMajorVersion, - IN ULONG SpMinorVersion, - OUT PULONG ReturnedProductType); - - - -#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ - -#if (NTDDI_VERSION >= NTDDI_WIN7) - - -NTSYSAPI -BOOLEAN -NTAPI -RtlCreateHashTable( - IN OUT PRTL_DYNAMIC_HASH_TABLE *HashTable OPTIONAL, - IN ULONG Shift, - IN ULONG Flags); - -NTSYSAPI -VOID -NTAPI -RtlDeleteHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable); - -NTSYSAPI -BOOLEAN -NTAPI -RtlInsertEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, - IN ULONG_PTR Signature, - IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); - -NTSYSAPI -BOOLEAN -NTAPI -RtlRemoveEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, - IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); - -NTSYSAPI -PRTL_DYNAMIC_HASH_TABLE_ENTRY -NTAPI -RtlLookupEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN ULONG_PTR Signature, - OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); - -NTSYSAPI -PRTL_DYNAMIC_HASH_TABLE_ENTRY -NTAPI -RtlGetNextEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context); - -NTSYSAPI -BOOLEAN -NTAPI -RtlInitEnumerationHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -PRTL_DYNAMIC_HASH_TABLE_ENTRY -NTAPI -RtlEnumerateEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -VOID -NTAPI -RtlEndEnumerationHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -BOOLEAN -NTAPI -RtlInitWeakEnumerationHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -PRTL_DYNAMIC_HASH_TABLE_ENTRY -NTAPI -RtlWeaklyEnumerateEntryHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -VOID -NTAPI -RtlEndWeakEnumerationHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable, - IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); - -NTSYSAPI -BOOLEAN -NTAPI -RtlExpandHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable); - -NTSYSAPI -BOOLEAN -NTAPI -RtlContractHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable); - - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - - -#if defined(_AMD64_) || defined(_IA64_) - - - -//DECLSPEC_DEPRECATED_DDK_WINXP -FORCEINLINE -LARGE_INTEGER -NTAPI_INLINE -RtlLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER Divisor, - OUT PLARGE_INTEGER Remainder OPTIONAL) -{ - LARGE_INTEGER ret; - ret.QuadPart = Dividend.QuadPart / Divisor.QuadPart; - if (Remainder) - Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; - return ret; -} - -#else - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -LARGE_INTEGER -NTAPI -RtlLargeIntegerDivide( - IN LARGE_INTEGER Dividend, - IN LARGE_INTEGER Divisor, - OUT PLARGE_INTEGER Remainder OPTIONAL); -#endif - - -#endif /* defined(_AMD64_) || defined(_IA64_) */ - - - -#ifdef RTL_USE_AVL_TABLES - -#define RtlInitializeGenericTable RtlInitializeGenericTableAvl -#define RtlInsertElementGenericTable RtlInsertElementGenericTableAvl -#define RtlInsertElementGenericTableFull RtlInsertElementGenericTableFullAvl -#define RtlDeleteElementGenericTable RtlDeleteElementGenericTableAvl -#define RtlLookupElementGenericTable RtlLookupElementGenericTableAvl -#define RtlLookupElementGenericTableFull RtlLookupElementGenericTableFullAvl -#define RtlEnumerateGenericTable RtlEnumerateGenericTableAvl -#define RtlEnumerateGenericTableWithoutSplaying RtlEnumerateGenericTableWithoutSplayingAvl -#define RtlGetElementGenericTable RtlGetElementGenericTableAvl -#define RtlNumberGenericTableElements RtlNumberGenericTableElementsAvl -#define RtlIsGenericTableEmpty RtlIsGenericTableEmptyAvl - -#endif /* RTL_USE_AVL_TABLES */ - -#define RtlInitializeSplayLinks(Links) { \ - PRTL_SPLAY_LINKS _SplayLinks; \ - _SplayLinks = (PRTL_SPLAY_LINKS)(Links); \ - _SplayLinks->Parent = _SplayLinks; \ - _SplayLinks->LeftChild = NULL; \ - _SplayLinks->RightChild = NULL; \ -} - -#define RtlIsLeftChild(Links) \ - (RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) - -#define RtlIsRightChild(Links) \ - (RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) - -#define RtlRightChild(Links) \ - ((PRTL_SPLAY_LINKS)(Links))->RightChild - -#define RtlIsRoot(Links) \ - (RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)) - -#define RtlLeftChild(Links) \ - ((PRTL_SPLAY_LINKS)(Links))->LeftChild - -#define RtlParent(Links) \ - ((PRTL_SPLAY_LINKS)(Links))->Parent - -#define RtlInsertAsLeftChild(ParentLinks,ChildLinks) \ - { \ - PRTL_SPLAY_LINKS _SplayParent; \ - PRTL_SPLAY_LINKS _SplayChild; \ - _SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \ - _SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \ - _SplayParent->LeftChild = _SplayChild; \ - _SplayChild->Parent = _SplayParent; \ - } - -#define RtlInsertAsRightChild(ParentLinks,ChildLinks) \ - { \ - PRTL_SPLAY_LINKS _SplayParent; \ - PRTL_SPLAY_LINKS _SplayChild; \ - _SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \ - _SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \ - _SplayParent->RightChild = _SplayChild; \ - _SplayChild->Parent = _SplayParent; \ - } - -#if !defined(MIDL_PASS) - -FORCEINLINE -LUID -NTAPI_INLINE -RtlConvertLongToLuid( - IN LONG Val) -{ - LUID Luid; - LARGE_INTEGER Temp; - - Temp.QuadPart = Val; - Luid.LowPart = Temp.u.LowPart; - Luid.HighPart = Temp.u.HighPart; - return Luid; -} - -FORCEINLINE -LUID -NTAPI_INLINE -RtlConvertUlongToLuid( - IN ULONG Val) -{ - LUID Luid; - - Luid.LowPart = Val; - Luid.HighPart = 0; - return Luid; -} - -#endif /* !defined(MIDL_PASS) */ - -#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_) -#define RtlGetCallersAddress(CallersAddress, CallersCaller) \ - *CallersAddress = (PVOID)_ReturnAddress(); \ - *CallersCaller = NULL; -#else -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -VOID -NTAPI -RtlGetCallersAddress( - OUT PVOID *CallersAddress, - OUT PVOID *CallersCaller); -#endif -#endif - -#if !defined(MIDL_PASS) && !defined(SORTPP_PASS) - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -FORCEINLINE -VOID -NTAPI -RtlInitHashTableContext( - IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) -{ - Context->ChainHead = NULL; - Context->PrevLinkage = NULL; -} - -FORCEINLINE -VOID -NTAPI -RtlInitHashTableContextFromEnumerator( - IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context, - IN PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator) -{ - Context->ChainHead = Enumerator->ChainHead; - Context->PrevLinkage = Enumerator->HashEntry.Linkage.Blink; -} - -FORCEINLINE -VOID -NTAPI -RtlReleaseHashTableContext( - IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) -{ - UNREFERENCED_PARAMETER(Context); - return; -} - -FORCEINLINE -ULONG -NTAPI -RtlTotalBucketsHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable) -{ - return HashTable->TableSize; -} - -FORCEINLINE -ULONG -NTAPI -RtlNonEmptyBucketsHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable) -{ - return HashTable->NonEmptyBuckets; -} - -FORCEINLINE -ULONG -NTAPI -RtlEmptyBucketsHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable) -{ - return HashTable->TableSize - HashTable->NonEmptyBuckets; -} - -FORCEINLINE -ULONG -NTAPI -RtlTotalEntriesHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable) -{ - return HashTable->NumEntries; -} - -FORCEINLINE -ULONG -NTAPI -RtlActiveEnumeratorsHashTable( - IN PRTL_DYNAMIC_HASH_TABLE HashTable) -{ - return HashTable->NumEnumerators; -} - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - -#endif /* !defined(MIDL_PASS) && !defined(SORTPP_PASS) */ - -/****************************************************************************** - * Security Manager Functions * - ******************************************************************************/ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -BOOLEAN -NTAPI -SeSinglePrivilegeCheck( - IN LUID PrivilegeValue, - IN KPROCESSOR_MODE PreviousMode); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - -/****************************************************************************** - * ZwXxx Functions * - ******************************************************************************/ - - - -NTSYSAPI -NTSTATUS -NTAPI -ZwAllocateLocallyUniqueId( - OUT PLUID Luid); - -NTSYSAPI -NTSTATUS -NTAPI -ZwTerminateProcess( - IN HANDLE ProcessHandle OPTIONAL, - IN NTSTATUS ExitStatus); - -NTSYSAPI -NTSTATUS -NTAPI -ZwOpenProcess( - OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId OPTIONAL); - - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - - -NTSTATUS -NTAPI -ZwCancelTimer( - IN HANDLE TimerHandle, - OUT PBOOLEAN CurrentState OPTIONAL); - -NTSTATUS -NTAPI -ZwCreateTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN TIMER_TYPE TimerType); - -NTSTATUS -NTAPI -ZwOpenTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -NTSYSAPI -NTSTATUS -NTAPI -ZwSetInformationThread( - IN HANDLE ThreadHandle, - IN THREADINFOCLASS ThreadInformationClass, - IN PVOID ThreadInformation, - IN ULONG ThreadInformationLength); - -NTSTATUS -NTAPI -ZwSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, - IN PVOID TimerContext OPTIONAL, - IN BOOLEAN ResumeTimer, - IN LONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL); - -NTSYSAPI -NTSTATUS -NTAPI -ZwDisplayString( - IN PUNICODE_STRING String); - -NTSYSAPI -NTSTATUS -NTAPI -ZwPowerInformation( - IN POWER_INFORMATION_LEVEL PowerInformationLevel, - IN PVOID InputBuffer OPTIONAL, - IN ULONG InputBufferLength, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength); - -NTSYSAPI -NTSTATUS -NTAPI -ZwQueryVolumeInformationFile( - IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID FsInformation, - IN ULONG Length, - IN FS_INFORMATION_CLASS FsInformationClass); - -NTSYSAPI -NTSTATUS -NTAPI -ZwDeviceIoControlFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG IoControlCode, - IN PVOID InputBuffer OPTIONAL, - IN ULONG InputBufferLength, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength); - - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ - - -#if (NTDDI_VERSION >= NTDDI_WIN7) - -NTSTATUS -NTAPI -ZwSetTimerEx( - IN HANDLE TimerHandle, - IN TIMER_SET_INFORMATION_CLASS TimerSetInformationClass, - IN OUT PVOID TimerSetInformation, - IN ULONG TimerSetInformationLength); - - -#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ - - - -/* UNSORTED */ - -#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType) \ - ((ConditionMask) = VerSetConditionMask((ConditionMask), \ - (TypeBitMask), (ComparisonType))) - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTSYSAPI -ULONGLONG -NTAPI -VerSetConditionMask( - IN ULONGLONG ConditionMask, - IN ULONG TypeMask, - IN UCHAR Condition); -#endif - -typedef struct _KERNEL_USER_TIMES { - LARGE_INTEGER CreateTime; - LARGE_INTEGER ExitTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; -} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES; - -/* NtXxx Functions */ - -typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION { - SystemFirmwareTable_Enumerate, - SystemFirmwareTable_Get -} SYSTEM_FIRMWARE_TABLE_ACTION; - -typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION { - ULONG ProviderSignature; - SYSTEM_FIRMWARE_TABLE_ACTION Action; - ULONG TableID; - ULONG TableBufferLength; - UCHAR TableBuffer[ANYSIZE_ARRAY]; -} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION; - -typedef NTSTATUS -(__cdecl *PFNFTH)( - IN OUT PSYSTEM_FIRMWARE_TABLE_INFORMATION SystemFirmwareTableInfo); - -typedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER { - ULONG ProviderSignature; - BOOLEAN Register; - PFNFTH FirmwareTableHandler; - PVOID DriverObject; -} SYSTEM_FIRMWARE_TABLE_HANDLER, *PSYSTEM_FIRMWARE_TABLE_HANDLER; - -typedef ULONG_PTR -(NTAPI *PDRIVER_VERIFIER_THUNK_ROUTINE)( - IN PVOID Context); - -typedef struct _DRIVER_VERIFIER_THUNK_PAIRS { - PDRIVER_VERIFIER_THUNK_ROUTINE PristineRoutine; - PDRIVER_VERIFIER_THUNK_ROUTINE NewRoutine; -} DRIVER_VERIFIER_THUNK_PAIRS, *PDRIVER_VERIFIER_THUNK_PAIRS; - -#define DRIVER_VERIFIER_SPECIAL_POOLING 0x0001 -#define DRIVER_VERIFIER_FORCE_IRQL_CHECKING 0x0002 -#define DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES 0x0004 -#define DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS 0x0008 -#define DRIVER_VERIFIER_IO_CHECKING 0x0010 - -#define SHARED_GLOBAL_FLAGS_ERROR_PORT_V 0x0 -#define SHARED_GLOBAL_FLAGS_ERROR_PORT (1UL << SHARED_GLOBAL_FLAGS_ERROR_PORT_V) - -#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V 0x1 -#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED (1UL << SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V) - -#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V 0x2 -#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED (1UL << SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V) - -#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V 0x3 -#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED \ - (1UL << SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V) - -#define SHARED_GLOBAL_FLAGS_SPARE_V 0x4 -#define SHARED_GLOBAL_FLAGS_SPARE \ - (1UL << SHARED_GLOBAL_FLAGS_SPARE_V) - -#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V 0x5 -#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED \ - (1UL << SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V) - -#define SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED_V 0x6 -#define SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED \ - (1UL << SHARED_GLOBAL_FLAGS_SEH_VALIDATION_ENABLED_V) - -#define EX_INIT_BITS(Flags, Bit) \ - *((Flags)) |= (Bit) // Safe to use before concurrently accessible - -#define EX_TEST_SET_BIT(Flags, Bit) \ - InterlockedBitTestAndSet ((PLONG)(Flags), (Bit)) - -#define EX_TEST_CLEAR_BIT(Flags, Bit) \ - InterlockedBitTestAndReset ((PLONG)(Flags), (Bit)) - -#define PCCARD_MAP_ERROR 0x01 -#define PCCARD_DEVICE_PCI 0x10 - -#define PCCARD_SCAN_DISABLED 0x01 -#define PCCARD_MAP_ZERO 0x02 -#define PCCARD_NO_TIMER 0x03 -#define PCCARD_NO_PIC 0x04 -#define PCCARD_NO_LEGACY_BASE 0x05 -#define PCCARD_DUP_LEGACY_BASE 0x06 -#define PCCARD_NO_CONTROLLERS 0x07 - -#define MAXIMUM_EXPANSION_SIZE (KERNEL_LARGE_STACK_SIZE - (PAGE_SIZE / 2)) - -/* Filesystem runtime library routines */ - -#if (NTDDI_VERSION >= NTDDI_WIN2K) -NTKERNELAPI -BOOLEAN -NTAPI -FsRtlIsTotalDeviceFailure( - IN NTSTATUS Status); -#endif - -/* FIXME : These definitions below doesn't belong to NTDDK */ - #ifdef __cplusplus } #endif + + +#endif /* _NTDDK_ */ From 0d06145871de5ce59b65af191447143f3507400c Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Fri, 4 Jun 2010 06:36:12 +0000 Subject: [PATCH 217/292] [KERNEL32], [WIN32CSR] - Make Get/SetConsoleTitle more compatible with windows; in particular, transfer title via capture buffer to allow for longer titles. - Tighten up capture buffer validation in win32csr. svn path=/trunk/; revision=47562 --- reactos/dll/win32/kernel32/misc/console.c | 202 +++++++----------- reactos/include/reactos/subsys/csrss/csrss.h | 9 +- .../subsystems/win32/csrss/win32csr/alias.c | 32 +-- .../win32/csrss/win32csr/coninput.c | 10 +- .../win32/csrss/win32csr/conoutput.c | 15 +- .../subsystems/win32/csrss/win32csr/console.c | 46 ++-- .../subsystems/win32/csrss/win32csr/dllmain.c | 26 +++ .../win32/csrss/win32csr/win32csr.h | 4 + 8 files changed, 151 insertions(+), 193 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index aaf48ac882f..17e1e51e30c 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -3418,6 +3418,64 @@ GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, } +static DWORD +IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); + NTSTATUS Status; + + if (nSize == 0) + return 0; + + Request.Data.GetTitleRequest.Length = nSize * (bUnicode ? 1 : sizeof(WCHAR)); + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.GetTitleRequest.Length); + if (CaptureBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + CsrAllocateMessagePointer(CaptureBuffer, + Request.Data.GetTitleRequest.Length, + (PVOID*)&Request.Data.GetTitleRequest.Title); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status))) + { + CsrFreeCaptureBuffer(CaptureBuffer); + SetLastErrorByStatus(Status); + return 0; + } + + if (bUnicode) + { + if (nSize >= sizeof(WCHAR)) + wcscpy((LPWSTR)lpConsoleTitle, Request.Data.GetTitleRequest.Title); + } + else + { + if (nSize < Request.Data.GetTitleRequest.Length / sizeof(WCHAR) || + !WideCharToMultiByte(CP_ACP, // ANSI code page + 0, // performance and mapping flags + Request.Data.GetTitleRequest.Title, // address of wide-character string + -1, // number of characters in string + (LPSTR)lpConsoleTitle, // address of buffer for new string + nSize, // size of buffer + NULL, // FAST + NULL)) + { + /* Yes, if the buffer isn't big enough, it returns 0... Bad API */ + *(LPSTR)lpConsoleTitle = '\0'; + Request.Data.GetTitleRequest.Length = 0; + } + } + CsrFreeCaptureBuffer(CaptureBuffer); + + return Request.Data.GetTitleRequest.Length / sizeof(WCHAR); +} + /*-------------------------------------------------------------- * GetConsoleTitleW * @@ -3428,49 +3486,9 @@ WINAPI GetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (Request == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); - - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status))) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return 0; - } - - if (nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length) - { - nSize--; - } - else - { - nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR); - } - memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR)); - lpConsoleTitle[nSize] = L'\0'; - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return nSize; + return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE); } - /*-------------------------------------------------------------- * GetConsoleTitleA * @@ -3483,28 +3501,7 @@ WINAPI GetConsoleTitleA(LPSTR lpConsoleTitle, DWORD nSize) { - WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1]; - DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1; - DWORD nWritten; - - if (!lpConsoleTitle || !nSize) return 0; - nWideTitle = GetConsoleTitleW((LPWSTR) WideTitle, nWideTitle); - if (!nWideTitle) return 0; - - if ((nWritten = WideCharToMultiByte(CP_ACP, // ANSI code page - 0, // performance and mapping flags - (LPWSTR) WideTitle, // address of wide-character string - nWideTitle, // number of characters in string - lpConsoleTitle, // address of buffer for new string - nSize - 1, // size of buffer - NULL, // FAST - NULL))) // FAST - { - lpConsoleTitle[nWritten] = '\0'; - return nWritten; - } - - return 0; + return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE); } @@ -3517,41 +3514,33 @@ BOOL WINAPI SetConsoleTitleW(LPCWSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); NTSTATUS Status; - unsigned int c; - Request = RtlAllocateHeap(RtlGetProcessHeap(), 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + Request.Data.SetTitleRequest.Length = wcslen(lpConsoleTitle) * sizeof(WCHAR); + + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.SetTitleRequest.Length); + if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)lpConsoleTitle, + Request.Data.SetTitleRequest.Length, + (PVOID*)&Request.Data.SetTitleRequest.Title); - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); SetLastErrorByStatus(Status); - return(FALSE); + return FALSE; } - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - return TRUE; } @@ -3567,43 +3556,18 @@ BOOL WINAPI SetConsoleTitleA(LPCSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - unsigned int c; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + ULONG Length = strlen(lpConsoleTitle) + 1; + LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); + BOOL Ret; + if (!WideTitle) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - - CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); - - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return(FALSE); - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return TRUE; + MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length); + Ret = SetConsoleTitleW(WideTitle); + HeapFree(GetProcessHeap(), 0, WideTitle); + return Ret; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 0b707582f6f..df1e971682b 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -207,13 +207,13 @@ typedef struct typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_SET_TITLE, *PCSRSS_SET_TITLE; typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_GET_TITLE, *PCSRSS_GET_TITLE; typedef struct @@ -487,11 +487,6 @@ typedef struct #define CSRSS_MAX_READ_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) -#define CSRSS_MAX_GET_PROCESS_LIST (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)) - -/* WCHARs, not bytes! */ -#define CSRSS_MAX_TITLE_LENGTH 80 -#define CSRSS_MAX_ALIAS_TARGET_LENGTH 80 #define CREATE_PROCESS (0x0) #define TERMINATE_PROCESS (0x1) diff --git a/reactos/subsystems/win32/csrss/win32csr/alias.c b/reactos/subsystems/win32/csrss/win32csr/alias.c index 569948a4f41..74159544440 100644 --- a/reactos/subsystems/win32/csrss/win32csr/alias.c +++ b/reactos/subsystems/win32/csrss/win32csr/alias.c @@ -31,21 +31,6 @@ typedef struct tagALIAS_HEADER } ALIAS_HEADER, *PALIAS_HEADER; -/* Ensure that a buffer is contained within the process's shared memory section. */ -static BOOL -ValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, ULONG Size) -{ - ULONG Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || Size > (ProcessData->CsrSectionViewSize - Offset)) - { - DPRINT1("Invalid buffer %p %d; not within %p %d\n", - Buffer, Size, ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); - return FALSE; - } - return TRUE; -} - static PALIAS_HEADER IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName) @@ -415,7 +400,8 @@ CSR_API(CsrGetConsoleAlias) return STATUS_BUFFER_TOO_SMALL; } - if (!ValidateBuffer(ProcessData, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, lpTarget, + Request->Data.GetConsoleAlias.TargetBufferLength, 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -457,9 +443,10 @@ CSR_API(CsrGetAllConsoleAliases) return STATUS_BUFFER_OVERFLOW; } - if (!ValidateBuffer(ProcessData, - Request->Data.GetAllConsoleAlias.AliasBuffer, - Request->Data.GetAllConsoleAlias.AliasBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetAllConsoleAlias.AliasBuffer, + Request->Data.GetAllConsoleAlias.AliasBufferLength, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -532,9 +519,10 @@ CSR_API(CsrGetConsoleAliasesExes) return STATUS_INVALID_PARAMETER; } - if (!ValidateBuffer(ProcessData, - Request->Data.GetConsoleAliasesExes.ExeNames, - Request->Data.GetConsoleAliasesExes.Length)) + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetConsoleAliasesExes.ExeNames, + Request->Data.GetConsoleAliasesExes.Length, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index 8b3c8849950..eb1781baa8a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -678,7 +678,6 @@ CSR_API(CsrPeekConsoleInput) { NTSTATUS Status; PCSRSS_CONSOLE Console; - DWORD Size; DWORD Length; PLIST_ENTRY CurrentItem; PINPUT_RECORD InputRecord; @@ -698,10 +697,8 @@ CSR_API(CsrPeekConsoleInput) InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; Length = Request->Data.PeekConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -749,7 +746,6 @@ CSR_API(CsrWriteConsoleInput) PCSRSS_CONSOLE Console; NTSTATUS Status; DWORD Length; - DWORD Size; DWORD i; ConsoleInput* Record; @@ -766,10 +762,8 @@ CSR_API(CsrWriteConsoleInput) InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; Length = Request->Data.WriteConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; diff --git a/reactos/subsystems/win32/csrss/win32csr/conoutput.c b/reactos/subsystems/win32/csrss/win32csr/conoutput.c index b401ca23abd..6b2a3a38358 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conoutput.c +++ b/reactos/subsystems/win32/csrss/win32csr/conoutput.c @@ -1084,7 +1084,6 @@ CSR_API(CsrWriteConsoleOutput) COORD BufferSize; NTSTATUS Status; PBYTE Ptr; - DWORD PSize; DPRINT("CsrWriteConsoleOutput\n"); @@ -1101,12 +1100,10 @@ CSR_API(CsrWriteConsoleOutput) Console = Buff->Header.Console; BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; - PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || - (((ULONG_PTR)CharInfo + PSize) > - ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) { ConioUnlockScreenBuffer(Buff); return STATUS_ACCESS_VIOLATION; @@ -1395,8 +1392,6 @@ CSR_API(CsrReadConsoleOutput) PCHAR_INFO CharInfo; PCHAR_INFO CurCharInfo; PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - DWORD Length; DWORD SizeX, SizeY; NTSTATUS Status; COORD BufferSize; @@ -1423,14 +1418,12 @@ CSR_API(CsrReadConsoleOutput) ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; - Length = BufferSize.X * BufferSize.Y; - Size = Length * sizeof(CHAR_INFO); /* FIXME: Is this correct? */ CodePage = ProcessData->Console->OutputCodePage; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) { ConioUnlockScreenBuffer(Buff); return STATUS_ACCESS_VIOLATION; diff --git a/reactos/subsystems/win32/csrss/win32csr/console.c b/reactos/subsystems/win32/csrss/win32csr/console.c index 8b6d4d7e6f4..57a1a0f573e 100644 --- a/reactos/subsystems/win32/csrss/win32csr/console.c +++ b/reactos/subsystems/win32/csrss/win32csr/console.c @@ -455,19 +455,15 @@ CSR_API(CsrSetTitle) DPRINT("CsrSetTitle\n"); - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) - + Request->Data.SetTitleRequest.Length) + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title, + Request->Data.SetTitleRequest.Length, 1)) { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; + return STATUS_ACCESS_VIOLATION; } Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); if(NT_SUCCESS(Status)) { Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); @@ -507,6 +503,13 @@ CSR_API(CsrGetTitle) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title, + Request->Data.GetTitleRequest.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status)) { @@ -515,19 +518,16 @@ CSR_API(CsrGetTitle) } /* Copy title of the console to the user title buffer */ - RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); + if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR)) + { + Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length); + memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length); + Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0'; + } + Request->Data.GetTitleRequest.Length = Console->Title.Length; - memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, - Console->Title.Length); - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; ConioUnlockConsole(Console); - - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } return STATUS_SUCCESS; } @@ -754,7 +754,6 @@ CSR_API(CsrGetProcessList) PLIST_ENTRY current_entry; ULONG nItems = 0; NTSTATUS Status; - ULONG_PTR Offset; DPRINT("CsrGetProcessList\n"); @@ -762,13 +761,8 @@ CSR_API(CsrGetProcessList) Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Buffer = Request->Data.GetProcessListRequest.ProcessId; - Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) - || Offset & (sizeof(DWORD) - 1)) - { + if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD))) return STATUS_ACCESS_VIOLATION; - } Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status)) diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 640f0fb163e..009303ea811 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -100,6 +100,32 @@ DllMain(HANDLE hDll, return TRUE; } +/* Ensure that a captured buffer is safe to access */ +BOOL FASTCALL +Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, + SIZE_T NumElements, SIZE_T ElementSize) +{ + /* Check that the following conditions are true: + * 1. The start of the buffer is somewhere within the process's + * shared memory section view. + * 2. The remaining space in the view is at least as large as the buffer. + * (NB: Please don't try to "optimize" this by using multiplication + * instead of division; remember that 2147483648 * 2 = 0.) + * 3. The buffer is DWORD-aligned. + */ + ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || NumElements > (ProcessData->CsrSectionViewSize - Offset) / ElementSize + || (Offset & (sizeof(DWORD) - 1)) != 0) + { + DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n", + Buffer, NumElements, ElementSize, + ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); + return FALSE; + } + return TRUE; +} + NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h index 111c27db80a..0417740984e 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.h @@ -63,6 +63,10 @@ CSR_API(CsrVerifyHandle); CSR_API(CsrDuplicateHandle); CSR_API(CsrGetInputWaitHandle); +BOOL FASTCALL Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, + PVOID Buffer, + SIZE_T NumElements, + SIZE_T ElementSize); NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); From 32f5fc6eab6ecd8e3b2ccdb5ce752dbd2a5ee3cb Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 10:17:55 +0000 Subject: [PATCH 218/292] [HAL] - Move memory functions from halinit.c to new memory.c - HalpAllocPhysicalMemory: MemoryFirmwareTemporary -> LoaderFirmwareTemporary (same value, different enum) svn path=/trunk/; revision=47563 --- reactos/hal/halx86/generic/halinit.c | 213 ----------------------- reactos/hal/halx86/generic/memory.c | 234 ++++++++++++++++++++++++++ reactos/hal/halx86/hal_generic.rbuild | 5 +- 3 files changed, 237 insertions(+), 215 deletions(-) create mode 100644 reactos/hal/halx86/generic/memory.c diff --git a/reactos/hal/halx86/generic/halinit.c b/reactos/hal/halx86/generic/halinit.c index db54eb59d63..6a6b1660694 100644 --- a/reactos/hal/halx86/generic/halinit.c +++ b/reactos/hal/halx86/generic/halinit.c @@ -14,223 +14,10 @@ /* GLOBALS *******************************************************************/ -/* Share with Mm headers? */ -#define MM_HAL_VA_START (PVOID)0xFFC00000 -#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024)) - BOOLEAN HalpPciLockSettings; -ULONG HalpUsedAllocDescriptors; -MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]; -PVOID HalpHeapStart = MM_HAL_HEAP_START; /* PRIVATE FUNCTIONS *********************************************************/ -ULONG -NTAPI -HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, - IN ULONG MaxAddress, - IN ULONG PageCount, - IN BOOLEAN Aligned) -{ - ULONG UsedDescriptors, Alignment, PhysicalAddress; - PFN_NUMBER MaxPage, BasePage; - PLIST_ENTRY NextEntry; - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock; - - /* Highest page we'll go */ - MaxPage = MaxAddress >> PAGE_SHIFT; - - /* We need at least two blocks */ - if ((HalpUsedAllocDescriptors + 2) > 64) return 0; - - /* Remember how many we have now */ - UsedDescriptors = HalpUsedAllocDescriptors; - - /* Loop the loader block memory descriptors */ - NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) - { - /* Get the block */ - MdBlock = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* No alignment by default */ - Alignment = 0; - - /* Unless requested, in which case we use a 64KB block alignment */ - if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage; - - /* Search for free memory */ - if ((MdBlock->MemoryType == LoaderFree) || - (MdBlock->MemoryType == MemoryFirmwareTemporary)) - { - /* Make sure the page is within bounds, including alignment */ - BasePage = MdBlock->BasePage; - if ((BasePage) && - (MdBlock->PageCount >= PageCount + Alignment) && - (BasePage + PageCount + Alignment < MaxPage)) - { - - /* We found an address */ - PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT; - break; - } - } - - /* Keep trying */ - NextEntry = NextEntry->Flink; - } - - /* If we didn't find anything, get out of here */ - if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0; - - /* Okay, now get a descriptor */ - NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors]; - NewBlock->PageCount = PageCount; - NewBlock->BasePage = MdBlock->BasePage + Alignment; - NewBlock->MemoryType = LoaderHALCachedMemory; - - /* Update count */ - UsedDescriptors++; - HalpUsedAllocDescriptors = UsedDescriptors; - - /* Check if we had any alignment */ - if (Alignment) - { - /* Check if we had leftovers */ - if ((MdBlock->PageCount - Alignment) != PageCount) - { - /* Get the next descriptor */ - FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors]; - FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount; - FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount; - - /* One more */ - HalpUsedAllocDescriptors++; - - /* Insert it into the list */ - InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry); - } - - /* Use this descriptor */ - NewBlock->PageCount = Alignment; - InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry); - } - else - { - /* Consume memory from this block */ - MdBlock->BasePage += PageCount; - MdBlock->PageCount -= PageCount; - - /* Insert the descriptor */ - InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry); - - /* Remove the entry if the whole block was allocated */ - if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry); - } - - /* Return the address */ - return PhysicalAddress; -} - -PVOID -NTAPI -HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG PageCount) -{ - PHARDWARE_PTE PointerPte; - ULONG UsedPages = 0; - PVOID VirtualAddress, BaseAddress; - - /* Start at the current HAL heap base */ - BaseAddress = HalpHeapStart; - VirtualAddress = BaseAddress; - - /* Loop until we have all the pages required */ - while (UsedPages < PageCount) - { - /* If this overflows past the HAL heap, it means there's no space */ - if (VirtualAddress == NULL) return NULL; - - /* Get the PTE for this address */ - PointerPte = HalAddressToPte(VirtualAddress); - - /* Go to the next page */ - VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); - - /* Check if the page is available */ - if (PointerPte->Valid) - { - /* PTE has data, skip it and start with a new base address */ - BaseAddress = VirtualAddress; - UsedPages = 0; - continue; - } - - /* PTE is available, keep going on this run */ - UsedPages++; - } - - /* Take the base address of the page plus the actual offset in the address */ - VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress + - BYTE_OFFSET(PhysicalAddress.LowPart)); - - /* If we are starting at the heap, move the heap */ - if (BaseAddress == HalpHeapStart) - { - /* Past this allocation */ - HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE)); - } - - /* Loop pages that can be mapped */ - while (UsedPages--) - { - /* Fill out the PTE */ - PointerPte = HalAddressToPte(BaseAddress); - PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT; - PointerPte->Valid = 1; - PointerPte->Write = 1; - - /* Move to the next address */ - PhysicalAddress.QuadPart += PAGE_SIZE; - BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE); - } - - /* Flush the TLB and return the address */ - HalpFlushTLB(); - return VirtualAddress; -} - -VOID -NTAPI -HalpUnmapVirtualAddress(IN PVOID VirtualAddress, - IN ULONG PageCount) -{ - PHARDWARE_PTE PointerPte; - ULONG i; - - /* Only accept valid addresses */ - if (VirtualAddress < MM_HAL_VA_START) return; - - /* Align it down to page size */ - VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1)); - - /* Loop PTEs */ - PointerPte = HalAddressToPte(VirtualAddress); - for (i = 0; i < PageCount; i++) - { - *(PULONG)PointerPte = 0; - PointerPte++; - } - - /* Flush the TLB */ - HalpFlushTLB(); - - /* Put the heap back */ - if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress; -} - VOID NTAPI HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock) diff --git a/reactos/hal/halx86/generic/memory.c b/reactos/hal/halx86/generic/memory.c new file mode 100644 index 00000000000..74f20cbc6ed --- /dev/null +++ b/reactos/hal/halx86/generic/memory.c @@ -0,0 +1,234 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/memory.c + * PURPOSE: HAL memory management + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* Share with Mm headers? */ +#define MM_HAL_VA_START (PVOID)0xFFC00000 +#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024)) + +/* GLOBALS *******************************************************************/ + +ULONG HalpUsedAllocDescriptors; +MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]; +PVOID HalpHeapStart = MM_HAL_HEAP_START; + + +/* PRIVATE FUNCTIONS *********************************************************/ + + +ULONG +NTAPI +HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG MaxAddress, + IN ULONG PageCount, + IN BOOLEAN Aligned) +{ + ULONG UsedDescriptors, Alignment, PhysicalAddress; + PFN_NUMBER MaxPage, BasePage; + PLIST_ENTRY NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock; + + /* Highest page we'll go */ + MaxPage = MaxAddress >> PAGE_SHIFT; + + /* We need at least two blocks */ + if ((HalpUsedAllocDescriptors + 2) > 64) return 0; + + /* Remember how many we have now */ + UsedDescriptors = HalpUsedAllocDescriptors; + + /* Loop the loader block memory descriptors */ + NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) + { + /* Get the block */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* No alignment by default */ + Alignment = 0; + + /* Unless requested, in which case we use a 64KB block alignment */ + if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage; + + /* Search for free memory */ + if ((MdBlock->MemoryType == LoaderFree) || + (MdBlock->MemoryType == LoaderFirmwareTemporary)) + { + /* Make sure the page is within bounds, including alignment */ + BasePage = MdBlock->BasePage; + if ((BasePage) && + (MdBlock->PageCount >= PageCount + Alignment) && + (BasePage + PageCount + Alignment < MaxPage)) + { + + /* We found an address */ + PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT; + break; + } + } + + /* Keep trying */ + NextEntry = NextEntry->Flink; + } + + /* If we didn't find anything, get out of here */ + if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0; + + /* Okay, now get a descriptor */ + NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors]; + NewBlock->PageCount = PageCount; + NewBlock->BasePage = MdBlock->BasePage + Alignment; + NewBlock->MemoryType = LoaderHALCachedMemory; + + /* Update count */ + UsedDescriptors++; + HalpUsedAllocDescriptors = UsedDescriptors; + + /* Check if we had any alignment */ + if (Alignment) + { + /* Check if we had leftovers */ + if ((MdBlock->PageCount - Alignment) != PageCount) + { + /* Get the next descriptor */ + FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors]; + FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount; + FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount; + + /* One more */ + HalpUsedAllocDescriptors++; + + /* Insert it into the list */ + InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry); + } + + /* Use this descriptor */ + NewBlock->PageCount = Alignment; + InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry); + } + else + { + /* Consume memory from this block */ + MdBlock->BasePage += PageCount; + MdBlock->PageCount -= PageCount; + + /* Insert the descriptor */ + InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry); + + /* Remove the entry if the whole block was allocated */ + if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry); + } + + /* Return the address */ + return PhysicalAddress; +} + +PVOID +NTAPI +HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG PageCount) +{ + PHARDWARE_PTE PointerPte; + ULONG UsedPages = 0; + PVOID VirtualAddress, BaseAddress; + + /* Start at the current HAL heap base */ + BaseAddress = HalpHeapStart; + VirtualAddress = BaseAddress; + + /* Loop until we have all the pages required */ + while (UsedPages < PageCount) + { + /* If this overflows past the HAL heap, it means there's no space */ + if (VirtualAddress == NULL) return NULL; + + /* Get the PTE for this address */ + PointerPte = HalAddressToPte(VirtualAddress); + + /* Go to the next page */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + + /* Check if the page is available */ + if (PointerPte->Valid) + { + /* PTE has data, skip it and start with a new base address */ + BaseAddress = VirtualAddress; + UsedPages = 0; + continue; + } + + /* PTE is available, keep going on this run */ + UsedPages++; + } + + /* Take the base address of the page plus the actual offset in the address */ + VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress + + BYTE_OFFSET(PhysicalAddress.LowPart)); + + /* If we are starting at the heap, move the heap */ + if (BaseAddress == HalpHeapStart) + { + /* Past this allocation */ + HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE)); + } + + /* Loop pages that can be mapped */ + while (UsedPages--) + { + /* Fill out the PTE */ + PointerPte = HalAddressToPte(BaseAddress); + PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT; + PointerPte->Valid = 1; + PointerPte->Write = 1; + + /* Move to the next address */ + PhysicalAddress.QuadPart += PAGE_SIZE; + BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE); + } + + /* Flush the TLB and return the address */ + HalpFlushTLB(); + return VirtualAddress; +} + +VOID +NTAPI +HalpUnmapVirtualAddress(IN PVOID VirtualAddress, + IN ULONG PageCount) +{ + PHARDWARE_PTE PointerPte; + ULONG i; + + /* Only accept valid addresses */ + if (VirtualAddress < MM_HAL_VA_START) return; + + /* Align it down to page size */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1)); + + /* Loop PTEs */ + PointerPte = HalAddressToPte(VirtualAddress); + for (i = 0; i < PageCount; i++) + { + *(PULONG)PointerPte = 0; + PointerPte++; + } + + /* Flush the TLB */ + HalpFlushTLB(); + + /* Put the heap back */ + if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress; +} + diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index 3532d001d18..ed5ec3a00cf 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -20,7 +20,7 @@ display.c dma.c drive.c - halinit.c + memory.c misc.c profil.c reboot.c @@ -29,6 +29,7 @@ usage.c bios.c + halinit.c portio.c systimer.S @@ -46,7 +47,7 @@ systimer.S - + From a95f10c4760181cc1e80fb053902192b1561d6d4 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 10:51:44 +0000 Subject: [PATCH 219/292] [NTOSKRNL] Implement KeRegisterInterruptHandler and KeQueryInterruptHandler for amd64 svn path=/trunk/; revision=47564 --- reactos/ntoskrnl/include/internal/amd64/ke.h | 46 ++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/reactos/ntoskrnl/include/internal/amd64/ke.h b/reactos/ntoskrnl/include/internal/amd64/ke.h index 2e43edc248d..482f614754a 100644 --- a/reactos/ntoskrnl/include/internal/amd64/ke.h +++ b/reactos/ntoskrnl/include/internal/amd64/ke.h @@ -157,6 +157,52 @@ KiRundownThread(IN PKTHREAD Thread) #endif } +/* Registers an interrupt handler with an IDT vector */ +FORCEINLINE +VOID +KeRegisterInterruptHandler(IN ULONG Vector, + IN PVOID Handler) +{ + UCHAR Entry; + PKIDTENTRY64 Idt; + + /* Get the entry from the HAL */ + Entry = HalVectorToIDTEntry(Vector); + + /* Now set the data */ + Idt = &KeGetPcr()->IdtBase[Entry]; + Idt->OffsetLow = (ULONG_PTR)Handler & 0xffff; + Idt->OffsetMiddle = ((ULONG_PTR)Handler >> 16) & 0xffff; + Idt->OffsetHigh = (ULONG_PTR)Handler >> 32; + Idt->Selector = KGDT64_R0_CODE; + Idt->IstIndex = 0; + Idt->Type = 0x0e; + Idt->Dpl = 0; + Idt->Present = 1; + Idt->Reserved0 = 0; + Idt->Reserved1 = 0; +} + +/* Returns the registered interrupt handler for a given IDT vector */ +FORCEINLINE +PVOID +KeQueryInterruptHandler(IN ULONG Vector) +{ + UCHAR Entry; + PKIDTENTRY64 Idt; + + /* Get the entry from the HAL */ + Entry = HalVectorToIDTEntry(Vector); + + /* Get the IDT entry */ + Idt = &KeGetPcr()->IdtBase[Entry]; + + /* Return the address */ + return (PVOID)((ULONG64)Idt->OffsetHigh << 32 | + (ULONG64)Idt->OffsetMiddle << 16 | + (ULONG64)Idt->OffsetLow); +} + VOID FORCEINLINE KiEndInterrupt(IN KIRQL Irql, From 2b0533a1b03a625b86d92dec5607c5993485a108 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 10:59:19 +0000 Subject: [PATCH 220/292] [HAL] - Move all amd64 specific files to one amd64 folder - Compile x86 specific timer code only on x86 - Use KeRegisterInterruptHandler instead of manual idt manipulation - add missing stubs for amd64 svn path=/trunk/; revision=47565 --- reactos/hal/halx86/amd64/halinit.c | 31 ++++++ reactos/hal/halx86/{mp => }/amd64/mps.S | 0 reactos/hal/halx86/amd64/processor.c | 97 +++++++++++++++++++ reactos/hal/halx86/amd64/stubs.c | 97 +++++++++++++++++++ .../hal/halx86/{generic => }/amd64/systimer.S | 0 .../hal/halx86/{generic => }/amd64/x86bios.c | 7 +- reactos/hal/halx86/generic/amd64/.gitignore | 0 reactos/hal/halx86/generic/timer.c | 2 + reactos/hal/halx86/generic/usage.c | 8 +- reactos/hal/halx86/hal_generic.rbuild | 13 --- reactos/hal/halx86/halamd64.rbuild | 15 ++- 11 files changed, 239 insertions(+), 31 deletions(-) create mode 100644 reactos/hal/halx86/amd64/halinit.c rename reactos/hal/halx86/{mp => }/amd64/mps.S (100%) create mode 100644 reactos/hal/halx86/amd64/processor.c create mode 100644 reactos/hal/halx86/amd64/stubs.c rename reactos/hal/halx86/{generic => }/amd64/systimer.S (100%) rename reactos/hal/halx86/{generic => }/amd64/x86bios.c (99%) delete mode 100644 reactos/hal/halx86/generic/amd64/.gitignore diff --git a/reactos/hal/halx86/amd64/halinit.c b/reactos/hal/halx86/amd64/halinit.c new file mode 100644 index 00000000000..b9b305126d3 --- /dev/null +++ b/reactos/hal/halx86/amd64/halinit.c @@ -0,0 +1,31 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/amd64/halinit.c + * PURPOSE: HAL Entrypoint and Initialization + * PROGRAMMERS: + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* PRIVATE FUNCTIONS *********************************************************/ + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalInitSystem(IN ULONG BootPhase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + UNIMPLEMENTED; + return FALSE; +} diff --git a/reactos/hal/halx86/mp/amd64/mps.S b/reactos/hal/halx86/amd64/mps.S similarity index 100% rename from reactos/hal/halx86/mp/amd64/mps.S rename to reactos/hal/halx86/amd64/mps.S diff --git a/reactos/hal/halx86/amd64/processor.c b/reactos/hal/halx86/amd64/processor.c new file mode 100644 index 00000000000..255f50b8bf0 --- /dev/null +++ b/reactos/hal/halx86/amd64/processor.c @@ -0,0 +1,97 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/amd64/processor.c + * PURPOSE: HAL Processor Routines + * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +KAFFINITY HalpActiveProcessors; +KAFFINITY HalpDefaultInterruptAffinity; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +HaliHaltSystem(VOID) +{ + /* Disable interrupts and halt the CPU */ + _disable(); + __halt(); +} + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +HalInitializeProcessor(IN ULONG ProcessorNumber, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + /* Set default stall count */ + KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT; + + /* Update the interrupt affinity and processor mask */ + InterlockedBitTestAndSet((PLONG)&HalpActiveProcessors, ProcessorNumber); + InterlockedBitTestAndSet((PLONG)&HalpDefaultInterruptAffinity, + ProcessorNumber); + + /* Register routines for KDCOM */ + //HalpRegisterKdSupportFunctions(); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalAllProcessorsStarted(VOID) +{ + /* Do nothing */ + return TRUE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN PKPROCESSOR_STATE ProcessorState) +{ + /* Ready to start */ + return FALSE; +} + +/* + * @implemented + */ +VOID +NTAPI +HalProcessorIdle(VOID) +{ + /* Enable interrupts and halt the processor */ + _enable(); + __halt(); +} + +/* + * @implemented + */ +VOID +NTAPI +HalRequestIpi(KAFFINITY TargetProcessors) +{ + UNIMPLEMENTED; + __debugbreak(); +} + +/* EOF */ diff --git a/reactos/hal/halx86/amd64/stubs.c b/reactos/hal/halx86/amd64/stubs.c new file mode 100644 index 00000000000..ee295d17944 --- /dev/null +++ b/reactos/hal/halx86/amd64/stubs.c @@ -0,0 +1,97 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING.ARM in the top level directory + * FILE: hal/halx86/amd64/stubs.c + * PURPOSE: HAL stubs + * PROGRAMMERS: + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +LARGE_INTEGER HalpPerformanceFrequency; + + +/* FUNCTIONS ******************************************************************/ + +VOID +FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +VOID +FASTCALL +HalRequestSoftwareInterrupt( + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +BOOLEAN +NTAPI +HalBeginSystemInterrupt( + IN KIRQL Irql, + IN UCHAR Vector, + OUT PKIRQL OldIrql) +{ + UNIMPLEMENTED; + return FALSE; +} + +BOOLEAN +NTAPI +HalEnableSystemInterrupt( + IN UCHAR Vector, + IN KIRQL Irql, + IN KINTERRUPT_MODE InterruptMode) +{ + UNIMPLEMENTED; + return FALSE; +} + +VOID +NTAPI +HalDisableSystemInterrupt( + IN UCHAR Vector, + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +VOID +NTAPI +HalEndSystemInterrupt( + IN KIRQL OldIrql, + IN PKTRAP_FRAME TrapFrame) +{ + UNIMPLEMENTED; +} + +LARGE_INTEGER +NTAPI +KeQueryPerformanceCounter( + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL) +{ + LARGE_INTEGER Result; + +// ASSERT(HalpPerformanceFrequency.QuadPart != 0); + + /* Does the caller want the frequency? */ + if (PerformanceFrequency) + { + /* Return value */ + *PerformanceFrequency = HalpPerformanceFrequency; + } + + Result.QuadPart = __rdtsc(); + return Result; +} + diff --git a/reactos/hal/halx86/generic/amd64/systimer.S b/reactos/hal/halx86/amd64/systimer.S similarity index 100% rename from reactos/hal/halx86/generic/amd64/systimer.S rename to reactos/hal/halx86/amd64/systimer.S diff --git a/reactos/hal/halx86/generic/amd64/x86bios.c b/reactos/hal/halx86/amd64/x86bios.c similarity index 99% rename from reactos/hal/halx86/generic/amd64/x86bios.c rename to reactos/hal/halx86/amd64/x86bios.c index 3b43bf1d95f..a814873cbe0 100644 --- a/reactos/hal/halx86/generic/amd64/x86bios.c +++ b/reactos/hal/halx86/amd64/x86bios.c @@ -12,7 +12,7 @@ //#define NDEBUG #include -#include "x86emu.h" +//#include "x86emu.h" /* This page serves as fallback for pages used by Mm */ #define DEFAULT_PAGE 0x21 @@ -216,6 +216,7 @@ x86BiosWriteMemory( return STATUS_SUCCESS; } +#if 0 BOOLEAN NTAPI x86BiosCall( @@ -261,11 +262,13 @@ x86BiosCall( return TRUE; } +#endif BOOLEAN NTAPI HalpBiosDisplayReset(VOID) { +#if 0 X86_BIOS_REGISTERS Registers; ULONG OldEflags; @@ -283,7 +286,7 @@ HalpBiosDisplayReset(VOID) /* Restore previous flags */ __writeeflags(OldEflags); - +#endif return TRUE; } diff --git a/reactos/hal/halx86/generic/amd64/.gitignore b/reactos/hal/halx86/generic/amd64/.gitignore deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/reactos/hal/halx86/generic/timer.c b/reactos/hal/halx86/generic/timer.c index 6d90dada9b8..524b6cecb34 100644 --- a/reactos/hal/halx86/generic/timer.c +++ b/reactos/hal/halx86/generic/timer.c @@ -109,6 +109,7 @@ HalpInitializeClock(VOID) HalpCurrentRollOver = RollOver; } +#ifdef _M_IX86 #ifndef _MINIHAL_ VOID FASTCALL @@ -163,6 +164,7 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame) } #endif +#endif /* PUBLIC FUNCTIONS ***********************************************************/ diff --git a/reactos/hal/halx86/generic/usage.c b/reactos/hal/halx86/generic/usage.c index 02c86e2a046..c35df96c3e5 100644 --- a/reactos/hal/halx86/generic/usage.c +++ b/reactos/hal/halx86/generic/usage.c @@ -509,17 +509,11 @@ HalpEnableInterruptHandler(IN UCHAR Flags, IN PVOID Handler, IN KINTERRUPT_MODE Mode) { - UCHAR Entry; - - /* Convert the vector into the IDT entry */ - Entry = HalVectorToIDTEntry(SystemVector); - /* Register the vector */ HalpRegisterVector(Flags, BusVector, SystemVector, Irql); /* Connect the interrupt */ - ((PKIPCR)KeGetPcr())->IDT[Entry].ExtendedOffset = (USHORT)(((ULONG_PTR)Handler >> 16) & 0xFFFF); - ((PKIPCR)KeGetPcr())->IDT[Entry].Offset = (USHORT)((ULONG_PTR)Handler); + KeRegisterInterruptHandler(SystemVector, Handler); /* Enable the interrupt */ HalEnableSystemInterrupt(SystemVector, Irql, Mode); diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index ed5ec3a00cf..a6ee63b3b88 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -36,19 +36,6 @@ trap.S - - - - - x86bios.c - - - - - systimer.S - - - hal.h diff --git a/reactos/hal/halx86/halamd64.rbuild b/reactos/hal/halx86/halamd64.rbuild index 92c4f29983d..02f633c9fd0 100644 --- a/reactos/hal/halx86/halamd64.rbuild +++ b/reactos/hal/halx86/halamd64.rbuild @@ -8,6 +8,7 @@ include + hal_generic @@ -19,18 +20,14 @@ spinlock.c - + + x86bios.c + halinit.c + stubs.c + systimer.S processor.c - From eca252dba7a9cd80e2fa34dbd186e9f85557e013 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Fri, 4 Jun 2010 11:30:14 +0000 Subject: [PATCH 221/292] [win32k] - CreateWindow: initialize window position after sending WM_GETMINMAXINFO message svn path=/trunk/; revision=47566 --- reactos/subsystems/win32/win32k/ntuser/window.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index ee1f7aea849..5379fcbc3ed 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1700,20 +1700,9 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, Wnd->hModule = Cs->hInstance; Wnd->style = Cs->style & ~WS_VISIBLE; Wnd->ExStyle = Cs->dwExStyle; - Wnd->rcWindow.left = Cs->x; - Wnd->rcWindow.top = Cs->y; - Wnd->rcWindow.right = Cs->x + Cs->cx; - Wnd->rcWindow.bottom = Cs->y + Cs->cy; Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; Wnd->spwndOwner = OwnerWindow ? OwnerWindow->Wnd : NULL; Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL; - - if (Wnd->style & WS_CHILD && ParentWindow) - { - RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, - ParentWindow->Wnd->rcClient.top); - } - Wnd->rcClient = Wnd->rcWindow; IntReferenceMessageQueue(Window->pti->MessageQueue); if (Wnd->spwndParent != NULL && Cs->hwndParent != 0) From 3c5af5bea1278dbdc51244d53448e117dcfd3fc5 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 15:58:43 +0000 Subject: [PATCH 222/292] [KS] - KSSTREAM_POINTER_OFFSET doesn't have an Alignment member on 64 bit systems. Comment the use out in these cases. It should probably be removed completely, as it's only an alignment / dummy value, but I leave this to the expert in this field. - ULONG -> ULONG_PTR for pointer casts svn path=/trunk/; revision=47567 --- reactos/drivers/ksfilter/ks/pin.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/pin.c b/reactos/drivers/ksfilter/ks/pin.c index 019e5ce6023..a95755c2279 100644 --- a/reactos/drivers/ksfilter/ks/pin.c +++ b/reactos/drivers/ksfilter/ks/pin.c @@ -1332,7 +1332,9 @@ IKsPin_PrepareStreamHeader( else StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetOut; +#ifndef _WIN64 StreamPointer->StreamPointer.Offset->Alignment = 0; +#endif StreamPointer->StreamPointer.Offset->Count = 0; StreamPointer->StreamPointer.Offset->Data = NULL; StreamPointer->StreamPointer.Offset->Remaining = 0; @@ -1352,7 +1354,9 @@ IKsPin_PrepareStreamHeader( /* FIXME */ ASSERT(Length); +#ifndef _WIN64 StreamPointer->StreamPointer.Offset->Alignment = 0; +#endif StreamPointer->StreamPointer.Context = NULL; StreamPointer->StreamPointer.Pin = &This->Pin; StreamPointer->StreamPointer.Offset->Count = Length; @@ -1543,7 +1547,7 @@ KsStreamPointerClone( IKsPinImpl * This; PKSISTREAM_POINTER CurFrame; PKSISTREAM_POINTER NewFrame; - ULONG RefCount; + ULONG_PTR RefCount; NTSTATUS Status; ULONG Size; @@ -1562,7 +1566,7 @@ KsStreamPointerClone( return STATUS_INSUFFICIENT_RESOURCES; /* get current irp stack location */ - RefCount = (ULONG)CurFrame->Irp->Tail.Overlay.DriverContext[0]; + RefCount = (ULONG_PTR)CurFrame->Irp->Tail.Overlay.DriverContext[0]; /* increment reference count */ RefCount++; From 05740b55565b0cfda996751477795dc37ff705ad Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Fri, 4 Jun 2010 16:31:56 +0000 Subject: [PATCH 223/292] [WIN32CSR] Consistently store console input events internally as unicode. svn path=/trunk/; revision=47568 --- .../win32/csrss/win32csr/coninput.c | 73 +++++++++++-------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index eb1781baa8a..2773e8233a7 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -26,7 +26,7 @@ CSR_API(CsrReadConsole) { PLIST_ENTRY CurrentEntry; ConsoleInput *Input; - PUCHAR Buffer; + PCHAR Buffer; PWCHAR UnicodeBuffer; ULONG i; ULONG nNumberOfCharsToRead, CharSize; @@ -42,7 +42,7 @@ CSR_API(CsrReadConsole) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Buffer = Request->Data.ReadConsoleRequest.Buffer; + Buffer = (PCHAR)Request->Data.ReadConsoleRequest.Buffer; UnicodeBuffer = (PWCHAR)Buffer; Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, &Console, GENERIC_READ); @@ -64,21 +64,20 @@ CSR_API(CsrReadConsole) /* only pay attention to valid ascii chars, on key down */ if (KEY_EVENT == Input->InputEvent.EventType && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') + && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') { /* * backspace handling - if we are in charge of echoing it then we handle it here * otherwise we treat it like a normal char. */ - if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 + if (L'\b' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar && 0 != (Console->Mode & ENABLE_ECHO_INPUT)) { /* echo if it has not already been done, and either we or the client has chars to be deleted */ if (! Input->Echoed && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); } if (0 != i) { @@ -101,17 +100,20 @@ CSR_API(CsrReadConsole) else { if(Request->Data.ReadConsoleRequest.Unicode) - ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); + UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; else - Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i], &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar); } /* echo to screen if enabled and we did not already echo the char */ if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && ! Input->Echoed - && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + && L'\r' != Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); } } else @@ -215,15 +217,15 @@ ConioProcessChar(PCSRSS_CONSOLE Console, if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) { - case '\r': + case L'\r': /* first add the \r */ KeyEventRecord->InputEvent.EventType = KEY_EVENT; updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; KeyEventRecord->Echoed = FALSE; KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r'; + KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\r'; InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); Console->WaitingChars++; KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); @@ -236,7 +238,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console, KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n'; + KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\n'; KeyEventRecord->Fake = TRUE; break; } @@ -247,17 +249,17 @@ ConioProcessChar(PCSRSS_CONSOLE Console, /* if line input mode is enabled, only wake the client on enter key down */ if (0 == (Console->Mode & ENABLE_LINE_INPUT) || Console->EarlyReturn - || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + || (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) { - if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + if (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) { Console->WaitingLines++; } } KeyEventRecord->Echoed = FALSE; if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && L'\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) { /* walk the input queue looking for a char to backspace */ @@ -265,7 +267,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console, TempInput != (ConsoleInput *) &Console->InputEvents && (KEY_EVENT == TempInput->InputEvent.EventType || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); + || L'\b' == TempInput->InputEvent.Event.KeyEvent.uChar.UnicodeChar); TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) { /* NOP */; @@ -277,9 +279,11 @@ ConioProcessChar(PCSRSS_CONSOLE Console, RemoveEntryList(&TempInput->ListEntry); if (TempInput->Echoed) { - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); } HeapFree(Win32CsrApiHeap, 0, TempInput); RemoveEntryList(&KeyEventRecord->ListEntry); @@ -292,14 +296,16 @@ ConioProcessChar(PCSRSS_CONSOLE Console, { /* echo chars if we are supposed to and client is waiting for some */ if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar + && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) + && L'\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) { /* mark the char as already echoed */ - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); Console->EchoCount--; KeyEventRecord->Echoed = TRUE; } @@ -515,7 +521,6 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) HeapFree(Win32CsrApiHeap, 0, ConInRec); return; } - /* FIXME - convert to ascii */ ConioProcessChar(Console, ConInRec); } @@ -568,7 +573,7 @@ CSR_API(CsrReadInputEvent) { if (0 != (Console->Mode & ENABLE_LINE_INPUT) && Input->InputEvent.Event.KeyEvent.bKeyDown - && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) + && L'\r' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) { Console->WaitingLines--; } @@ -782,11 +787,15 @@ CSR_API(CsrWriteConsoleInput) Record->Fake = FALSE; //Record->InputEvent = *InputRecord++; memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); - if (KEY_EVENT == Record->InputEvent.EventType) + if (!Request->Data.WriteConsoleInputRequest.Unicode && + Record->InputEvent.EventType == KEY_EVENT) { - /* FIXME - convert from unicode to ascii!! */ - ConioProcessChar(Console, Record); + CHAR AsciiChar = Record->InputEvent.Event.KeyEvent.uChar.AsciiChar; + ConsoleInputAnsiCharToUnicodeChar(Console, + &Record->InputEvent.Event.KeyEvent.uChar.UnicodeChar, + &AsciiChar); } + ConioProcessChar(Console, Record); } ConioUnlockConsole(Console); From 86ed4d64b5ec9d2f064579f978f9be6e715a021c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 16:56:14 +0000 Subject: [PATCH 224/292] [HAL] Delete empty folder svn path=/trunk/; revision=47569 --- reactos/hal/halx86/mp/amd64/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 reactos/hal/halx86/mp/amd64/.gitignore diff --git a/reactos/hal/halx86/mp/amd64/.gitignore b/reactos/hal/halx86/mp/amd64/.gitignore deleted file mode 100644 index e69de29bb2d..00000000000 From 1c28c16dfefc01859a50ec1fb68e2ef0719720a4 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 4 Jun 2010 17:40:11 +0000 Subject: [PATCH 225/292] [NTOS]: Allocate non-paged pool pages with MiRemoveAnyPage instead of MmAllocPage. svn path=/trunk/; revision=47570 --- reactos/ntoskrnl/mm/ARM3/pool.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index 17c99223e00..915e407a6cf 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -590,10 +590,8 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, TempPte = ValidKernelPte; do { - // - // Allocate a page - // - PageFrameNumber = MmAllocPage(MC_NPPOOL); + /* Allocate a page */ + PageFrameNumber = MiRemoveAnyPage(0); /* Get the PFN entry for it and fill it out */ Pfn1 = MiGetPfnEntry(PageFrameNumber); From d3c4ade827878c94026caeb8f114375fb08929cc Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 4 Jun 2010 17:49:36 +0000 Subject: [PATCH 226/292] Testers: Please test this build. [NTOS]: Implement a MI_MAKE_HARDWARE_PTE macro for the generation of valid kernel PTEs instead of always taking the ValidKernelPte and changing its flags. This macro will take into account the protection mask (up until now ignored) and use the array previously implemented to determine the correct hardware PTE settings. Assertions are also added to validate correct usage of the macro, and later revisions will fill out NT-specific fields to help deal with transition PTEs, page faults, etc. [NTOS]: Make the stack code the first user of this macro, for the stack PTEs. Good testing base as we create kernel stacks very often. [NTOS]: The NT MM ABI specifies that in between the allocation of a new PTE and its initialization as a valid PFN, the PTE entry should be an invalid PTE, and should only be marked valid after the PFN has been initialized. For stack PTEs, do this -- first allocating the page, making it invalid, then initializing the PFN, and then writing the valid page. svn path=/trunk/; revision=47571 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 23 ++++++++++++++++++ reactos/ntoskrnl/mm/ARM3/procsup.c | 38 +++++++++++++++--------------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index a670bcdb3fd..8dd1698675f 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -445,6 +445,29 @@ extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT]; #define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) #define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1]) +// +// Creates a valid kernel PTE with the given protection +// +FORCEINLINE +VOID +MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte, + IN PMMPTE MappingPte, + IN ULONG ProtectionMask, + IN PFN_NUMBER PageFrameNumber) +{ + /* Only valid for kernel, non-session PTEs */ + ASSERT(MappingPte > MiHighestUserPte); + ASSERT(!MI_IS_SESSION_PTE(MappingPte)); + ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP)); + + /* Start fresh */ + *NewPte = ValidKernelPte; + + /* Set the protection and page */ + NewPte->u.Hard.PageFrameNumber = PageFrameNumber; + NewPte->u.Long |= MmProtectToPteMask[ProtectionMask]; +} + // // Returns if the page is physically resident (ie: a large page) // FIXFIX: CISC/x86 only? diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index e82a567d329..551b685b09a 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -107,7 +107,7 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, PFN_NUMBER StackPtes, StackPages; PMMPTE PointerPte, StackPte; PVOID BaseAddress; - MMPTE TempPte; + MMPTE TempPte, InvalidPte; KIRQL OldIrql; PFN_NUMBER PageFrameIndex; ULONG i; @@ -151,13 +151,12 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, if (GuiStack) PointerPte += BYTES_TO_PAGES(KERNEL_LARGE_STACK_SIZE - KERNEL_LARGE_STACK_COMMIT); - // - // Setup the template stack PTE - // - TempPte = ValidKernelPte; - MI_MAKE_LOCAL_PAGE(&TempPte); - MI_MAKE_DIRTY_PAGE(&TempPte); - TempPte.u.Hard.PageFrameNumber = 0; + + /* Setup the temporary invalid PTE */ + MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS); + + /* Setup the template stack PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte + 1, MM_READWRITE, 0); // // Acquire the PFN DB lock @@ -174,8 +173,10 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, // PointerPte++; - /* Get a page */ + /* Get a page and write the current invalid PTE */ PageFrameIndex = MiRemoveAnyPage(0); + ASSERT(InvalidPte.u.Hard.Valid == 0); + *PointerPte = InvalidPte; /* Initialize the PFN entry for this page */ MiInitializePfn(PageFrameIndex, PointerPte, 1); @@ -210,7 +211,7 @@ MmGrowKernelStackEx(IN PVOID StackPointer, PMMPTE LimitPte, NewLimitPte, LastPte; PFN_NUMBER StackPages; KIRQL OldIrql; - MMPTE TempPte; + MMPTE TempPte, InvalidPte; PFN_NUMBER PageFrameIndex; // @@ -251,13 +252,8 @@ MmGrowKernelStackEx(IN PVOID StackPointer, LimitPte--; StackPages = (LimitPte - NewLimitPte + 1); - // - // Setup the template stack PTE - // - TempPte = ValidKernelPte; - MI_MAKE_LOCAL_PAGE(&TempPte); - MI_MAKE_DIRTY_PAGE(&TempPte); - TempPte.u.Hard.PageFrameNumber = 0; + /* Setup the temporary invalid PTE */ + MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS); // // Acquire the PFN DB lock @@ -269,14 +265,18 @@ MmGrowKernelStackEx(IN PVOID StackPointer, // while (LimitPte >= NewLimitPte) { - /* Get a page */ + /* Get a page and write the current invalid PTE */ PageFrameIndex = MiRemoveAnyPage(0); + ASSERT(InvalidPte.u.Hard.Valid == 0); + *LimitPte = InvalidPte; /* Initialize the PFN entry for this page */ MiInitializePfn(PageFrameIndex, LimitPte, 1); + /* Setup the template stack PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex); + /* Write the valid PTE */ - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; ASSERT(LimitPte->u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 1); *LimitPte-- = TempPte; From 6659ae1d98fd80866b4e81331bae35f3cfe2f129 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Fri, 4 Jun 2010 18:26:22 +0000 Subject: [PATCH 227/292] [WIN32CSR] Console input simplification: - Put code for processing events for line input in one place, instead of duplicating it everywhere - Remove "Fake" and "NotChar" fields from ConsoleInput struct. ConioProcessKey didn't actually add Fake events; they were used for the \n when converting \r to \r\n, but this is better done by the line input code. - Build an input line completely on the server side; this will make it practical to add history and more sophisticated editing later svn path=/trunk/; revision=47572 --- reactos/dll/win32/kernel32/misc/console.c | 16 +- reactos/include/reactos/subsys/csrss/csrss.h | 2 +- .../win32/csrss/win32csr/coninput.c | 444 +++++++----------- .../subsystems/win32/csrss/win32csr/conio.h | 12 +- .../subsystems/win32/csrss/win32csr/console.c | 7 +- 5 files changed, 173 insertions(+), 308 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 17e1e51e30c..905a6735388 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -1566,6 +1566,9 @@ IntReadConsole(HANDLE hConsoleInput, } Request->Status = STATUS_SUCCESS; + Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; + Request->Data.ReadConsoleRequest.Unicode = bUnicode; + Request->Data.ReadConsoleRequest.FullReadSize = (WORD)nNumberOfCharsToRead; CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE); do @@ -1582,10 +1585,7 @@ IntReadConsole(HANDLE hConsoleInput, } } - Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; - Request->Data.ReadConsoleRequest.Unicode = bUnicode; Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead; Status = CsrClientCallServer(Request, NULL, @@ -1607,16 +1607,6 @@ IntReadConsole(HANDLE hConsoleInput, Request->Data.ReadConsoleRequest.Buffer, Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize); CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead; - - if (Request->Status == STATUS_NOTIFY_CLEANUP) - { - if(CharsRead > 0) - { - CharsRead--; - nNumberOfCharsToRead++; - } - Request->Status = STATUS_PENDING; - } } while (Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0); diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index df1e971682b..8119392bc0b 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -70,8 +70,8 @@ typedef struct { HANDLE ConsoleHandle; BOOL Unicode; + WORD FullReadSize; WORD NrCharactersToRead; - WORD nCharsCanBeDeleted; /* number of chars already in buffer that can be backspaced */ HANDLE EventHandle; ULONG NrCharactersRead; BYTE Buffer[0]; diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index 2773e8233a7..a945e2efc23 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -22,13 +22,62 @@ /* FUNCTIONS *****************************************************************/ +static VOID +ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) +{ + if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) + { + /* backspace handling - if we are in charge of echoing it then we handle it here + * otherwise we treat it like a normal char. + */ + if (Console->LineSize > 0) + { + Console->LineSize--; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); + } + } + else if (KeyEvent->uChar.UnicodeChar == L'\r') + { + /* TODO: add line to history */ + + Console->LineBuffer[Console->LineSize++] = L'\r'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); + if (Console->Mode & ENABLE_PROCESSED_INPUT) + { + Console->LineBuffer[Console->LineSize++] = L'\n'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE); + } + Console->LineComplete = TRUE; + Console->LinePos = 0; + } + else if (KeyEvent->uChar.UnicodeChar != L'\0') + { + if (Console->LineSize + 2 < Console->LineMaxSize) + { + Console->LineBuffer[Console->LineSize++] = KeyEvent->uChar.UnicodeChar; + /* echo to screen if enabled */ + if (Console->Mode & ENABLE_ECHO_INPUT) + { + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &KeyEvent->uChar.UnicodeChar, 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + } + } + } +} + CSR_API(CsrReadConsole) { PLIST_ENTRY CurrentEntry; ConsoleInput *Input; PCHAR Buffer; PWCHAR UnicodeBuffer; - ULONG i; + ULONG i = 0; ULONG nNumberOfCharsToRead, CharSize; PCSRSS_CONSOLE Console; NTSTATUS Status; @@ -51,110 +100,94 @@ CSR_API(CsrReadConsole) return Status; } Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; - for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) + + Status = STATUS_PENDING; /* we haven't read anything (yet) */ + if (Console->Mode & ENABLE_LINE_INPUT) { - /* remove input event from queue */ - CurrentEntry = RemoveHeadList(&Console->InputEvents); - if (IsListEmpty(&Console->InputEvents)) + if (Console->LineBuffer == NULL) { - ResetEvent(Console->ActiveEvent); + /* Starting a new line */ + Console->LineMaxSize = max(256, Request->Data.ReadConsoleRequest.FullReadSize); + Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR)); + if (Console->LineBuffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto done; + } + Console->LineComplete = FALSE; + Console->LineSize = 0; + Console->LinePos = 0; } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - /* only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') + /* If we don't have a complete line yet, process the pending input */ + while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents)) { - /* - * backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if (L'\b' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar && 0 - != (Console->Mode & ENABLE_ECHO_INPUT)) + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) { - /* echo if it has not already been done, and either we or the client has chars to be deleted */ - if (! Input->Echoed - && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) - { - ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); - } - if (0 != i) - { - i -= 2; /* if we already have something to return, just back it up by 2 */ - } - else - { - /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ - Console->WaitingChars--; - ConioUnlockConsole(Console); - HeapFree(Win32CsrApiHeap, 0, Input); - Request->Data.ReadConsoleRequest.NrCharactersRead = 0; - return STATUS_NOTIFY_CLEANUP; + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - } - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; - Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ - } - /* do not copy backspace to buffer */ - else + /* only pay attention to key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown) { - if(Request->Data.ReadConsoleRequest.Unicode) - UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; - else - ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i], &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar); - } - /* echo to screen if enabled and we did not already echo the char */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) - && ! Input->Echoed - && L'\r' != Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + ConioLineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); } + HeapFree(Win32CsrApiHeap, 0, Input); } - else + + /* Check if we have a complete line to read from */ + if (Console->LineComplete) { - i--; + while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize) + { + WCHAR Char = Console->LineBuffer[Console->LinePos++]; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; + else + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + } + if (Console->LinePos == Console->LineSize) + { + HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer); + Console->LineBuffer = NULL; + Status = STATUS_SUCCESS; /* Entire line has been read */ + } } - Console->WaitingChars--; - HeapFree(Win32CsrApiHeap, 0, Input); } + else + { + /* Character input */ + while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents)) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to valid ascii chars, on key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown + && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') + { + WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; + else + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + Status = STATUS_SUCCESS; /* did read something */ + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + } +done: Request->Data.ReadConsoleRequest.NrCharactersRead = i; - if (0 == i) - { - Status = STATUS_PENDING; /* we didn't read anything */ - } - else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) - { - if (0 == Console->WaitingLines || - (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) - { - Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ - } - else - { - Console->WaitingLines--; - Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ - } - } - else - { - Status = STATUS_SUCCESS; /* not line buffered, did read something */ - } - - if (Status == STATUS_PENDING) - { - Console->EchoCount = nNumberOfCharsToRead - i; - } - else - { - Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ - } - ConioUnlockConsole(Console); if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) @@ -179,28 +212,24 @@ ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) } } -static VOID FASTCALL +static NTSTATUS FASTCALL ConioProcessChar(PCSRSS_CONSOLE Console, - ConsoleInput *KeyEventRecord) + PINPUT_RECORD InputEvent) { - BOOL updown; - ConsoleInput *TempInput; - - if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) + /* Check for pause or unpause */ + if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) { - WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; + WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) { - DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; + DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; if (Console->Mode & ENABLE_LINE_INPUT && (vk == VK_PAUSE || (vk == 'S' && (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) { ConioPause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; + return STATUS_SUCCESS; } } else @@ -209,110 +238,19 @@ ConioProcessChar(PCSRSS_CONSOLE Console, vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) { ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; + return STATUS_SUCCESS; } } } - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) - { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - case L'\r': - /* first add the \r */ - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; - KeyEventRecord->Echoed = FALSE; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\r'; - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == KeyEventRecord) - { - DPRINT1("Failed to allocate KeyEventRecord\n"); - return; - } - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\n'; - KeyEventRecord->Fake = TRUE; - break; - } - } /* add event to the queue */ - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - /* if line input mode is enabled, only wake the client on enter key down */ - if (0 == (Console->Mode & ENABLE_LINE_INPUT) - || Console->EarlyReturn - || (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) - { - if (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - Console->WaitingLines++; - } - } - KeyEventRecord->Echoed = FALSE; - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && L'\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - /* walk the input queue looking for a char to backspace */ - for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; - TempInput != (ConsoleInput *) &Console->InputEvents - && (KEY_EVENT == TempInput->InputEvent.EventType - || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || L'\b' == TempInput->InputEvent.Event.KeyEvent.uChar.UnicodeChar); - TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) - { - /* NOP */; - } - /* if we found one, delete it, otherwise, wake the client */ - if (TempInput != (ConsoleInput *) &Console->InputEvents) - { - /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ - RemoveEntryList(&TempInput->ListEntry); - if (TempInput->Echoed) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - } - HeapFree(Win32CsrApiHeap, 0, TempInput); - RemoveEntryList(&KeyEventRecord->ListEntry); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - Console->WaitingChars -= 2; - return; - } - } - else - { - /* echo chars if we are supposed to and client is waiting for some */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && L'\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - /* mark the char as already echoed */ - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - Console->EchoCount--; - KeyEventRecord->Echoed = TRUE; - } - } - - /* Console->WaitingChars++; */ + ConsoleInput *ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (ConInRec == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + ConInRec->InputEvent = *InputEvent; + InsertTailList(&Console->InputEvents, &ConInRec->ListEntry); SetEvent(Console->ActiveEvent); + return STATUS_SUCCESS; } static DWORD FASTCALL @@ -354,15 +292,14 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) * or translated keys may be involved. */ static UINT LastVirtualKey = 0; DWORD ShiftState; - ConsoleInput *ConInRec; UINT RepeatCount; - CHAR AsciiChar; WCHAR UnicodeChar; UINT VirtualKeyCode; UINT VirtualScanCode; BOOL Down = FALSE; INPUT_RECORD er; - ULONG ResultSize = 0; + BOOLEAN Fake; // synthesized, not a real event + BOOLEAN NotChar; // message should not be used to return a character RepeatCount = 1; VirtualScanCode = (msg->lParam >> 16) & 0xff; @@ -393,11 +330,6 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) UnicodeChar = (1 == RetChars ? Chars[0] : 0); } - if (0 == ResultSize) - { - AsciiChar = 0; - } - er.EventType = KEY_EVENT; er.Event.KeyEvent.bKeyDown = Down; er.Event.KeyEvent.wRepeatCount = RepeatCount; @@ -433,38 +365,26 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) return; } - ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - - if (NULL == ConInRec) - { - return; - } - - ConInRec->InputEvent = er; - ConInRec->Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - ConInRec->Echoed = FALSE; - if (ConInRec->NotChar) + Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + if (NotChar) LastVirtualKey = msg->wParam; - DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", + DPRINT ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n", Down ? "down" : "up ", (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? "char" : "key ", - ConInRec->Fake ? "fake" : "real", - ConInRec->NotChar ? "notc" : "char", + Fake ? "fake" : "real", + NotChar ? "notc" : "char", VirtualScanCode, VirtualKeyCode, - (AsciiChar >= ' ') ? AsciiChar : '.', + (UnicodeChar >= L' ') ? UnicodeChar : L'.', ShiftState); - if (ConInRec->Fake && ConInRec->NotChar) - { - HeapFree(Win32CsrApiHeap, 0, ConInRec); + if (Fake) return; - } /* process Ctrl-C and Ctrl-Break */ if (Console->Mode & ENABLE_PROCESSED_INPUT && @@ -483,7 +403,6 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) current_entry = current_entry->Flink; ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); } - HeapFree(Win32CsrApiHeap, 0, ConInRec); return; } @@ -518,10 +437,9 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) } ConioDrawConsole(Console); } - HeapFree(Win32CsrApiHeap, 0, ConInRec); return; } - ConioProcessChar(Console, ConInRec); + ConioProcessChar(Console, &er); } CSR_API(CsrReadInputEvent) @@ -551,7 +469,7 @@ CSR_API(CsrReadInputEvent) Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); CurrentEntry = CurrentEntry->Flink; - if (Done && !Input->Fake) + if (Done) { Request->Data.ReadInputRequest.MoreEvents = TRUE; break; @@ -559,7 +477,7 @@ CSR_API(CsrReadInputEvent) RemoveEntryList(&Input->ListEntry); - if (!Done && !Input->Fake) + if (!Done) { Request->Data.ReadInputRequest.Input = Input->InputEvent; if (Request->Data.ReadInputRequest.Unicode == FALSE) @@ -569,29 +487,13 @@ CSR_API(CsrReadInputEvent) Done = TRUE; } - if (Input->InputEvent.EventType == KEY_EVENT) - { - if (0 != (Console->Mode & ENABLE_LINE_INPUT) - && Input->InputEvent.Event.KeyEvent.bKeyDown - && L'\r' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - Console->WaitingLines--; - } - Console->WaitingChars--; - } HeapFree(Win32CsrApiHeap, 0, Input); } if (Done) - { Status = STATUS_SUCCESS; - Console->EarlyReturn = FALSE; - } else - { Status = STATUS_PENDING; - Console->EarlyReturn = TRUE; /* mark for early return */ - } if (IsListEmpty(&Console->InputEvents)) { @@ -632,7 +534,6 @@ CSR_API(CsrFlushInputBuffer) HeapFree(Win32CsrApiHeap, 0, Input); } ResetEvent(Console->ActiveEvent); - Console->WaitingChars=0; ConioUnlockConsole(Console); @@ -645,7 +546,6 @@ CSR_API(CsrGetNumberOfConsoleInputEvents) PCSRSS_CONSOLE Console; PLIST_ENTRY CurrentItem; DWORD NumEvents; - ConsoleInput *Input; DPRINT("CsrGetNumberOfConsoleInputEvents\n"); @@ -664,12 +564,8 @@ CSR_API(CsrGetNumberOfConsoleInputEvents) /* If there are any events ... */ while (CurrentItem != &Console->InputEvents) { - Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); CurrentItem = CurrentItem->Flink; - if (!Input->Fake) - { - NumEvents++; - } + NumEvents++; } ConioUnlockConsole(Console); @@ -719,16 +615,10 @@ CSR_API(CsrPeekConsoleInput) { Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - if (Item->Fake) - { - CurrentItem = CurrentItem->Flink; - continue; - } - ++NumItems; *InputRecord = Item->InputEvent; - if (Request->Data.ReadInputRequest.Unicode == FALSE) + if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE) { ConioInputEventToAnsi(Console, InputRecord); } @@ -752,7 +642,6 @@ CSR_API(CsrWriteConsoleInput) NTSTATUS Status; DWORD Length; DWORD i; - ConsoleInput* Record; DPRINT("CsrWriteConsoleInput\n"); @@ -774,35 +663,24 @@ CSR_API(CsrWriteConsoleInput) return STATUS_ACCESS_VIOLATION; } - for (i = 0; i < Length; i++) + for (i = 0; i < Length && NT_SUCCESS(Status); i++) { - Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == Record) - { - ConioUnlockConsole(Console); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Record->Echoed = FALSE; - Record->Fake = FALSE; - //Record->InputEvent = *InputRecord++; - memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); if (!Request->Data.WriteConsoleInputRequest.Unicode && - Record->InputEvent.EventType == KEY_EVENT) + InputRecord->EventType == KEY_EVENT) { - CHAR AsciiChar = Record->InputEvent.Event.KeyEvent.uChar.AsciiChar; + CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; ConsoleInputAnsiCharToUnicodeChar(Console, - &Record->InputEvent.Event.KeyEvent.uChar.UnicodeChar, + &InputRecord->Event.KeyEvent.uChar.UnicodeChar, &AsciiChar); } - ConioProcessChar(Console, Record); + Status = ConioProcessChar(Console, InputRecord++); } ConioUnlockConsole(Console); Request->Data.WriteConsoleInputRequest.Length = i; - return STATUS_SUCCESS; + return Status; } /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 2befcaf0b2d..3ff3a19ceab 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -75,14 +75,15 @@ typedef struct tagCSRSS_CONSOLE PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */ HANDLE ActiveEvent; LIST_ENTRY InputEvents; /* List head for input event queue */ - WORD WaitingChars; - WORD WaitingLines; /* number of chars and lines in input queue */ + PWCHAR LineBuffer; /* current line being input, in line buffered mode */ + WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */ + WORD LineSize; /* current size of line */ + WORD LinePos; /* current position within line */ + BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */ LIST_ENTRY BufferList; /* List of all screen buffers for this console */ PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ WORD Mode; /* Console mode flags */ - WORD EchoCount; /* count of chars to echo, in line buffered mode */ UNICODE_STRING Title; /* Title of console */ - BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ HWND hWindow; COORD Size; @@ -101,9 +102,6 @@ typedef struct ConsoleInput_t { LIST_ENTRY ListEntry; INPUT_RECORD InputEvent; - BOOLEAN Echoed; // already been echoed or not - BOOLEAN Fake; // synthesized, not a real event - BOOLEAN NotChar; // message should not be used to return a character } ConsoleInput; /* CONSOLE_SELECTION_INFO dwFlags values */ diff --git a/reactos/subsystems/win32/csrss/win32csr/console.c b/reactos/subsystems/win32/csrss/win32csr/console.c index 57a1a0f573e..5ace9ab3a3b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/console.c +++ b/reactos/subsystems/win32/csrss/win32csr/console.c @@ -81,13 +81,10 @@ CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); Console->ReferenceCount = 0; - Console->WaitingChars = 0; - Console->WaitingLines = 0; - Console->EchoCount = 0; + Console->LineBuffer = NULL; Console->Header.Type = CONIO_CONSOLE_MAGIC; Console->Header.Console = Console; Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - Console->EarlyReturn = FALSE; InitializeListHead(&Console->BufferList); Console->ActiveBuffer = NULL; InitializeListHead(&Console->InputEvents); @@ -333,6 +330,8 @@ ConioDeleteConsole(Object_t *Object) } ConioCleanupConsole(Console); + if (Console->LineBuffer) + RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer); ConioDeleteScreenBuffer(Console->ActiveBuffer); if (!IsListEmpty(&Console->BufferList)) { From ffc6aac247b24f18e18c3eaa7864249594555a47 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 18:37:14 +0000 Subject: [PATCH 228/292] [MMEBUDDY] Make mmebuddy more 64bit compliant. Based on r40127 by Samuel Serapion with some modifications by me. svn path=/trunk/; revision=47573 --- reactos/include/reactos/libs/sound/mmebuddy.h | 16 +++++++------- .../sound/mmebuddy/auxiliary/auxMessage.c | 10 ++++----- .../drivers/sound/mmebuddy/midi/midMessage.c | 10 ++++----- .../drivers/sound/mmebuddy/midi/modMessage.c | 10 ++++----- .../drivers/sound/mmebuddy/mixer/mxdMessage.c | 22 +++++++++---------- reactos/lib/drivers/sound/mmebuddy/mmewrap.c | 20 ++++++++--------- .../lib/drivers/sound/mmebuddy/wave/header.c | 2 +- .../drivers/sound/mmebuddy/wave/widMessage.c | 12 +++++----- .../drivers/sound/mmebuddy/wave/wodMessage.c | 12 +++++----- 9 files changed, 57 insertions(+), 57 deletions(-) diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index 4e1583230c1..cae6f3f1489 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -400,8 +400,8 @@ ReleaseEntrypointMutex( VOID NotifyMmeClient( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, - IN DWORD Message, - IN DWORD Parameter); + IN UINT Message, + IN DWORD_PTR Parameter); MMRESULT MmeGetSoundDeviceCapabilities( @@ -413,20 +413,20 @@ MmeGetSoundDeviceCapabilities( MMRESULT MmeOpenWaveDevice( IN MMDEVICE_TYPE DeviceType, - IN DWORD DeviceId, + IN UINT DeviceId, IN LPWAVEOPENDESC OpenParameters, IN DWORD Flags, - OUT DWORD* PrivateHandle); + OUT DWORD_PTR* PrivateHandle); MMRESULT MmeCloseDevice( - IN DWORD PrivateHandle); + IN DWORD_PTR PrivateHandle); MMRESULT MmeGetPosition( IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN MMTIME* Time, IN DWORD Size); @@ -441,7 +441,7 @@ MmeGetDeviceInterfaceString( MMRESULT MmeSetState( - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN BOOL bStart); @@ -456,7 +456,7 @@ MmeSetState( MMRESULT MmeResetWavePlayback( - IN DWORD PrivateHandle); + IN DWORD_PTR PrivateHandle); /* diff --git a/reactos/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c b/reactos/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c index f248a48e400..9cfa0d941e6 100644 --- a/reactos/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY auxMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/reactos/lib/drivers/sound/mmebuddy/midi/midMessage.c b/reactos/lib/drivers/sound/mmebuddy/midi/midMessage.c index a99b6dc29ad..9e1a0ec24f6 100644 --- a/reactos/lib/drivers/sound/mmebuddy/midi/midMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/midi/midMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY midMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/reactos/lib/drivers/sound/mmebuddy/midi/modMessage.c b/reactos/lib/drivers/sound/mmebuddy/midi/modMessage.c index bde698719e4..febfca516b5 100644 --- a/reactos/lib/drivers/sound/mmebuddy/midi/modMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/midi/modMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY modMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index 86e63773c0e..cf870540ba1 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -20,10 +20,10 @@ MMRESULT MmeGetLineInfo( - IN DWORD Message, - IN DWORD PrivateHandle, - IN DWORD Parameter1, - IN DWORD Parameter2) + IN UINT Message, + IN DWORD_PTR PrivateHandle, + IN DWORD_PTR Parameter1, + IN DWORD_PTR Parameter2) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -54,7 +54,7 @@ MmeGetLineInfo( MMRESULT MmeCloseMixerDevice( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -122,7 +122,7 @@ MmeOpenMixerDevice( } /* Store the device instance pointer in the private handle - is DWORD safe here? */ - *PrivateHandle = (DWORD) SoundDeviceInstance; + *PrivateHandle = (DWORD_PTR) SoundDeviceInstance; /* Store the additional information we were given - FIXME: Need flags! */ SetSoundDeviceInstanceMmeData(SoundDeviceInstance, @@ -151,11 +151,11 @@ MmeOpenMixerDevice( DWORD APIENTRY mxdMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c index 63f3e6f5c5a..960c4839a50 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c +++ b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c @@ -22,7 +22,7 @@ MMRESULT MmeSetState( - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN BOOL bStart) { MMRESULT Result; @@ -64,8 +64,8 @@ MmeSetState( VOID NotifyMmeClient( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, - IN DWORD Message, - IN DWORD Parameter) + IN UINT Message, + IN DWORD_PTR Parameter) { SND_ASSERT( SoundDeviceInstance ); @@ -121,10 +121,10 @@ MmeGetSoundDeviceCapabilities( MMRESULT MmeOpenWaveDevice( IN MMDEVICE_TYPE DeviceType, - IN DWORD DeviceId, + IN UINT DeviceId, IN LPWAVEOPENDESC OpenParameters, IN DWORD Flags, - OUT DWORD* PrivateHandle) + OUT DWORD_PTR* PrivateHandle) { MMRESULT Result; @@ -170,8 +170,8 @@ MmeOpenWaveDevice( return TranslateInternalMmResult(Result); } - /* Store the device instance pointer in the private handle - is DWORD safe here? */ - *PrivateHandle = (DWORD) SoundDeviceInstance; + /* Store the device instance pointer in the private handle */ + *PrivateHandle = (DWORD_PTR)SoundDeviceInstance; /* Store the additional information we were given - FIXME: Need flags! */ SetSoundDeviceInstanceMmeData(SoundDeviceInstance, @@ -195,7 +195,7 @@ MmeOpenWaveDevice( MMRESULT MmeCloseDevice( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -235,7 +235,7 @@ MmeCloseDevice( MMRESULT MmeResetWavePlayback( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -284,7 +284,7 @@ MMRESULT MmeGetPosition( IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN MMTIME* Time, IN DWORD Size) { diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/header.c b/reactos/lib/drivers/sound/mmebuddy/wave/header.c index bf5b80b6496..b4d7fdcf119 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/header.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/header.c @@ -359,5 +359,5 @@ CompleteWaveHeader( /* Safe to do this without thread protection, as we're done with the header */ NotifyMmeClient(SoundDeviceInstance, DeviceType == WAVE_OUT_DEVICE_TYPE ? WOM_DONE : WIM_DATA, - (DWORD) Header); + (DWORD_PTR)Header); } diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c index ce1e4dffce3..47825aeccd9 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c @@ -25,11 +25,11 @@ DWORD APIENTRY widMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; @@ -72,7 +72,7 @@ widMessage( DeviceId, (LPWAVEOPENDESC) Parameter1, Parameter2, - (DWORD*) PrivateHandle); + (DWORD_PTR*) PrivateHandle); break; } diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c b/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c index de579f32200..70bd6b70d05 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c @@ -34,11 +34,11 @@ MMRESULT HelloWorld(PSOUND_DEVICE_INSTANCE Instance, PVOID String) DWORD APIENTRY wodMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; @@ -69,7 +69,7 @@ wodMessage( DeviceId, (LPWAVEOPENDESC) Parameter1, Parameter2, - (DWORD*) PrivateHandle); + (DWORD_PTR*)PrivateHandle); break; } From f150c299f21eb64230b881c93ae396f10500dfce Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 20:16:26 +0000 Subject: [PATCH 229/292] [DDK] Fix definition of USE_DMA_MACROS svn path=/trunk/; revision=47574 --- reactos/include/ddk/ntddk.h | 12 ------------ reactos/include/ddk/wdm.h | 21 +++++++++------------ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 0e02581425d..3a51cd86bd0 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -852,18 +852,6 @@ typedef union _PCI_EXPRESS_PME_REQUESTOR_ID { USHORT AsUSHORT; } PCI_EXPRESS_PME_REQUESTOR_ID, *PPCI_EXPRESS_PME_REQUESTOR_ID; -#if defined(_WIN64) - -#ifndef USE_DMA_MACROS -#define USE_DMA_MACROS -#endif - -#ifndef NO_LEGACY_DRIVERS -#define NO_LEGACY_DRIVERS -#endif - -#endif /* defined(_WIN64) */ - typedef enum _PHYSICAL_COUNTER_RESOURCE_DESCRIPTOR_TYPE { ResourceTypeSingle = 0, ResourceTypeRange, diff --git a/reactos/include/ddk/wdm.h b/reactos/include/ddk/wdm.h index 563801bfece..e097c4e1794 100644 --- a/reactos/include/ddk/wdm.h +++ b/reactos/include/ddk/wdm.h @@ -124,6 +124,15 @@ extern "C" { #endif +#if defined(_WIN64) +#if !defined(USE_DMA_MACROS) && !defined(_NTHAL_) +#define USE_DMA_MACROS +#endif +#ifndef NO_LEGACY_DRIVERS +#define NO_LEGACY_DRIVERS +#endif +#endif /* defined(_WIN64) */ + /* Forward declarations */ struct _IRP; struct _MDL; @@ -3698,18 +3707,6 @@ typedef enum _CM_ERROR_CONTROL_TYPE { #define WDM_MAJORVERSION 0x06 #define WDM_MINORVERSION 0x00 -#if defined(_WIN64) - -#ifndef USE_DMA_MACROS -#define USE_DMA_MACROS -#endif - -#ifndef NO_LEGACY_DRIVERS -#define NO_LEGACY_DRIVERS -#endif - -#endif /* defined(_WIN64) */ - #define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS #define CONNECT_FULLY_SPECIFIED 0x1 From 63ce635b0fb56a31d7695e2d2b24c33bdc3fb41d Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 4 Jun 2010 20:18:27 +0000 Subject: [PATCH 230/292] [NTOS]: Build paged pool demand-zero PTE with MI_MAKE_SOFTWARE_PTE macro. [NTOS]: Handle paged pool demand-zero fault fulfillment with MI_MAKE_HARDWARE_PTE macro. [NTOS]: Use MiRemoveAnyPage instead of MmAllocPage, in paged pool demand-zero fault fulfillment. These changes affect code paths that are not currently in-use. svn path=/trunk/; revision=47575 --- reactos/ntoskrnl/mm/ARM3/pagfault.c | 20 +++++++++----------- reactos/ntoskrnl/mm/ARM3/pool.c | 8 +++----- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index ceff13bcc8d..362a7d57ed0 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -105,11 +105,12 @@ MiResolveDemandZeroFault(IN PVOID Address, OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); ASSERT(PointerPte->u.Hard.Valid == 0); - // - // Get a page - // - PageFrameNumber = MmAllocPage(MC_PPOOL); - DPRINT("New pool page: %lx\n", PageFrameNumber); + /* Get a page */ + PageFrameNumber = MiRemoveAnyPage(0); + DPRINT1("New pool page: %lx\n", PageFrameNumber); + + /* Initialize it */ + MiInitializePfn(PageFrameNumber, PointerPte, TRUE); // // Release PFN lock @@ -124,11 +125,8 @@ MiResolveDemandZeroFault(IN PVOID Address, /* Shouldn't see faults for user PTEs yet */ ASSERT(PointerPte > MiHighestUserPte); - // - // Build the PTE - // - TempPte = ValidKernelPte; - TempPte.u.Hard.PageFrameNumber = PageFrameNumber; + /* Build the PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, PointerPte->u.Soft.Protection, PageFrameNumber); ASSERT(TempPte.u.Hard.Valid == 1); ASSERT(PointerPte->u.Hard.Valid == 0); *PointerPte = TempPte; @@ -137,7 +135,7 @@ MiResolveDemandZeroFault(IN PVOID Address, // // It's all good now // - DPRINT("Paged pool page has now been paged in\n"); + DPRINT1("Paged pool page has now been paged in\n"); return STATUS_PAGE_FAULT_DEMAND_ZERO; } diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index 915e407a6cf..28cbe2e4db8 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -417,11 +417,9 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // KeFlushEntireTb(TRUE, TRUE); - // - // Setup a demand-zero writable PTE - // - TempPte.u.Long = 0; - MI_MAKE_WRITE_PAGE(&TempPte); + /* Setup a demand-zero writable PTE */ + DPRINT1("Setting up demand zero\n"); + MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); // // Find the first and last PTE, then loop them all From fc022a85068fb2f2ff232567c34508fd0acb9ebb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 4 Jun 2010 20:22:29 +0000 Subject: [PATCH 231/292] [FREELOADER] - Remove duplicated code - Add back the Mac hack but use 0x8A for the lowest CD-ROM drive number instead of 0x90 svn path=/trunk/; revision=47576 --- .../boot/freeldr/freeldr/arch/i386/i386disk.c | 42 +++++++---- .../boot/freeldr/freeldr/arch/i386/pcdisk.c | 70 +------------------ 2 files changed, 30 insertions(+), 82 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c index beeb15c7471..bcee4538a07 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c @@ -51,10 +51,32 @@ BOOLEAN DiskResetController(ULONG DriveNumber) BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber) { + static ULONG LastDriveNumber = 0xffffffff; + static BOOLEAN LastSupported; REGS RegsIn; REGS RegsOut; - DPRINTM(DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"); + DPRINTM(DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"); + + if (DriveNumber == LastDriveNumber) + { + DPRINTM(DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber); + return LastSupported; + } + + // Some BIOSes report that extended disk access functions are not supported + // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping + // with Intel Macs). Therefore we just return TRUE if we're booting from a CD - + // we can assume that all El Torito capable BIOSes support INT 13 extensions. + // We simply detect whether we're booting from CD by checking whether the drive + // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes. + if (DriveNumber >= 0x8A) + { + LastSupported = TRUE; + return TRUE; + } + + LastDriveNumber = DriveNumber; // IBM/MS INT 13 Extensions - INSTALLATION CHECK // AH = 41h @@ -90,35 +112,27 @@ BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber) if (!INT386_SUCCESS(RegsOut)) { // CF set on error (extensions not supported) + LastSupported = FALSE; return FALSE; } if (RegsOut.w.bx != 0xAA55) { // BX = AA55h if installed + LastSupported = FALSE; return FALSE; } - // Note: - // The original check is too strict because some BIOSes report that - // extended disk access functions are not suported when booting - // from a CD (e.g. Phoenix BIOS v6.00PG). Argh! -#if 0 if (!(RegsOut.w.cx & 0x0001)) { // CX = API subset support bitmap // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - return FALSE; - } -#endif - - // Use this relaxed check instead - if (RegsOut.w.cx == 0x0000) - { - // CX = API subset support bitmap + DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber); + LastSupported = FALSE; return FALSE; } + LastSupported = TRUE; return TRUE; } diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c index 0a89a84796b..304a8670107 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -264,72 +264,6 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(ULONG DriveNumber, ULONGLONG SectorNu return TRUE; } -static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber) -{ - static ULONG LastDriveNumber = 0xffffffff; - static BOOLEAN LastSupported; - REGS RegsIn; - REGS RegsOut; - - DPRINTM(DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"); - - if (DriveNumber == LastDriveNumber) - { - DPRINTM(DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber); - return LastSupported; - } - - LastDriveNumber = DriveNumber; - - // IBM/MS INT 13 Extensions - INSTALLATION CHECK - // AH = 41h - // BX = 55AAh - // DL = drive (80h-FFh) - // Return: - // CF set on error (extensions not supported) - // AH = 01h (invalid function) - // CF clear if successful - // BX = AA55h if installed - // AH = major version of extensions - // 01h = 1.x - // 20h = 2.0 / EDD-1.0 - // 21h = 2.1 / EDD-1.1 - // 30h = EDD-3.0 - // AL = internal use - // CX = API subset support bitmap - // DH = extension version (v2.0+ ??? -- not present in 1.x) - // - // Bitfields for IBM/MS INT 13 Extensions API support bitmap - // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported - // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported - // extended drive parameter table is valid - // Bits 3-15 reserved - RegsIn.b.ah = 0x41; - RegsIn.w.bx = 0x55AA; - RegsIn.b.dl = DriveNumber; - - // Reset the disk controller - Int386(0x13, &RegsIn, &RegsOut); - - if (!INT386_SUCCESS(RegsOut)) - { - // CF set on error (extensions not supported) - LastSupported = FALSE; - return FALSE; - } - - if (RegsOut.w.bx != 0xAA55) - { - // BX = AA55h if installed - LastSupported = FALSE; - return FALSE; - } - - LastSupported = TRUE; - return TRUE; -} - BOOLEAN PcDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { @@ -340,9 +274,9 @@ BOOLEAN PcDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULON // If so then check to see if Int13 extensions work // If they do then use them, otherwise default back to BIOS calls // - if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber)) + if ((DriveNumber >= 0x80) && DiskInt13ExtensionsSupported(DriveNumber)) { - DPRINTM(DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"); + DPRINTM(DPRINT_DISK, "Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, DiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"); // // LBA is easy, nothing to calculate From 682cf08ee8ee22d737e883a62ff8b9d4a74d456f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 4 Jun 2010 20:36:48 +0000 Subject: [PATCH 232/292] [FREELOADER] - Use the old method for identifying the drive type (based on partition number) which actually works for floppies now because I changed the DrivePartition value returned (floppy = 0, cdrom = 0xFF) in a previous commit - Fixes bug 5233 svn path=/trunk/; revision=47577 --- .../boot/freeldr/freeldr/arch/i386/hardware.c | 33 ++++--------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index 97577aa020c..f99e26780d6 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -433,41 +433,22 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) ULONGLONG SectorOffset = 0; ULONGLONG SectorCount = 0; PARTITION_TABLE_ENTRY PartitionTableEntry; - GEOMETRY Geometry; - EXTENDED_GEOMETRY ExtGeometry; CHAR FileName[1]; if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) return EINVAL; - ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY); - if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size)) + if (DrivePartition == 0xff) { - SectorSize = ExtGeometry.BytesPerSector; - SectorCount = ExtGeometry.Sectors; - } - else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry)) - { - SectorSize = Geometry.BytesPerSector; - SectorCount = Geometry.Sectors; + /* This is a CD-ROM device */ + SectorSize = 2048; } else { - DPRINTM(DPRINT_HWDETECT, "Using legacy sector size detection\n"); - - /* Fall back to legacy detection */ - if (DrivePartition == 0xff) - { - /* This is a CD-ROM device */ - SectorSize = 2048; - } - else - { - /* This is either a floppy disk device (DrivePartition == 0) or - * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but - * it doesn't matter which one because they both have 512 bytes per sector */ - SectorSize = 512; - } + /* This is either a floppy disk device (DrivePartition == 0) or + * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but + * it doesn't matter which one because they both have 512 bytes per sector */ + SectorSize = 512; } if (DrivePartition != 0xff && DrivePartition != 0) From c25fc39e6f8e9540c15b06d9b556fd25196fde4f Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jun 2010 21:50:06 +0000 Subject: [PATCH 233/292] [winnt.h] Fix definition of KNONVOLATILE_CONTEXT_POINTERS for amd64 svn path=/trunk/; revision=47578 --- reactos/include/psdk/winnt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index 66c94b21d6d..a10ad095b02 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -2300,8 +2300,8 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PM128A Xmm13; PM128A Xmm14; PM128A Xmm15; - }; - }; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; union { PULONG64 IntegerContext[16]; @@ -2322,8 +2322,8 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PULONG64 R13; PULONG64 R14; PULONG64 R15; - }; - }; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME2; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #define RUNTIME_FUNCTION_INDIRECT 0x1 From 25bf23bfc1fb6d1030a0d6015fa0414ec0f1d37f Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 4 Jun 2010 22:08:40 +0000 Subject: [PATCH 234/292] [NTOS]: When expanding paged pool, use MiRemoveAnyPage, not MmAllocPage. [NTOS]: When expanding paged pool, initialize the PFN entry for the allocated page. Note we might be in arbitrary process space, so the PTE is not necessary valid for the process causing the expansion. [NTOS]: Implement MiInitializePfnForOtherProcess to handle the case above. [NTOS]: Change two static ASSERTs into C_ASSERTs. Might break non-x86 builds for a bit (vs breaking them at boot, which is worse). Paged pool should start working soon. svn path=/trunk/; revision=47579 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 8 ++++ reactos/ntoskrnl/mm/ARM3/pagfault.c | 2 +- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 58 +++++++++++++++++++++++------ reactos/ntoskrnl/mm/ARM3/pool.c | 13 ++++--- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 8dd1698675f..efcc0537ebc 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -706,6 +706,14 @@ MiInitializePfn( IN BOOLEAN Modified ); +VOID +NTAPI +MiInitializePfnForOtherProcess( + IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN PFN_NUMBER PteFrame +); + VOID NTAPI MiDecrementShareCount( diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 362a7d57ed0..8fd0d15daee 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -65,7 +65,7 @@ MiCheckPdeForPagedPool(IN PVOID Address) if (PointerPde->u.Hard.Valid == 0) { /* This seems to be making the assumption that one PDE is one page long */ - ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); + C_ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); // // Copy it from our double-mapped system page directory diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 29777f6990a..00afacf0e77 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -16,6 +16,7 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +#if DBG #define ASSERT_LIST_INVARIANT(x) \ do { \ ASSERT(((x)->Total == 0 && \ @@ -25,6 +26,9 @@ do { \ (x)->Flink != LIST_HEAD && \ (x)->Blink != LIST_HEAD)); \ } while (0) +#else +#define ASSERT_LIST_INVARIANT(x) +#endif /* GLOBALS ********************************************************************/ @@ -58,7 +62,6 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, IN PMMPFN Entry) { PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT_LIST_INVARIANT(ListHead); @@ -133,6 +136,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* And now the head points back to us, since we are last */ ListHead->Blink = EntryIndex; + ASSERT_LIST_INVARIANT(ListHead); /* Update the page location */ Pfn1->u3.e1.PageLocation = ZeroedPageList; @@ -152,8 +156,6 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) KeSetEvent(MiHighMemoryEvent, 0, FALSE); } - ASSERT_LIST_INVARIANT(ListHead); - #if 0 /* Get the page color */ Color = EntryIndex & MmSecondaryColorMask; @@ -328,6 +330,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, } /* We are not on a list anymore */ + ASSERT_LIST_INVARIANT(ListHead); Pfn1->u1.Flink = Pfn1->u2.Blink = 0; /* Zero flags but restore color and cache */ @@ -335,8 +338,6 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, Pfn1->u3.e1.PageColor = OldColor; Pfn1->u3.e1.CacheAttribute = OldCache; - ASSERT_LIST_INVARIANT(ListHead); - #if 0 // When switching to ARM3 /* Get the first page on the color list */ ColorTable = &MmFreePagesByColor[ListName][Color]; @@ -433,11 +434,10 @@ MiRemoveAnyPage(IN ULONG Color) (Pfn1->u3.e1.PageLocation == ZeroedPageList)); ASSERT(Pfn1->u3.e2.ReferenceCount == 0); ASSERT(Pfn1->u2.ShareCount == 0); - - /* Return the page */ ASSERT_LIST_INVARIANT(&MmFreePageListHead); ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); - + + /* Return the page */ return PageIndex; } @@ -447,7 +447,6 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) { PFN_NUMBER Entry, Flink; PMMPFN Pfn1; - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT_LIST_INVARIANT(ListHead); @@ -474,7 +473,6 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) /* We are not on a list anymore */ Pfn1->u1.Flink = Pfn1->u2.Blink = 0; ListHead->Total--; - ASSERT_LIST_INVARIANT(ListHead); /* Return the head element */ @@ -529,6 +527,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Now make the list head point back to us (since we go at the end) */ ListHead->Blink = PageFrameIndex; + ASSERT_LIST_INVARIANT(ListHead); /* And initialize our own list pointers */ Pfn1->u1.Flink = LIST_HEAD; @@ -557,8 +556,6 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) KeSetEvent(MiHighMemoryEvent, 0, FALSE); } - ASSERT_LIST_INVARIANT(ListHead); - #if 0 // When using ARM3 PFN /* Get the page color */ Color = PageFrameIndex & MmSecondaryColorMask; @@ -762,4 +759,41 @@ MiDecrementShareCount(IN PMMPFN Pfn1, } } +VOID +NTAPI +MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN PFN_NUMBER PteFrame) +{ + PMMPFN Pfn1; + + /* Setup the PTE */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->PteAddress = PointerPte; + +#if 0 // When using ARM3 PFN + /* Make this a software PTE */ + MI_MAKE_SOFTWARE_PTE(&Pfn1->OriginalPte, MM_READWRITE); +#endif + + /* Setup the page */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u2.ShareCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; + Pfn1->u3.e1.Modified = TRUE; + Pfn1->u4.InPageError = FALSE; + + /* Did we get a PFN for the page table */ + if (PteFrame) + { + /* Store it */ + Pfn1->u4.PteFrame = PteFrame; + + /* Increase its share count so we don't get rid of it */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->u2.ShareCount++; + } +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index 28cbe2e4db8..c4a73746d6b 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -325,20 +325,23 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // ASSERT(PointerPte->u.Hard.Valid == 0); - // - // Request a paged pool page and write the PFN for it - // - PageFrameNumber = MmAllocPage(MC_PPOOL); + /* Request a page */ + PageFrameNumber = MiRemoveAnyPage(0); TempPte.u.Hard.PageFrameNumber = PageFrameNumber; // // Save it into our double-buffered system page directory // /* This seems to be making the assumption that one PDE is one page long */ - ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); + C_ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); MmSystemPagePtes[(ULONG_PTR)PointerPte & (PAGE_SIZE - 1) / sizeof(MMPTE)] = TempPte; + /* Initialize the PFN */ + MiInitializePfnForOtherProcess(PageFrameNumber, + PointerPte, + MmSystemPageDirectory[(PointerPte - (PMMPTE)PDE_BASE) / PDE_COUNT]); + /* Write the actual PTE now */ ASSERT(TempPte.u.Hard.Valid == 1); *PointerPte++ = TempPte; From ffcb1445f78e5769537dc7d0e1682c8e949f3648 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 5 Jun 2010 00:45:08 +0000 Subject: [PATCH 235/292] [KERNEL32], [WIN32CSR] - Implement console history (note: not too useful yet without any way to recall it) - Implement APIs GetConsoleCommandHistoryLength, GetConsoleCommandHistory, ExpungeConsoleCommandHistory, SetConsoleNumberOfCommands, GetConsoleHistoryInfo, SetConsoleHistoryInfo. - Remove stub of obsolete function SetConsoleCommandHistoryMode, which no longer exists in Windows. svn path=/trunk/; revision=47580 --- reactos/dll/win32/kernel32/kernel32.pspec | 3 +- reactos/dll/win32/kernel32/misc/console.c | 341 ++++++++++++++---- reactos/include/reactos/subsys/csrss/csrss.h | 43 +++ .../win32/csrss/win32csr/coninput.c | 2 +- .../subsystems/win32/csrss/win32csr/conio.h | 17 + .../subsystems/win32/csrss/win32csr/console.c | 4 + .../subsystems/win32/csrss/win32csr/dllmain.c | 6 + .../win32/csrss/win32csr/guiconsole.c | 32 +- .../win32/csrss/win32csr/win32csr.rbuild | 1 + 9 files changed, 352 insertions(+), 97 deletions(-) diff --git a/reactos/dll/win32/kernel32/kernel32.pspec b/reactos/dll/win32/kernel32/kernel32.pspec index cba32d9f29d..3c09b07cc44 100644 --- a/reactos/dll/win32/kernel32/kernel32.pspec +++ b/reactos/dll/win32/kernel32/kernel32.pspec @@ -316,6 +316,7 @@ @ stdcall GetConsoleFontInfo(long long long ptr) @ stdcall GetConsoleFontSize(long long) @ stdcall GetConsoleHardwareState(long long ptr) +@ stdcall GetConsoleHistoryInfo(ptr) @ stdcall GetConsoleInputExeNameA(long ptr) @ stdcall GetConsoleInputExeNameW(long ptr) @ stdcall GetConsoleInputWaitHandle() @@ -796,7 +797,6 @@ @ stdcall SetComputerNameW(wstr) @ stdcall SetConsoleActiveScreenBuffer(long) @ stdcall SetConsoleCP(long) -@ stdcall SetConsoleCommandHistoryMode(long) @ stdcall SetConsoleCtrlHandler(ptr long) @ stdcall SetConsoleCursor(long long) @ stdcall SetConsoleCursorInfo(long ptr) @@ -805,6 +805,7 @@ @ stdcall SetConsoleDisplayMode(long long ptr) @ stdcall SetConsoleFont(long long) @ stdcall SetConsoleHardwareState(long long long) +@ stdcall SetConsoleHistoryInfo(ptr) @ stdcall SetConsoleIcon(ptr) @ stdcall SetConsoleInputExeNameA(ptr) @ stdcall SetConsoleInputExeNameW(ptr) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 905a6735388..34b1e84a6aa 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -178,6 +178,37 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) ExitThread(nExitCode); } +/* Get the size needed to copy a string to a capture buffer, including alignment */ +static ULONG +IntStringSize(LPCVOID String, + BOOL Unicode) +{ + ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR); + return (Size + 3) & -4; +} + +/* Copy a string to a capture buffer */ +static VOID +IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer, + LPCVOID String, + BOOL Unicode, + PUNICODE_STRING RequestString) +{ + ULONG Size; + if (Unicode) + { + Size = wcslen(String) * sizeof(WCHAR); + CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer); + } + else + { + Size = strlen(String); + CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer); + Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR)) + * sizeof(WCHAR); + } + RequestString->Length = RequestString->MaximumLength = Size; +} /* FUNCTIONS *****************************************************************/ @@ -336,29 +367,56 @@ DuplicateConsoleHandle(HANDLE hConsole, } -/* - * @unimplemented (Undocumented) - */ -DWORD -WINAPI -ExpungeConsoleCommandHistoryW(DWORD Unknown0) +static BOOL +IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode) { - DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(EXPUNGE_COMMAND_HISTORY, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.ExpungeCommandHistory.ExeName); + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } +/* + * @implemented (Undocumented) + */ +BOOL +WINAPI +ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName) +{ + return IntExpungeConsoleCommandHistory(lpExeName, TRUE); +} /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ -DWORD +BOOL WINAPI -ExpungeConsoleCommandHistoryA (DWORD Unknown0) +ExpungeConsoleCommandHistoryA(LPCSTR lpExeName) { - DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntExpungeConsoleCommandHistory(lpExeName, FALSE); } @@ -772,61 +830,139 @@ GetConsoleAliasesLengthA(LPSTR lpExeName) } +static DWORD +IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY, CSR_CONSOLE); + NTSTATUS Status; + DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR)); + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) + + HistoryLength); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.GetCommandHistory.ExeName); + Request.Data.GetCommandHistory.Length = HistoryLength; + CsrAllocateMessagePointer(CaptureBuffer, HistoryLength, + (PVOID*)&Request.Data.GetCommandHistory.History); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + CsrFreeCaptureBuffer(CaptureBuffer); + SetLastErrorByStatus(Status); + return 0; + } + + if (bUnicode) + { + memcpy(lpHistory, + Request.Data.GetCommandHistory.History, + Request.Data.GetCommandHistory.Length); + } + else + { + WideCharToMultiByte(CP_ACP, 0, + Request.Data.GetCommandHistory.History, + Request.Data.GetCommandHistory.Length / sizeof(WCHAR), + lpHistory, + cbHistory, + NULL, NULL); + } + CsrFreeCaptureBuffer(CaptureBuffer); + return Request.Data.GetCommandHistory.Length; +} + /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryW(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +GetConsoleCommandHistoryW(LPWSTR lpHistory, + DWORD cbHistory, + LPCWSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE); } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryA(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +GetConsoleCommandHistoryA(LPSTR lpHistory, + DWORD cbHistory, + LPCSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE); } +static DWORD +IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY_LENGTH, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.GetCommandHistoryLength.ExeName); + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return 0; + } + return Request.Data.GetCommandHistoryLength.Length; +} + /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryLengthW(DWORD Unknown0) +GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistoryLength(lpExeName, TRUE); } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryLengthA(DWORD Unknown0) +GetConsoleCommandHistoryLengthA(LPCSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR); } + /* * @unimplemented */ @@ -1038,19 +1174,6 @@ OpenConsoleW(LPCWSTR wsName, } -/* - * @unimplemented (Undocumented) - */ -BOOL -WINAPI -SetConsoleCommandHistoryMode(DWORD dwMode) -{ - DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - /* * @unimplemented (Undocumented) */ @@ -1176,31 +1299,61 @@ SetConsoleMenuClose(DWORD Unknown0) } -/* - * @unimplemented (Undocumented) - */ -BOOL -WINAPI -SetConsoleNumberOfCommandsA(DWORD Unknown0, - DWORD Unknown1) +static BOOL +IntSetConsoleNumberOfCommands(DWORD dwNumCommands, + LPCVOID lpExeName, + BOOL bUnicode) { - DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(SET_HISTORY_NUMBER_COMMANDS, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.SetHistoryNumberCommands.ExeName); + Request.Data.SetHistoryNumberCommands.NumCommands = dwNumCommands; + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ BOOL WINAPI -SetConsoleNumberOfCommandsW(DWORD Unknown0, - DWORD Unknown1) +SetConsoleNumberOfCommandsA(DWORD dwNumCommands, + LPCWSTR lpExeName) { - DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE); +} + +/* + * @implemented (Undocumented) + */ +BOOL +WINAPI +SetConsoleNumberOfCommandsW(DWORD dwNumCommands, + LPCSTR lpExeName) +{ + return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE); } @@ -4027,30 +4180,60 @@ GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer) /*-------------------------------------------------------------- * GetConsoleHistoryInfo * - * @unimplemented + * @implemented */ BOOL WINAPI GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo) { - DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE); + NTSTATUS Status; + if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + lpConsoleHistoryInfo->HistoryBufferSize = Request.Data.GetHistoryInfo.HistoryBufferSize; + lpConsoleHistoryInfo->NumberOfHistoryBuffers = Request.Data.GetHistoryInfo.NumberOfHistoryBuffers; + lpConsoleHistoryInfo->dwFlags = Request.Data.GetHistoryInfo.dwFlags; + return TRUE; } /*-------------------------------------------------------------- * SetConsoleHistoryInfo * - * @unimplemented + * @implemented */ BOOL WINAPI SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo) { - DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE); + NTSTATUS Status; + if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + Request.Data.SetHistoryInfo.HistoryBufferSize = lpConsoleHistoryInfo->HistoryBufferSize; + Request.Data.SetHistoryInfo.NumberOfHistoryBuffers = lpConsoleHistoryInfo->NumberOfHistoryBuffers; + Request.Data.SetHistoryInfo.dwFlags = lpConsoleHistoryInfo->dwFlags; + Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 8119392bc0b..1f8628ef712 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -479,6 +479,37 @@ typedef struct CONSOLE_SELECTION_INFO Info; } CSRSS_GET_CONSOLE_SELECTION_INFO, *PCSRSS_GET_CONSOLE_SELECTION_INFO; +typedef struct +{ + UNICODE_STRING ExeName; + DWORD Length; +} CSRSS_GET_COMMAND_HISTORY_LENGTH, *PCSRSS_GET_COMMAND_HISTORY_LENGTH; + +typedef struct +{ + UNICODE_STRING ExeName; + PWCHAR History; + DWORD Length; +} CSRSS_GET_COMMAND_HISTORY, *PCSRSS_GET_COMMAND_HISTORY; + +typedef struct +{ + UNICODE_STRING ExeName; +} CSRSS_EXPUNGE_COMMAND_HISTORY, *PCSRSS_EXPUNGE_COMMAND_HISTORY; + +typedef struct +{ + UNICODE_STRING ExeName; + DWORD NumCommands; +} CSRSS_SET_HISTORY_NUMBER_COMMANDS, *PCSRSS_SET_HISTORY_NUMBER_COMMANDS; + +typedef struct +{ + DWORD HistoryBufferSize; + DWORD NumberOfHistoryBuffers; + DWORD dwFlags; +} CSRSS_GET_HISTORY_INFO, *PCSRSS_GET_HISTORY_INFO, + CSRSS_SET_HISTORY_INFO, *PCSRSS_SET_HISTORY_INFO; #define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) #define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) @@ -554,6 +585,12 @@ typedef struct #define CREATE_THREAD (0x3F) #define SET_SCREEN_BUFFER_SIZE (0x40) #define GET_CONSOLE_SELECTION_INFO (0x41) +#define GET_COMMAND_HISTORY_LENGTH (0x42) +#define GET_COMMAND_HISTORY (0x43) +#define EXPUNGE_COMMAND_HISTORY (0x44) +#define SET_HISTORY_NUMBER_COMMANDS (0x45) +#define GET_HISTORY_INFO (0x46) +#define SET_HISTORY_INFO (0x47) /* Keep in sync with definition below. */ #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) @@ -629,6 +666,12 @@ typedef struct _CSR_API_MESSAGE CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; + CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength; + CSRSS_GET_COMMAND_HISTORY GetCommandHistory; + CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory; + CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands; + CSRSS_GET_HISTORY_INFO GetHistoryInfo; + CSRSS_SET_HISTORY_INFO SetHistoryInfo; } Data; } CSR_API_MESSAGE, *PCSR_API_MESSAGE; diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index a945e2efc23..95955890217 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -39,7 +39,7 @@ ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) } else if (KeyEvent->uChar.UnicodeChar == L'\r') { - /* TODO: add line to history */ + HistoryAddEntry(Console); Console->LineBuffer[Console->LineSize++] = L'\r'; if (Console->Mode & ENABLE_ECHO_INPUT) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 3ff3a19ceab..5a60c21a5a7 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -80,6 +80,10 @@ typedef struct tagCSRSS_CONSOLE WORD LineSize; /* current size of line */ WORD LinePos; /* current position within line */ BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */ + LIST_ENTRY HistoryBuffers; + WORD HistoryBufferSize; /* size for newly created history buffers */ + WORD NumberOfHistoryBuffers; /* maximum number of history buffers allowed */ + BOOLEAN HistoryNoDup; /* remove old duplicate history entries */ LIST_ENTRY BufferList; /* List of all screen buffers for this console */ PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ WORD Mode; /* Console mode flags */ @@ -110,6 +114,8 @@ typedef struct ConsoleInput_t #define CONSOLE_SELECTION_NOT_EMPTY 0x2 #define CONSOLE_MOUSE_SELECTION 0x4 #define CONSOLE_MOUSE_DOWN 0x8 +/* HistoryFlags values */ +#define HISTORY_NO_DUP_FLAG 0x1 /* PauseFlags values (internal only) */ #define PAUSED_FROM_KEYBOARD 0x1 @@ -214,4 +220,15 @@ CSR_API(CsrGetAllConsoleAliasesLength); CSR_API(CsrGetConsoleAliasesExes); CSR_API(CsrGetConsoleAliasesExesLength); +/* history.c */ +struct tagHISTORY_BUFFER; +VOID FASTCALL HistoryAddEntry(PCSRSS_CONSOLE Console); +VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist); +CSR_API(CsrGetCommandHistoryLength); +CSR_API(CsrGetCommandHistory); +CSR_API(CsrExpungeCommandHistory); +CSR_API(CsrSetHistoryNumberCommands); +CSR_API(CsrGetHistoryInfo); +CSR_API(CsrSetHistoryInfo); + /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/console.c b/reactos/subsystems/win32/csrss/win32csr/console.c index 5ace9ab3a3b..6db2a2ec34a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/console.c +++ b/reactos/subsystems/win32/csrss/win32csr/console.c @@ -88,6 +88,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) InitializeListHead(&Console->BufferList); Console->ActiveBuffer = NULL; InitializeListHead(&Console->InputEvents); + InitializeListHead(&Console->HistoryBuffers); Console->CodePage = GetOEMCP(); Console->OutputCodePage = GetOEMCP(); @@ -332,6 +333,9 @@ ConioDeleteConsole(Object_t *Object) ConioCleanupConsole(Console); if (Console->LineBuffer) RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer); + while (!IsListEmpty(&Console->HistoryBuffers)) + HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink); + ConioDeleteScreenBuffer(Console->ActiveBuffer); if (!IsListEmpty(&Console->BufferList)) { diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 009303ea811..081788394bb 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -81,6 +81,12 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent), CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize), CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo), + CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH, CsrGetCommandHistoryLength), + CSRSS_DEFINE_API(GET_COMMAND_HISTORY, CsrGetCommandHistory), + CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY, CsrExpungeCommandHistory), + CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS, CsrSetHistoryNumberCommands), + CSRSS_DEFINE_API(GET_HISTORY_INFO, CsrGetHistoryInfo), + CSRSS_DEFINE_API(SET_HISTORY_INFO, CsrSetHistoryInfo), { 0, 0, NULL } }; diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index e274872a6eb..d46d9cb4428 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -30,12 +30,9 @@ typedef struct GUI_CONSOLE_DATA_TAG WCHAR FontName[LF_FACESIZE]; DWORD FontSize; DWORD FontWeight; - DWORD HistoryNoDup; DWORD FullScreen; DWORD QuickEdit; DWORD InsertMode; - DWORD NumberOfHistoryBuffers; - DWORD HistoryBufferSize; DWORD WindowPosition; DWORD UseRasterFonts; COLORREF ScreenText; @@ -413,22 +410,24 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->NumberOfHistoryBuffers == 5) + if (Console->NumberOfHistoryBuffers == 5) { RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); } else { - RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); + DWORD Temp = Console->NumberOfHistoryBuffers; + RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); } - if (GuiData->HistoryBufferSize == 50) + if (Console->HistoryBufferSize == 50) { RegDeleteKeyW(hKey, L"HistoryBufferSize"); } else { - RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); + DWORD Temp = Console->HistoryBufferSize; + RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); } if (GuiData->FullScreen == FALSE) @@ -458,13 +457,14 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); } - if (GuiData->HistoryNoDup == FALSE) + if (Console->HistoryNoDup == FALSE) { RegDeleteKeyW(hKey, L"HistoryNoDup"); } else { - RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + DWORD Temp = Console->HistoryNoDup; + RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); } if (GuiData->ScreenText == RGB(192, 192, 192)) @@ -564,7 +564,7 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA } else if (!wcscmp(szValueName, L"HistoryNoDup")) { - GuiData->HistoryNoDup = Value; + Console->HistoryNoDup = Value; } else if (!wcscmp(szValueName, L"WindowSize")) { @@ -603,12 +603,9 @@ GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_ wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); GuiData->FontSize = 0x0008000C; // font is 8x12 GuiData->FontWeight = FW_NORMAL; - GuiData->HistoryNoDup = FALSE; GuiData->FullScreen = FALSE; GuiData->QuickEdit = FALSE; GuiData->InsertMode = TRUE; - GuiData->HistoryBufferSize = 50; - GuiData->NumberOfHistoryBuffers = 5; GuiData->ScreenText = RGB(192, 192, 192); GuiData->ScreenBackground = RGB(0, 0, 0); GuiData->PopupText = RGB(128, 0, 128); @@ -617,6 +614,9 @@ GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_ GuiData->UseRasterFonts = TRUE; memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); + Console->HistoryBufferSize = 50; + Console->NumberOfHistoryBuffers = 5; + Console->HistoryNoDup = FALSE; Console->Size.X = 80; Console->Size.Y = 25; @@ -1437,8 +1437,8 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiD /* setup struct */ SharedInfo.InsertMode = GuiData->InsertMode; - SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; - SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers; + SharedInfo.HistoryBufferSize = Console->HistoryBufferSize; + SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; SharedInfo.ScreenText = GuiData->ScreenText; SharedInfo.ScreenBackground = GuiData->ScreenBackground; SharedInfo.PopupText = GuiData->PopupText; @@ -1450,7 +1450,7 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiD SharedInfo.FontSize = (DWORD)GuiData->FontSize; SharedInfo.FontWeight = GuiData->FontWeight; SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; - SharedInfo.HistoryNoDup = GuiData->HistoryNoDup; + SharedInfo.HistoryNoDup = Console->HistoryNoDup; SharedInfo.FullScreen = GuiData->FullScreen; SharedInfo.QuickEdit = GuiData->QuickEdit; memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 728bd6adea4..3cf0931c0fb 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -26,6 +26,7 @@ guiconsole.c handle.c harderror.c + history.c tuiconsole.c appswitch.c win32csr.rc From 9ef0181983756b4ba5ff6acad74a0177a046796f Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 5 Jun 2010 03:12:51 +0000 Subject: [PATCH 236/292] add missing file svn path=/trunk/; revision=47581 --- .../subsystems/win32/csrss/win32csr/history.c | 304 ++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 reactos/subsystems/win32/csrss/win32csr/history.c diff --git a/reactos/subsystems/win32/csrss/win32csr/history.c b/reactos/subsystems/win32/csrss/win32csr/history.c new file mode 100644 index 00000000000..c7dfbd5cabc --- /dev/null +++ b/reactos/subsystems/win32/csrss/win32csr/history.c @@ -0,0 +1,304 @@ +/* + * PROJECT: ReactOS CSRSS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsystems/win32/csrss/win32csr/history.c + * PURPOSE: Console input history functions + * PROGRAMMERS: Jeffrey Morlan + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +typedef struct tagHISTORY_BUFFER +{ + LIST_ENTRY ListEntry; + WORD MaxEntries; + WORD NumEntries; + PUNICODE_STRING Entries; + UNICODE_STRING ExeName; +} HISTORY_BUFFER, *PHISTORY_BUFFER; + +/* FUNCTIONS *****************************************************************/ + +static PHISTORY_BUFFER +HistoryGetBuffer(PCSRSS_CONSOLE Console) +{ + /* TODO: use actual EXE name sent from process that called ReadConsole */ + UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" }; + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + PHISTORY_BUFFER Hist; + + for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink) + { + Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE)) + return Hist; + } + + /* Couldn't find the buffer, create a new one */ + Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length); + if (!Hist) + return NULL; + Hist->MaxEntries = Console->HistoryBufferSize; + Hist->NumEntries = 0; + Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING)); + if (!Hist->Entries) + { + HeapFree(Win32CsrApiHeap, 0, Hist); + return NULL; + } + Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length; + Hist->ExeName.Buffer = (PWCHAR)(Hist + 1); + memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length); + InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry); + return Hist; +} + +VOID FASTCALL +HistoryAddEntry(PCSRSS_CONSOLE Console) +{ + UNICODE_STRING NewEntry; + PHISTORY_BUFFER Hist; + INT i; + + NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR); + NewEntry.Buffer = Console->LineBuffer; + + if (!(Hist = HistoryGetBuffer(Console))) + return; + + /* Don't add blank or duplicate entries */ + if (NewEntry.Length == 0 || Hist->MaxEntries == 0 || + (Hist->NumEntries > 0 && + RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE))) + { + return; + } + + if (Console->HistoryNoDup) + { + /* Check if this line has been entered before */ + for (i = Hist->NumEntries - 1; i >= 0; i--) + { + if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE)) + { + /* Just rotate the list to bring this entry to the end */ + NewEntry = Hist->Entries[i]; + memmove(&Hist->Entries[i], &Hist->Entries[i + 1], + (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING)); + Hist->Entries[Hist->NumEntries - 1] = NewEntry; + return; + } + } + } + + if (Hist->NumEntries == Hist->MaxEntries) + { + /* List is full, remove oldest entry */ + RtlFreeUnicodeString(&Hist->Entries[0]); + memmove(&Hist->Entries[0], &Hist->Entries[1], + --Hist->NumEntries * sizeof(UNICODE_STRING)); + } + + if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries]))) + Hist->NumEntries++; +} + +static PHISTORY_BUFFER +HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName) +{ + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + while (Entry != &Console->HistoryBuffers) + { + /* For the history APIs, the caller is allowed to give only part of the name */ + PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE)) + return Hist; + Entry = Entry->Flink; + } + return NULL; +} + +VOID FASTCALL +HistoryDeleteBuffer(PHISTORY_BUFFER Hist) +{ + while (Hist->NumEntries != 0) + RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]); + HeapFree(Win32CsrApiHeap, 0, Hist->Entries); + RemoveEntryList(&Hist->ListEntry); + HeapFree(Win32CsrApiHeap, 0, Hist); +} + +CSR_API(CsrGetCommandHistoryLength) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + ULONG Length = 0; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistoryLength.ExeName.Buffer, + Request->Data.GetCommandHistoryLength.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + Length += Hist->Entries[i].Length + sizeof(WCHAR); + } + Request->Data.GetCommandHistoryLength.Length = Length; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetCommandHistory) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History; + ULONG BufferSize = Request->Data.GetCommandHistory.Length; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) || + !Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistory.ExeName.Buffer, + Request->Data.GetCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + { + if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR))) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length); + Buffer += Hist->Entries[i].Length; + *(PWCHAR)Buffer = L'\0'; + Buffer += sizeof(WCHAR); + } + } + Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrExpungeCommandHistory) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.ExpungeCommandHistory.ExeName.Buffer, + Request->Data.ExpungeCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName); + if (Hist) + HistoryDeleteBuffer(Hist); + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryNumberCommands) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands; + PUNICODE_STRING OldEntryList, NewEntryList; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.SetHistoryNumberCommands.ExeName.Buffer, + Request->Data.SetHistoryNumberCommands.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName); + if (Hist) + { + OldEntryList = Hist->Entries; + NewEntryList = HeapAlloc(Win32CsrApiHeap, 0, + MaxEntries * sizeof(UNICODE_STRING)); + if (!NewEntryList) + { + Status = STATUS_NO_MEMORY; + } + else + { + /* If necessary, shrink by removing oldest entries */ + for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--) + RtlFreeUnicodeString(Hist->Entries++); + + Hist->MaxEntries = MaxEntries; + Hist->Entries = memcpy(NewEntryList, Hist->Entries, + Hist->NumEntries * sizeof(UNICODE_STRING)); + HeapFree(Win32CsrApiHeap, 0, OldEntryList); + } + } + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize; + Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; + Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize; + Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers; + Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG; + ConioUnlockConsole(Console); + } + return Status; +} + +/* EOF */ From f4f8ee78d1c08075312542b976b86e4596014d17 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 04:16:46 +0000 Subject: [PATCH 237/292] [NTOS]: Implement MiDeleteSystemPageableVm. [NTOS]: The paged pool free code was behaving incorrectly, assuming that paged pool was "locked down" and never paged out/reused (a valid NT operation mode), while the allocation code was assuming paged pool was a volatile, reusable, pageable resource (normal NT operation mode). The free code now assumes normal operation mode, and actually frees the freed paged pool pages, by using MiDeleteSystemPageableVm. I have a feeling this will make ARM3 paged pool work. svn path=/trunk/; revision=47582 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 9 +++ reactos/ntoskrnl/mm/ARM3/pool.c | 6 ++ reactos/ntoskrnl/mm/ARM3/virtual.c | 96 ++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index efcc0537ebc..67eeb4238cf 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -733,6 +733,15 @@ MiInsertPageInFreeList( IN PFN_NUMBER PageFrameIndex ); +PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm( + IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages +); + PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry( diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index c4a73746d6b..e3af2a6d6b5 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -264,6 +264,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // Get the page bit count // i = ((SizeInPages - 1) / 1024) + 1; + DPRINT1("Paged pool expansion: %d %x\n", i, SizeInPages); // // Check if there is enougn paged pool expansion space left @@ -666,6 +667,11 @@ MiFreePoolPages(IN PVOID StartingVa) // NumberOfPages = End - i + 1; + /* Delete the actual pages */ + PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i; + FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL); + ASSERT(FreePages == NumberOfPages); + // // Acquire the paged pool lock // diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 88ff54f5dcc..a517cba0892 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -29,6 +29,102 @@ MiProtectVirtualMemory(IN PEPROCESS Process, /* PRIVATE FUNCTIONS **********************************************************/ +PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm(IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages) +{ + PFN_NUMBER ActualPages = 0; + PETHREAD CurrentThread; + PMMPFN Pfn1, Pfn2; + PFN_NUMBER PageFrameIndex, PageTableIndex; + KIRQL OldIrql, LockIrql; + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* + * Now we must raise to APC_LEVEL and mark the thread as owner + * We don't actually implement a working set pushlock, so this is only + * for internal consistency (and blocking APCs) + */ + KeRaiseIrql(APC_LEVEL, &LockIrql); + CurrentThread = PsGetCurrentThread(); + KeEnterGuardedRegion(); + ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) && + (CurrentThread->OwnsSystemWorkingSetShared == 0)); + CurrentThread->OwnsSystemWorkingSetExclusive = 1; + + /* Loop all pages */ + while (PageCount) + { + /* Make sure there's some data about the page */ + if (PointerPte->u.Long) + { + /* As always, only handle current ARM3 scenarios */ + ASSERT(PointerPte->u.Soft.Prototype == 0); + ASSERT(PointerPte->u.Soft.Transition == 0); + ASSERT(PointerPte->u.Hard.Valid == 1); + + /* Normally this is one possibility -- freeing a valid page */ + if (PointerPte->u.Hard.Valid) + { + /* Get the page PFN */ + PageFrameIndex = PFN_FROM_PTE(PointerPte); + Pfn1 = MiGetPfnEntry(PageFrameIndex); + + /* Should not have any working set data yet */ + ASSERT(Pfn1->u1.WsIndex == 0); + + /* Actual valid, legitimate, pages */ + if (ValidPages) *ValidPages++; + + /* Get the page table entry */ + PageTableIndex = Pfn1->u4.PteFrame; + DPRINT1("Page table: %lx\n", PageTableIndex); + Pfn2 = MiGetPfnEntry(PageTableIndex); + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Delete it the page */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn1, PageFrameIndex); + + /* Decrement the page table too */ + #if 0 // ARM3: Dont't trust this yet + MiDecrementShareCount(Pfn2, PageTableIndex); + #endif + + /* Release the PFN database */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + /* Destroy the PTE */ + PointerPte->u.Long = 0; + } + + /* Actual legitimate pages */ + ActualPages++; + } + + /* Keep going */ + PointerPte++; + PageCount--; + } + + /* Re-enable APCs */ + ASSERT(KeAreAllApcsDisabled() == TRUE); + CurrentThread->OwnsSystemWorkingSetExclusive = 0; + KeLeaveGuardedRegion(); + KeLowerIrql(LockIrql); + + /* Flush the entire TLB */ + KeFlushEntireTb(TRUE, TRUE); + + /* Done */ + return ActualPages; +} + LONG MiGetExceptionInfo(IN PEXCEPTION_POINTERS ExceptionInfo, OUT PBOOLEAN HaveBadAddress, From 7da6d0a6e26628bf32c01c46aaad429b42153c01 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 5 Jun 2010 06:10:53 +0000 Subject: [PATCH 238/292] [WIN32CSR] Implement some basic line editing capability svn path=/trunk/; revision=47584 --- .../win32/csrss/win32csr/coninput.c | 147 +++++++++++++++--- .../win32/csrss/win32csr/win32csr.rbuild | 2 +- 2 files changed, 128 insertions(+), 21 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index 95955890217..51777ddac90 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -22,25 +22,143 @@ /* FUNCTIONS *****************************************************************/ +static VOID +ConioLineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos) +{ + if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT) + { + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + UINT OldCursorX = Buffer->CurrentX; + UINT OldCursorY = Buffer->CurrentY; + INT XY = OldCursorY * Buffer->MaxX + OldCursorX; + + XY += (Pos - Console->LinePos); + if (XY < 0) + XY = 0; + else if (XY >= Buffer->MaxY * Buffer->MaxX) + XY = Buffer->MaxY * Buffer->MaxX - 1; + + Buffer->CurrentX = XY % Buffer->MaxX; + Buffer->CurrentY = XY / Buffer->MaxX; + ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY); + } + + Console->LinePos = Pos; +} + +static VOID +ConioLineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion) +{ + UINT Pos = Console->LinePos; + UINT NewSize = Console->LineSize - NumToDelete + NumToInsert; + INT i; + + /* Make sure there's always enough room for ending \r\n */ + if (NewSize + 2 > Console->LineMaxSize) + return; + + memmove(&Console->LineBuffer[Pos + NumToInsert], + &Console->LineBuffer[Pos + NumToDelete], + (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR)); + memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR)); + + if (Console->Mode & ENABLE_ECHO_INPUT) + { + for (i = Pos; i < NewSize; i++) + { + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &Console->LineBuffer[i], 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + } + for (; i < Console->LineSize; i++) + { + ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE); + } + Console->LinePos = i; + } + + Console->LineSize = NewSize; + ConioLineInputSetPos(Console, Pos + NumToInsert); +} + static VOID ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) { + UINT Pos = Console->LinePos; + switch (KeyEvent->wVirtualKeyCode) + { + case VK_ESCAPE: + /* Clear entire line */ + ConioLineInputSetPos(Console, 0); + ConioLineInputEdit(Console, Console->LineSize, 0, NULL); + return; + case VK_HOME: + /* Move to start of line. With ctrl, erase everything left of cursor */ + ConioLineInputSetPos(Console, 0); + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + ConioLineInputEdit(Console, Pos, 0, NULL); + return; + case VK_END: + /* Move to end of line. With ctrl, erase everything right of cursor */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + ConioLineInputEdit(Console, Console->LineSize - Pos, 0, NULL); + else + ConioLineInputSetPos(Console, Console->LineSize); + return; + case VK_LEFT: + /* Move left. With ctrl, move to beginning of previous word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--; + while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--; + } + else + { + Pos -= (Pos > 0); + } + ConioLineInputSetPos(Console, Pos); + return; + case VK_RIGHT: + /* Move right. With ctrl, move to beginning of next word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++; + while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++; + } + else + { + Pos += (Pos < Console->LineSize); + } + ConioLineInputSetPos(Console, Pos); + return; + case VK_DELETE: + /* Remove character to right of cursor */ + if (Pos != Console->LineSize) + ConioLineInputEdit(Console, 1, 0, NULL); + return; + case VK_F6: + /* Insert a ^Z character */ + KeyEvent->uChar.UnicodeChar = 26; + break; + } + if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) { - /* backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if (Console->LineSize > 0) + /* backspace handling - if processed input enabled then we handle it here + * otherwise we treat it like a normal char. */ + if (Pos > 0) { - Console->LineSize--; - if (Console->Mode & ENABLE_ECHO_INPUT) - ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); + ConioLineInputSetPos(Console, Pos - 1); + ConioLineInputEdit(Console, 1, 0, NULL); } } else if (KeyEvent->uChar.UnicodeChar == L'\r') { HistoryAddEntry(Console); + ConioLineInputSetPos(Console, Console->LineSize); Console->LineBuffer[Console->LineSize++] = L'\r'; if (Console->Mode & ENABLE_ECHO_INPUT) ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); @@ -55,19 +173,8 @@ ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) } else if (KeyEvent->uChar.UnicodeChar != L'\0') { - if (Console->LineSize + 2 < Console->LineMaxSize) - { - Console->LineBuffer[Console->LineSize++] = KeyEvent->uChar.UnicodeChar; - /* echo to screen if enabled */ - if (Console->Mode & ENABLE_ECHO_INPUT) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &KeyEvent->uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - } - } + /* Normal character */ + ConioLineInputEdit(Console, 0, 1, &KeyEvent->uChar.UnicodeChar); } } diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 3cf0931c0fb..96e3be51b2f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -26,7 +26,7 @@ guiconsole.c handle.c harderror.c - history.c + history.c tuiconsole.c appswitch.c win32csr.rc From 89c8d4178cb14d9c3e3acdd9ac013d91ae55b681 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 5 Jun 2010 12:20:53 +0000 Subject: [PATCH 239/292] [NTOSKRNL] NtDuplicateToken: Fail, if a primary token is to be created from an impersonation token and and the impersonation level of the impersonation token is below SecurityImpersonation. svn path=/trunk/; revision=47586 --- reactos/ntoskrnl/se/token.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index aa281bc68d5..6ee52544ba4 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1871,6 +1871,21 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, } } + /* + * Fail, if a primary token is to be created from an impersonation token + * and and the impersonation level of the impersonation token is below SecurityImpersonation. + */ + if (Token->TokenType == TokenImpersonation && + TokenType == TokenPrimary && + Token->ImpersonationLevel < SecurityImpersonation) + { + ObDereferenceObject(Token); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + Status = SepDuplicateToken(Token, ObjectAttributes, EffectiveOnly, From a2a190f44b1b717f74c991265f3219c7ac0c2887 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 14:54:26 +0000 Subject: [PATCH 240/292] [NTOS]: In MiDeleteSystemPageableVm, should also handle the case where the PTE is demand-zero. This can happen if the caller allocated, say, 12KB (3 pages) of paged pool, only touched 4KB (1 page), and then frees the allocation -- the other 2 pages will still be demand-zero at this point. svn path=/trunk/; revision=47587 --- reactos/ntoskrnl/mm/ARM3/virtual.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index a517cba0892..02c17f51de9 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -64,7 +64,6 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte, /* As always, only handle current ARM3 scenarios */ ASSERT(PointerPte->u.Soft.Prototype == 0); ASSERT(PointerPte->u.Soft.Transition == 0); - ASSERT(PointerPte->u.Hard.Valid == 1); /* Normally this is one possibility -- freeing a valid page */ if (PointerPte->u.Hard.Valid) @@ -106,6 +105,20 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte, /* Actual legitimate pages */ ActualPages++; } + else + { + /* + * The only other ARM3 possibility is a demand zero page, which would + * mean freeing some of the paged pool pages that haven't even been + * touched yet, as part of a larger allocation. + * + * Right now, we shouldn't expect any page file information in the PTE + */ + ASSERT(PointerPte->u.Soft.PageFileHigh == 0); + + /* Destroy the PTE */ + PointerPte->u.Long = 0; + } /* Keep going */ PointerPte++; From 549eedeeb409b889d6ba5eb6e4e56328f4e71eaf Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 14:55:17 +0000 Subject: [PATCH 241/292] [NTOS]: In MiInitializePfnForOtherProcess, should increment the sharecount of the page table PFN entry, not the PFN entry of the PTE itself. Spotted by Stefan100. svn path=/trunk/; revision=47588 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 00afacf0e77..bc0167e03f2 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -791,7 +791,7 @@ MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, Pfn1->u4.PteFrame = PteFrame; /* Increase its share count so we don't get rid of it */ - Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PteFrame); Pfn1->u2.ShareCount++; } } From 6aad48190c9b4e7d9be8553bbee8ebd3507b0eac Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 14:59:50 +0000 Subject: [PATCH 242/292] [NTOS]: Don't assume that ANY fault in the system address range, not associated to a memory area, might be ARM3. Instead, since this hack only exists for early boot page pool support, make only treat this as an ARM3 fault when it happens in the paged pool area or higher. Leads to more direct Mm crashes when invalid page access happens, instead of infinite "PAGE FAULT ON PAGE TABLES". svn path=/trunk/; revision=47589 --- reactos/ntoskrnl/mm/mmfault.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index f908e608bed..6f04e941b42 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -284,13 +284,13 @@ MmAccessFault(IN BOOLEAN StoreInstruction, * can go away. */ MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address); - if ((!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)) || + if ((!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) || ((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3))) { // // Hand it off to more competent hands... // - DPRINT1("ARM3 fault\n"); + DPRINT1("ARM3 fault %p\n", MemoryArea); return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation); } From cb9c4019bbf17e84e0cbbdc5d46bdb341b3d5b62 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 16:53:54 +0000 Subject: [PATCH 243/292] [NTOS]: Define the POOL_HEADER for x64. [NTOS]: Define POOL_BLOCK_SIZE definition to set the minimum pool block size. In NT, this is equal to a LIST_ENTRY structure, because the Pool Allocator must be able to store a LIST_ENTRY into a freed pool block. This also determines the alignment of pool allocations. So 8 on x86, 16 on x64. [NTOS]: Don't depend on LIST_ENTRY, but use POOL_BLOCK_SIZE instead (on IA64, if we ever want to support this, the pool block size is different from a LIST_ENTRY/POOL_HEADER). [NTOS]: The following ASSERTs must hold: the POOL_HEADER must be as big as the the smallest pool block (POOL_BLOCK_SIZE), which must be at least as big as a LIST_ENTRY structure. 8 == 8 == 8 on x86, 16 == 16 == 16 on x64. svn path=/trunk/; revision=47592 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 67eeb4238cf..b5adad3e5fe 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -225,13 +225,18 @@ MmProtectToPteMask[32] = // Special IRQL value (found in assertions) // #define MM_NOIRQL (KIRQL)0xFFFFFFFF - + // // FIXFIX: These should go in ex.h after the pool merge // -#define POOL_LISTS_PER_PAGE (PAGE_SIZE / sizeof(LIST_ENTRY)) +#ifdef _M_AMD64 +#define POOL_BLOCK_SIZE 16 +#else +#define POOL_BLOCK_SIZE 8 +#endif +#define POOL_LISTS_PER_PAGE (PAGE_SIZE / POOL_BLOCK_SIZE) #define BASE_POOL_TYPE_MASK 1 -#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + sizeof(LIST_ENTRY))) +#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE)) typedef struct _POOL_DESCRIPTOR { @@ -256,16 +261,30 @@ typedef struct _POOL_HEADER { struct { +#ifdef _M_AMD64 + ULONG PreviousSize:8; + ULONG PoolIndex:8; + ULONG BlockSize:8; + ULONG PoolType:8; +#else USHORT PreviousSize:9; USHORT PoolIndex:7; USHORT BlockSize:9; USHORT PoolType:7; +#endif }; ULONG Ulong1; }; +#ifdef _M_AMD64 + ULONG PoolTag; +#endif union { +#ifdef _M_AMD64 + PEPROCESS ProcessBilled; +#else ULONG PoolTag; +#endif struct { USHORT AllocatorBackTraceIndex; @@ -274,11 +293,8 @@ typedef struct _POOL_HEADER }; } POOL_HEADER, *PPOOL_HEADER; -// -// Everything depends on this -// -C_ASSERT(sizeof(POOL_HEADER) == 8); -C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY)); +C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE); +C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY)); extern ULONG ExpNumberOfPagedPools; extern POOL_DESCRIPTOR NonPagedPoolDescriptor; From e8b356d8003f5954a5d551187a753f8b59cf4a3d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 5 Jun 2010 17:51:12 +0000 Subject: [PATCH 244/292] [NTOSKRNL] - Print the base address of the process that we killed to make debugging much easier svn path=/trunk/; revision=47593 --- reactos/ntoskrnl/ke/i386/exp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 38dded77062..ebc327fb58c 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -1082,10 +1082,11 @@ DispatchToUser: } /* 3rd strike, kill the process */ - DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n", + DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n", PsGetCurrentProcess()->ImageFileName, ExceptionRecord->ExceptionCode, - ExceptionRecord->ExceptionAddress); + ExceptionRecord->ExceptionAddress, + PsGetCurrentProcess()->SectionBaseAddress); ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, From fc1ffb8a44b4c4d615b30b55a654636d040d901b Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 17:53:17 +0000 Subject: [PATCH 245/292] [NTOS]: Use logical math operations on the various block<->entry<->free_list_head operations in the pool code, instead of works-by-chance-and-assumption pointer math operations. This will now allow pool implementations where the pool header is not the size of a pool block (and the size of a LIST_ENTRY, by definition, although, even that, could change, if we choose to implement a cache-aligned overhead). svn path=/trunk/; revision=47594 --- reactos/ntoskrnl/mm/ARM3/expool.c | 60 +++++++++++++++++++------------ 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index c10d8c87d56..e73d3e112aa 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -28,6 +28,13 @@ PPOOL_DESCRIPTOR PoolVector[2]; PVOID PoolTrackTable; PKGUARDED_MUTEX ExpPagedPoolMutex; +/* Pool block/header/list access macros */ +#define POOL_ENTRY(x) (PPOOL_HEADER)((ULONG_PTR)x - sizeof(POOL_HEADER)) +#define POOL_FREE_BLOCK(x) (PLIST_ENTRY)((ULONG_PTR)x + sizeof(POOL_HEADER)) +#define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)x + ((i) * POOL_BLOCK_SIZE)) +#define POOL_NEXT_BLOCK(x) POOL_BLOCK(x, x->BlockSize) +#define POOL_PREV_BLOCK(x) POOL_BLOCK(x, -x->PreviousSize) + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -68,7 +75,11 @@ ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor, // NextEntry = PoolDescriptor->ListHeads; LastEntry = NextEntry + POOL_LISTS_PER_PAGE; - while (NextEntry < LastEntry) InitializeListHead(NextEntry++); + while (NextEntry < LastEntry) + { + InitializeListHead(NextEntry); + NextEntry++; + } } VOID @@ -239,8 +250,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // request would've been treated as a POOL_MAX_ALLOC earlier and resulted in // the direct allocation of pages. // - i = (NumberOfBytes + sizeof(POOL_HEADER) + sizeof(LIST_ENTRY) - 1) / - sizeof(POOL_HEADER); + i = (NumberOfBytes + sizeof(POOL_HEADER) + (POOL_BLOCK_SIZE - 1)) / POOL_BLOCK_SIZE; // // Loop in the free lists looking for a block if this size. Start with the @@ -281,7 +291,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // there is a guarantee that any block on this list will either be // of the correct size, or perhaps larger. // - Entry = (PPOOL_HEADER)RemoveHeadList(ListHead) - 1; + Entry = POOL_ENTRY(RemoveHeadList(ListHead)); ASSERT(Entry->BlockSize >= i); ASSERT(Entry->PoolType == 0); @@ -302,7 +312,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // turn it into a fragment that contains the leftover data // that we don't need to satisfy the caller's request // - FragmentEntry = Entry + i; + FragmentEntry = POOL_BLOCK(Entry, i); FragmentEntry->BlockSize = Entry->BlockSize - i; // @@ -314,7 +324,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // Now get the block that follows the new fragment and check // if it's still on the same page as us (and not at the end) // - NextEntry = FragmentEntry + FragmentEntry->BlockSize; + NextEntry = POOL_NEXT_BLOCK(FragmentEntry); if (PAGE_ALIGN(NextEntry) != NextEntry) { // @@ -346,14 +356,14 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // This is the entry that will actually end up holding the // allocation! // - Entry += Entry->BlockSize; + Entry = POOL_NEXT_BLOCK(Entry); Entry->PreviousSize = FragmentEntry->BlockSize; // // And now let's go to the entry after that one and check if // it's still on the same page, and not at the end // - NextEntry = Entry + i; + NextEntry = POOL_BLOCK(Entry, i); if (PAGE_ALIGN(NextEntry) != NextEntry) { // @@ -387,7 +397,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // Insert the free entry into the free list for this size // InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - (PLIST_ENTRY)FragmentEntry + 1); + POOL_FREE_BLOCK(FragmentEntry)); } } @@ -402,7 +412,9 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // Return the pool allocation // Entry->PoolTag = Tag; - return ++Entry; + (POOL_FREE_BLOCK(Entry))->Flink = NULL; + (POOL_FREE_BLOCK(Entry))->Blink = NULL; + return POOL_FREE_BLOCK(Entry); } } while (++ListHead != &PoolDesc->ListHeads[POOL_LISTS_PER_PAGE]); @@ -410,6 +422,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // There were no free entries left, so we have to allocate a new fresh page // Entry = MiAllocatePoolPages(PoolType, PAGE_SIZE); + ASSERT(Entry != NULL); Entry->Ulong1 = 0; Entry->BlockSize = i; Entry->PoolType = PoolType + 1; @@ -420,8 +433,8 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // to create now. The free bytes are the whole page minus what was allocated // and then converted into units of block headers. // - BlockSize = (PAGE_SIZE / sizeof(POOL_HEADER)) - i; - FragmentEntry = Entry + i; + BlockSize = (PAGE_SIZE / POOL_BLOCK_SIZE) - i; + FragmentEntry = POOL_BLOCK(Entry, i); FragmentEntry->Ulong1 = 0; FragmentEntry->BlockSize = BlockSize; FragmentEntry->PreviousSize = i; @@ -442,8 +455,8 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // And insert the free entry into the free list for this block size // InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - (PLIST_ENTRY)FragmentEntry + 1); - + POOL_FREE_BLOCK(FragmentEntry)); + // // Release the pool lock // @@ -454,7 +467,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // And return the pool allocation // Entry->PoolTag = Tag; - return ++Entry; + return POOL_FREE_BLOCK(Entry); } /* @@ -485,7 +498,7 @@ ExFreePoolWithTag(IN PVOID P, POOL_TYPE PoolType; PPOOL_DESCRIPTOR PoolDesc; BOOLEAN Combined = FALSE; - +#if 1 // // Check for paged pool // @@ -498,6 +511,7 @@ ExFreePoolWithTag(IN PVOID P, ExFreePagedPool(P); return; } +#endif // // Quickly deal with big page allocations @@ -526,7 +540,7 @@ ExFreePoolWithTag(IN PVOID P, // // Get the pointer to the next entry // - NextEntry = Entry + BlockSize; + NextEntry = POOL_BLOCK(Entry, BlockSize); // // Acquire the pool lock @@ -559,7 +573,7 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList((PLIST_ENTRY)NextEntry + 1); + RemoveEntryList(POOL_FREE_BLOCK(NextEntry)); } // @@ -577,7 +591,7 @@ ExFreePoolWithTag(IN PVOID P, // // Great, grab that entry and check if it's free // - NextEntry = Entry - Entry->PreviousSize; + NextEntry = POOL_PREV_BLOCK(Entry); if (NextEntry->PoolType == 0) { // @@ -596,7 +610,7 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList((PLIST_ENTRY)NextEntry + 1); + RemoveEntryList(POOL_FREE_BLOCK(NextEntry)); } // @@ -618,7 +632,7 @@ ExFreePoolWithTag(IN PVOID P, // page, they could've all been combined). // if ((PAGE_ALIGN(Entry) == Entry) && - (PAGE_ALIGN(Entry + Entry->BlockSize) == Entry + Entry->BlockSize)) + (PAGE_ALIGN(POOL_NEXT_BLOCK(Entry)) == POOL_NEXT_BLOCK(Entry))) { // // In this case, release the pool lock, and free the page @@ -644,7 +658,7 @@ ExFreePoolWithTag(IN PVOID P, // Get the first combined block (either our original to begin with, or // the one after the original, depending if we combined with the previous) // - NextEntry = Entry + BlockSize; + NextEntry = POOL_NEXT_BLOCK(Entry); // // As long as the next block isn't on a page boundary, have it point @@ -656,7 +670,7 @@ ExFreePoolWithTag(IN PVOID P, // // Insert this new free block, and release the pool lock // - InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], (PLIST_ENTRY)Entry + 1); + InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], POOL_FREE_BLOCK(Entry)); ExUnlockPool(PoolDesc, OldIrql); } From 81589f83caed3f27c814bfeaed3610addfaa4f7f Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 17:54:19 +0000 Subject: [PATCH 246/292] [NTOS]: Defensive programming on the pool macros. svn path=/trunk/; revision=47595 --- reactos/ntoskrnl/mm/ARM3/expool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index e73d3e112aa..568fb79bb80 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -29,11 +29,11 @@ PVOID PoolTrackTable; PKGUARDED_MUTEX ExpPagedPoolMutex; /* Pool block/header/list access macros */ -#define POOL_ENTRY(x) (PPOOL_HEADER)((ULONG_PTR)x - sizeof(POOL_HEADER)) -#define POOL_FREE_BLOCK(x) (PLIST_ENTRY)((ULONG_PTR)x + sizeof(POOL_HEADER)) -#define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)x + ((i) * POOL_BLOCK_SIZE)) -#define POOL_NEXT_BLOCK(x) POOL_BLOCK(x, x->BlockSize) -#define POOL_PREV_BLOCK(x) POOL_BLOCK(x, -x->PreviousSize) +#define POOL_ENTRY(x) (PPOOL_HEADER)((ULONG_PTR)(x) - sizeof(POOL_HEADER)) +#define POOL_FREE_BLOCK(x) (PLIST_ENTRY)((ULONG_PTR)(x) + sizeof(POOL_HEADER)) +#define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)(x) + ((i) * POOL_BLOCK_SIZE)) +#define POOL_NEXT_BLOCK(x) POOL_BLOCK((x), (x)->BlockSize) +#define POOL_PREV_BLOCK(x) POOL_BLOCK((x), -(x)->PreviousSize) /* PRIVATE FUNCTIONS **********************************************************/ From 745031cf0b70011be78184c248780799c241ec78 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 18:02:45 +0000 Subject: [PATCH 247/292] [NTOS]: Add some paranoid-invariant list access checks to the pool code. They serve a dual purpose: catch pool corruption by broken drivers/kernel code, as well as catch malicious modification of the pool links as part of a kernel-mode exploit. [NTOS]: Not yet used, thanks to Arthur for the idea. See comment for more information. svn path=/trunk/; revision=47596 --- reactos/ntoskrnl/mm/ARM3/expool.c | 119 +++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index 568fb79bb80..dd4598a7d12 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -34,7 +34,124 @@ PKGUARDED_MUTEX ExpPagedPoolMutex; #define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)(x) + ((i) * POOL_BLOCK_SIZE)) #define POOL_NEXT_BLOCK(x) POOL_BLOCK((x), (x)->BlockSize) #define POOL_PREV_BLOCK(x) POOL_BLOCK((x), -(x)->PreviousSize) - + +/* + * Pool list access debug macros, similar to Arthur's pfnlist.c work. + * Microsoft actually implements similar checks in the Windows Server 2003 SP1 + * pool code, but only for checked builds. + * As of Vista, however, an MSDN Blog entry by a Security Team Manager indicates + * that these checks are done even on retail builds, due to the increasing + * number of kernel-mode attacks which depend on dangling list pointers and other + * kinds of list-based attacks. + * For now, I will leave these checks on all the time, but later they are likely + * to be DBG-only, at least until there are enough kernel-mode security attacks + * against ReactOS to warrant the performance hit. + * + */ +FORCEINLINE +PLIST_ENTRY +ExpDecodePoolLink(IN PLIST_ENTRY Link) +{ + return (PLIST_ENTRY)((ULONG_PTR)Link & ~1); +} + +FORCEINLINE +PLIST_ENTRY +ExpEncodePoolLink(IN PLIST_ENTRY Link) +{ + return (PLIST_ENTRY)((ULONG_PTR)Link | 1); +} + +FORCEINLINE +VOID +ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) +{ + if ((ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Flink)->Blink) != ListHead) || + (ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Blink)->Flink) != ListHead)) + { + KeBugCheckEx(BAD_POOL_HEADER, + 3, + (ULONG_PTR)ListHead, + (ULONG_PTR)ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Flink)->Blink), + (ULONG_PTR)ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Blink)->Flink)); + } +} + +FORCEINLINE +VOID +ExpInitializePoolListHead(IN PLIST_ENTRY ListHead) +{ + ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead); +} + +FORCEINLINE +BOOLEAN +ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead) +{ + return (ExpDecodePoolLink(ListHead->Flink) == ListHead); +} + +FORCEINLINE +VOID +ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Blink, Flink; + Flink = ExpDecodePoolLink(Entry->Flink); + Blink = ExpDecodePoolLink(Entry->Blink); + Blink->Flink = ExpEncodePoolLink(Flink); + Flink->Blink = ExpEncodePoolLink(Blink); +} + +FORCEINLINE +PLIST_ENTRY +ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Head; + Head = ExpDecodePoolLink(ListHead->Flink); + ExpRemovePoolEntryList(Head); + return Head; +} + +FORCEINLINE +PLIST_ENTRY +ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Tail; + Tail = ExpDecodePoolLink(ListHead->Blink); + ExpRemovePoolEntryList(Tail); + return Tail; +} + +FORCEINLINE +VOID +ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Blink; + ExpCheckPoolLinks(ListHead); + Blink = ExpDecodePoolLink(ListHead->Blink); + Entry->Flink = ExpEncodePoolLink(ListHead); + Entry->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(Entry); + ListHead->Blink = ExpEncodePoolLink(Entry); + ExpCheckPoolLinks(ListHead); +} + +FORCEINLINE +VOID +ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Flink; + ExpCheckPoolLinks(ListHead); + Flink = ExpDecodePoolLink(ListHead->Blink); + Entry->Flink = ExpEncodePoolLink(Flink); + Entry->Blink = ExpEncodePoolLink(ListHead); + Flink->Blink = ExpEncodePoolLink(Entry); + ListHead->Flink = ExpEncodePoolLink(Entry); + ExpCheckPoolLinks(ListHead); +} + /* PRIVATE FUNCTIONS **********************************************************/ VOID From ffce25e51549fa0764074e7c136514c042c54a41 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sat, 5 Jun 2010 18:17:42 +0000 Subject: [PATCH 248/292] [WIN32CSR] - Implement basic support for history in line editing - Reorganize code to reflect that line input is more coupled to history than it is to character input svn path=/trunk/; revision=47597 --- .../win32/csrss/win32csr/coninput.c | 159 +---- .../subsystems/win32/csrss/win32csr/conio.h | 5 +- .../subsystems/win32/csrss/win32csr/history.c | 304 ---------- .../win32/csrss/win32csr/lineinput.c | 574 ++++++++++++++++++ .../win32/csrss/win32csr/win32csr.rbuild | 2 +- 5 files changed, 580 insertions(+), 464 deletions(-) delete mode 100644 reactos/subsystems/win32/csrss/win32csr/history.c create mode 100644 reactos/subsystems/win32/csrss/win32csr/lineinput.c diff --git a/reactos/subsystems/win32/csrss/win32csr/coninput.c b/reactos/subsystems/win32/csrss/win32csr/coninput.c index 51777ddac90..fa770aaade3 100644 --- a/reactos/subsystems/win32/csrss/win32csr/coninput.c +++ b/reactos/subsystems/win32/csrss/win32csr/coninput.c @@ -22,162 +22,6 @@ /* FUNCTIONS *****************************************************************/ -static VOID -ConioLineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos) -{ - if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT) - { - PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; - UINT OldCursorX = Buffer->CurrentX; - UINT OldCursorY = Buffer->CurrentY; - INT XY = OldCursorY * Buffer->MaxX + OldCursorX; - - XY += (Pos - Console->LinePos); - if (XY < 0) - XY = 0; - else if (XY >= Buffer->MaxY * Buffer->MaxX) - XY = Buffer->MaxY * Buffer->MaxX - 1; - - Buffer->CurrentX = XY % Buffer->MaxX; - Buffer->CurrentY = XY / Buffer->MaxX; - ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY); - } - - Console->LinePos = Pos; -} - -static VOID -ConioLineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion) -{ - UINT Pos = Console->LinePos; - UINT NewSize = Console->LineSize - NumToDelete + NumToInsert; - INT i; - - /* Make sure there's always enough room for ending \r\n */ - if (NewSize + 2 > Console->LineMaxSize) - return; - - memmove(&Console->LineBuffer[Pos + NumToInsert], - &Console->LineBuffer[Pos + NumToDelete], - (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR)); - memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR)); - - if (Console->Mode & ENABLE_ECHO_INPUT) - { - for (i = Pos; i < NewSize; i++) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &Console->LineBuffer[i], 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - } - for (; i < Console->LineSize; i++) - { - ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE); - } - Console->LinePos = i; - } - - Console->LineSize = NewSize; - ConioLineInputSetPos(Console, Pos + NumToInsert); -} - -static VOID -ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) -{ - UINT Pos = Console->LinePos; - switch (KeyEvent->wVirtualKeyCode) - { - case VK_ESCAPE: - /* Clear entire line */ - ConioLineInputSetPos(Console, 0); - ConioLineInputEdit(Console, Console->LineSize, 0, NULL); - return; - case VK_HOME: - /* Move to start of line. With ctrl, erase everything left of cursor */ - ConioLineInputSetPos(Console, 0); - if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - ConioLineInputEdit(Console, Pos, 0, NULL); - return; - case VK_END: - /* Move to end of line. With ctrl, erase everything right of cursor */ - if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - ConioLineInputEdit(Console, Console->LineSize - Pos, 0, NULL); - else - ConioLineInputSetPos(Console, Console->LineSize); - return; - case VK_LEFT: - /* Move left. With ctrl, move to beginning of previous word */ - if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - { - while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--; - while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--; - } - else - { - Pos -= (Pos > 0); - } - ConioLineInputSetPos(Console, Pos); - return; - case VK_RIGHT: - /* Move right. With ctrl, move to beginning of next word */ - if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - { - while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++; - while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++; - } - else - { - Pos += (Pos < Console->LineSize); - } - ConioLineInputSetPos(Console, Pos); - return; - case VK_DELETE: - /* Remove character to right of cursor */ - if (Pos != Console->LineSize) - ConioLineInputEdit(Console, 1, 0, NULL); - return; - case VK_F6: - /* Insert a ^Z character */ - KeyEvent->uChar.UnicodeChar = 26; - break; - } - - if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) - { - /* backspace handling - if processed input enabled then we handle it here - * otherwise we treat it like a normal char. */ - if (Pos > 0) - { - ConioLineInputSetPos(Console, Pos - 1); - ConioLineInputEdit(Console, 1, 0, NULL); - } - } - else if (KeyEvent->uChar.UnicodeChar == L'\r') - { - HistoryAddEntry(Console); - - ConioLineInputSetPos(Console, Console->LineSize); - Console->LineBuffer[Console->LineSize++] = L'\r'; - if (Console->Mode & ENABLE_ECHO_INPUT) - ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); - if (Console->Mode & ENABLE_PROCESSED_INPUT) - { - Console->LineBuffer[Console->LineSize++] = L'\n'; - if (Console->Mode & ENABLE_ECHO_INPUT) - ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE); - } - Console->LineComplete = TRUE; - Console->LinePos = 0; - } - else if (KeyEvent->uChar.UnicodeChar != L'\0') - { - /* Normal character */ - ConioLineInputEdit(Console, 0, 1, &KeyEvent->uChar.UnicodeChar); - } -} - CSR_API(CsrReadConsole) { PLIST_ENTRY CurrentEntry; @@ -224,6 +68,7 @@ CSR_API(CsrReadConsole) Console->LineComplete = FALSE; Console->LineSize = 0; Console->LinePos = 0; + Console->LineUpPressed = FALSE; } /* If we don't have a complete line yet, process the pending input */ @@ -241,7 +86,7 @@ CSR_API(CsrReadConsole) if (KEY_EVENT == Input->InputEvent.EventType && Input->InputEvent.Event.KeyEvent.bKeyDown) { - ConioLineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); + LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); } HeapFree(Win32CsrApiHeap, 0, Input); } diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 5a60c21a5a7..bd66928bddd 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -80,6 +80,7 @@ typedef struct tagCSRSS_CONSOLE WORD LineSize; /* current size of line */ WORD LinePos; /* current position within line */ BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */ + BOOLEAN LineUpPressed; LIST_ENTRY HistoryBuffers; WORD HistoryBufferSize; /* size for newly created history buffers */ WORD NumberOfHistoryBuffers; /* maximum number of history buffers allowed */ @@ -220,9 +221,8 @@ CSR_API(CsrGetAllConsoleAliasesLength); CSR_API(CsrGetConsoleAliasesExes); CSR_API(CsrGetConsoleAliasesExesLength); -/* history.c */ +/* lineinput.c */ struct tagHISTORY_BUFFER; -VOID FASTCALL HistoryAddEntry(PCSRSS_CONSOLE Console); VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist); CSR_API(CsrGetCommandHistoryLength); CSR_API(CsrGetCommandHistory); @@ -230,5 +230,6 @@ CSR_API(CsrExpungeCommandHistory); CSR_API(CsrSetHistoryNumberCommands); CSR_API(CsrGetHistoryInfo); CSR_API(CsrSetHistoryInfo); +VOID FASTCALL LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent); /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/history.c b/reactos/subsystems/win32/csrss/win32csr/history.c deleted file mode 100644 index c7dfbd5cabc..00000000000 --- a/reactos/subsystems/win32/csrss/win32csr/history.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * PROJECT: ReactOS CSRSS - * LICENSE: GPL - See COPYING in the top level directory - * FILE: subsystems/win32/csrss/win32csr/history.c - * PURPOSE: Console input history functions - * PROGRAMMERS: Jeffrey Morlan - */ - -/* INCLUDES ******************************************************************/ - -#define NDEBUG -#include "w32csr.h" -#include - -typedef struct tagHISTORY_BUFFER -{ - LIST_ENTRY ListEntry; - WORD MaxEntries; - WORD NumEntries; - PUNICODE_STRING Entries; - UNICODE_STRING ExeName; -} HISTORY_BUFFER, *PHISTORY_BUFFER; - -/* FUNCTIONS *****************************************************************/ - -static PHISTORY_BUFFER -HistoryGetBuffer(PCSRSS_CONSOLE Console) -{ - /* TODO: use actual EXE name sent from process that called ReadConsole */ - UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" }; - PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; - PHISTORY_BUFFER Hist; - - for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink) - { - Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); - if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE)) - return Hist; - } - - /* Couldn't find the buffer, create a new one */ - Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length); - if (!Hist) - return NULL; - Hist->MaxEntries = Console->HistoryBufferSize; - Hist->NumEntries = 0; - Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING)); - if (!Hist->Entries) - { - HeapFree(Win32CsrApiHeap, 0, Hist); - return NULL; - } - Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length; - Hist->ExeName.Buffer = (PWCHAR)(Hist + 1); - memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length); - InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry); - return Hist; -} - -VOID FASTCALL -HistoryAddEntry(PCSRSS_CONSOLE Console) -{ - UNICODE_STRING NewEntry; - PHISTORY_BUFFER Hist; - INT i; - - NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR); - NewEntry.Buffer = Console->LineBuffer; - - if (!(Hist = HistoryGetBuffer(Console))) - return; - - /* Don't add blank or duplicate entries */ - if (NewEntry.Length == 0 || Hist->MaxEntries == 0 || - (Hist->NumEntries > 0 && - RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE))) - { - return; - } - - if (Console->HistoryNoDup) - { - /* Check if this line has been entered before */ - for (i = Hist->NumEntries - 1; i >= 0; i--) - { - if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE)) - { - /* Just rotate the list to bring this entry to the end */ - NewEntry = Hist->Entries[i]; - memmove(&Hist->Entries[i], &Hist->Entries[i + 1], - (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING)); - Hist->Entries[Hist->NumEntries - 1] = NewEntry; - return; - } - } - } - - if (Hist->NumEntries == Hist->MaxEntries) - { - /* List is full, remove oldest entry */ - RtlFreeUnicodeString(&Hist->Entries[0]); - memmove(&Hist->Entries[0], &Hist->Entries[1], - --Hist->NumEntries * sizeof(UNICODE_STRING)); - } - - if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries]))) - Hist->NumEntries++; -} - -static PHISTORY_BUFFER -HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName) -{ - PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; - while (Entry != &Console->HistoryBuffers) - { - /* For the history APIs, the caller is allowed to give only part of the name */ - PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); - if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE)) - return Hist; - Entry = Entry->Flink; - } - return NULL; -} - -VOID FASTCALL -HistoryDeleteBuffer(PHISTORY_BUFFER Hist) -{ - while (Hist->NumEntries != 0) - RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]); - HeapFree(Win32CsrApiHeap, 0, Hist->Entries); - RemoveEntryList(&Hist->ListEntry); - HeapFree(Win32CsrApiHeap, 0, Hist); -} - -CSR_API(CsrGetCommandHistoryLength) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - PHISTORY_BUFFER Hist; - ULONG Length = 0; - INT i; - - if (!Win32CsrValidateBuffer(ProcessData, - Request->Data.GetCommandHistoryLength.ExeName.Buffer, - Request->Data.GetCommandHistoryLength.ExeName.Length, 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); - if (Hist) - { - for (i = 0; i < Hist->NumEntries; i++) - Length += Hist->Entries[i].Length + sizeof(WCHAR); - } - Request->Data.GetCommandHistoryLength.Length = Length; - ConioUnlockConsole(Console); - } - return Status; -} - -CSR_API(CsrGetCommandHistory) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - PHISTORY_BUFFER Hist; - PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History; - ULONG BufferSize = Request->Data.GetCommandHistory.Length; - INT i; - - if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) || - !Win32CsrValidateBuffer(ProcessData, - Request->Data.GetCommandHistory.ExeName.Buffer, - Request->Data.GetCommandHistory.ExeName.Length, 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); - if (Hist) - { - for (i = 0; i < Hist->NumEntries; i++) - { - if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR))) - { - Status = STATUS_BUFFER_OVERFLOW; - break; - } - memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length); - Buffer += Hist->Entries[i].Length; - *(PWCHAR)Buffer = L'\0'; - Buffer += sizeof(WCHAR); - } - } - Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History; - ConioUnlockConsole(Console); - } - return Status; -} - -CSR_API(CsrExpungeCommandHistory) -{ - PCSRSS_CONSOLE Console; - PHISTORY_BUFFER Hist; - NTSTATUS Status; - - if (!Win32CsrValidateBuffer(ProcessData, - Request->Data.ExpungeCommandHistory.ExeName.Buffer, - Request->Data.ExpungeCommandHistory.ExeName.Length, 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName); - if (Hist) - HistoryDeleteBuffer(Hist); - ConioUnlockConsole(Console); - } - return Status; -} - -CSR_API(CsrSetHistoryNumberCommands) -{ - PCSRSS_CONSOLE Console; - PHISTORY_BUFFER Hist; - NTSTATUS Status; - WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands; - PUNICODE_STRING OldEntryList, NewEntryList; - - if (!Win32CsrValidateBuffer(ProcessData, - Request->Data.SetHistoryNumberCommands.ExeName.Buffer, - Request->Data.SetHistoryNumberCommands.ExeName.Length, 1)) - { - return STATUS_ACCESS_VIOLATION; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName); - if (Hist) - { - OldEntryList = Hist->Entries; - NewEntryList = HeapAlloc(Win32CsrApiHeap, 0, - MaxEntries * sizeof(UNICODE_STRING)); - if (!NewEntryList) - { - Status = STATUS_NO_MEMORY; - } - else - { - /* If necessary, shrink by removing oldest entries */ - for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--) - RtlFreeUnicodeString(Hist->Entries++); - - Hist->MaxEntries = MaxEntries; - Hist->Entries = memcpy(NewEntryList, Hist->Entries, - Hist->NumEntries * sizeof(UNICODE_STRING)); - HeapFree(Win32CsrApiHeap, 0, OldEntryList); - } - } - ConioUnlockConsole(Console); - } - return Status; -} - -CSR_API(CsrGetHistoryInfo) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize; - Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; - Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup; - ConioUnlockConsole(Console); - } - return Status; -} - -CSR_API(CsrSetHistoryInfo) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (NT_SUCCESS(Status)) - { - Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize; - Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers; - Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG; - ConioUnlockConsole(Console); - } - return Status; -} - -/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/lineinput.c b/reactos/subsystems/win32/csrss/win32csr/lineinput.c new file mode 100644 index 00000000000..957cb07cbfe --- /dev/null +++ b/reactos/subsystems/win32/csrss/win32csr/lineinput.c @@ -0,0 +1,574 @@ +/* + * PROJECT: ReactOS CSRSS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsystems/win32/csrss/win32csr/lineinput.c + * PURPOSE: Console line input functions + * PROGRAMMERS: Jeffrey Morlan + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +typedef struct tagHISTORY_BUFFER +{ + LIST_ENTRY ListEntry; + WORD Position; + WORD MaxEntries; + WORD NumEntries; + PUNICODE_STRING Entries; + UNICODE_STRING ExeName; +} HISTORY_BUFFER, *PHISTORY_BUFFER; + +/* FUNCTIONS *****************************************************************/ + +static PHISTORY_BUFFER +HistoryCurrentBuffer(PCSRSS_CONSOLE Console) +{ + /* TODO: use actual EXE name sent from process that called ReadConsole */ + UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" }; + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + PHISTORY_BUFFER Hist; + + for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink) + { + Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE)) + return Hist; + } + + /* Couldn't find the buffer, create a new one */ + Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length); + if (!Hist) + return NULL; + Hist->MaxEntries = Console->HistoryBufferSize; + Hist->NumEntries = 0; + Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING)); + if (!Hist->Entries) + { + HeapFree(Win32CsrApiHeap, 0, Hist); + return NULL; + } + Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length; + Hist->ExeName.Buffer = (PWCHAR)(Hist + 1); + memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length); + InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry); + return Hist; +} + +static VOID +HistoryAddEntry(PCSRSS_CONSOLE Console) +{ + UNICODE_STRING NewEntry; + PHISTORY_BUFFER Hist; + INT i; + + NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR); + NewEntry.Buffer = Console->LineBuffer; + + if (!(Hist = HistoryCurrentBuffer(Console))) + return; + + /* Don't add blank or duplicate entries */ + if (NewEntry.Length == 0 || Hist->MaxEntries == 0 || + (Hist->NumEntries > 0 && + RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE))) + { + return; + } + + if (Console->HistoryNoDup) + { + /* Check if this line has been entered before */ + for (i = Hist->NumEntries - 1; i >= 0; i--) + { + if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE)) + { + /* Just rotate the list to bring this entry to the end */ + NewEntry = Hist->Entries[i]; + memmove(&Hist->Entries[i], &Hist->Entries[i + 1], + (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING)); + Hist->Entries[Hist->NumEntries - 1] = NewEntry; + Hist->Position = Hist->NumEntries - 1; + return; + } + } + } + + if (Hist->NumEntries == Hist->MaxEntries) + { + /* List is full, remove oldest entry */ + RtlFreeUnicodeString(&Hist->Entries[0]); + memmove(&Hist->Entries[0], &Hist->Entries[1], + --Hist->NumEntries * sizeof(UNICODE_STRING)); + } + + if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries]))) + Hist->NumEntries++; + Hist->Position = Hist->NumEntries - 1; +} + +static VOID +HistoryGetCurrentEntry(PCSRSS_CONSOLE Console, PUNICODE_STRING Entry) +{ + PHISTORY_BUFFER Hist; + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + Entry->Length = 0; + else + *Entry = Hist->Entries[Hist->Position]; +} + +static PHISTORY_BUFFER +HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName) +{ + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + while (Entry != &Console->HistoryBuffers) + { + /* For the history APIs, the caller is allowed to give only part of the name */ + PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE)) + return Hist; + Entry = Entry->Flink; + } + return NULL; +} + +VOID FASTCALL +HistoryDeleteBuffer(PHISTORY_BUFFER Hist) +{ + if (!Hist) + return; + while (Hist->NumEntries != 0) + RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]); + HeapFree(Win32CsrApiHeap, 0, Hist->Entries); + RemoveEntryList(&Hist->ListEntry); + HeapFree(Win32CsrApiHeap, 0, Hist); +} + +CSR_API(CsrGetCommandHistoryLength) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + ULONG Length = 0; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistoryLength.ExeName.Buffer, + Request->Data.GetCommandHistoryLength.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + Length += Hist->Entries[i].Length + sizeof(WCHAR); + } + Request->Data.GetCommandHistoryLength.Length = Length; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetCommandHistory) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History; + ULONG BufferSize = Request->Data.GetCommandHistory.Length; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) || + !Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistory.ExeName.Buffer, + Request->Data.GetCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + { + if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR))) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length); + Buffer += Hist->Entries[i].Length; + *(PWCHAR)Buffer = L'\0'; + Buffer += sizeof(WCHAR); + } + } + Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrExpungeCommandHistory) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.ExpungeCommandHistory.ExeName.Buffer, + Request->Data.ExpungeCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName); + HistoryDeleteBuffer(Hist); + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryNumberCommands) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands; + PUNICODE_STRING OldEntryList, NewEntryList; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.SetHistoryNumberCommands.ExeName.Buffer, + Request->Data.SetHistoryNumberCommands.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName); + if (Hist) + { + OldEntryList = Hist->Entries; + NewEntryList = HeapAlloc(Win32CsrApiHeap, 0, + MaxEntries * sizeof(UNICODE_STRING)); + if (!NewEntryList) + { + Status = STATUS_NO_MEMORY; + } + else + { + /* If necessary, shrink by removing oldest entries */ + for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--) + { + RtlFreeUnicodeString(Hist->Entries++); + Hist->Position += (Hist->Position == 0); + } + + Hist->MaxEntries = MaxEntries; + Hist->Entries = memcpy(NewEntryList, Hist->Entries, + Hist->NumEntries * sizeof(UNICODE_STRING)); + HeapFree(Win32CsrApiHeap, 0, OldEntryList); + } + } + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize; + Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; + Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize; + Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers; + Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG; + ConioUnlockConsole(Console); + } + return Status; +} + +static VOID +LineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos) +{ + if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT) + { + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + UINT OldCursorX = Buffer->CurrentX; + UINT OldCursorY = Buffer->CurrentY; + INT XY = OldCursorY * Buffer->MaxX + OldCursorX; + + XY += (Pos - Console->LinePos); + if (XY < 0) + XY = 0; + else if (XY >= Buffer->MaxY * Buffer->MaxX) + XY = Buffer->MaxY * Buffer->MaxX - 1; + + Buffer->CurrentX = XY % Buffer->MaxX; + Buffer->CurrentY = XY / Buffer->MaxX; + ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY); + } + + Console->LinePos = Pos; +} + +static VOID +LineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion) +{ + UINT Pos = Console->LinePos; + UINT NewSize = Console->LineSize - NumToDelete + NumToInsert; + INT i; + + /* Make sure there's always enough room for ending \r\n */ + if (NewSize + 2 > Console->LineMaxSize) + return; + + memmove(&Console->LineBuffer[Pos + NumToInsert], + &Console->LineBuffer[Pos + NumToDelete], + (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR)); + memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR)); + + if (Console->Mode & ENABLE_ECHO_INPUT) + { + for (i = Pos; i < NewSize; i++) + { + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &Console->LineBuffer[i], 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + } + for (; i < Console->LineSize; i++) + { + ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE); + } + Console->LinePos = i; + } + + Console->LineSize = NewSize; + LineInputSetPos(Console, Pos + NumToInsert); +} + +static VOID +LineInputRecallHistory(PCSRSS_CONSOLE Console, INT Offset) +{ + PHISTORY_BUFFER Hist; + + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + return; + + Offset += Hist->Position; + Offset = max(Offset, 0); + Offset = min(Offset, Hist->NumEntries - 1); + Hist->Position = Offset; + + LineInputSetPos(Console, 0); + LineInputEdit(Console, Console->LineSize, + Hist->Entries[Offset].Length / sizeof(WCHAR), + Hist->Entries[Offset].Buffer); +} + +VOID FASTCALL +LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) +{ + UINT Pos = Console->LinePos; + PHISTORY_BUFFER Hist; + UNICODE_STRING Entry; + INT HistPos; + + switch (KeyEvent->wVirtualKeyCode) + { + case VK_ESCAPE: + /* Clear entire line */ + LineInputSetPos(Console, 0); + LineInputEdit(Console, Console->LineSize, 0, NULL); + return; + case VK_HOME: + /* Move to start of line. With ctrl, erase everything left of cursor */ + LineInputSetPos(Console, 0); + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + LineInputEdit(Console, Pos, 0, NULL); + return; + case VK_END: + /* Move to end of line. With ctrl, erase everything right of cursor */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + LineInputEdit(Console, Console->LineSize - Pos, 0, NULL); + else + LineInputSetPos(Console, Console->LineSize); + return; + case VK_LEFT: + /* Move left. With ctrl, move to beginning of previous word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--; + while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--; + } + else + { + Pos -= (Pos > 0); + } + LineInputSetPos(Console, Pos); + return; + case VK_RIGHT: + case VK_F1: + /* Move right. With ctrl, move to beginning of next word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++; + while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++; + LineInputSetPos(Console, Pos); + return; + } + else + { + /* Recall one character (but don't overwrite current line) */ + HistoryGetCurrentEntry(Console, &Entry); + if (Pos < Console->LineSize) + LineInputSetPos(Console, Pos + 1); + else if (Pos * sizeof(WCHAR) < Entry.Length) + LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]); + } + return; + case VK_DELETE: + /* Remove character to right of cursor */ + if (Pos != Console->LineSize) + LineInputEdit(Console, 1, 0, NULL); + return; + case VK_PRIOR: + /* Recall first history entry */ + LineInputRecallHistory(Console, -((WORD)-1)); + return; + case VK_NEXT: + /* Recall last history entry */ + LineInputRecallHistory(Console, +((WORD)-1)); + return; + case VK_UP: + case VK_F5: + /* Recall previous history entry. On first time, actually recall the + * current (usually last) entry; on subsequent times go back. */ + LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0); + Console->LineUpPressed = TRUE; + return; + case VK_DOWN: + /* Recall next history entry */ + LineInputRecallHistory(Console, +1); + return; + case VK_F3: + /* Recall remainder of current history entry */ + HistoryGetCurrentEntry(Console, &Entry); + if (Pos * sizeof(WCHAR) < Entry.Length) + { + UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos); + UINT DeleteSize = min(Console->LineSize - Pos, InsertSize); + LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]); + } + return; + case VK_F6: + /* Insert a ^Z character */ + KeyEvent->uChar.UnicodeChar = 26; + break; + case VK_F7: + if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + HistoryDeleteBuffer(HistoryCurrentBuffer(Console)); + return; + case VK_F8: + /* Search for history entries starting with input. */ + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + return; + + /* Like Up/F5, on first time start from current (usually last) entry, + * but on subsequent times start at previous entry. */ + if (Console->LineUpPressed) + Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1; + Console->LineUpPressed = TRUE; + + Entry.Length = Console->LinePos * sizeof(WCHAR); + Entry.Buffer = Console->LineBuffer; + + /* Keep going backwards, even wrapping around to the end, + * until we get back to starting point */ + HistPos = Hist->Position; + do + { + if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE)) + { + Hist->Position = HistPos; + LineInputEdit(Console, Console->LineSize - Pos, + Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos, + &Hist->Entries[HistPos].Buffer[Pos]); + /* Cursor stays where it was */ + LineInputSetPos(Console, Pos); + return; + } + if (--HistPos < 0) HistPos += Hist->NumEntries; + } while (HistPos != Hist->Position); + return; + } + + if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) + { + /* backspace handling - if processed input enabled then we handle it here + * otherwise we treat it like a normal char. */ + if (Pos > 0) + { + LineInputSetPos(Console, Pos - 1); + LineInputEdit(Console, 1, 0, NULL); + } + } + else if (KeyEvent->uChar.UnicodeChar == L'\r') + { + HistoryAddEntry(Console); + + /* TODO: Expand aliases */ + + LineInputSetPos(Console, Console->LineSize); + Console->LineBuffer[Console->LineSize++] = L'\r'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); + if (Console->Mode & ENABLE_PROCESSED_INPUT) + { + Console->LineBuffer[Console->LineSize++] = L'\n'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE); + } + Console->LineComplete = TRUE; + Console->LinePos = 0; + } + else if (KeyEvent->uChar.UnicodeChar != L'\0') + { + /* Normal character */ + LineInputEdit(Console, 0, 1, &KeyEvent->uChar.UnicodeChar); + } +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 96e3be51b2f..c6d4843abea 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -26,7 +26,7 @@ guiconsole.c handle.c harderror.c - history.c + lineinput.c tuiconsole.c appswitch.c win32csr.rc From 5d77839f4fd12214bcb353c84d991cca18a08c32 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 18:26:15 +0000 Subject: [PATCH 249/292] [NTOS]: Fix Exp*PoolList macros. Also make then non-inlined, so we can see who called them in a stack trace. [NTOS]: Enable them. This boots on my system -- if it doesn't boot on yours, someone is corrupting your nonpaged pool. Reverting this patch is NOT the solution to your woes. svn path=/trunk/; revision=47598 --- reactos/ntoskrnl/mm/ARM3/expool.c | 82 +++++++++++++++++++------------ 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index dd4598a7d12..63b32363e20 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -39,30 +39,33 @@ PKGUARDED_MUTEX ExpPagedPoolMutex; * Pool list access debug macros, similar to Arthur's pfnlist.c work. * Microsoft actually implements similar checks in the Windows Server 2003 SP1 * pool code, but only for checked builds. + * * As of Vista, however, an MSDN Blog entry by a Security Team Manager indicates * that these checks are done even on retail builds, due to the increasing * number of kernel-mode attacks which depend on dangling list pointers and other * kinds of list-based attacks. + * * For now, I will leave these checks on all the time, but later they are likely * to be DBG-only, at least until there are enough kernel-mode security attacks * against ReactOS to warrant the performance hit. * + * For now, these are not made inline, so we can get good stack traces. */ -FORCEINLINE +NTAPI PLIST_ENTRY ExpDecodePoolLink(IN PLIST_ENTRY Link) { return (PLIST_ENTRY)((ULONG_PTR)Link & ~1); } -FORCEINLINE +NTAPI PLIST_ENTRY ExpEncodePoolLink(IN PLIST_ENTRY Link) { return (PLIST_ENTRY)((ULONG_PTR)Link | 1); } -FORCEINLINE +NTAPI VOID ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) { @@ -77,52 +80,56 @@ ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) } } -FORCEINLINE +NTAPI VOID ExpInitializePoolListHead(IN PLIST_ENTRY ListHead) { ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead); } -FORCEINLINE +NTAPI BOOLEAN ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead) { return (ExpDecodePoolLink(ListHead->Flink) == ListHead); } -FORCEINLINE +NTAPI VOID ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) { PLIST_ENTRY Blink, Flink; Flink = ExpDecodePoolLink(Entry->Flink); Blink = ExpDecodePoolLink(Entry->Blink); - Blink->Flink = ExpEncodePoolLink(Flink); Flink->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(Flink); } -FORCEINLINE +NTAPI PLIST_ENTRY ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) { - PLIST_ENTRY Head; - Head = ExpDecodePoolLink(ListHead->Flink); - ExpRemovePoolEntryList(Head); - return Head; + PLIST_ENTRY Entry, Flink; + Entry = ExpDecodePoolLink(ListHead->Flink); + Flink = ExpDecodePoolLink(Entry->Flink); + ListHead->Flink = ExpEncodePoolLink(Flink); + Flink->Blink = ExpEncodePoolLink(ListHead); + return Entry; } -FORCEINLINE +NTAPI PLIST_ENTRY ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) { - PLIST_ENTRY Tail; - Tail = ExpDecodePoolLink(ListHead->Blink); - ExpRemovePoolEntryList(Tail); - return Tail; + PLIST_ENTRY Entry, Blink; + Entry = ExpDecodePoolLink(ListHead->Blink); + Blink = ExpDecodePoolLink(Entry->Blink); + ListHead->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(ListHead); + return Entry; } -FORCEINLINE +NTAPI VOID ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) @@ -137,14 +144,14 @@ ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, ExpCheckPoolLinks(ListHead); } -FORCEINLINE +NTAPI VOID ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) { PLIST_ENTRY Flink; ExpCheckPoolLinks(ListHead); - Flink = ExpDecodePoolLink(ListHead->Blink); + Flink = ExpDecodePoolLink(ListHead->Flink); Entry->Flink = ExpEncodePoolLink(Flink); Entry->Blink = ExpEncodePoolLink(ListHead); Flink->Blink = ExpEncodePoolLink(Entry); @@ -194,7 +201,7 @@ ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor, LastEntry = NextEntry + POOL_LISTS_PER_PAGE; while (NextEntry < LastEntry) { - InitializeListHead(NextEntry); + ExpInitializePoolListHead(NextEntry); NextEntry++; } } @@ -379,7 +386,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // Are there any free entries available on this list? // - if (!IsListEmpty(ListHead)) + if (!ExpIsPoolListEmpty(ListHead)) { // // Acquire the pool lock now @@ -389,7 +396,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // And make sure the list still has entries // - if (IsListEmpty(ListHead)) + if (ExpIsPoolListEmpty(ListHead)) { // // Someone raced us (and won) before we had a chance to acquire @@ -408,7 +415,9 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // there is a guarantee that any block on this list will either be // of the correct size, or perhaps larger. // - Entry = POOL_ENTRY(RemoveHeadList(ListHead)); + ExpCheckPoolLinks(ListHead); + Entry = POOL_ENTRY(ExpRemovePoolHeadList(ListHead)); + ExpCheckPoolLinks(ListHead); ASSERT(Entry->BlockSize >= i); ASSERT(Entry->PoolType == 0); @@ -508,13 +517,15 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // "full" entry, which contains enough bytes for a linked list // and thus can be used for allocations (up to 8 bytes...) // + ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]); if (BlockSize != 1) { // // Insert the free entry into the free list for this size // - InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - POOL_FREE_BLOCK(FragmentEntry)); + ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1], + POOL_FREE_BLOCK(FragmentEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry)); } } @@ -571,8 +582,10 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // And insert the free entry into the free list for this block size // - InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - POOL_FREE_BLOCK(FragmentEntry)); + ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]); + ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1], + POOL_FREE_BLOCK(FragmentEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry)); // // Release the pool lock @@ -690,7 +703,10 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry)); + ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink)); } // @@ -727,7 +743,10 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry)); + ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink)); } // @@ -787,7 +806,8 @@ ExFreePoolWithTag(IN PVOID P, // // Insert this new free block, and release the pool lock // - InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], POOL_FREE_BLOCK(Entry)); + ExpInsertPoolHeadList(&PoolDesc->ListHeads[BlockSize - 1], POOL_FREE_BLOCK(Entry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(Entry)); ExUnlockPool(PoolDesc, OldIrql); } From ed9f4ad2de7cf5f39577cb255d39ba787ec63686 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 19:17:21 +0000 Subject: [PATCH 250/292] [NTOS]: Kill debug spew. svn path=/trunk/; revision=47599 --- reactos/ntoskrnl/mm/ARM3/virtual.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 02c17f51de9..a4dcea797b0 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -80,7 +80,6 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte, /* Get the page table entry */ PageTableIndex = Pfn1->u4.PteFrame; - DPRINT1("Page table: %lx\n", PageTableIndex); Pfn2 = MiGetPfnEntry(PageTableIndex); /* Lock the PFN database */ From 5f1255ce5b3c251650cb729bb6e17ef138ddd793 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 19:19:28 +0000 Subject: [PATCH 251/292] [NTOS]: Fix up POOL_PREV_BLOCK based on suggestion by hpoussin. [NTOS]: Fix up NTAPI location in function definition. [NTOS]: Implement even more stringent header checks: ExpCheckPoolHeader and ExpCheckPoolBlocks. Normally we would only want this on a DBG build, but I am enabling them for now until I can fix paged pool. If your machine crashes, reverting this commit is NOT the solution (boots for me). [NTOS]: Add a AllowPagedPool BOOLEAN that will allow us to selectively enable when the ARM3 pool can be used, playing around with the situation that causes the corruption, and perhaps making it easier to find/fix. svn path=/trunk/; revision=47600 --- reactos/ntoskrnl/mm/ARM3/expool.c | 165 +++++++++++++++++++++++++++--- 1 file changed, 148 insertions(+), 17 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index 63b32363e20..a924abe7b56 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -19,6 +19,8 @@ #undef ExAllocatePoolWithQuota #undef ExAllocatePoolWithQuotaTag +BOOLEAN AllowPagedPool = FALSE; + /* GLOBALS ********************************************************************/ ULONG ExpNumberOfPagedPools; @@ -33,7 +35,7 @@ PKGUARDED_MUTEX ExpPagedPoolMutex; #define POOL_FREE_BLOCK(x) (PLIST_ENTRY)((ULONG_PTR)(x) + sizeof(POOL_HEADER)) #define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)(x) + ((i) * POOL_BLOCK_SIZE)) #define POOL_NEXT_BLOCK(x) POOL_BLOCK((x), (x)->BlockSize) -#define POOL_PREV_BLOCK(x) POOL_BLOCK((x), -(x)->PreviousSize) +#define POOL_PREV_BLOCK(x) POOL_BLOCK((x), -((x)->PreviousSize)) /* * Pool list access debug macros, similar to Arthur's pfnlist.c work. @@ -51,22 +53,22 @@ PKGUARDED_MUTEX ExpPagedPoolMutex; * * For now, these are not made inline, so we can get good stack traces. */ -NTAPI PLIST_ENTRY +NTAPI ExpDecodePoolLink(IN PLIST_ENTRY Link) { return (PLIST_ENTRY)((ULONG_PTR)Link & ~1); } -NTAPI PLIST_ENTRY +NTAPI ExpEncodePoolLink(IN PLIST_ENTRY Link) { return (PLIST_ENTRY)((ULONG_PTR)Link | 1); } -NTAPI VOID +NTAPI ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) { if ((ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Flink)->Blink) != ListHead) || @@ -80,22 +82,22 @@ ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) } } -NTAPI VOID +NTAPI ExpInitializePoolListHead(IN PLIST_ENTRY ListHead) { ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead); } -NTAPI BOOLEAN +NTAPI ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead) { return (ExpDecodePoolLink(ListHead->Flink) == ListHead); } -NTAPI VOID +NTAPI ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) { PLIST_ENTRY Blink, Flink; @@ -105,8 +107,8 @@ ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) Blink->Flink = ExpEncodePoolLink(Flink); } -NTAPI PLIST_ENTRY +NTAPI ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) { PLIST_ENTRY Entry, Flink; @@ -117,8 +119,8 @@ ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) return Entry; } -NTAPI PLIST_ENTRY +NTAPI ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) { PLIST_ENTRY Entry, Blink; @@ -129,8 +131,8 @@ ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) return Entry; } -NTAPI VOID +NTAPI ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) { @@ -144,8 +146,8 @@ ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, ExpCheckPoolLinks(ListHead); } -NTAPI VOID +NTAPI ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) { @@ -159,6 +161,131 @@ ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, ExpCheckPoolLinks(ListHead); } +VOID +NTAPI +ExpCheckPoolHeader(IN PPOOL_HEADER Entry) +{ + PPOOL_HEADER PreviousEntry, NextEntry; + + /* Is there a block before this one? */ + if (Entry->PreviousSize) + { + /* Get it */ + PreviousEntry = POOL_PREV_BLOCK(Entry); + + /* The two blocks must be on the same page! */ + if (PAGE_ALIGN(Entry) != PAGE_ALIGN(PreviousEntry)) + { + /* Something is awry */ + KeBugCheckEx(BAD_POOL_HEADER, + 6, + (ULONG_PTR)PreviousEntry, + __LINE__, + (ULONG_PTR)Entry); + } + + /* This block should also indicate that it's as large as we think it is */ + if (PreviousEntry->BlockSize != Entry->PreviousSize) + { + /* Otherwise, someone corrupted one of the sizes */ + KeBugCheckEx(BAD_POOL_HEADER, + 5, + (ULONG_PTR)PreviousEntry, + __LINE__, + (ULONG_PTR)Entry); + } + } + else if (PAGE_ALIGN(Entry) != Entry) + { + /* If there's no block before us, we are the first block, so we should be on a page boundary */ + KeBugCheckEx(BAD_POOL_HEADER, + 7, + 0, + __LINE__, + (ULONG_PTR)Entry); + } + + /* This block must have a size */ + if (!Entry->BlockSize) + { + /* Someone must've corrupted this field */ + KeBugCheckEx(BAD_POOL_HEADER, + 8, + 0, + __LINE__, + (ULONG_PTR)Entry); + } + + /* Okay, now get the next block */ + NextEntry = POOL_NEXT_BLOCK(Entry); + + /* If this is the last block, then we'll be page-aligned, otherwise, check this block */ + if (PAGE_ALIGN(NextEntry) != NextEntry) + { + /* The two blocks must be on the same page! */ + if (PAGE_ALIGN(Entry) != PAGE_ALIGN(NextEntry)) + { + /* Something is messed up */ + KeBugCheckEx(BAD_POOL_HEADER, + 9, + (ULONG_PTR)NextEntry, + __LINE__, + (ULONG_PTR)Entry); + } + + /* And this block should think we are as large as we truly are */ + if (NextEntry->PreviousSize != Entry->BlockSize) + { + /* Otherwise, someone corrupted the field */ + KeBugCheckEx(BAD_POOL_HEADER, + 5, + (ULONG_PTR)NextEntry, + __LINE__, + (ULONG_PTR)Entry); + } + } +} + +VOID +NTAPI +ExpCheckPoolBlocks(IN PVOID Block) +{ + BOOLEAN FoundBlock; + SIZE_T Size = 0; + PPOOL_HEADER Entry; + + /* Get the first entry for this page, make sure it really is the first */ + Entry = PAGE_ALIGN(Block); + ASSERT(Entry->PreviousSize == 0); + + /* Now scan each entry */ + while (TRUE) + { + /* When we actually found our block, remember this */ + if (Entry == Block) FoundBlock = TRUE; + + /* Now validate this block header */ + ExpCheckPoolHeader(Entry); + + /* And go to the next one, keeping track of our size */ + Size += Entry->BlockSize; + Entry = POOL_NEXT_BLOCK(Entry); + + /* If we hit the last block, stop */ + if (Size >= (PAGE_SIZE / POOL_BLOCK_SIZE)) break; + + /* If we hit the end of the page, stop */ + if (PAGE_ALIGN(Entry) == Entry) break; + } + + /* We must've found our block, and we must have hit the end of the page */ + if ((PAGE_ALIGN(Entry) != Entry) || !(FoundBlock)) + { + /* Otherwise, the blocks are messed up */ + KeBugCheckEx(BAD_POOL_HEADER, 10, (ULONG_PTR)Block, __LINE__, (ULONG_PTR)Entry); + } +} + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -331,8 +458,8 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // Check for paged pool // - if (PoolType == PagedPool) return ExAllocatePagedPoolWithTag(PagedPool, NumberOfBytes, Tag); - + if (!(AllowPagedPool) && (PoolType == PagedPool)) return ExAllocatePagedPoolWithTag(PagedPool, NumberOfBytes, Tag); + // // Some sanity checks // @@ -418,6 +545,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, ExpCheckPoolLinks(ListHead); Entry = POOL_ENTRY(ExpRemovePoolHeadList(ListHead)); ExpCheckPoolLinks(ListHead); + ExpCheckPoolBlocks(Entry); ASSERT(Entry->BlockSize >= i); ASSERT(Entry->PoolType == 0); @@ -534,6 +662,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // and release the lock since we're done // Entry->PoolType = PoolType + 1; + ExpCheckPoolBlocks(Entry); ExUnlockPool(PoolDesc, OldIrql); // @@ -590,12 +719,14 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // Release the pool lock // + ExpCheckPoolBlocks(Entry); ExUnlockPool(PoolDesc, OldIrql); } // // And return the pool allocation // + ExpCheckPoolBlocks(Entry); Entry->PoolTag = Tag; return POOL_FREE_BLOCK(Entry); } @@ -628,12 +759,12 @@ ExFreePoolWithTag(IN PVOID P, POOL_TYPE PoolType; PPOOL_DESCRIPTOR PoolDesc; BOOLEAN Combined = FALSE; -#if 1 + // // Check for paged pool // - if ((P >= MmPagedPoolBase) && - (P <= (PVOID)((ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize))) + if (!(AllowPagedPool) && ((P >= MmPagedPoolBase) && + (P <= (PVOID)((ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize)))) { // // Use old allocator @@ -641,7 +772,6 @@ ExFreePoolWithTag(IN PVOID P, ExFreePagedPool(P); return; } -#endif // // Quickly deal with big page allocations @@ -680,6 +810,7 @@ ExFreePoolWithTag(IN PVOID P, // // Check if the next allocation is at the end of the page // + ExpCheckPoolBlocks(Entry); if (PAGE_ALIGN(NextEntry) != NextEntry) { // From c28fc63bf4deb133ea6b98723260d2bbb24a5d5a Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 5 Jun 2010 19:32:46 +0000 Subject: [PATCH 252/292] [NTOS]: Even after allowing ARM3 paged pool, we should still use the old allocator to free allocations made by the old allocator! svn path=/trunk/; revision=47601 --- reactos/ntoskrnl/mm/ARM3/expool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index a924abe7b56..c3d60b39387 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -763,8 +763,8 @@ ExFreePoolWithTag(IN PVOID P, // // Check for paged pool // - if (!(AllowPagedPool) && ((P >= MmPagedPoolBase) && - (P <= (PVOID)((ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize)))) + if ((P >= MmPagedPoolBase) && + (P <= (PVOID)((ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize))) { // // Use old allocator From 570567b87e75e7a7606973ce0204a7131b83d4bd Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 00:49:26 +0000 Subject: [PATCH 253/292] [NTOS]: Kill some debug spew. svn path=/trunk/; revision=47604 --- reactos/ntoskrnl/mm/ARM3/pagfault.c | 4 ++-- reactos/ntoskrnl/mm/ARM3/pool.c | 1 - reactos/ntoskrnl/mm/mmfault.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 8fd0d15daee..68c1bfecd9c 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -107,7 +107,7 @@ MiResolveDemandZeroFault(IN PVOID Address, /* Get a page */ PageFrameNumber = MiRemoveAnyPage(0); - DPRINT1("New pool page: %lx\n", PageFrameNumber); + DPRINT("New pool page: %lx\n", PageFrameNumber); /* Initialize it */ MiInitializePfn(PageFrameNumber, PointerPte, TRUE); @@ -135,7 +135,7 @@ MiResolveDemandZeroFault(IN PVOID Address, // // It's all good now // - DPRINT1("Paged pool page has now been paged in\n"); + DPRINT("Paged pool page has now been paged in\n"); return STATUS_PAGE_FAULT_DEMAND_ZERO; } diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index e3af2a6d6b5..37cb2e59fcf 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -422,7 +422,6 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, KeFlushEntireTb(TRUE, TRUE); /* Setup a demand-zero writable PTE */ - DPRINT1("Setting up demand zero\n"); MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); // diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index 6f04e941b42..c4a81739c38 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -290,7 +290,7 @@ MmAccessFault(IN BOOLEAN StoreInstruction, // // Hand it off to more competent hands... // - DPRINT1("ARM3 fault %p\n", MemoryArea); + DPRINT("ARM3 fault %p\n", MemoryArea); return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation); } From 143221853b71888658b1832cfe081c9e25300408 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 01:04:03 +0000 Subject: [PATCH 254/292] [NTOS]: Fix for the the bug that broke ARM3 paged pool (and has been corrupting ReactOS paged pool behind the scenes for years): When a KCB (key stuff) is allocated, the key name associated with it receives an NCB (name stuff). In case this name is already used, a cache exists, and an existing NCB is grabbed, and its reference count is increased. When the KCB goes away, its NCB loses a reference. When all references are gone, the NCB is destroyed. Simple enough. It turns out that what was currently happening is that an NCB would get dereferenced to 0, deleted, but still remained attached to a valid KCB (shouldn't happen). When that KCB went away, the NCB's reference count was dropped to... -1, and then -2, -3, -4, etc. Remember this is a FREED NCB. In other words, freed pool, that might now belong to someone else, was getting "-1" operations on it. So any value stored in that freed pool would get decremented by one. In ARM3 paged pool, because the allocator keeps a linked list, what would happen is that the FLINK pointer would be 0xE0F01234 instead of 0xE1A01234. What happened is that "0xE1A0" was treated as the reference count of the freed NCB, and it kept getting dereferenced down to 0xE0F0. Proving this was easy, by adding an ASSERT(Ncb->RefCount >= 1) to the routine that dereferences NCBs. Obviously, we should not try to dereference an NCB that has a reference count of 0, because that NCB is now gone. Adding this ASSERT immediately caught the error, regardless of which pool implementation was being used, so this was a problem in ReactOS today, right now. My first thought was that we were taking references to NCBs without incrementing the reference count. The NCB gets referenced in two places: when it gets created, and everytime a cached NCB is re-used for a new KCB (all this in CmpGetNameControlBlock). After adding some tracing code, I discovered that CmpGetNameControlBlock would sometimes return an NCB that was cached, but without referencing it. I did not understand why, since the code says "if (Found) Ncb->RefCount++". Further analysis showed that what would happen, on this particular instance, is that NCB "Foo" was being Found, but NCB "Bar" was returned instead. Therefore, causing some serious issues: First, NCB Foo was receiving too many references. Secondly, NCB Bar was not being referenced. Worse though, it turns out this would happen when "Foo" was the CORRECT NCB, and "Bar" was an INCORRECT NCB. What do we mean by correct and incorrect? Well, because NCBs are hashed, it's possible for two NCB hashes to be VERY SIMILAR, but only ONE OF THOSE NCBs will be the right one -- for example, HKLM\Software\Hello vs HKLM\Software\Hell. In our case, when a KCB for "Hello" was searching for the "Hello" NCB, the "Hello NCB would get a reference, but the "Hell" NCB would be returned. In other words, whenever a HASH COLLISION happened, the incorrect NCB was returned, probably messing up registry code in the process. Subsequently, when the KCB was dereferneced, it was attached to this incorrect, under-referenced NCB. Since in ANY hash collision with "Hell", in our example, the "Hell" NCB would come first, subsequent searches for "Hellmaster", "Hellboy", "Hello World" would all still return "Hell". Eventually when all these KCBs would go away, the "Hell" NCB would reach even -18 references. The simple solution? When the CORRECT NCB is found, STOP SEARCHING! By adding a simple "break" statement. Otherwise, even after the correct NCB is found, further, incorrect, collided NCBs are found, and eventually the last one ("Hell", in our example) got returned, and under-referenced, while "Hellmaster" and "Hellboy" were not returned, but LEAKED REFERENCES. There you have it folks, MEMORY CORRUPTION (USE-AFTER-FREE), INCORRECT REGISTRY NAME PARSHING, REFERENCE LEAKS and REFERENCE UNDERRUNS, all due to ONE missing "break;". -r svn path=/trunk/; revision=47605 --- reactos/ntoskrnl/config/cmkcbncb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/config/cmkcbncb.c b/reactos/ntoskrnl/config/cmkcbncb.c index a26de07cf1b..a123a3cee56 100644 --- a/reactos/ntoskrnl/config/cmkcbncb.c +++ b/reactos/ntoskrnl/config/cmkcbncb.c @@ -234,7 +234,9 @@ CmpGetNameControlBlock(IN PUNICODE_STRING NodeName) if (Found) { /* Reference it */ + ASSERT(Ncb->RefCount != 0xFFFF); Ncb->RefCount++; + break; } } @@ -320,6 +322,7 @@ CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb) CmpAcquireNcbLockExclusiveByKey(ConvKey); /* Decrease the reference count */ + ASSERT(Ncb->RefCount >= 1); if (!(--Ncb->RefCount)) { /* Find the NCB in the table */ @@ -579,7 +582,7 @@ CmpDereferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb) NewRefCount = OldRefCount - 1; /* Check if we still have references */ - if( (NewRefCount & 0xFFFF) > 0) + if ((NewRefCount & 0xFFFF) > 0) { /* Do the dereference */ if (InterlockedCompareExchange((PLONG)&Kcb->RefCount, From 01194e41b904c0c269356d4fd9cf8f489e3fb206 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 04:37:53 +0000 Subject: [PATCH 255/292] [NTOS]: Silence more debug spew. svn path=/trunk/; revision=47607 --- reactos/ntoskrnl/mm/ARM3/pagfault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 68c1bfecd9c..073b091b7c6 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -91,7 +91,7 @@ MiResolveDemandZeroFault(IN PVOID Address, { PFN_NUMBER PageFrameNumber; MMPTE TempPte; - DPRINT1("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", + DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", Address, Process); From 854ff3471b3d1e4b4467d9a2a0da68b2f1cd6287 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 04:38:51 +0000 Subject: [PATCH 256/292] [NTOS]: Clean up /mm a bit, move sysldr.c into ARM3. svn path=/trunk/; revision=47608 --- reactos/ntoskrnl/mm/{ => ARM3}/sysldr.c | 2 +- reactos/ntoskrnl/mm/elf.inc.h | 705 ----------------------- reactos/ntoskrnl/mm/elf32.c | 154 ----- reactos/ntoskrnl/mm/elf64.c | 11 - reactos/ntoskrnl/ntoskrnl-generic.rbuild | 2 +- 5 files changed, 2 insertions(+), 872 deletions(-) rename reactos/ntoskrnl/mm/{ => ARM3}/sysldr.c (99%) delete mode 100644 reactos/ntoskrnl/mm/elf.inc.h delete mode 100644 reactos/ntoskrnl/mm/elf32.c delete mode 100644 reactos/ntoskrnl/mm/elf64.c diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c similarity index 99% rename from reactos/ntoskrnl/mm/sysldr.c rename to reactos/ntoskrnl/mm/ARM3/sysldr.c index a242b4b2f6c..2c4a09cfd3a 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -15,7 +15,7 @@ #line 16 "ARM³::LOADER" #define MODULE_INVOLVED_IN_ARM3 -#include "./ARM3/miarm.h" +#include "../ARM3/miarm.h" /* GCC's incompetence strikes again */ __inline diff --git a/reactos/ntoskrnl/mm/elf.inc.h b/reactos/ntoskrnl/mm/elf.inc.h deleted file mode 100644 index 2360bffd1d2..00000000000 --- a/reactos/ntoskrnl/mm/elf.inc.h +++ /dev/null @@ -1,705 +0,0 @@ -#define NDEBUG -#include - -#include - -#ifndef __ELF_WORD_SIZE -#error __ELF_WORD_SIZE must be defined -#endif - -#include - -/* TODO: Intsafe should be made into a library, as it's generally useful */ -static __inline BOOLEAN Intsafe_CanAddULongPtr -( - IN ULONG_PTR Addend1, - IN ULONG_PTR Addend2 -) -{ - return Addend1 <= (MAXULONG_PTR - Addend2); -} - -#define Intsafe_CanAddSizeT Intsafe_CanAddULongPtr - -static __inline BOOLEAN Intsafe_CanAddULong32 -( - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - return Addend1 <= (MAXULONG - Addend2); -} - -static __inline BOOLEAN Intsafe_AddULong32 -( - OUT PULONG32 Result, - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - if(!Intsafe_CanAddULong32(Addend1, Addend2)) - return FALSE; - - *Result = Addend1 + Addend2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanAddULong64 -( - IN ULONG64 Addend1, - IN ULONG64 Addend2 -) -{ - return Addend1 <= (((ULONG64)-1) - Addend2); -} - -static __inline BOOLEAN Intsafe_AddULong64 -( - OUT PULONG64 Result, - IN ULONG64 Addend1, - IN ULONG64 Addend2 -) -{ - if(!Intsafe_CanAddULong64(Addend1, Addend2)) - return FALSE; - - *Result = Addend1 + Addend2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanMulULong32 -( - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - return Factor1 <= (MAXULONG / Factor2); -} - -static __inline BOOLEAN Intsafe_MulULong32 -( - OUT PULONG32 Result, - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - if(!Intsafe_CanMulULong32(Factor1, Factor2)) - return FALSE; - - *Result = Factor1 * Factor2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanOffsetPointer -( - IN CONST VOID * Pointer, - IN SIZE_T Offset -) -{ - /* FIXME: (PVOID)MAXULONG_PTR isn't necessarily a valid address */ - return Intsafe_CanAddULongPtr((ULONG_PTR)Pointer, Offset); -} - -#if __ELF_WORD_SIZE == 32 -#define ElfFmtpAddSize Intsafe_AddULong32 -#define ElfFmtpReadAddr ElfFmtpReadULong -#define ElfFmtpReadOff ElfFmtpReadULong -#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong -#define ElfFmtpSafeReadOff ElfFmtpSafeReadULong -#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong -#elif __ELF_WORD_SIZE == 64 -#define ElfFmtpAddSize Intsafe_AddULong64 -#define ElfFmtpReadAddr ElfFmtpReadULong64 -#define ElfFmtpReadOff ElfFmtpReadULong64 -#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong64 -#define ElfFmtpSafeReadOff ElfFmtpSafeReadULong64 -#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong64 -#endif - -/* TODO: these are standard DDK/PSDK macros */ -#define RtlRetrieveUlonglong(DST_, SRC_) \ - (RtlCopyMemory((DST_), (SRC_), sizeof(ULONG64))) - -#ifndef RTL_FIELD_SIZE -#define RTL_FIELD_SIZE(TYPE_, FIELD_) (sizeof(((TYPE_ *)0)->FIELD_)) -#endif - -#ifndef RTL_SIZEOF_THROUGH_FIELD -#define RTL_SIZEOF_THROUGH_FIELD(TYPE_, FIELD_) \ - (FIELD_OFFSET(TYPE_, FIELD_) + RTL_FIELD_SIZE(TYPE_, FIELD_)) -#endif - -#ifndef RTL_CONTAINS_FIELD -#define RTL_CONTAINS_FIELD(P_, SIZE_, FIELD_) \ - ((ULONG_PTR)(P_) + (ULONG_PTR)(SIZE_) > (ULONG_PTR)&((P_)->FIELD_) + sizeof((P_)->FIELD_)) -#endif - -#define ELFFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \ - ( \ - (FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \ - (RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \ - ) - -#define ELFFMT_MAKE_ULONG64(BYTE1_, BYTE2_, BYTE3_, BYTE4_, BYTE5_, BYTE6_, BYTE7_, BYTE8_) \ - ( \ - (((ULONG64)ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_)) << 0) | \ - (((ULONG64)ELFFMT_MAKE_ULONG(BYTE5_, BYTE6_, BYTE7_, BYTE8_)) << 32) \ - ) - -#define ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_) \ - ( \ - (((ULONG)ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_)) << 0) | \ - (((ULONG)ELFFMT_MAKE_USHORT(BYTE3_, BYTE4_)) << 16) \ - ) - -#define ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_) \ - ( \ - (((USHORT)(BYTE1_)) << 0) | \ - (((USHORT)(BYTE2_)) << 8) \ - ) - -static __inline ULONG64 ElfFmtpReadULong64 -( - IN ULONG64 Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return (ULONG64)-1; -} - -static __inline ULONG ElfFmtpReadULong -( - IN ULONG Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return MAXULONG; -} - -static __inline USHORT ElfFmtpReadUShort -( - IN USHORT Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_USHORT(p[0], p[1]); - case ELFDATA2MSB: return ELFFMT_MAKE_USHORT(p[1], p[0]); - } - - ASSERT(FALSE); - return (USHORT)-1; -} - -static __inline ULONG64 ElfFmtpSafeReadULong64 -( - IN CONST ULONG64 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG64 nSafeInput; - - RtlRetrieveUlonglong(&nSafeInput, Input); - - p = (PUCHAR)&nSafeInput; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return (ULONG64)-1; -} - -static __inline ULONG ElfFmtpSafeReadULong -( - IN CONST ULONG32 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG nSafeInput; - union - { - CONST ULONG32 *ConstInput; - ULONG32 *Input; - }pInput = {Input}; - - RtlRetrieveUlong(&nSafeInput, pInput.Input); - - if(DataType == ELF_TARG_DATA) - return nSafeInput; - - p = (PUCHAR)&nSafeInput; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return MAXULONG; -} - -static __inline BOOLEAN ElfFmtpIsPowerOf2(IN Elf_Addr Number) -{ - if(Number == 0) - return FALSE; - - return (Number & (Number - 1)) == 0; -} - -static __inline Elf_Addr ElfFmtpModPow2 -( - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size)); - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off)); - ASSERT(ElfFmtpIsPowerOf2(Alignment)); - return Address & (Alignment - 1); -} - -static __inline Elf_Addr ElfFmtpAlignDown -( - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size)); - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off)); - ASSERT(ElfFmtpIsPowerOf2(Alignment)); - return Address & ~(Alignment - 1); -} - -static __inline BOOLEAN ElfFmtpAlignUp -( - OUT Elf_Addr * AlignedAddress, - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - Elf_Addr nExcess = ElfFmtpModPow2(Address, Alignment); - - if(nExcess == 0) - { - *AlignedAddress = Address; - return nExcess == 0; - } - else - return ElfFmtpAddSize(AlignedAddress, Address, Alignment - nExcess); -} - -/* - References: - [1] Tool Interface Standards (TIS) Committee, "Executable and Linking Format - (ELF) Specification", Version 1.2 -*/ -NTSTATUS NTAPI -#if __ELF_WORD_SIZE == 32 -Elf32FmtCreateSection -#elif __ELF_WORD_SIZE == 64 -Elf64FmtCreateSection -#endif -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -) -{ - NTSTATUS nStatus; - const Elf_Ehdr * pehHeader; - const Elf_Phdr * pphPHdrs; - BOOLEAN fPageAligned; - ULONG nData; - ULONG nPHdrCount; - ULONG cbPHdrSize; - Elf_Off cbPHdrOffset; - PVOID pBuffer; - PMM_SECTION_SEGMENT pssSegments; - Elf_Addr nImageBase = 0; - Elf_Addr nEntryPoint; - ULONG32 nPrevVirtualEndOfSegment = 0; - ULONG i; - ULONG j; - - (void)Intsafe_AddULong64; - (void)Intsafe_MulULong32; - (void)ElfFmtpReadULong64; - (void)ElfFmtpSafeReadULong64; - (void)ElfFmtpReadULong; - -#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; } - - pBuffer = NULL; - - nStatus = STATUS_INVALID_IMAGE_FORMAT; - - /* Ensure the file contains the full header */ - /* - EXEFMT_LOAD_HEADER_SIZE is 8KB: enough to contain an ELF header (at least in - all the classes defined as of December 2004). If FileHeaderSize is less than - sizeof(Elf_Ehdr), it means the file itself is small enough not to contain a - full ELF header - */ - ASSERT(sizeof(Elf_Ehdr) <= EXEFMT_LOAD_HEADER_SIZE); - - if(FileHeaderSize < sizeof(Elf_Ehdr)) - DIE(("The file is truncated, doesn't contain the full header\n")); - - pehHeader = FileHeader; - ASSERT(((ULONG_PTR)pehHeader % TYPE_ALIGNMENT(Elf_Ehdr)) == 0); - - nData = pehHeader->e_ident[EI_DATA]; - - /* Validate the header */ - if(ElfFmtpReadUShort(pehHeader->e_ehsize, nData) < sizeof(Elf_Ehdr)) - DIE(("Inconsistent value for e_ehsize\n")); - - /* Calculate size and offset of the program headers */ - cbPHdrSize = ElfFmtpReadUShort(pehHeader->e_phentsize, nData); - - if(cbPHdrSize != sizeof(Elf_Phdr)) - DIE(("Inconsistent value for e_phentsize\n")); - - /* MAXUSHORT * MAXUSHORT < MAXULONG */ - nPHdrCount = ElfFmtpReadUShort(pehHeader->e_phnum, nData); - ASSERT(Intsafe_CanMulULong32(cbPHdrSize, nPHdrCount)); - cbPHdrSize *= nPHdrCount; - - cbPHdrOffset = ElfFmtpReadOff(pehHeader->e_phoff, nData); - - /* The initial header doesn't contain the program headers */ - if(cbPHdrOffset > FileHeaderSize || cbPHdrSize > (FileHeaderSize - cbPHdrOffset)) - { - NTSTATUS nReadStatus; - LARGE_INTEGER lnOffset; - PVOID pData; - ULONG cbReadSize; - - /* Will worry about this when ELF128 comes */ - ASSERT(sizeof(cbPHdrOffset) <= sizeof(lnOffset.QuadPart)); - - lnOffset.QuadPart = (LONG64)cbPHdrOffset; - - /* - We can't support executable files larger than 8 Exabytes - it's a limitation - of the I/O system (only 63-bit offsets are supported). Quote: - - [...] the total amount of printed material in the world is estimated to be - around a fifth of an exabyte. [...] [Source: Wikipedia] - */ - if(lnOffset.u.HighPart < 0) - DIE(("The program header is too far into the file\n")); - - nReadStatus = ReadFileCb - ( - File, - &lnOffset, - cbPHdrSize, - &pData, - &pBuffer, - &cbReadSize - ); - - if(!NT_SUCCESS(nReadStatus)) - { - nStatus = nReadStatus; - DIE(("ReadFile failed, status %08X\n", nStatus)); - } - - ASSERT(pData); - ASSERT(pBuffer); - ASSERT(Intsafe_CanOffsetPointer(pData, cbReadSize)); - - if(cbReadSize < cbPHdrSize) - DIE(("The file didn't contain the program headers\n")); - - /* Force the buffer to be aligned */ - if((ULONG_PTR)pData % TYPE_ALIGNMENT(Elf_Phdr)) - { - ASSERT(((ULONG_PTR)pBuffer % TYPE_ALIGNMENT(Elf_Phdr)) == 0); - RtlMoveMemory(pBuffer, pData, cbPHdrSize); - pphPHdrs = pBuffer; - } - else - pphPHdrs = pData; - } - else - { - ASSERT(Intsafe_CanAddSizeT(cbPHdrOffset, 0)); - ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbPHdrOffset)); - pphPHdrs = (PVOID)((ULONG_PTR)FileHeader + (ULONG_PTR)cbPHdrOffset); - } - - /* Allocate the segments */ - pssSegments = AllocateSegmentsCb(nPHdrCount); - - if(pssSegments == NULL) - { - nStatus = STATUS_INSUFFICIENT_RESOURCES; - DIE(("Out of memory\n")); - } - - ImageSectionObject->Segments = pssSegments; - - fPageAligned = TRUE; - - /* Fill in the segments */ - for(i = 0, j = 0; i < nPHdrCount; ++ i) - { - switch(ElfFmtpSafeReadULong(&pphPHdrs[i].p_type, nData)) - { - case PT_LOAD: - { - static const ULONG ProgramHeaderFlagsToProtect[8] = - { - PAGE_NOACCESS, /* 0 */ - PAGE_EXECUTE_READ, /* PF_X */ - PAGE_READWRITE, /* PF_W */ - PAGE_EXECUTE_READWRITE, /* PF_X | PF_W */ - PAGE_READONLY, /* PF_R */ - PAGE_EXECUTE_READ, /* PF_X | PF_R */ - PAGE_READWRITE, /* PF_W | PF_R */ - PAGE_EXECUTE_READWRITE /* PF_X | PF_W | PF_R */ - }; - - Elf_Size nAlignment; - Elf_Off nFileOffset; - Elf_Addr nVirtualAddr; - Elf_Size nAdj; - Elf_Size nVirtualSize = 0; - Elf_Size nFileSize = 0; - - ASSERT(j <= nPHdrCount); - - /* Retrieve and validate the segment alignment */ - nAlignment = ElfFmtpSafeReadSize(&pphPHdrs[i].p_align, nData); - - if(nAlignment == 0) - nAlignment = 1; - else if(!ElfFmtpIsPowerOf2(nAlignment)) - DIE(("Alignment of loadable segment isn't a power of 2\n")); - - if(nAlignment < PAGE_SIZE) - fPageAligned = FALSE; - - /* Retrieve the addresses and calculate the adjustment */ - nFileOffset = ElfFmtpSafeReadOff(&pphPHdrs[i].p_offset, nData); - nVirtualAddr = ElfFmtpSafeReadAddr(&pphPHdrs[i].p_vaddr, nData); - - nAdj = ElfFmtpModPow2(nFileOffset, nAlignment); - - if(nAdj != ElfFmtpModPow2(nVirtualAddr, nAlignment)) - DIE(("File and memory address of loadable segment not congruent modulo alignment\n")); - - /* Retrieve, adjust and align the file size and memory size */ - if(!ElfFmtpAddSize(&nFileSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_filesz, nData), nAdj)) - DIE(("Can't adjust the file size of loadable segment\n")); - - if(!ElfFmtpAddSize(&nVirtualSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_memsz, nData), nAdj)) - DIE(("Can't adjust the memory size of lodable segment\n")); - - if(!ElfFmtpAlignUp(&nVirtualSize, nVirtualSize, nAlignment)) - DIE(("Can't align the memory size of lodable segment\n")); - - if(nFileSize > nVirtualSize) - nFileSize = nVirtualSize; - - if(nVirtualSize > MAXULONG) - DIE(("Virtual image larger than 4GB\n")); - - ASSERT(nFileSize <= MAXULONG); - - pssSegments[j].Length = (ULONG)(nVirtualSize & 0xFFFFFFFF); - pssSegments[j].RawLength = (ULONG)(nFileSize & 0xFFFFFFFF); - - /* File offset */ - nFileOffset = ElfFmtpAlignDown(nFileOffset, nAlignment); - -#if __ELF_WORD_SIZE >= 64 - ASSERT(sizeof(nFileOffset) == sizeof(LONG64)); - - if(((LONG64)nFileOffset) < 0) - DIE(("File offset of loadable segment is too large\n")); -#endif - - pssSegments[j].FileOffset = (LONG64)nFileOffset; - - /* Virtual address */ - nVirtualAddr = ElfFmtpAlignDown(nVirtualAddr, nAlignment); - - if(j == 0) - { - /* First segment: its address is the base address of the image */ - nImageBase = nVirtualAddr; - pssSegments[j].VirtualAddress = 0; - - /* Several places make this assumption */ - if(pssSegments[j].FileOffset != 0) - DIE(("First loadable segment doesn't contain the ELF header\n")); - } - else - { - Elf_Size nVirtualOffset; - - /* Other segment: store the offset from the base address */ - if(nVirtualAddr <= nImageBase) - DIE(("Loadable segments are not sorted\n")); - - nVirtualOffset = nVirtualAddr - nImageBase; - - if(nVirtualOffset > MAXULONG) - DIE(("Virtual image larger than 4GB\n")); - - pssSegments[j].VirtualAddress = (ULONG)(nVirtualOffset & 0xFFFFFFFF); - - if(pssSegments[j].VirtualAddress != nPrevVirtualEndOfSegment) - DIE(("Loadable segments are not sorted and contiguous\n")); - } - - /* Memory protection */ - pssSegments[j].Protection = ProgramHeaderFlagsToProtect - [ - ElfFmtpSafeReadULong(&pphPHdrs[i].p_flags, nData) & (PF_R | PF_W | PF_X) - ]; - - /* Characteristics */ - /* - TODO: need to add support for the shared, non-pageable, non-cacheable and - discardable attributes. This involves extensions to the ELF format, so it's - nothing to be taken lightly - */ - if(pssSegments[j].Protection & PAGE_IS_EXECUTABLE) - { - ImageSectionObject->Executable = TRUE; - pssSegments[j].Characteristics = IMAGE_SCN_CNT_CODE; - } - else if(pssSegments[j].RawLength == 0) - pssSegments[j].Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA; - else - pssSegments[j].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA; - - /* - FIXME: see the TODO above. This is the safest way to load ELF drivers, for - now, if a bit wasteful of memory - */ - pssSegments[j].Characteristics |= IMAGE_SCN_MEM_NOT_PAGED; - - /* Copy-on-write */ - pssSegments[j].WriteCopy = TRUE; - - if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[j].VirtualAddress, pssSegments[j].Length)) - DIE(("Virtual image larger than 4GB\n")); - - ++ j; - break; - } - } - } - - if(j == 0) - DIE(("No loadable segments\n")); - - ImageSectionObject->NrSegments = j; - - *Flags = - EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED | - EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP; - - if(fPageAligned) - *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED; - - nEntryPoint = ElfFmtpReadAddr(pehHeader->e_entry, nData); - - if(nEntryPoint < nImageBase || nEntryPoint - nImageBase > nPrevVirtualEndOfSegment) - DIE(("Entry point not within the virtual image\n")); - - ASSERT(nEntryPoint >= nImageBase); - ASSERT((nEntryPoint - nImageBase) <= MAXULONG); - ImageSectionObject->EntryPoint = nEntryPoint - nImageBase; - - /* TODO: support Wine executables and read these values from nt_headers */ - ImageSectionObject->ImageCharacteristics |= - IMAGE_FILE_EXECUTABLE_IMAGE | - IMAGE_FILE_LINE_NUMS_STRIPPED | - IMAGE_FILE_LOCAL_SYMS_STRIPPED | - (nImageBase > MAXULONG ? IMAGE_FILE_LARGE_ADDRESS_AWARE : 0) | - IMAGE_FILE_DEBUG_STRIPPED; - - if(nData == ELFDATA2LSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_LO; - else if(nData == ELFDATA2MSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_HI; - - /* Base address outside the possible address space */ - if(nImageBase > MAXULONG_PTR) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_NONE; - /* Position-independent image, base address doesn't matter */ - else if(nImageBase == 0) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_ANY; - /* Use the specified base address */ - else - ImageSectionObject->ImageBase = (ULONG_PTR)nImageBase; - - /* safest bet */ - ImageSectionObject->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; - ImageSectionObject->MinorSubsystemVersion = 0; - ImageSectionObject->MajorSubsystemVersion = 4; - - /* Success, at last */ - nStatus = STATUS_SUCCESS; - -l_Return: - if(pBuffer) - ExFreePool(pBuffer); - - return nStatus; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/mm/elf32.c b/reactos/ntoskrnl/mm/elf32.c deleted file mode 100644 index 4e56e4408fc..00000000000 --- a/reactos/ntoskrnl/mm/elf32.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf32.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 32 -#include "elf.inc.h" - -extern NTSTATUS NTAPI Elf64FmtCreateSection -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -); - -NTSTATUS NTAPI ElfFmtCreateSection -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -) -{ - ULONG nDataType; - const Elf32_Ehdr * pehTempHeader; - - ASSERT(FileHeader); - ASSERT(FileHeaderSize > 0); - ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize)); - ASSERT(File); - ASSERT(ImageSectionObject); - ASSERT(Flags); - ASSERT(ReadFileCb); - ASSERT(AllocateSegmentsCb); - - pehTempHeader = FileHeader; - ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf32_Ehdr)) == 0); - ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf64_Ehdr)) == 0); - - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_ident)); - - /* File too small to be identified */ - if(!RTL_CONTAINS_FIELD(pehTempHeader, FileHeaderSize, e_ident[EI_MAG3])) - return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT; - - /* Not an ELF file */ - if - ( - pehTempHeader->e_ident[EI_MAG0] != ELFMAG0 || - pehTempHeader->e_ident[EI_MAG1] != ELFMAG1 || - pehTempHeader->e_ident[EI_MAG2] != ELFMAG2 || - pehTempHeader->e_ident[EI_MAG3] != ELFMAG3 - ) - return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT; - - /* Validate the data type */ - nDataType = pehTempHeader->e_ident[EI_DATA]; - - switch(nDataType) - { - case ELFDATA2LSB: - case ELFDATA2MSB: - break; - - default: - return STATUS_INVALID_IMAGE_FORMAT; - } - - /* Validate the version */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_version)); - - if - ( - pehTempHeader->e_ident[EI_VERSION] != EV_CURRENT || - ElfFmtpReadULong(pehTempHeader->e_version, nDataType) != EV_CURRENT - ) - return STATUS_INVALID_IMAGE_FORMAT; - - /* Validate the file type */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_type)); - - switch(ElfFmtpReadUShort(pehTempHeader->e_type, nDataType)) - { - case ET_DYN: ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL; - case ET_EXEC: break; - default: return STATUS_INVALID_IMAGE_FORMAT; - } - - /* Convert the target machine */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_machine)); - ASSERT(ImageSectionObject->Machine == IMAGE_FILE_MACHINE_UNKNOWN); - - switch(ElfFmtpReadUShort(pehTempHeader->e_machine, nDataType)) - { - case EM_386: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; break; - case EM_MIPS_RS3_LE: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_R3000; break; - -#if 0 - /* TODO: need to read e_flags for full identification */ - case EM_SH: break; -#endif - - case EM_ARM: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_ARM; break; - case EM_PPC: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_POWERPC; break; - case EM_IA_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_IA64; break; - case EM_ALPHA: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AXP64; break; - case EM_X86_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AMD64; break; - case EM_M32R: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_M32R; break; - } - - /* Call the appropriate handler for the class-specific fields */ - switch(pehTempHeader->e_ident[EI_CLASS]) - { - case ELFCLASS32: - return Elf32FmtCreateSection - ( - FileHeader, - FileHeaderSize, - File, - ImageSectionObject, - Flags, - ReadFileCb, - AllocateSegmentsCb - ); - - case ELFCLASS64: - return Elf64FmtCreateSection - ( - FileHeader, - FileHeaderSize, - File, - ImageSectionObject, - Flags, - ReadFileCb, - AllocateSegmentsCb - ); - } - - /* Unknown class */ - return STATUS_INVALID_IMAGE_FORMAT; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/mm/elf64.c b/reactos/ntoskrnl/mm/elf64.c deleted file mode 100644 index 783f5a00534..00000000000 --- a/reactos/ntoskrnl/mm/elf64.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf64.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 64 -#include "elf.inc.h" diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 5dc63c62e56..68ad293fe9d 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -404,6 +404,7 @@ pfnlist.c pool.c procsup.c + sysldr.c syspte.c virtual.c @@ -425,7 +426,6 @@ region.c rmap.c section.c - sysldr.c virtual.c elf32.c From 5e130771e7ef49df64d96416a7cff5c2a0eb325c Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 6 Jun 2010 07:21:53 +0000 Subject: [PATCH 257/292] [rtl] - Fix a overlooked change needed due to mbstowcs fix. Use the number of WCHARs vice number of bytes to calculate end of xmlbuf. svn path=/trunk/; revision=47613 --- reactos/lib/rtl/actctx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/lib/rtl/actctx.c b/reactos/lib/rtl/actctx.c index 9ad67e053fd..40883a8ff22 100644 --- a/reactos/lib/rtl/actctx.c +++ b/reactos/lib/rtl/actctx.c @@ -1603,8 +1603,8 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident mbstowcs( new_buff, buffer, size); xmlbuf.ptr = new_buff; - DPRINT("Buffer %S\n", new_buff); - xmlbuf.end = xmlbuf.ptr + len; + + xmlbuf.end = xmlbuf.ptr + len / sizeof(WCHAR); status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf ); RtlFreeHeap( RtlGetProcessHeap(), 0, new_buff ); From f301a8c2d33a1ad539e307ad657b2aa18ab1d45d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 6 Jun 2010 07:35:21 +0000 Subject: [PATCH 258/292] [NTOSKNRL] Add the possibility to break on all first chance exceptions, by passing /FIRSTCHANCE on the command line. Enable it temporary to get some more information from the sysreg crash. svn path=/trunk/; revision=47614 --- reactos/boot/bootdata/txtsetup.sif | 2 +- reactos/ntoskrnl/kdbg/kdb.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index 704228d07f7..71a514b0350 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -58,7 +58,7 @@ Cabinet=reactos.cab [SetupData] DefaultPath = \ReactOS OsLoadOptions = "/NOGUIBOOT /NODEBUG" -DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1" +DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1 /FIRSTCHANCE" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=SCREEN" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=BOCHS" diff --git a/reactos/ntoskrnl/kdbg/kdb.c b/reactos/ntoskrnl/kdbg/kdb.c index 9fb099c8b10..30eb071c2d1 100644 --- a/reactos/ntoskrnl/kdbg/kdb.c +++ b/reactos/ntoskrnl/kdbg/kdb.c @@ -1710,6 +1710,11 @@ KdbpGetCommandLineSettings( p2 += 8; KdbDebugState |= KD_DEBUG_KDNOECHO; } + else if (!_strnicmp(p2, "FIRSTCHANCE", 11)) + { + p2 += 11; + KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways); + } p1 = p2; } From ebd10beb1f407a24a12b202440106a9e9360e8f1 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 6 Jun 2010 07:52:32 +0000 Subject: [PATCH 259/292] Add /KDSERIAL to the command line, to make sysreg able to bt in first stage. svn path=/trunk/; revision=47615 --- reactos/boot/bootdata/txtsetup.sif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index 71a514b0350..c822c2fbc3e 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -58,7 +58,7 @@ Cabinet=reactos.cab [SetupData] DefaultPath = \ReactOS OsLoadOptions = "/NOGUIBOOT /NODEBUG" -DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1 /FIRSTCHANCE" +DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1 /FIRSTCHANCE /KDSERIAL" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=SCREEN" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=BOCHS" From 08b2876a257b53609a24d57a3e7a9ca4f475c895 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 13:42:19 +0000 Subject: [PATCH 260/292] [NTOS]: Fix a loop off-by-one when saving the page table index in contigious memory allocation PFNs. Spotted by Stefan100. svn path=/trunk/; revision=47620 --- reactos/ntoskrnl/mm/ARM3/contmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/contmem.c b/reactos/ntoskrnl/mm/ARM3/contmem.c index 2f3eda954e2..94c8650f6ef 100644 --- a/reactos/ntoskrnl/mm/ARM3/contmem.c +++ b/reactos/ntoskrnl/mm/ARM3/contmem.c @@ -352,8 +352,8 @@ MiFindContiguousMemory(IN PFN_NUMBER LowestPfn, do { /* Write the PTE address */ - Pfn1->PteAddress = PointerPte++; - Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte)); + Pfn1->PteAddress = PointerPte; + Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte++)); } while (Pfn1++ < EndPfn); /* Return the address */ From 49448736a21cafe10f28ec6cea17fa73f4d6ba03 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 14:12:28 +0000 Subject: [PATCH 261/292] [NTOS]: Implement MiRemoveZeroPage and MiZeroPhysicalPage. Not yet used. svn path=/trunk/; revision=47621 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index bc0167e03f2..ab72198ed35 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -56,6 +56,20 @@ PMMPFNLIST MmPageLocationList[] = }; /* FUNCTIONS ******************************************************************/ +VOID +NTAPI +MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex) +{ + KIRQL OldIrql; + PVOID VirtualAddress; + PEPROCESS Process = PsGetCurrentProcess(); + + /* Map in hyperspace, then wipe it using XMMI or MEMSET */ + VirtualAddress = MiMapPageInHyperSpace(Process, PageFrameIndex, &OldIrql); + KeZeroPages(VirtualAddress, PAGE_SIZE); + MiUnmapPageInHyperSpace(Process, VirtualAddress, OldIrql); +} + VOID NTAPI MiInsertInListTail(IN PMMPFNLIST ListHead, @@ -441,6 +455,79 @@ MiRemoveAnyPage(IN ULONG Color) return PageIndex; } +PFN_NUMBER +NTAPI +MiRemoveZeroPage(IN ULONG Color) +{ + PFN_NUMBER PageIndex; + PMMPFN Pfn1; + BOOLEAN Zero; + + /* Make sure PFN lock is held and we have pages */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(MmAvailablePages != 0); + ASSERT(Color < MmSecondaryColors); + + /* Check the colored zero list */ +#if 0 // Enable when using ARM3 database */ + PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; + if (PageIndex == LIST_HEAD) + { +#endif + /* Check the zero list */ + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + PageIndex = MmZeroedPageListHead.Flink; + Color = PageIndex & MmSecondaryColorMask; + if (PageIndex == LIST_HEAD) + { + ASSERT(MmZeroedPageListHead.Total == 0); + Zero = TRUE; +#if 0 // Enable when using ARM3 database */ + /* Check the colored free list */ + PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; + if (PageIndex == LIST_HEAD) + { +#endif + /* Check the free list */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + PageIndex = MmFreePageListHead.Flink; + Color = PageIndex & MmSecondaryColorMask; + ASSERT(PageIndex != LIST_HEAD); + if (PageIndex == LIST_HEAD) + { + /* FIXME: Should check the standby list */ + ASSERT(MmZeroedPageListHead.Total == 0); + } +#if 0 // Enable when using ARM3 database */ + } +#endif + } +#if 0 // Enable when using ARM3 database */ + } +#endif + /* Sanity checks */ + Pfn1 = MiGetPfnEntry(PageIndex); + ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) || + (Pfn1->u3.e1.PageLocation == ZeroedPageList)); + + /* Remove the page from its list */ + PageIndex = MiRemovePageByColor(PageIndex, Color); + ASSERT(Pfn1 == MiGetPfnEntry(PageIndex)); + + /* Zero it, if needed */ + if (Zero) MiZeroPhysicalPage(PageIndex); + + /* Sanity checks */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + ASSERT(Pfn1->u2.ShareCount == 0); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + + /* Return the page */ + return PageIndex; +} + + PMMPFN NTAPI MiRemoveHeadList(IN PMMPFNLIST ListHead) From abefb827e7f4483f1e353e16445288d62367be10 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 14:13:35 +0000 Subject: [PATCH 262/292] [NTOS]: Don't use MmAllocPage for the first paged pool PDE, instead, use MiRemoveZeroPage. [NTOS]: Use MiInitializePfnForOtherProcess to setup the first paged pool PDE. svn path=/trunk/; revision=47622 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 6 ++++++ reactos/ntoskrnl/mm/ARM3/mminit.c | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index b5adad3e5fe..759bdabcfc0 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -743,6 +743,12 @@ MiRemoveAnyPage( IN ULONG Color ); +PFN_NUMBER +NTAPI +MiRemoveZeroPage( + IN ULONG Color +); + VOID NTAPI MiInsertPageInFreeList( diff --git a/reactos/ntoskrnl/mm/ARM3/mminit.c b/reactos/ntoskrnl/mm/ARM3/mminit.c index eba66b18311..f47b3bb8b38 100644 --- a/reactos/ntoskrnl/mm/ARM3/mminit.c +++ b/reactos/ntoskrnl/mm/ARM3/mminit.c @@ -1586,15 +1586,18 @@ MiBuildPagedPool(VOID) // OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - // - // Allocate a page and map the first paged pool PDE - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); + /* Allocate a page and map the first paged pool PDE */ + PageFrameIndex = MiRemoveZeroPage(0); TempPte.u.Hard.PageFrameNumber = PageFrameIndex; ASSERT(PointerPde->u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 1); *PointerPde = TempPte; + /* Initialize the PFN entry for it */ + MiInitializePfnForOtherProcess(PageFrameIndex, + PointerPde, + MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]); + // // Release the PFN database lock // From aa574a3c900fbbb4237b25965843a1e1274dc5c3 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 14:15:18 +0000 Subject: [PATCH 263/292] [NTOS]: A PFN entry is not necessarily physical only if it is higher than MmHighestPhysicalPage. It can also be physical if it lies in a memory hole within the min-max physical page range. We can detect this by using our PFN Bitmap. So replace all "Is this an I/O mapping?" checks with a check on whether or not the PFN Database entry is NULL (which will check for us both of these statements). This ought to be a macro... svn path=/trunk/; revision=47623 --- reactos/ntoskrnl/mm/ARM3/iosup.c | 6 +++--- reactos/ntoskrnl/mm/ARM3/mdlsup.c | 2 +- reactos/ntoskrnl/mm/mmdbg.c | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/iosup.c b/reactos/ntoskrnl/mm/ARM3/iosup.c index 1a174509382..5d8cb2e12da 100644 --- a/reactos/ntoskrnl/mm/ARM3/iosup.c +++ b/reactos/ntoskrnl/mm/ARM3/iosup.c @@ -90,8 +90,8 @@ MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, // Also translate the cache attribute // Pfn = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT); - IsIoMapping = (Pfn > MmHighestPhysicalPage) ? TRUE : FALSE; - if (!IsIoMapping) Pfn1 = MiGetPfnEntry(Pfn); + Pfn1 = MiGetPfnEntry(Pfn); + IsIoMapping = (Pfn1 == NULL) ? TRUE : FALSE; CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType]; // @@ -219,7 +219,7 @@ MmUnmapIoSpace(IN PVOID BaseAddress, // // Is this an I/O mapping? // - if (Pfn > MmHighestPhysicalPage) + if (!MiGetPfnEntry(Pfn)) { // // Destroy the PTE diff --git a/reactos/ntoskrnl/mm/ARM3/mdlsup.c b/reactos/ntoskrnl/mm/ARM3/mdlsup.c index 1b95448fc43..078de3de1c8 100644 --- a/reactos/ntoskrnl/mm/ARM3/mdlsup.c +++ b/reactos/ntoskrnl/mm/ARM3/mdlsup.c @@ -129,7 +129,7 @@ MmBuildMdlForNonPagedPool(IN PMDL Mdl) // // Check if this is an I/O mapping // - if (Pfn > MmHighestPhysicalPage) Mdl->MdlFlags |= MDL_IO_SPACE; + if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE; } /* diff --git a/reactos/ntoskrnl/mm/mmdbg.c b/reactos/ntoskrnl/mm/mmdbg.c index fd11099e1fd..313516b1bf3 100644 --- a/reactos/ntoskrnl/mm/mmdbg.c +++ b/reactos/ntoskrnl/mm/mmdbg.c @@ -85,10 +85,8 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, // Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT); - // - // Check if this could be an I/O mapping - // - if (Pfn > MmHighestPhysicalPage) + /* Check if this could be an I/O mapping */ + if (!MiGetPfnEntry(Pfn)) { // // FIXME: We don't support this yet From 5867b89ee6f31b25df090d87f4c732da410c1296 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 14:24:18 +0000 Subject: [PATCH 264/292] [NTOS]: Another one bites the dust, another one bites the dust. And another one gone and another one gone. Another one bites the dust, yeah. Out of the doorway the bullets rip, Repeating to the sound of the beat. svn path=/trunk/; revision=47624 --- reactos/ntoskrnl/mm/{ => ARM3}/mmdbg.c | 13 ++++++++++--- reactos/ntoskrnl/mm/ARM3/sysldr.c | 4 ++-- reactos/ntoskrnl/ntoskrnl-generic.rbuild | 4 +--- 3 files changed, 13 insertions(+), 8 deletions(-) rename reactos/ntoskrnl/mm/{ => ARM3}/mmdbg.c (96%) diff --git a/reactos/ntoskrnl/mm/mmdbg.c b/reactos/ntoskrnl/mm/ARM3/mmdbg.c similarity index 96% rename from reactos/ntoskrnl/mm/mmdbg.c rename to reactos/ntoskrnl/mm/ARM3/mmdbg.c index 313516b1bf3..7444f7d57f5 100644 --- a/reactos/ntoskrnl/mm/mmdbg.c +++ b/reactos/ntoskrnl/mm/ARM3/mmdbg.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/mm/mmdbg.c + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/mmdbg.c * PURPOSE: Memory Manager support routines for the Kernel Debugger * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) */ @@ -9,10 +9,17 @@ /* INCLUDES *******************************************************************/ #include -#include "ARM3/miarm.h" #define NDEBUG #include +#line 16 "ARM³::DEBUGSUP" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +#ifndef _WINKD_ +#define KdpDprintf DPRINT +#endif + /* GLOBALS ********************************************************************/ PMMPTE MmDebugPte = MiAddressToPte(MI_DEBUG_MAPPING); diff --git a/reactos/ntoskrnl/mm/ARM3/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c index 2c4a09cfd3a..ef1a8cf265f 100644 --- a/reactos/ntoskrnl/mm/ARM3/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel -* LICENSE: GPL - See COPYING in the top level directory -* FILE: ntoskrnl/mm/sysldr.c +* LICENSE: BSD - See COPYING.ARM in the top level directory +* FILE: ntoskrnl/mm/ARM3/sysldr.c * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files. * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * ReactOS Portable Systems Group diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 68ad293fe9d..c89b9c97683 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -397,6 +397,7 @@ iosup.c largepag.c mdlsup.c + mmdbg.c mminit.c mmsup.c ncache.c @@ -412,9 +413,6 @@ balance.c freelist.c marea.c - - mmdbg.c - mmfault.c mminit.c mpw.c From 8e367dfc1bcd2472d5eb37af3a5ec1607a6220f6 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Sun, 6 Jun 2010 14:42:03 +0000 Subject: [PATCH 265/292] - Fix a comment and remove a superfluous extern. svn path=/trunk/; revision=47625 --- reactos/ntoskrnl/mm/ARM3/mmdbg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/mmdbg.c b/reactos/ntoskrnl/mm/ARM3/mmdbg.c index 7444f7d57f5..41260f224c3 100644 --- a/reactos/ntoskrnl/mm/ARM3/mmdbg.c +++ b/reactos/ntoskrnl/mm/ARM3/mmdbg.c @@ -42,7 +42,6 @@ NTAPI MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, IN ULONG Flags) { - extern MMPTE ValidKernelPte; PFN_NUMBER Pfn; MMPTE TempPte; PVOID MappingBaseAddress; @@ -83,7 +82,7 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, MappingBaseAddress = MiPteToAddress(MmDebugPte); // - // + // Get the template // TempPte = ValidKernelPte; From 55e7a4b5bf8471750b351e498adf129d4ef0d3ef Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 15:49:54 +0000 Subject: [PATCH 266/292] [COMPBATT]: Remove useless function. svn path=/trunk/; revision=47626 --- reactos/drivers/bus/acpi/compbatt/compbatt.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/reactos/drivers/bus/acpi/compbatt/compbatt.c b/reactos/drivers/bus/acpi/compbatt/compbatt.c index a0b17f83e45..094cb4e6b6e 100644 --- a/reactos/drivers/bus/acpi/compbatt/compbatt.c +++ b/reactos/drivers/bus/acpi/compbatt/compbatt.c @@ -214,15 +214,6 @@ CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -CompBattGetBatteryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG Tag) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, From d7372c2dc47a61525f8ef76fe2d94ee6c0270a28 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 15:59:42 +0000 Subject: [PATCH 267/292] [NTOS]: Enable usage of ARM3 paged pool, up until Mm Phase 2. [NTOS]: Re-arrange some of the init code, now that we have access to ARM3 paged pool early-on. Move more code to ARM3::INIT in its right place. [NTOS]: Enable using the ARM3 PFN Database, getting rid of the old ReactOS PFN database. Should reduce physical memory usage now that we don't have two copies anymore. [NTOS]: Fix the ARM3 PFN Datbase initialization code. [NTOS]: Get rid of MiInitializePageList, use MiGetPfnEntryOffset instead of hard-coded pointer math in freelist.c. This is the last big low-level Mm/ARM3 patch for a long, long time. svn path=/trunk/; revision=47627 --- reactos/ntoskrnl/include/internal/mm.h | 6 +- reactos/ntoskrnl/mm/ARM3/expool.c | 2 +- reactos/ntoskrnl/mm/ARM3/i386/init.c | 24 +++---- reactos/ntoskrnl/mm/ARM3/mminit.c | 86 +++++++++--------------- reactos/ntoskrnl/mm/freelist.c | 90 +------------------------- reactos/ntoskrnl/mm/mminit.c | 29 +++------ 6 files changed, 54 insertions(+), 183 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index db7003d1438..d8c61786f3f 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -364,7 +364,7 @@ typedef struct _MMPFN } u4; } MMPFN, *PMMPFN; -extern PMMPFN MmPfnDatabase[2]; +extern PMMPFN MmPfnDatabase; typedef struct _MMPFNLIST { @@ -1095,7 +1095,7 @@ MiGetPfnEntry(IN PFN_TYPE Pfn) if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, Pfn))) return NULL; /* Get the entry */ - Page = &MmPfnDatabase[0][Pfn]; + Page = &MmPfnDatabase[Pfn]; /* Return it */ return Page; @@ -1108,7 +1108,7 @@ MiGetPfnEntryIndex(IN PMMPFN Pfn1) // // This will return the Page Frame Number (PFN) from the MMPFN // - return Pfn1 - MmPfnDatabase[0]; + return Pfn1 - MmPfnDatabase; } PFN_TYPE diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index c3d60b39387..83d62b785ac 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -19,7 +19,7 @@ #undef ExAllocatePoolWithQuota #undef ExAllocatePoolWithQuotaTag -BOOLEAN AllowPagedPool = FALSE; +BOOLEAN AllowPagedPool = TRUE; /* GLOBALS ********************************************************************/ diff --git a/reactos/ntoskrnl/mm/ARM3/i386/init.c b/reactos/ntoskrnl/mm/ARM3/i386/init.c index c0226ebc8ac..ed15b402192 100644 --- a/reactos/ntoskrnl/mm/ARM3/i386/init.c +++ b/reactos/ntoskrnl/mm/ARM3/i386/init.c @@ -306,7 +306,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // then add the color tables and convert to pages // MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN); - MxPfnAllocation <<= 1; + //MxPfnAllocation <<= 1; MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2); MxPfnAllocation >>= PAGE_SHIFT; @@ -380,19 +380,13 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // with the old memory manager, so we'll create a "Shadow PFN Database" // instead, and arbitrarly start it at 0xB0000000. // - // We actually create two PFN databases, one for ReactOS starting here, - // and the next one used for ARM3, which starts right after. The MmPfnAllocation - // variable actually holds the size of both (the colored tables come after - // the ARM3 PFN database). - // - MmPfnDatabase[0] = (PVOID)0xB0000000; - MmPfnDatabase[1] = &MmPfnDatabase[0][MmHighestPhysicalPage]; - ASSERT(((ULONG_PTR)MmPfnDatabase[0] & (PDE_MAPPED_VA - 1)) == 0); + MmPfnDatabase = (PVOID)0xB0000000; + ASSERT(((ULONG_PTR)MmPfnDatabase & (PDE_MAPPED_VA - 1)) == 0); // // Non paged pool comes after the PFN database // - MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase[0] + + MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT)); // @@ -443,7 +437,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // // Now we need pages for the page tables which will map initial NP // - StartPde = MiAddressToPde(MmPfnDatabase[0]); + StartPde = MiAddressToPde(MmPfnDatabase); EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); while (StartPde <= EndPde) @@ -510,12 +504,14 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Initialize the color tables */ MiInitializeColorTables(); + /* ReactOS Stuff */ + extern KEVENT ZeroPageThreadEvent; + KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); + /* Build the PFN Database */ MiInitializePfnDatabase(LoaderBlock); + MmInitializeBalancer(MmAvailablePages, 0); - /* Call back into shitMM to setup the ReactOS PFN database */ - MmInitializePageList(); - // // Reset the descriptor back so we can create the correct memory blocks // diff --git a/reactos/ntoskrnl/mm/ARM3/mminit.c b/reactos/ntoskrnl/mm/ARM3/mminit.c index f47b3bb8b38..c79b31d4e07 100644 --- a/reactos/ntoskrnl/mm/ARM3/mminit.c +++ b/reactos/ntoskrnl/mm/ARM3/mminit.c @@ -439,7 +439,7 @@ MiInitializeColorTables(VOID) MMPTE TempPte = ValidKernelPte; /* The color table starts after the ARM3 PFN database */ - MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[1][MmHighestPhysicalPage + 1]; + MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[MmHighestPhysicalPage + 1]; /* Loop the PTEs. We have two color tables for each secondary color */ PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]); @@ -585,8 +585,8 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) } /* Get the PTEs for this range */ - PointerPte = MiAddressToPte(&MmPfnDatabase[0][BasePage]); - LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[0][BasePage + PageCount]) - 1); + PointerPte = MiAddressToPte(&MmPfnDatabase[BasePage]); + LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[BasePage + PageCount]) - 1); DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount); /* Loop them */ @@ -625,49 +625,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Next! */ PointerPte++; } - - /* Get the PTEs for this range */ - PointerPte = MiAddressToPte(&MmPfnDatabase[1][BasePage]); - LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[1][BasePage + PageCount]) - 1); - DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount); - - /* Loop them */ - while (PointerPte <= LastPte) - { - /* We'll only touch PTEs that aren't already valid */ - if (PointerPte->u.Hard.Valid == 0) - { - /* Use the next free page */ - TempPte.u.Hard.PageFrameNumber = FreePage; - ASSERT(FreePageCount != 0); - - /* Consume free pages */ - FreePage++; - FreePageCount--; - if (!FreePageCount) - { - /* Out of memory */ - KeBugCheckEx(INSTALL_MORE_MEMORY, - MmNumberOfPhysicalPages, - FreePageCount, - MxOldFreeDescriptor.PageCount, - 1); - } - - /* Write out this PTE */ - PagesLeft++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - - /* Zero this page */ - RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); - } - - /* Next! */ - PointerPte++; - } - + /* Do the next address range */ NextEntry = MdBlock->ListEntry.Flink; } @@ -706,7 +664,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) if (MiIsRegularMemory(LoaderBlock, PageFrameIndex)) { /* Yes we do, set it up */ - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); Pfn1->u4.PteFrame = StartupPdIndex; Pfn1->PteAddress = PointerPde; Pfn1->u2.ShareCount++; @@ -745,7 +703,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MmSizeOfNonPagedPoolInBytes))) { /* Get the PFN entry and make sure it too is valid */ - Pfn2 = MI_PFN_TO_PFNENTRY(PtePageIndex); + Pfn2 = MiGetPfnEntry(PtePageIndex); if ((MmIsAddressValid(Pfn2)) && (MmIsAddressValid(Pfn2 + 1))) { @@ -785,7 +743,7 @@ MiBuildPfnDatabaseZeroPage(VOID) PMMPDE PointerPde; /* Grab the lowest page and check if it has no real references */ - Pfn1 = MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage); + Pfn1 = MiGetPfnEntry(MmLowestPhysicalPage); if (!(MmLowestPhysicalPage) && !(Pfn1->u3.e2.ReferenceCount)) { /* Make it a bogus page to catch errors */ @@ -810,6 +768,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PMMPFN Pfn1; PMMPTE PointerPte; PMMPDE PointerPde; + KIRQL OldIrql; /* Now loop through the descriptors */ NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; @@ -860,14 +819,18 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Get the last page of this descriptor. Note we loop backwards */ PageFrameIndex += PageCount - 1; - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); + + /* Lock the PFN Database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); while (PageCount--) { /* If the page really has no references, mark it as free */ if (!Pfn1->u3.e2.ReferenceCount) { + /* Add it to the free list */ Pfn1->u3.e1.CacheAttribute = MiNonCached; - //MiInsertPageInFreeList(PageFrameIndex); + MiInsertPageInFreeList(PageFrameIndex); } /* Go to the next page */ @@ -875,6 +838,9 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PageFrameIndex--; } + /* Release PFN database */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + /* Done with this block */ break; @@ -890,7 +856,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Map these pages with the KSEG0 mapping that adds 0x80000000 */ PointerPte = MiAddressToPte(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); while (PageCount--) { /* Check if the page is really unused */ @@ -940,15 +906,15 @@ MiBuildPfnDatabaseSelf(VOID) PMMPFN Pfn1; /* Loop the PFN database page */ - PointerPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage)); - LastPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmHighestPhysicalPage)); + PointerPte = MiAddressToPte(MiGetPfnEntry(MmLowestPhysicalPage)); + LastPte = MiAddressToPte(MiGetPfnEntry(MmHighestPhysicalPage)); while (PointerPte <= LastPte) { /* Make sure the page is valid */ if (PointerPte->u.Hard.Valid == 1) { /* Get the PFN entry and just mark it referenced */ - Pfn1 = MI_PFN_TO_PFNENTRY(PointerPte->u.Hard.PageFrameNumber); + Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber); Pfn1->u2.ShareCount = 1; Pfn1->u3.e2.ReferenceCount = 1; } @@ -1258,7 +1224,7 @@ MmDumpArmPfnDatabase(VOID) // for (i = 0; i <= MmHighestPhysicalPage; i++) { - Pfn1 = MI_PFN_TO_PFNENTRY(i); + Pfn1 = MiGetPfnEntry(i); if (!Pfn1) continue; // @@ -1848,7 +1814,7 @@ MmArmInitSystem(IN ULONG Phase, // Sync us up with ReactOS Mm // MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); - MiSyncARM3WithROS(MmPfnDatabase[0], (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); + MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1)); // @@ -2029,6 +1995,12 @@ MmArmInitSystem(IN ULONG Phase, /* Size up paged pool and build the shadow system page directory */ MiBuildPagedPool(); + + /* Debugger physical memory support is now ready to be used */ + MiDbgReadyForPhysical = TRUE; + + /* Initialize the loaded module list */ + MiInitializeLoadedModuleList(LoaderBlock); } // diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index afdad865dfe..c3156ec79e5 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -33,8 +33,7 @@ #define PHYSICAL_PAGE MMPFN #define PPHYSICAL_PAGE PMMPFN -/* The first array contains ReactOS PFNs, the second contains ARM3 PFNs */ -PPHYSICAL_PAGE MmPfnDatabase[2]; +PPHYSICAL_PAGE MmPfnDatabase; PFN_NUMBER MmAvailablePages; PFN_NUMBER MmResidentAvailablePages; @@ -448,89 +447,6 @@ MmDumpPfnDatabase(VOID) KeLowerIrql(OldIrql); } -VOID -NTAPI -MmInitializePageList(VOID) -{ - ULONG i; - PHYSICAL_PAGE UsedPage; - PMEMORY_ALLOCATION_DESCRIPTOR Md; - PLIST_ENTRY NextEntry; - ULONG NrSystemPages = 0; - KIRQL OldIrql; - - /* This is what a used page looks like */ - RtlZeroMemory(&UsedPage, sizeof(UsedPage)); - UsedPage.u3.e1.PageLocation = ActiveAndValid; - UsedPage.u3.e2.ReferenceCount = 1; - - /* Lock PFN database */ - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - - /* Loop the memory descriptors */ - for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; - NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; - NextEntry = NextEntry->Flink) - { - /* Get the descriptor */ - Md = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* Skip bad memory */ - if ((Md->MemoryType == LoaderFirmwarePermanent) || - (Md->MemoryType == LoaderBBTMemory) || - (Md->MemoryType == LoaderSpecialMemory) || - (Md->MemoryType == LoaderBad)) - { - // - // We do not build PFN entries for this - // - continue; - } - else if ((Md->MemoryType == LoaderFree) || - (Md->MemoryType == LoaderLoadedProgram) || - (Md->MemoryType == LoaderFirmwareTemporary) || - (Md->MemoryType == LoaderOsloaderStack)) - { - /* Loop every page part of the block */ - for (i = 0; i < Md->PageCount; i++) - { - /* Mark it as a free page */ - MmPfnDatabase[0][Md->BasePage + i].u3.e1.PageLocation = FreePageList; - MiInsertInListTail(&MmFreePageListHead, - &MmPfnDatabase[0][Md->BasePage + i]); - MmAvailablePages++; - } - } - else - { - /* Loop every page part of the block */ - for (i = 0; i < Md->PageCount; i++) - { - /* Everything else is used memory */ - MmPfnDatabase[0][Md->BasePage + i] = UsedPage; - NrSystemPages++; - } - } - } - - /* Finally handle the pages describing the PFN database themselves */ - for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++) - { - /* Mark it as used kernel memory */ - MmPfnDatabase[0][i] = UsedPage; - NrSystemPages++; - } - - /* Release the PFN database lock */ - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - - KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); - DPRINT("Pages: %x %x\n", MmAvailablePages, NrSystemPages); - MmInitializeBalancer(MmAvailablePages, NrSystemPages); -} - VOID NTAPI MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead) @@ -695,7 +611,7 @@ MmAllocPage(ULONG Type) MmAvailablePages--; - PfnOffset = PageDescriptor - MmPfnDatabase[0]; + PfnOffset = MiGetPfnEntryIndex(PageDescriptor); if ((NeedClear) && (Type != MC_SYSTEM)) { MiZeroPage(PfnOffset); @@ -761,7 +677,7 @@ MmZeroPageThreadMain(PVOID Ignored) PageDescriptor = MiRemoveHeadList(&MmFreePageListHead); /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); - Pfn = PageDescriptor - MmPfnDatabase[0]; + Pfn = MiGetPfnEntryIndex(PageDescriptor); Status = MiZeroPage(Pfn); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index cb10634fdc2..83c45f145b9 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -109,7 +109,7 @@ MiInitSystemMemoryAreas() // // Protect the PFN database // - BaseAddress = MmPfnDatabase[0]; + BaseAddress = MmPfnDatabase; Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, @@ -292,8 +292,8 @@ MiDbgDumpAddressSpace(VOID) (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize, "Paged Pool"); DPRINT1(" 0x%p - 0x%p\t%s\n", - MmPfnDatabase[0], - (ULONG_PTR)MmPfnDatabase[0] + (MxPfnAllocation << PAGE_SHIFT), + MmPfnDatabase, + (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT), "PFN Database"); DPRINT1(" 0x%p - 0x%p\t%s\n", MmNonPagedPoolStart, @@ -371,18 +371,8 @@ MmInitSystem(IN ULONG Phase, /* Dump memory descriptors */ if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); - // - // Initialize ARM³ in phase 0 - // + /* Initialize ARM³ in phase 0 */ MmArmInitSystem(0, KeLoaderBlock); - -#if defined(_WINKD_) - // - // Everything required for the debugger to read and write - // physical memory is now set up - // - MiDbgReadyForPhysical = TRUE; -#endif /* Put the paged pool after the loaded modules */ MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart + @@ -394,15 +384,10 @@ MmInitSystem(IN ULONG Phase, /* Dump the address space */ MiDbgDumpAddressSpace(); - - /* Initialize paged pool */ - MmInitializePagedPool(); - - /* Initialize the loaded module list */ - MiInitializeLoadedModuleList(LoaderBlock); } else if (Phase == 1) { + MmInitializePagedPool(); MiInitializeUserPfnBitmap(); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeRmapList(); @@ -453,7 +438,9 @@ MmInitSystem(IN ULONG Phase, } else if (Phase == 2) { - + /* Enough fun for now */ + extern BOOLEAN AllowPagedPool; + AllowPagedPool = FALSE; } return TRUE; From f44eee190b536ee0362aa20d9ba9d6d271ba3d4f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 18:09:25 +0000 Subject: [PATCH 268/292] [NDIS] - Implement miniport timer queuing - Add some BUGCODE_ID_DRIVER bug check cases for missing interrupt deregistration, missing timer cancellation, and invalid IRQL when calling NdisMAllocateSharedMemory svn path=/trunk/; revision=47630 --- reactos/drivers/network/ndis/ndis/memory.c | 9 +++ reactos/drivers/network/ndis/ndis/miniport.c | 25 ++++++++ reactos/drivers/network/ndis/ndis/time.c | 62 +++++++++++++++++++- 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/network/ndis/ndis/memory.c b/reactos/drivers/network/ndis/ndis/memory.c index 7696389e876..3d96170ea4c 100644 --- a/reactos/drivers/network/ndis/ndis/memory.c +++ b/reactos/drivers/network/ndis/ndis/memory.c @@ -171,6 +171,15 @@ NdisMAllocateSharedMemory( NDIS_DbgPrint(MAX_TRACE,("Called.\n")); + if (KeGetCurrentIrql() != PASSIVE_LEVEL) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + Length, + 0, + 1); + } + *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer( Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached); } diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index daaf7cac1b1..4492caffe32 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -365,6 +365,15 @@ MiniResetComplete( KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + if (Adapter->NdisMiniportBlock.ResetStatus != NDIS_STATUS_PENDING) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + (ULONG_PTR)Status, + (ULONG_PTR)AddressingReset, + 0); + } + Adapter->NdisMiniportBlock.ResetStatus = Status; CurrentEntry = Adapter->ProtocolListHead.Flink; @@ -1959,6 +1968,22 @@ NdisIPnPStartDevice( { NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); + if (Adapter->NdisMiniportBlock.Interrupt) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } + if (Adapter->NdisMiniportBlock.TimerQueue) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } return NdisStatus; } diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index 75a65f3b24f..0872ee70458 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -95,6 +95,32 @@ NdisInitializeTimer( KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); } +VOID DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) +{ + PNDIS_MINIPORT_TIMER CurrentTimer; + + ASSERT(Timer->Miniport->TimerQueue); + + if (Timer->Miniport->TimerQueue == Timer) + { + Timer->Miniport->TimerQueue = Timer->NextDeferredTimer; + } + else + { + CurrentTimer = Timer->Miniport->TimerQueue; + while (CurrentTimer->NextDeferredTimer) + { + if (CurrentTimer->NextDeferredTimer == Timer) + { + CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer; + return; + } + CurrentTimer = CurrentTimer->NextDeferredTimer; + } + ASSERT(FALSE); + } +} + /* * @implemented @@ -118,6 +144,25 @@ NdisMCancelTimer( ASSERT(Timer); *TimerCancelled = KeCancelTimer (&Timer->Timer); + + DequeueMiniportTimer(Timer); +} + +VOID NTAPI +MiniTimerDpcFunction(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PNDIS_MINIPORT_TIMER Timer = DeferredContext; + + Timer->MiniportTimerFunction(Dpc, + Timer->MiniportTimerContext, + SystemArgument1, + SystemArgument2); + + /* FIXME: We can't call this if we have a periodic timer */ + //DequeueMiniportTimer(Timer); } @@ -145,9 +190,14 @@ NdisMInitializeTimer( { PAGED_CODE(); ASSERT(Timer); - KeInitializeTimer (&Timer->Timer); - KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); + KeInitializeTimer (&Timer->Timer); + KeInitializeDpc (&Timer->Dpc, MiniTimerDpcFunction, Timer); + + Timer->MiniportTimerFunction = TimerFunction; + Timer->MiniportTimerContext = FunctionContext; + Timer->Miniport = &((PLOGICAL_ADAPTER)MiniportAdapterHandle)->NdisMiniportBlock; + Timer->NextDeferredTimer = NULL; } @@ -177,6 +227,10 @@ NdisMSetPeriodicTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000); + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + KeSetTimerEx (&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc); } @@ -208,6 +262,10 @@ NdisMSetTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc); } From dd3d52b5ed20eaa477f4bd83bb8aa33d44013458 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 6 Jun 2010 18:32:57 +0000 Subject: [PATCH 269/292] [WIN32K] assert -> ASSERT svn path=/trunk/; revision=47631 --- reactos/subsystems/win32/win32k/misc/driver.c | 4 ++-- reactos/subsystems/win32/win32k/ntuser/message.c | 2 +- reactos/subsystems/win32/win32k/objects/device.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/misc/driver.c b/reactos/subsystems/win32/win32k/misc/driver.c index 1219f94effa..f427e3ff3bf 100644 --- a/reactos/subsystems/win32/win32k/misc/driver.c +++ b/reactos/subsystems/win32/win32k/misc/driver.c @@ -597,7 +597,7 @@ INT DRIVER_ReferenceDriver (LPCWSTR Name) Driver = Driver->Next; } DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - assert( GenericDriver != 0 ); + ASSERT( GenericDriver != 0 ); return ++GenericDriver->ReferenceCount; } @@ -615,7 +615,7 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name) Driver = Driver->Next; } DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - assert( GenericDriver != 0 ); + ASSERT( GenericDriver != 0 ); return --GenericDriver->ReferenceCount; } /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index b6d8ab70443..e78ce5aeca2 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -145,7 +145,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) break; default: - assert(FALSE); + ASSERT(FALSE); Size = 0; break; } diff --git a/reactos/subsystems/win32/win32k/objects/device.c b/reactos/subsystems/win32/win32k/objects/device.c index b8d322f09ac..9ebe3a5ec28 100644 --- a/reactos/subsystems/win32/win32k/objects/device.c +++ b/reactos/subsystems/win32/win32k/objects/device.c @@ -1745,7 +1745,7 @@ IntEnumDisplaySettings( } while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd) { - assert(CachedMode->dmSize > 0); + ASSERT(CachedMode->dmSize > 0); CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra); } if (CachedMode >= CachedDevModesEnd) From d607e811d901c0e30cf9437e2b70b337fbb3929c Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 6 Jun 2010 18:34:57 +0000 Subject: [PATCH 270/292] [WIN32K] Free allocations with the tag that was used to allocate them svn path=/trunk/; revision=47632 --- reactos/subsystems/win32/win32k/ntuser/msgqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index 5e408a817cc..33b8119a0d2 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -983,7 +983,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) } /* free the message */ - ExFreePool(Message); + ExFreePoolWithTag(Message, TAG_USRMSG); return(TRUE); } @@ -1060,7 +1060,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) } /* free the message */ - ExFreePool(SentMessage); + ExFreePoolWithTag(SentMessage, TAG_USRMSG); CurrentEntry = MessageQueue->SentMessagesListHead.Flink; } From 622c4a0919078d13b670b513bd36654eec776a4b Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Sun, 6 Jun 2010 18:45:46 +0000 Subject: [PATCH 271/292] [NTOS] Inline writing to PTEs through MI_WRITE_VALID/INVALID_PTE. svn path=/trunk/; revision=47633 --- reactos/ntoskrnl/mm/ARM3/hypermap.c | 8 ++------ reactos/ntoskrnl/mm/ARM3/i386/init.c | 26 +++++--------------------- reactos/ntoskrnl/mm/ARM3/iosup.c | 7 +------ reactos/ntoskrnl/mm/ARM3/mdlsup.c | 3 +-- reactos/ntoskrnl/mm/ARM3/miarm.h | 27 +++++++++++++++++++++++++++ reactos/ntoskrnl/mm/ARM3/mminit.c | 17 +++++------------ reactos/ntoskrnl/mm/ARM3/ncache.c | 4 +--- reactos/ntoskrnl/mm/ARM3/pagfault.c | 7 ++----- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 6 ++++-- reactos/ntoskrnl/mm/ARM3/pool.c | 7 ++----- reactos/ntoskrnl/mm/ARM3/procsup.c | 18 ++++++------------ reactos/ntoskrnl/mm/ARM3/sysldr.c | 18 +++++++----------- 12 files changed, 63 insertions(+), 85 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/hypermap.c b/reactos/ntoskrnl/mm/ARM3/hypermap.c index 80f371620a0..fca9e03929b 100644 --- a/reactos/ntoskrnl/mm/ARM3/hypermap.c +++ b/reactos/ntoskrnl/mm/ARM3/hypermap.c @@ -82,9 +82,7 @@ MiMapPageInHyperSpace(IN PEPROCESS Process, // Write the current PTE // PointerPte += Offset; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); // // Return the address @@ -176,9 +174,7 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, // Set the correct PTE to write to, and set its new value // PointerPte--; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); } while (--NumberOfPages); // diff --git a/reactos/ntoskrnl/mm/ARM3/i386/init.c b/reactos/ntoskrnl/mm/ARM3/i386/init.c index ed15b402192..7b7f6c4e7db 100644 --- a/reactos/ntoskrnl/mm/ARM3/i386/init.c +++ b/reactos/ntoskrnl/mm/ARM3/i386/init.c @@ -410,17 +410,11 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); while (StartPde <= EndPde) { - // - // Sanity check - // - ASSERT(StartPde->u.Hard.Valid == 0); - // // Get a page // TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; + MI_WRITE_VALID_PTE(StartPde, TempPde); // // Zero out the page table @@ -442,18 +436,12 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MmSizeOfNonPagedPoolInBytes - 1)); while (StartPde <= EndPde) { - // - // Sanity check - // - ASSERT(StartPde->u.Hard.Valid == 0); - // // Get a page // TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; - + MI_WRITE_VALID_PTE(StartPde, TempPde); + // // Zero out the page table // @@ -483,9 +471,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // Use one of our contigous pages // TempPte.u.Hard.PageFrameNumber = PageFrameIndex++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } // @@ -548,9 +534,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PageFrameIndex = MiRemoveAnyPage(0); TempPde.u.Hard.PageFrameNumber = PageFrameIndex; TempPde.u.Hard.Global = FALSE; // Hyperspace is local! - ASSERT(StartPde->u.Hard.Valid == 0); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; + MI_WRITE_VALID_PTE(StartPde, TempPde); /* Flush the TLB */ KeFlushCurrentTb(); diff --git a/reactos/ntoskrnl/mm/ARM3/iosup.c b/reactos/ntoskrnl/mm/ARM3/iosup.c index 5d8cb2e12da..d02d7d41847 100644 --- a/reactos/ntoskrnl/mm/ARM3/iosup.c +++ b/reactos/ntoskrnl/mm/ARM3/iosup.c @@ -171,16 +171,11 @@ MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, // do { - // - // Start out with nothing - // - ASSERT(PointerPte->u.Hard.Valid == 0); - // // Write the PFN // TempPte.u.Hard.PageFrameNumber = Pfn++; - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--PageCount); // diff --git a/reactos/ntoskrnl/mm/ARM3/mdlsup.c b/reactos/ntoskrnl/mm/ARM3/mdlsup.c index 078de3de1c8..7488e52544c 100644 --- a/reactos/ntoskrnl/mm/ARM3/mdlsup.c +++ b/reactos/ntoskrnl/mm/ARM3/mdlsup.c @@ -416,9 +416,8 @@ MmMapLockedPagesSpecifyCache(IN PMDL Mdl, // // Write the PTE // - ASSERT(PointerPte->u.Hard.Valid == 0); TempPte.u.Hard.PageFrameNumber = *MdlPages; - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (++MdlPages < LastPage); // diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 759bdabcfc0..2c6e9da01ba 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -499,6 +499,33 @@ MI_IS_PHYSICAL_ADDRESS(IN PVOID Address) return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid)); } +// +// Writes a valid PTE +// +VOID +FORCEINLINE +MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, + IN MMPTE TempPte) +{ + /* Write the valid PTE */ + ASSERT(PointerPte->u.Hard.Valid == 0); + ASSERT(TempPte.u.Hard.Valid == 1); + *PointerPte = TempPte; +} + +// +// Writes an invalid PTE +// +VOID +FORCEINLINE +MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, + IN MMPTE InvalidPte) +{ + /* Write the invalid PTE */ + ASSERT(InvalidPte.u.Hard.Valid == 0); + *PointerPte = InvalidPte; +} + NTSTATUS NTAPI MmArmInitSystem( diff --git a/reactos/ntoskrnl/mm/ARM3/mminit.c b/reactos/ntoskrnl/mm/ARM3/mminit.c index c79b31d4e07..1e79a23c6cf 100644 --- a/reactos/ntoskrnl/mm/ARM3/mminit.c +++ b/reactos/ntoskrnl/mm/ARM3/mminit.c @@ -453,9 +453,8 @@ MiInitializeColorTables(VOID) { /* Get a page and map it */ TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Zero out the page */ RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); } @@ -614,9 +613,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Write out this PTE */ PagesLeft++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); /* Zero this page */ RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); @@ -1482,9 +1479,7 @@ MiBuildPagedPool(VOID) TempPte = ValidKernelPte; ASSERT(PD_COUNT == 1); TempPte.u.Hard.PageFrameNumber = MmSystemPageDirectory[0]; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); // // Let's get back to paged pool work: size it up. @@ -1555,9 +1550,7 @@ MiBuildPagedPool(VOID) /* Allocate a page and map the first paged pool PDE */ PageFrameIndex = MiRemoveZeroPage(0); TempPte.u.Hard.PageFrameNumber = PageFrameIndex; - ASSERT(PointerPde->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPde = TempPte; + MI_WRITE_VALID_PTE(PointerPde, TempPte); /* Initialize the PFN entry for it */ MiInitializePfnForOtherProcess(PageFrameIndex, diff --git a/reactos/ntoskrnl/mm/ARM3/ncache.c b/reactos/ntoskrnl/mm/ARM3/ncache.c index 659811dc57b..d49d72f3054 100644 --- a/reactos/ntoskrnl/mm/ARM3/ncache.c +++ b/reactos/ntoskrnl/mm/ARM3/ncache.c @@ -154,9 +154,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) // Set the PFN in the page and write it // TempPte.u.Hard.PageFrameNumber = PageFrameIndex; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--PageCount); // diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 073b091b7c6..05fdb2dcade 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -127,11 +127,8 @@ MiResolveDemandZeroFault(IN PVOID Address, /* Build the PTE */ MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, PointerPte->u.Soft.Protection, PageFrameNumber); - ASSERT(TempPte.u.Hard.Valid == 1); - ASSERT(PointerPte->u.Hard.Valid == 0); - *PointerPte = TempPte; - ASSERT(PointerPte->u.Hard.Valid == 1); - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + // // It's all good now // diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index ab72198ed35..fb24d9fdbff 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -747,6 +747,9 @@ MiAllocatePfn(IN PMMPTE PointerPte, KIRQL OldIrql; PFN_NUMBER PageFrameIndex; MMPTE TempPte; + + /* Sanity check that we aren't passed a valid PTE */ + ASSERT(PointerPte->u.Hard.Valid == 0); /* Make an empty software PTE */ MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); @@ -767,8 +770,7 @@ MiAllocatePfn(IN PMMPTE PointerPte, PageFrameIndex = MiRemoveAnyPage(0); /* Write the software PTE */ - ASSERT(PointerPte->u.Hard.Valid == 0); - *PointerPte = TempPte; + MI_WRITE_INVALID_PTE(PointerPte, TempPte); PointerPte->u.Soft.Protection |= Protection; /* Initialize its PFN entry */ diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index 37cb2e59fcf..849db1c9a91 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -344,8 +344,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, MmSystemPageDirectory[(PointerPte - (PMMPTE)PDE_BASE) / PDE_COUNT]); /* Write the actual PTE now */ - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); // // Move on to the next expansion address @@ -604,9 +603,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, /* Write the PTE for it */ TempPte.u.Hard.PageFrameNumber = PageFrameNumber; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--SizeInPages > 0); // diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index 551b685b09a..eb577050a7d 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -175,17 +175,14 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, /* Get a page and write the current invalid PTE */ PageFrameIndex = MiRemoveAnyPage(0); - ASSERT(InvalidPte.u.Hard.Valid == 0); - *PointerPte = InvalidPte; - + MI_WRITE_INVALID_PTE(PointerPte, InvalidPte); + /* Initialize the PFN entry for this page */ MiInitializePfn(PageFrameIndex, PointerPte, 1); /* Write the valid PTE */ TempPte.u.Hard.PageFrameNumber = PageFrameIndex; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); } // Bug #4835 @@ -267,9 +264,8 @@ MmGrowKernelStackEx(IN PVOID StackPointer, { /* Get a page and write the current invalid PTE */ PageFrameIndex = MiRemoveAnyPage(0); - ASSERT(InvalidPte.u.Hard.Valid == 0); - *LimitPte = InvalidPte; - + MI_WRITE_INVALID_PTE(LimitPte, InvalidPte); + /* Initialize the PFN entry for this page */ MiInitializePfn(PageFrameIndex, LimitPte, 1); @@ -277,9 +273,7 @@ MmGrowKernelStackEx(IN PVOID StackPointer, MI_MAKE_HARDWARE_PTE(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex); /* Write the valid PTE */ - ASSERT(LimitPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *LimitPte-- = TempPte; + MI_WRITE_VALID_PTE(LimitPte--, TempPte); } // diff --git a/reactos/ntoskrnl/mm/ARM3/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c index ef1a8cf265f..d8f7157eb21 100644 --- a/reactos/ntoskrnl/mm/ARM3/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -173,12 +173,10 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, { /* Allocate a page */ TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE); - + /* Write it */ - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Move on */ PointerPte++; } @@ -1451,15 +1449,13 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Copy the old data */ OldPte = *StartPte; ASSERT(OldPte.u.Hard.Valid == 1); - + /* Set page number from the loader's memory */ TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber; - + /* Write it */ - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Move on */ PointerPte++; StartPte++; From 218cfae51d36753faf9d92862c087736ea8069a5 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 6 Jun 2010 18:51:43 +0000 Subject: [PATCH 272/292] [WIN32K] Use TAG_GDIICM tag for ICM allocations svn path=/trunk/; revision=47634 --- reactos/subsystems/win32/win32k/objects/icm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/icm.c b/reactos/subsystems/win32/win32k/objects/icm.c index dd99ea3d89d..f0d7ef72e7a 100644 --- a/reactos/subsystems/win32/win32k/objects/icm.c +++ b/reactos/subsystems/win32/win32k/objects/icm.c @@ -146,7 +146,7 @@ NtGdiGetDeviceGammaRamp(HDC hDC, return FALSE; } - SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP)); + SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM); if (!SafeRamp) { DC_UnlockDc(dc); @@ -174,7 +174,7 @@ NtGdiGetDeviceGammaRamp(HDC hDC, _SEH2_END; DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); if (!NT_SUCCESS(Status)) { @@ -377,7 +377,7 @@ NtGdiSetDeviceGammaRamp(HDC hDC, return FALSE; } - SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP)); + SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM); if (!SafeRamp) { DC_UnlockDc(dc); @@ -402,14 +402,14 @@ NtGdiSetDeviceGammaRamp(HDC hDC, if (!NT_SUCCESS(Status)) { DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); SetLastNtError(Status); return FALSE; } Ret = IntSetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp, TRUE); DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); return Ret; } From a4aeb090df1e46b39018344826d77d7e6c4a6b46 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 6 Jun 2010 19:11:52 +0000 Subject: [PATCH 273/292] [WIN32K] - Use TAG_PALETTE for palette entries - Remove mapping codes, the functions from pre r9000 don't even exist anymore svn path=/trunk/; revision=47635 --- .../subsystems/win32/win32k/include/palette.h | 5 ---- .../subsystems/win32/win32k/objects/palette.c | 26 ++++--------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/palette.h b/reactos/subsystems/win32/win32k/include/palette.h index 43f59e6efca..76839b075f5 100644 --- a/reactos/subsystems/win32/win32k/include/palette.h +++ b/reactos/subsystems/win32/win32k/include/palette.h @@ -2,8 +2,6 @@ #include -#define NO_MAPPING - #define PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */ #define PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */ @@ -79,9 +77,6 @@ BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); HPALETTE FASTCALL PALETTE_Init (VOID); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); -#ifndef NO_MAPPING -INT APIENTRY PALETTE_SetMapping(PALOBJ* palPtr, UINT uStart, UINT uNum, BOOL mapOnly); -#endif INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); INT FASTCALL PALETTE_GetObject(PPALETTE pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer); diff --git a/reactos/subsystems/win32/win32k/objects/palette.c b/reactos/subsystems/win32/win32k/objects/palette.c index 8fcbbe4077c..e108b5c6885 100644 --- a/reactos/subsystems/win32/win32k/objects/palette.c +++ b/reactos/subsystems/win32/win32k/objects/palette.c @@ -61,9 +61,6 @@ HPALETTE FASTCALL PALETTE_Init(VOID) int i; HPALETTE hpalette; PLOGPALETTE palPtr; -#ifndef NO_MAPPING - PALOBJ *palObj; -#endif // create default palette (20 system colors) palPtr = ExAllocatePoolWithTag(PagedPool, @@ -85,19 +82,6 @@ HPALETTE FASTCALL PALETTE_Init(VOID) hpalette = NtGdiCreatePaletteInternal(palPtr,NB_RESERVED_COLORS); ExFreePoolWithTag(palPtr, TAG_PALETTE); -#ifndef NO_MAPPING - palObj = (PALOBJ*)PALETTE_LockPalette(hpalette); - if (palObj) - { - if (!(palObj->mapping = ExAllocatePool(PagedPool, sizeof(int) * 20))) - { - DbgPrint("Win32k: Can not create palette mapping -- out of memory!"); - return FALSE; - } - PALETTE_UnlockPalette(palObj); - } -#endif - /* palette_size = visual->map_entries; */ gpalRGB.Mode = PAL_RGB; @@ -232,7 +216,7 @@ PALETTE_Cleanup(PVOID ObjectBody) PPALETTE pPal = (PPALETTE)ObjectBody; if (NULL != pPal->IndexedColors) { - ExFreePool(pPal->IndexedColors); + ExFreePoolWithTag(pPal->IndexedColors, TAG_PALETTE); } return TRUE; @@ -453,7 +437,7 @@ NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries ) else { /* FIXME - Handle PalGDI == NULL!!!! */ - DPRINT1("waring PalGDI is NULL \n"); + DPRINT1("PalGDI is NULL\n"); } return NewPalette; } @@ -981,7 +965,7 @@ NtGdiDoPalette( if (pUnsafeEntries) { - pEntries = ExAllocatePool(PagedPool, cEntries * sizeof(PALETTEENTRY)); + pEntries = ExAllocatePoolWithTag(PagedPool, cEntries * sizeof(PALETTEENTRY), TAG_PALETTE); if (!pEntries) return 0; if (bInbound) @@ -993,7 +977,7 @@ NtGdiDoPalette( } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - ExFreePool(pEntries); + ExFreePoolWithTag(pEntries, TAG_PALETTE); _SEH2_YIELD(return 0); } _SEH2_END @@ -1047,7 +1031,7 @@ NtGdiDoPalette( } _SEH2_END } - ExFreePool(pEntries); + ExFreePoolWithTag(pEntries, TAG_PALETTE); } return ret; From c01132e4ff2df452db006140c9a0f4a1dd85999b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 19:18:19 +0000 Subject: [PATCH 274/292] [NDIS] - Only dequeue the timer in the DPC if the Period is 0 (which means that it's NOT a periodic timer so we only get called once) - Attempt to dequeue the timer before inserting it so we don't end up with multiple copies of the same timer on the timer queue if somebody calls NdisMSet(Periodic)Timer twice svn path=/trunk/; revision=47636 --- reactos/drivers/network/ndis/ndis/time.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index 0872ee70458..d03acb9dde4 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -95,7 +95,7 @@ NdisInitializeTimer( KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); } -VOID DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) +BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) { PNDIS_MINIPORT_TIMER CurrentTimer; @@ -104,6 +104,8 @@ VOID DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) if (Timer->Miniport->TimerQueue == Timer) { Timer->Miniport->TimerQueue = Timer->NextDeferredTimer; + Timer->NextDeferredTimer = NULL; + return TRUE; } else { @@ -113,11 +115,12 @@ VOID DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) if (CurrentTimer->NextDeferredTimer == Timer) { CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer; - return; + Timer->NextDeferredTimer = NULL; + return TRUE; } CurrentTimer = CurrentTimer->NextDeferredTimer; } - ASSERT(FALSE); + return FALSE; } } @@ -161,8 +164,8 @@ MiniTimerDpcFunction(PKDPC Dpc, SystemArgument1, SystemArgument2); - /* FIXME: We can't call this if we have a periodic timer */ - //DequeueMiniportTimer(Timer); + /* Only dequeue if the timer has a period of 0 */ + if (!Timer->Timer.Period) DequeueMiniportTimer(Timer); } @@ -227,6 +230,9 @@ NdisMSetPeriodicTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000); + /* Dequeue the timer if it is queued already */ + DequeueMiniportTimer(Timer); + /* Add the timer at the head of the timer queue */ Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; Timer->Miniport->TimerQueue = Timer; @@ -262,6 +268,9 @@ NdisMSetTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); + /* Dequeue the timer if it is queued already */ + DequeueMiniportTimer(Timer); + /* Add the timer at the head of the timer queue */ Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; Timer->Miniport->TimerQueue = Timer; From 928accdc2c5ec7168caadd6dbcfae31d7d4a73c9 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 6 Jun 2010 19:29:20 +0000 Subject: [PATCH 275/292] [WIN32K] - Use TAG_KEYBOARD for keyboard layouts - Free TAG_ACCEL and TAG_DRIVER allocations with their tags svn path=/trunk/; revision=47637 --- reactos/subsystems/win32/win32k/misc/driver.c | 6 +++--- reactos/subsystems/win32/win32k/ntuser/accelerator.c | 2 +- reactos/subsystems/win32/win32k/ntuser/kbdlayout.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/subsystems/win32/win32k/misc/driver.c b/reactos/subsystems/win32/win32k/misc/driver.c index f427e3ff3bf..8b25b137b33 100644 --- a/reactos/subsystems/win32/win32k/misc/driver.c +++ b/reactos/subsystems/win32/win32k/misc/driver.c @@ -167,7 +167,7 @@ PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name) if (!NT_SUCCESS(Status)) { - ExFreePool(FullName); + ExFreePoolWithTag(FullName, TAG_DRIVER); return NULL; } @@ -572,8 +572,8 @@ BOOL DRIVER_UnregisterDriver(LPCWSTR Name) if (Driver != NULL) { - ExFreePool(Driver->Name); - ExFreePool(Driver); + ExFreePoolWithTag(Driver->Name, TAG_DRIVER); + ExFreePoolWithTag(Driver, TAG_DRIVER); return TRUE; } diff --git a/reactos/subsystems/win32/win32k/ntuser/accelerator.c b/reactos/subsystems/win32/win32k/ntuser/accelerator.c index b59f1d1b7de..d963344af32 100644 --- a/reactos/subsystems/win32/win32k/ntuser/accelerator.c +++ b/reactos/subsystems/win32/win32k/ntuser/accelerator.c @@ -436,7 +436,7 @@ NtUserDestroyAcceleratorTable( if (Accel->Table != NULL) { - ExFreePool(Accel->Table); + ExFreePoolWithTag(Accel->Table, TAG_ACCEL); Accel->Table = NULL; } diff --git a/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c b/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c index 8ee11dc3983..5d04cd81902 100644 --- a/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c +++ b/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c @@ -199,7 +199,7 @@ static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId) ULONG hKl; LANGID langid; - NewKbl = ExAllocatePool(PagedPool, sizeof(KBL)); + NewKbl = ExAllocatePoolWithTag(PagedPool, sizeof(KBL), TAG_KEYBOARD); if(!NewKbl) { @@ -212,7 +212,7 @@ static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId) if(!UserLoadKbdDll(NewKbl->Name, &NewKbl->hModule, &NewKbl->KBTables)) { DPRINT("%s: failed to load %x dll!\n", __FUNCTION__, LocaleId); - ExFreePool(NewKbl); + ExFreePoolWithTag(NewKbl, TAG_KEYBOARD); return NULL; } @@ -401,7 +401,7 @@ BOOL UserUnloadKbl(PKBL pKbl) //Unload the layout EngUnloadImage(pKbl->hModule); RemoveEntryList(&pKbl->List); - ExFreePool(pKbl); + ExFreePoolWithTag(pKbl, TAG_KEYBOARD); } return TRUE; From 6e1d1db7aff95aa72a9ec0fec3f7ca9fb83ddbad Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 21:31:58 +0000 Subject: [PATCH 276/292] Forgot to remove this ASSERT for r47636 svn path=/trunk/; revision=47639 --- reactos/drivers/network/ndis/ndis/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index d03acb9dde4..772557f5289 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -99,7 +99,8 @@ BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) { PNDIS_MINIPORT_TIMER CurrentTimer; - ASSERT(Timer->Miniport->TimerQueue); + if (!Timer->Miniport->TimerQueue) + return FALSE; if (Timer->Miniport->TimerQueue == Timer) { From 444eec451190d6edffbbb691d9a7b957fa714fa7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 22:08:40 +0000 Subject: [PATCH 277/292] [NDIS] - Hold the miniport lock when we work with the timer queue - Use the return value of KeSetTimer(Ex) to determine whether we need to queue the timer in our queue, otherwise we just use the entry that is already there - Add more assertions svn path=/trunk/; revision=47642 --- reactos/drivers/network/ndis/ndis/time.c | 56 ++++++++++++++++-------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index 772557f5289..0e8cdd46473 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -99,6 +99,8 @@ BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) { PNDIS_MINIPORT_TIMER CurrentTimer; + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + if (!Timer->Miniport->TimerQueue) return FALSE; @@ -143,13 +145,21 @@ NdisMCancelTimer( * - call at IRQL <= DISPATCH_LEVEL */ { + KIRQL OldIrql; + ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(TimerCancelled); ASSERT(Timer); *TimerCancelled = KeCancelTimer (&Timer->Timer); - DequeueMiniportTimer(Timer); + if (*TimerCancelled) + { + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If it's somebody already dequeued it, something is wrong (maybe a double-cancel?) */ + if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); + } } VOID NTAPI @@ -166,7 +176,13 @@ MiniTimerDpcFunction(PKDPC Dpc, SystemArgument2); /* Only dequeue if the timer has a period of 0 */ - if (!Timer->Timer.Period) DequeueMiniportTimer(Timer); + if (!Timer->Timer.Period) + { + KeAcquireSpinLockAtDpcLevel(&Timer->Miniport->Lock); + /* If someone already dequeued it, something is wrong (borked timer implementation?) */ + if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); + KeReleaseSpinLockFromDpcLevel(&Timer->Miniport->Lock); + } } @@ -224,6 +240,7 @@ NdisMSetPeriodicTimer( */ { LARGE_INTEGER Timeout; + KIRQL OldIrql; ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(Timer); @@ -231,14 +248,15 @@ NdisMSetPeriodicTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000); - /* Dequeue the timer if it is queued already */ - DequeueMiniportTimer(Timer); - - /* Add the timer at the head of the timer queue */ - Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; - Timer->Miniport->TimerQueue = Timer; - - KeSetTimerEx (&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc); + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */ + if (!KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc)) + { + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + } + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); } @@ -262,6 +280,7 @@ NdisMSetTimer( */ { LARGE_INTEGER Timeout; + KIRQL OldIrql; ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(Timer); @@ -269,14 +288,15 @@ NdisMSetTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); - /* Dequeue the timer if it is queued already */ - DequeueMiniportTimer(Timer); - - /* Add the timer at the head of the timer queue */ - Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; - Timer->Miniport->TimerQueue = Timer; - - KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc); + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */ + if (!KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc)) + { + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + } + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); } From fbc1db9487c7caaae0534adf07f17ac281b11495 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 23:07:26 +0000 Subject: [PATCH 278/292] [MSAFD] - Fix many times where we wait for an operation but don't update our status and return if it failed - Fix the overlapped pending case in writing which was completely broken (callers would detect an error but GetLastError would return 0 because we didn't store the error in the lpErrno variable) - Fix many times where we pass a pointer to an event that we close without waiting - Fix a bug in WSPEnumNetworkEvents when we would set WSAEINVAL in the lpErrno variable but not return SOCKET_ERROR so the error got ignored svn path=/trunk/; revision=47643 --- reactos/dll/win32/msafd/misc/dllmain.c | 48 +++++++++++++++++++------- reactos/dll/win32/msafd/misc/event.c | 14 +++++--- reactos/dll/win32/msafd/misc/sndrcv.c | 25 ++++++++------ 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index 97e82f867e1..a8ab0dc4969 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -566,7 +566,7 @@ WSPCloseSocket(IN SOCKET Handle, NtClose((HANDLE)Handle); NtClose(SockEvent); - return NO_ERROR; + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); } @@ -666,13 +666,17 @@ WSPBind(SOCKET Handle, Status = IOSB.Status; } + NtClose( SockEvent ); + HeapFree(GlobalHeap, 0, BindData); + + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); + /* Set up Socket Data */ Socket->SharedData.State = SocketBound; Socket->TdiAddressHandle = (HANDLE)IOSB.Information; - NtClose( SockEvent ); - HeapFree(GlobalHeap, 0, BindData); - if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_BIND)) + if (Socket->HelperEvents & WSH_NOTIFY_BIND) { Status = Socket->HelperData->WSHNotify(Socket->HelperContext, Socket->Handle, @@ -739,14 +743,17 @@ WSPListen(SOCKET Handle, { WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; - } + } + + NtClose( SockEvent ); + + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); /* Set to Listening */ Socket->SharedData.Listening = TRUE; - NtClose( SockEvent ); - - if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_LISTEN)) + if (Socket->HelperEvents & WSH_NOTIFY_LISTEN) { Status = Socket->HelperData->WSHNotify(Socket->HelperContext, Socket->Handle, @@ -907,6 +914,7 @@ WSPSelect(int nfds, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } /* Clear the Structures */ @@ -1440,6 +1448,9 @@ WSPConnect(SOCKET Handle, WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; } + + if (Status != STATUS_SUCCESS) + goto notify; } /* Dynamic Structure...ugh */ @@ -1485,6 +1496,9 @@ WSPConnect(SOCKET Handle, WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; } + + if (Status != STATUS_SUCCESS) + goto notify; } /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */ @@ -1516,6 +1530,9 @@ WSPConnect(SOCKET Handle, Status = IOSB.Status; } + if (Status != STATUS_SUCCESS) + goto notify; + Socket->TdiConnectionHandle = (HANDLE)IOSB.Information; /* Get any pending connect data */ @@ -1539,14 +1556,15 @@ WSPConnect(SOCKET Handle, } } + AFD_DbgPrint(MID_TRACE,("Ending\n")); + +notify: /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ SockReenableAsyncSelectEvent(Socket, FD_CONNECT); - AFD_DbgPrint(MID_TRACE,("Ending\n")); - NtClose( SockEvent ); if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT)) @@ -2139,8 +2157,12 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } + if (Status != STATUS_SUCCESS) + return -1; + /* Return Information */ if (Ulong != NULL) { @@ -2210,11 +2232,12 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } NtClose( SockEvent ); - return 0; + return Status == STATUS_SUCCESS ? 0 : -1; } @@ -2275,11 +2298,12 @@ int CreateContext(PSOCKET_INFORMATION Socket) if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } NtClose( SockEvent ); - return 0; + return Status == STATUS_SUCCESS ? 0 : -1; } BOOLEAN SockCreateOrReferenceAsyncThread(VOID) diff --git a/reactos/dll/win32/msafd/misc/event.c b/reactos/dll/win32/msafd/misc/event.c index 19d5f23d617..d79fe20019e 100644 --- a/reactos/dll/win32/msafd/misc/event.c +++ b/reactos/dll/win32/msafd/misc/event.c @@ -104,12 +104,16 @@ WSPEventSelect( /* Wait for return */ if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } AFD_DbgPrint(MID_TRACE,("Waited\n")); NtClose( SockEvent ); + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); + AFD_DbgPrint(MID_TRACE,("Closed event\n")); /* Set Socket Data*/ @@ -168,13 +172,16 @@ WSPEnumNetworkEvents( /* Wait for return */ if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); - Status = STATUS_SUCCESS; + Status = IOSB.Status; } AFD_DbgPrint(MID_TRACE,("Waited\n")); NtClose( SockEvent ); + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); + AFD_DbgPrint(MID_TRACE,("Closed event\n")); AFD_DbgPrint(MID_TRACE,("About to touch struct at %x (%d)\n", lpNetworkEvents, sizeof(*lpNetworkEvents))); @@ -226,12 +233,9 @@ WSPEnumNetworkEvents( lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_GROUP_QOS_BIT]); } - if( NT_SUCCESS(Status) ) *lpErrno = 0; - else *lpErrno = WSAEINVAL; - AFD_DbgPrint(MID_TRACE,("Leaving\n")); - return 0; + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, NULL); } /* EOF */ diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index 3c5b2d5c232..57f9569086f 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -182,7 +182,7 @@ WSPRecv(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -209,6 +209,9 @@ WSPRecv(SOCKET Handle, /* Return the Flags */ *ReceiveFlags = 0; + if (Status == STATUS_PENDING) + return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); + switch (Status) { case STATUS_RECEIVE_EXPEDITED: @@ -223,7 +226,7 @@ WSPRecv(SOCKET Handle, } /* Re-enable Async Event */ - if (*ReceiveFlags == MSG_OOB) + if (*ReceiveFlags & MSG_OOB) { SockReenableAsyncSelectEvent(Socket, FD_OOB); } @@ -334,7 +337,7 @@ WSPRecvFrom(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -356,6 +359,9 @@ WSPRecvFrom(SOCKET Handle, /* Return the Flags */ *ReceiveFlags = 0; + if (Status == STATUS_PENDING) + return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); + switch (Status) { case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; @@ -461,7 +467,7 @@ WSPSend(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -483,7 +489,7 @@ WSPSend(SOCKET Handle, if (Status == STATUS_PENDING) { AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n")); - return WSA_IO_PENDING; + return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } /* Re-enable Async Event */ @@ -613,7 +619,7 @@ WSPSendTo(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -638,11 +644,8 @@ WSPSendTo(SOCKET Handle, HeapFree(GlobalHeap, 0, BindAddress); } - if (Status == STATUS_PENDING) - return WSA_IO_PENDING; - - /* Re-enable Async Event */ - SockReenableAsyncSelectEvent(Socket, FD_WRITE); + if (Status != STATUS_PENDING) + SockReenableAsyncSelectEvent(Socket, FD_WRITE); return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } From 8404cbb5404076c3626fb81f0eec26814f36c258 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Sun, 6 Jun 2010 23:45:20 +0000 Subject: [PATCH 279/292] Add Opera 9 to rapps. Update OOo to 3.2.1 and the last time... fix the FF2 link. svn path=/trunk/; revision=47644 --- .../applications/rapps/rapps/firefox2.txt | 17 +------------ .../rapps/rapps/openoffice3.0.txt | 19 +++++++-------- .../base/applications/rapps/rapps/opera9.txt | 24 +++++++++++++++++++ 3 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 reactos/base/applications/rapps/rapps/opera9.txt diff --git a/reactos/base/applications/rapps/rapps/firefox2.txt b/reactos/base/applications/rapps/rapps/firefox2.txt index 3cf7dc27921..e0b62661193 100644 --- a/reactos/base/applications/rapps/rapps/firefox2.txt +++ b/reactos/base/applications/rapps/rapps/firefox2.txt @@ -8,35 +8,20 @@ Description = The most popular and one of the best free Web Browsers out there. Size = 5.8M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/en-US/Firefox%20Setup%202.0.0.20.exe +URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%202.0.0.20.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. -Size = 5.5M -URLSite = http://www.mozilla-europe.org/de/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/de/Firefox%20Setup%202.0.0.20.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. -Size = 5.6M -URLSite = http://www.mozilla-europe.org/es/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/es-ES/Firefox%20Setup%202.0.0.20.exe [Section.0414] Description = Mest populære og best ogsÃ¥ gratis nettleserene der ute. -Size = 5.6M -URLSite = http://www.mozilla-europe.org/no/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/nb-NO/Firefox%20Setup%202.0.0.20.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. -Size = 6.3M -URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/pl/Firefox%20Setup%202.0.0.20.exe [Section.0419] Description = Один из Ñамых популÑрных и лучших беÑплатных браузеров. -Size = 6.4M -URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/ru/Firefox%20Setup%202.0.0.20.exe diff --git a/reactos/base/applications/rapps/rapps/openoffice3.0.txt b/reactos/base/applications/rapps/rapps/openoffice3.0.txt index b9ee71bd025..9ae02ef5d4e 100644 --- a/reactos/base/applications/rapps/rapps/openoffice3.0.txt +++ b/reactos/base/applications/rapps/rapps/openoffice3.0.txt @@ -2,30 +2,29 @@ [Section] Name = OpenOffice 3.0 -Version = 3.2.0 +Version = 3.2.1 Licence = LGPL Description = THE Open Source Office Suite. -Size = 135.4MB +Size = 134.0MB Category = 6 URLSite = http://www.openoffice.org/ -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/stable/3.2.0/OOo_3.2.0_Win32Intel_install_en-US.exe +URLDownload = http://ftp3.gwdg.de/pub/openoffice/stable/3.2.1/OOo_3.2.1_Win_x86_install_en-US.exe CDPath = none [Section.0407] Description = DIE Open Source Office Suite. URLSite = http://de.openoffice.org/ -Size = 145.8MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/de/3.2.0/OOo_3.2.0_Win32Intel_install_de.exe +Size = 144.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/de/3.2.1/OOo_3.2.1_Win_x86_install_de.exe [Section.040a] Description = La suite de ofimática de código abierto. URLSite = http://es.openoffice.org/ -Version = 3.1.0 -Size = 119.4MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/es/3.2.0/OOo_3.2.0_Win32Intel_install_es.exe +Size = 144.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/es/3.2.1/OOo_3.2.1_Win_x86_install-wJRE_es.exe [Section.0415] Description = Otwarty pakiet biurowy. URLSite = http://pl.openoffice.org/ -Size = 133.2MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/pl/3.2.0/OOo_3.2.0_Win32Intel_install_pl.exe +Size = 130.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/pl/3.2.1/OOo_3.2.1_Win_x86_install_pl.exe diff --git a/reactos/base/applications/rapps/rapps/opera9.txt b/reactos/base/applications/rapps/rapps/opera9.txt new file mode 100644 index 00000000000..e951d00bc2a --- /dev/null +++ b/reactos/base/applications/rapps/rapps/opera9.txt @@ -0,0 +1,24 @@ +; UTF-8 + +[Section] +Name = Opera +Version = 9.64 +Licence = Freeware +Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client. +Size = 7.2M +Category = 5 +URLSite = http://www.opera.com/ +URLDownload = http://get4.opera.com/pub/opera/win/964/int/Opera_964_int_Setup.exe +CDPath = none + +[Section.0407] +Description = Der populäre Opera Browser mit vielen fortschrittlichen Eigenschaften, enthält einen Mail und BitTorrent Client. + +[Section.040a] +Description = Popular navegador web con muchas características avanzadas e incluye un cliente de correo y BitTorrent. + +[Section.0415] +Description = Popularna przeglÄ…darka internetowa z wieloma zaawansowanymi funkcjami, zawierajÄ…ca klientów: poczty oraz BitTorrent. + +[Section.0419] +Description = ПопулÑрный браузер Ñо многими дополнительными возможноÑÑ‚Ñми, включающий клиентов почты и BitTorrent. From 0b3f90dce4d0f70aa1a2aa38db8cb2e6732b9868 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 23:49:27 +0000 Subject: [PATCH 280/292] Remove an unintended change svn path=/trunk/; revision=47645 --- reactos/dll/win32/msafd/misc/sndrcv.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index 57f9569086f..7f27fd43eb0 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -209,9 +209,6 @@ WSPRecv(SOCKET Handle, /* Return the Flags */ *ReceiveFlags = 0; - if (Status == STATUS_PENDING) - return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); - switch (Status) { case STATUS_RECEIVE_EXPEDITED: @@ -359,9 +356,6 @@ WSPRecvFrom(SOCKET Handle, /* Return the Flags */ *ReceiveFlags = 0; - if (Status == STATUS_PENDING) - return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); - switch (Status) { case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; From e0549f61008d95ecde6879b7ad7d3517b9303a76 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 00:24:27 +0000 Subject: [PATCH 281/292] [MSAFD] - Use a linked list to store the socket information instead of allocating a massive array (1024 elements!) for each process in DllMain to hold all of the pointers - Fix a massive memory leak (free the socket information which we leaked for every socket we allocated) - This improves performance because we don't have to look through an array of stale socket information pointers (which we never actually removed from the socket information array in the old code) and the new code queues the socket information at the head of the list which makes newer sockets faster to access svn path=/trunk/; revision=47646 --- reactos/dll/win32/msafd/misc/dllmain.c | 53 ++++++++++++++++++-------- reactos/dll/win32/msafd/msafd.h | 1 + 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index a8ab0dc4969..9142a39958d 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -23,7 +23,7 @@ HANDLE GlobalHeap; WSPUPCALLTABLE Upcalls; LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest; ULONG SocketCount = 0; -PSOCKET_INFORMATION *Sockets = NULL; +PSOCKET_INFORMATION SocketListHead = NULL; LIST_ENTRY SockHelpersListHead = { NULL, NULL }; ULONG SockAsyncThreadRefCount; HANDLE SockAsyncHelperAfdHandle; @@ -292,8 +292,8 @@ WSPSocket(int AddressFamily, NULL); /* Save in Process Sockets List */ - Sockets[SocketCount] = Socket; - SocketCount ++; + Socket->NextSocket = SocketListHead; + SocketListHead = Socket; /* Create the Socket Context */ CreateContext(Socket); @@ -423,7 +423,7 @@ WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno) { IO_STATUS_BLOCK IoStatusBlock; - PSOCKET_INFORMATION Socket = NULL; + PSOCKET_INFORMATION Socket = NULL, CurrentSocket; NTSTATUS Status; HANDLE SockEvent; AFD_DISCONNECT_INFO DisconnectInfo; @@ -562,6 +562,27 @@ WSPCloseSocket(IN SOCKET Handle, NtClose(Socket->TdiConnectionHandle); Socket->TdiConnectionHandle = NULL; + if (SocketListHead == Socket) + { + SocketListHead = SocketListHead->NextSocket; + } + else + { + CurrentSocket = SocketListHead; + while (CurrentSocket->NextSocket) + { + if (CurrentSocket->NextSocket == Socket) + { + CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket; + break; + } + + CurrentSocket = CurrentSocket->NextSocket; + } + } + + HeapFree(GlobalHeap, 0, Socket); + /* Close the handle */ NtClose((HANDLE)Handle); NtClose(SockEvent); @@ -2244,16 +2265,22 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle) { - ULONG i; + PSOCKET_INFORMATION CurrentSocket; - for (i=0; iHandle == Handle) + return SocketListHead; + + CurrentSocket = SocketListHead; + while (CurrentSocket->NextSocket) { - if (Sockets[i]->Handle == Handle) - { - return Sockets[i]; - } + if (CurrentSocket->Handle == Handle) + return CurrentSocket; + + CurrentSocket = CurrentSocket->NextSocket; } - return 0; + + return NULL; } int CreateContext(PSOCKET_INFORMATION Socket) @@ -2771,10 +2798,6 @@ DllMain(HANDLE hInstDll, /* Heap to use when allocating */ GlobalHeap = GetProcessHeap(); - /* Allocate Heap for 1024 Sockets, can be expanded later */ - Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024); - if (!Sockets) return FALSE; - AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n")); break; diff --git a/reactos/dll/win32/msafd/msafd.h b/reactos/dll/win32/msafd/msafd.h index 2ae98c67069..dbdbc2e24a0 100755 --- a/reactos/dll/win32/msafd/msafd.h +++ b/reactos/dll/win32/msafd/msafd.h @@ -100,6 +100,7 @@ typedef struct _SOCKET_INFORMATION { BOOL TrySAN; SOCKADDR WSLocalAddress; SOCKADDR WSRemoteAddress; + struct _SOCKET_INFORMATION *NextSocket; } SOCKET_INFORMATION, *PSOCKET_INFORMATION; From 9cf21247631bfc382f2ceb8680872fb9de428472 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 00:44:00 +0000 Subject: [PATCH 282/292] I hate making the same mistake twice in one day svn path=/trunk/; revision=47647 --- reactos/dll/win32/msafd/misc/dllmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index 9142a39958d..c8da9744592 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -22,7 +22,6 @@ DWORD DebugTraceLevel = 0; HANDLE GlobalHeap; WSPUPCALLTABLE Upcalls; LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest; -ULONG SocketCount = 0; PSOCKET_INFORMATION SocketListHead = NULL; LIST_ENTRY SockHelpersListHead = { NULL, NULL }; ULONG SockAsyncThreadRefCount; @@ -2267,6 +2266,9 @@ GetSocketStructure(SOCKET Handle) { PSOCKET_INFORMATION CurrentSocket; + if (!SocketListHead) + return NULL; + /* This is a special case */ if (SocketListHead->Handle == Handle) return SocketListHead; From af870b6e47f9ac95374f8e7c67c7abf956b40e21 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 7 Jun 2010 00:58:55 +0000 Subject: [PATCH 283/292] [DHCP/FTP]: Fix building on OS X hosts. svn path=/trunk/; revision=47648 --- reactos/base/applications/network/ftp/ftp.rbuild | 11 +++++++++++ reactos/dll/win32/dhcpcsvc/dhcpcsvc.rbuild | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/reactos/base/applications/network/ftp/ftp.rbuild b/reactos/base/applications/network/ftp/ftp.rbuild index fce05853523..60f7ea5c659 100644 --- a/reactos/base/applications/network/ftp/ftp.rbuild +++ b/reactos/base/applications/network/ftp/ftp.rbuild @@ -4,6 +4,17 @@ . + + _chdir + _getcwd + _mktemp + _unlink + _close + _fileno + _read + _write + _lseek + ws2_32 iphlpapi oldnames diff --git a/reactos/dll/win32/dhcpcsvc/dhcpcsvc.rbuild b/reactos/dll/win32/dhcpcsvc/dhcpcsvc.rbuild index 773c295b21c..7afd68b4775 100644 --- a/reactos/dll/win32/dhcpcsvc/dhcpcsvc.rbuild +++ b/reactos/dll/win32/dhcpcsvc/dhcpcsvc.rbuild @@ -7,6 +7,10 @@ iphlpapi advapi32 oldnames + + + _tzset + adapter.c alloc.c From ad1721c01643fcb01a52b9f072341f77a254803c Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 7 Jun 2010 01:09:41 +0000 Subject: [PATCH 284/292] [HAL]: Bus support in the HAL actually creates a further wedge between the different x86 HALs: There are actually two dinstinct implementations. On the ACPI HAL, the system is assumed not to have things like special ISA, MCA, EISA buses, and a PCI driver is used in combination with the ACPI Interface for PCI Bus support. On non-ACPI systems, the legacy "Bus Handler" library is used, and the HAL provides a core set of CMOS, EISA, ISA, MCA and PCI bus handlers, each with their own routines and specific code. Additionally, PCI IRQ Routing and other PCI bus internals are handled directly by the HAL -- on the ACPI HAL, the PCI Bus support is implemented through a "Fake"/static bus handler, just to keep the functions shared. On ReactOS, both the ACPI and non-ACPI HAL were currently using a mix of both HAL bus handling types, mostly implemented the "ACPI way" (with a fake PCI bus handler and such). As a result, none of the Hal*Bus HALDISPATCH routines were implemented, which bus drivers expect to find when they're not on ACPI systems (ReactOS today). eVb's new PCI driver was crashing, for example. Furthermore, legacy systems suffer, because the ACPI HAL Bus routines (that we currently have) expect perfect ACPI-style-compliant systems, not the legacy crap from the early 90ies. This works fine in VMs and new hardware, but old hardware is left behind. This patch basically corrects the first part of the problem, by making the bus handling support separate between ACPI and non-ACPI HALs. For now, the code remains 100% the same in functionality between both. However, I have started adding the first few elements: [HAL]: Implement HalRegisterBusHandler HALDISPATCH routine. [HAL]: On legacy HALs, register the CMOS, ISA, SYSTEM handlers. [HAL]: Add cmosbus.c. Stub all bus-specific bus handler routines in the xxxbus.c files. No real functionality change occurs with this patch, yet. svn path=/trunk/; revision=47649 --- .../generic/{bus/halbus.c => acpi/busemul.c} | 36 +- reactos/hal/halx86/generic/acpi/halacpi.c | 18 + reactos/hal/halx86/generic/bus/bushndlr.c | 186 ------- reactos/hal/halx86/generic/bus/isabus.c | 7 - reactos/hal/halx86/generic/bus/sysbus.c | 7 - reactos/hal/halx86/generic/halinit.c | 2 +- .../hal/halx86/generic/legacy/bus/bushndlr.c | 424 +++++++++++++++ .../hal/halx86/generic/legacy/bus/cmosbus.c | 47 ++ .../hal/halx86/generic/legacy/bus/isabus.c | 32 ++ .../halx86/generic/{ => legacy}/bus/pcibus.c | 2 + .../halx86/generic/{ => legacy}/bus/pcidata.c | 0 .../hal/halx86/generic/legacy/bus/sysbus.c | 47 ++ reactos/hal/halx86/generic/legacy/bussupp.c | 488 ++++++++++++++++++ reactos/hal/halx86/generic/legacy/halpcat.c | 15 +- reactos/hal/halx86/hal_generic.rbuild | 8 - reactos/hal/halx86/hal_generic_acpi.rbuild | 6 + reactos/hal/halx86/hal_generic_pcat.rbuild | 9 + reactos/hal/halx86/hal_mini.rbuild | 17 +- reactos/hal/halx86/include/bus.h | 138 +++-- reactos/hal/halx86/include/halp.h | 6 + 20 files changed, 1212 insertions(+), 283 deletions(-) rename reactos/hal/halx86/generic/{bus/halbus.c => acpi/busemul.c} (91%) delete mode 100644 reactos/hal/halx86/generic/bus/bushndlr.c delete mode 100644 reactos/hal/halx86/generic/bus/isabus.c delete mode 100644 reactos/hal/halx86/generic/bus/sysbus.c create mode 100644 reactos/hal/halx86/generic/legacy/bus/bushndlr.c create mode 100644 reactos/hal/halx86/generic/legacy/bus/cmosbus.c create mode 100644 reactos/hal/halx86/generic/legacy/bus/isabus.c rename reactos/hal/halx86/generic/{ => legacy}/bus/pcibus.c (99%) rename reactos/hal/halx86/generic/{ => legacy}/bus/pcidata.c (100%) create mode 100644 reactos/hal/halx86/generic/legacy/bus/sysbus.c create mode 100644 reactos/hal/halx86/generic/legacy/bussupp.c diff --git a/reactos/hal/halx86/generic/bus/halbus.c b/reactos/hal/halx86/generic/acpi/busemul.c similarity index 91% rename from reactos/hal/halx86/generic/bus/halbus.c rename to reactos/hal/halx86/generic/acpi/busemul.c index d8e478f450f..7a317f56728 100644 --- a/reactos/hal/halx86/generic/bus/halbus.c +++ b/reactos/hal/halx86/generic/acpi/busemul.c @@ -1,22 +1,20 @@ /* * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/halbus.c - * PURPOSE: Bus Support Routines - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: hal/halx86/generic/acpi/busemul.c + * PURPOSE: ACPI HAL Bus Handler Emulation Code + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include #define NDEBUG #include -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ -ULONG HalpBusType; - -/* PRIVATE FUNCTIONS *********************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ VOID NTAPI @@ -83,11 +81,11 @@ HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, ULONG NTAPI -HalpGetSystemInterruptVector(IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity) +HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) { ULONG Vector = IRQ2VECTOR(BusInterruptLevel); *Irql = (KIRQL)VECTOR2IRQL(Vector); @@ -250,11 +248,11 @@ HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, OUT PKAFFINITY Affinity) { /* Call the system bus translator */ - return HalpGetSystemInterruptVector(BusNumber, - BusInterruptLevel, - BusInterruptVector, - Irql, - Affinity); + return HalpGetSystemInterruptVector_Acpi(BusNumber, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); } /* diff --git a/reactos/hal/halx86/generic/acpi/halacpi.c b/reactos/hal/halx86/generic/acpi/halacpi.c index 1efee7996a4..22d3c9b6a72 100644 --- a/reactos/hal/halx86/generic/acpi/halacpi.c +++ b/reactos/hal/halx86/generic/acpi/halacpi.c @@ -879,6 +879,24 @@ HalpInitializePciBus(VOID) HalpGetNMICrashFlag(); } +VOID +NTAPI +HalpInitNonBusHandler(VOID) +{ + /* These should be written by the PCI driver later, but we give defaults */ + HalPciTranslateBusAddress = HalpTranslateBusAddress; + HalPciAssignSlotResources = HalpAssignSlotResources; + HalFindBusAddressTranslation = HalpFindBusAddressTranslation; +} + +VOID +NTAPI +HalpInitBusHandlers(VOID) +{ + /* On ACPI, we only have a fake PCI bus to worry about */ + HalpInitNonBusHandler(); +} + VOID NTAPI HalpBuildAddressMap(VOID) diff --git a/reactos/hal/halx86/generic/bus/bushndlr.c b/reactos/hal/halx86/generic/bus/bushndlr.c deleted file mode 100644 index 18121360a62..00000000000 --- a/reactos/hal/halx86/generic/bus/bushndlr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/bushndlr.c - * PURPOSE: Generic HAL Bus Handler Support - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ - -/* INCLUDES *******************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS ********************************************************************/ - -KSPIN_LOCK HalpBusDatabaseSpinLock; -KEVENT HalpBusDatabaseEvent; -LIST_ENTRY HalpAllBusHandlers; -PARRAY HalpBusTable; -PARRAY HalpConfigTable; - -/* PRIVATE FUNCTIONS **********************************************************/ - -PARRAY -NTAPI -HalpAllocateArray(IN ULONG ArraySize) -{ - PARRAY Array; - ULONG Size; - - /* Compute array size */ - if (ArraySize == MAXULONG) ArraySize = 0; - Size = ArraySize * sizeof(PARRAY) + sizeof(ARRAY); - - /* Allocate the array */ - Array = ExAllocatePoolWithTag(NonPagedPool, - Size, - 'BusH'); - if (!Array) KeBugCheckEx(HAL_MEMORY_ALLOCATION, Size, 0, (ULONG_PTR)__FILE__, __LINE__); - - /* Initialize it */ - Array->ArraySize = ArraySize; - RtlZeroMemory(Array->Element, sizeof(PVOID) * (ArraySize + 1)); - return Array; -} - -VOID -NTAPI -HalpGrowArray(IN PARRAY *CurrentArray, - IN PARRAY *NewArray) -{ - PVOID Tmp; - - /* Check if the current array doesn't exist yet, or if it's smaller than the new one */ - if (!(*CurrentArray) || ((*NewArray)->ArraySize > (*CurrentArray)->ArraySize)) - { - /* Does it exist (and can it fit?) */ - if (*CurrentArray) - { - /* Copy the current array into the new one */ - RtlCopyMemory(&(*NewArray)->Element, - &(*CurrentArray)->Element, - sizeof(PVOID) * ((*CurrentArray)->ArraySize + 1)); - } - - /* Swap the pointers (XOR swap would be more l33t) */ - Tmp = *CurrentArray; - *CurrentArray = *NewArray; - *NewArray = Tmp; - } -} - -PBUS_HANDLER -FASTCALL -HalpLookupHandler(IN PARRAY Array, - IN ULONG Type, - IN ULONG Number, - IN BOOLEAN AddReference) -{ - PHAL_BUS_HANDLER Bus; - PBUS_HANDLER Handler = NULL; - - /* Make sure the entry exists */ - if (Array->ArraySize >= Type) - { - /* Retrieve it */ - Array = Array->Element[Type]; - - /* Make sure the entry array exists */ - if ((Array) && (Array->ArraySize >= Number)) - { - /* Retrieve the bus and its handler */ - Bus = Array->Element[Number]; - Handler = &Bus->Handler; - - /* Reference the handler if needed */ - if (AddReference) Bus->ReferenceCount++; - } - } - - /* Return the handler */ - return Handler; -} - -VOID -FASTCALL -HaliReferenceBusHandler(IN PBUS_HANDLER Handler) -{ - PHAL_BUS_HANDLER Bus; - - /* Find and reference the bus handler */ - Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); - Bus->ReferenceCount++; -} - -VOID -FASTCALL -HaliDereferenceBusHandler(IN PBUS_HANDLER Handler) -{ - PHAL_BUS_HANDLER Bus; - - /* Find and dereference the bus handler */ - Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); - Bus->ReferenceCount--; - ASSERT(Bus->ReferenceCount != 0); -} - -PBUS_HANDLER -FASTCALL -HaliHandlerForBus(IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber) -{ - /* Lookup the interface in the bus table */ - return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, FALSE); -} - -PBUS_HANDLER -FASTCALL -HaliHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, - IN ULONG BusNumber) -{ - /* Lookup the configuration in the configuration table */ - return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, FALSE); -} - -PBUS_HANDLER -FASTCALL -HaliReferenceHandlerForBus(IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber) -{ - /* Lookup the interface in the bus table, and reference the handler */ - return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, TRUE); -} - -PBUS_HANDLER -FASTCALL -HaliReferenceHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, - IN ULONG BusNumber) -{ - /* Lookup the configuration in the configuration table and add a reference */ - return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, TRUE); -} - -VOID -NTAPI -HalpInitBusHandler(VOID) -{ - /* Setup the bus lock */ - KeInitializeSpinLock(&HalpBusDatabaseSpinLock); - - /* Setup the bus event */ - KeInitializeEvent(&HalpBusDatabaseEvent, SynchronizationEvent, TRUE); - - /* Setup the bus configuration and bus table */ - HalpBusTable = HalpAllocateArray(0); - HalpConfigTable = HalpAllocateArray(0); - - /* Setup the bus list */ - InitializeListHead(&HalpAllBusHandlers); - - /* These should be written by the PCI driver later, but we give defaults */ - HalPciTranslateBusAddress = HalpTranslateBusAddress; - HalPciAssignSlotResources = HalpAssignSlotResources; - HalFindBusAddressTranslation = HalpFindBusAddressTranslation; -} diff --git a/reactos/hal/halx86/generic/bus/isabus.c b/reactos/hal/halx86/generic/bus/isabus.c deleted file mode 100644 index 7e9631f6536..00000000000 --- a/reactos/hal/halx86/generic/bus/isabus.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/isabus.c - * PURPOSE: - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ diff --git a/reactos/hal/halx86/generic/bus/sysbus.c b/reactos/hal/halx86/generic/bus/sysbus.c deleted file mode 100644 index d011cb568c5..00000000000 --- a/reactos/hal/halx86/generic/bus/sysbus.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/sysbus.c - * PURPOSE: - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ diff --git a/reactos/hal/halx86/generic/halinit.c b/reactos/hal/halx86/generic/halinit.c index 6a6b1660694..f0ebd33d4ca 100644 --- a/reactos/hal/halx86/generic/halinit.c +++ b/reactos/hal/halx86/generic/halinit.c @@ -155,7 +155,7 @@ HalInitSystem(IN ULONG BootPhase, else if (BootPhase == 1) { /* Initialize bus handlers */ - HalpInitBusHandler(); + HalpInitBusHandlers(); #ifndef _MINIHAL_ /* Enable IRQ 0 */ diff --git a/reactos/hal/halx86/generic/legacy/bus/bushndlr.c b/reactos/hal/halx86/generic/legacy/bus/bushndlr.c new file mode 100644 index 00000000000..6186d540ff4 --- /dev/null +++ b/reactos/hal/halx86/generic/legacy/bus/bushndlr.c @@ -0,0 +1,424 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/bushndlr.c + * PURPOSE: Generic HAL Bus Handler Support + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +KSPIN_LOCK HalpBusDatabaseSpinLock; +KEVENT HalpBusDatabaseEvent; +LIST_ENTRY HalpAllBusHandlers; +PARRAY HalpBusTable; +PARRAY HalpConfigTable; + +/* PRIVATE FUNCTIONS **********************************************************/ + +PARRAY +NTAPI +HalpAllocateArray(IN ULONG ArraySize) +{ + PARRAY Array; + ULONG Size; + + /* Compute array size */ + if (ArraySize == MAXULONG) ArraySize = 0; + Size = ArraySize * sizeof(PARRAY) + sizeof(ARRAY); + + /* Allocate the array */ + Array = ExAllocatePoolWithTag(NonPagedPool, + Size, + 'BusH'); + if (!Array) KeBugCheckEx(HAL_MEMORY_ALLOCATION, Size, 0, (ULONG_PTR)__FILE__, __LINE__); + + /* Initialize it */ + Array->ArraySize = ArraySize; + RtlZeroMemory(Array->Element, sizeof(PVOID) * (ArraySize + 1)); + return Array; +} + +VOID +NTAPI +HalpGrowArray(IN PARRAY *CurrentArray, + IN PARRAY *NewArray) +{ + PVOID Tmp; + + /* Check if the current array doesn't exist yet, or if it's smaller than the new one */ + if (!(*CurrentArray) || ((*NewArray)->ArraySize > (*CurrentArray)->ArraySize)) + { + /* Does it exist (and can it fit?) */ + if (*CurrentArray) + { + /* Copy the current array into the new one */ + RtlCopyMemory(&(*NewArray)->Element, + &(*CurrentArray)->Element, + sizeof(PVOID) * ((*CurrentArray)->ArraySize + 1)); + } + + /* Swap the pointers (XOR swap would be more l33t) */ + Tmp = *CurrentArray; + *CurrentArray = *NewArray; + *NewArray = Tmp; + } +} + +PBUS_HANDLER +FASTCALL +HalpLookupHandler(IN PARRAY Array, + IN ULONG Type, + IN ULONG Number, + IN BOOLEAN AddReference) +{ + PHAL_BUS_HANDLER Bus; + PBUS_HANDLER Handler = NULL; + + /* Make sure the entry exists */ + if (Array->ArraySize >= Type) + { + /* Retrieve it */ + Array = Array->Element[Type]; + + /* Make sure the entry array exists */ + if ((Array) && (Array->ArraySize >= Number)) + { + /* Retrieve the bus and its handler */ + Bus = Array->Element[Number]; + Handler = &Bus->Handler; + + /* Reference the handler if needed */ + if (AddReference) Bus->ReferenceCount++; + } + } + + /* Return the handler */ + return Handler; +} + +ULONG +NTAPI +HalpNoBusData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + /* Not implemented */ + DPRINT1("STUB GetSetBusData\n"); + return 0; +} + +NTSTATUS +NTAPI +HalpNoAdjustResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList) +{ + DPRINT1("STUB Adjustment\n"); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +HalpNoAssignSlotResources(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + DPRINT1("STUB Assignment\n"); + return STATUS_NOT_SUPPORTED; +} + +VOID +FASTCALL +HaliReferenceBusHandler(IN PBUS_HANDLER Handler) +{ + PHAL_BUS_HANDLER Bus; + + /* Find and reference the bus handler */ + Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); + Bus->ReferenceCount++; +} + +VOID +FASTCALL +HaliDereferenceBusHandler(IN PBUS_HANDLER Handler) +{ + PHAL_BUS_HANDLER Bus; + + /* Find and dereference the bus handler */ + Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); + Bus->ReferenceCount--; + ASSERT(Bus->ReferenceCount != 0); +} + +PBUS_HANDLER +FASTCALL +HaliHandlerForBus(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber) +{ + /* Lookup the interface in the bus table */ + return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, FALSE); +} + +PBUS_HANDLER +FASTCALL +HaliHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber) +{ + /* Lookup the configuration in the configuration table */ + return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, FALSE); +} + +PBUS_HANDLER +FASTCALL +HaliReferenceHandlerForBus(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber) +{ + /* Lookup the interface in the bus table, and reference the handler */ + return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, TRUE); +} + +PBUS_HANDLER +FASTCALL +HaliReferenceHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber) +{ + /* Lookup the configuration in the configuration table and add a reference */ + return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, TRUE); +} + +#ifndef _MINIHAL_ +NTSTATUS +NTAPI +HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, + IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber, + IN INTERFACE_TYPE ParentBusType, + IN ULONG ParentBusNumber, + IN ULONG ExtraData, + IN PINSTALL_BUS_HANDLER InstallCallback, + OUT PBUS_HANDLER *ReturnedBusHandler) +{ + PHAL_BUS_HANDLER Bus, OldHandler = NULL; + PHAL_BUS_HANDLER* BusEntry; + PVOID CodeHandle; + PARRAY InterfaceArray, InterfaceBusNumberArray, ConfigArray, ConfigBusNumberArray; + PBUS_HANDLER ParentHandler; + KIRQL OldIrql; + NTSTATUS Status; + DPRINT1("HAL BUS REGISTRATION: %d.%d on bus %d with parent %d on bus %d\n", + InterfaceType, ConfigType, BusNumber, ParentBusType, ParentBusNumber); + + /* Make sure we have a valid handler */ + ASSERT((InterfaceType != InterfaceTypeUndefined) || + (ConfigType != ConfigurationSpaceUndefined)); + + /* Allocate the bus handler */ + Bus = ExAllocatePoolWithTag(NonPagedPool, + sizeof(HAL_BUS_HANDLER) + ExtraData, + 'HsuB'); + if (!Bus) return STATUS_INSUFFICIENT_RESOURCES; + + /* Return the handler */ + *ReturnedBusHandler = &Bus->Handler; + + /* Don't page us out */ + CodeHandle = MmLockPagableDataSection(&HaliRegisterBusHandler); + + /* Synchronize with anyone else */ + KeWaitForSingleObject(&HalpBusDatabaseEvent, + WrExecutive, + KernelMode, + FALSE, + NULL); + + /* Check for unknown/root bus */ + if (BusNumber == -1) + { + /* We must have an interface */ + ASSERT(InterfaceType != InterfaceTypeUndefined); + + /* Find the right bus */ + BusNumber = 0; + while (HaliHandlerForBus(InterfaceType, BusNumber)) BusNumber++; + } + + /* Allocate arrays for the handler */ + InterfaceArray = HalpAllocateArray(InterfaceType); + InterfaceBusNumberArray = HalpAllocateArray(BusNumber); + ConfigArray = HalpAllocateArray(ConfigType); + ConfigBusNumberArray = HalpAllocateArray(BusNumber); + + /* Only proceed if all allocations succeeded */ + if (InterfaceArray && InterfaceBusNumberArray && ConfigArray && ConfigBusNumberArray) + { + /* Find the parent handler if any */ + ParentHandler = HaliReferenceHandlerForBus(ParentBusType, ParentBusNumber); + + /* Initialize the handler */ + RtlZeroMemory(Bus, sizeof(HAL_BUS_HANDLER) + ExtraData); + Bus->ReferenceCount = 1; + + /* Fill out bus data */ + Bus->Handler.BusNumber = BusNumber; + Bus->Handler.InterfaceType = InterfaceType; + Bus->Handler.ConfigurationType = ConfigType; + Bus->Handler.ParentHandler = ParentHandler; + + /* Fill out dummy handlers */ + Bus->Handler.GetBusData = HalpNoBusData; + Bus->Handler.SetBusData = HalpNoBusData; + Bus->Handler.AdjustResourceList = HalpNoAdjustResourceList; + Bus->Handler.AssignSlotResources = HalpNoAssignSlotResources; + + /* Make space for extra data */ + if (ExtraData) Bus->Handler.BusData = Bus + 1; + + /* Check for a parent handler */ + if (ParentHandler) + { + /* Inherit the parent routines */ + Bus->Handler.GetBusData = ParentHandler->GetBusData; + Bus->Handler.SetBusData = ParentHandler->SetBusData; + Bus->Handler.AdjustResourceList = ParentHandler->AdjustResourceList; + Bus->Handler.AssignSlotResources = ParentHandler->AssignSlotResources; + Bus->Handler.TranslateBusAddress = ParentHandler->TranslateBusAddress; + Bus->Handler.GetInterruptVector = ParentHandler->GetInterruptVector; + } + + /* We don't support this yet */ + ASSERT(!InstallCallback); + + /* Lock the buses */ + KeAcquireSpinLock(&HalpBusDatabaseSpinLock, &OldIrql); + + /* Make space for the interface */ + HalpGrowArray(&HalpBusTable, &InterfaceArray); + + /* Check if we really have an interface */ + if (InterfaceType != InterfaceTypeUndefined) + { + /* Make space for the association */ + HalpGrowArray((PARRAY*)&HalpBusTable->Element[InterfaceType], + &InterfaceBusNumberArray); + + /* Get the bus handler pointer */ + BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpBusTable->Element[InterfaceType])->Element[BusNumber]; + + /* Check if there was already a handler there, and set the new one */ + if (*BusEntry) OldHandler = *BusEntry; + *BusEntry = Bus; + } + + /* Now add a space for the configuration space */ + HalpGrowArray(&HalpConfigTable, &ConfigArray); + + /* Check if we really have one */ + if (ConfigType != ConfigurationSpaceUndefined) + { + /* Make space for this association */ + HalpGrowArray((PARRAY*)&HalpConfigTable->Element[ConfigType], + &ConfigBusNumberArray); + + /* Get the bus handler pointer */ + BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpConfigTable->Element[ConfigType])->Element[BusNumber]; + if (*BusEntry) + { + /* Get the old entry, but make sure it's the same we had before */ + ASSERT((OldHandler == NULL) || (OldHandler == *BusEntry)); + OldHandler = *BusEntry; + } + + /* Set the new entry */ + *BusEntry = Bus; + } + + /* Link the adapter */ + InsertTailList(&HalpAllBusHandlers, &Bus->AllHandlers); + + /* Remove the old linkage */ + Bus = OldHandler; + if (Bus) RemoveEntryList(&Bus->AllHandlers); + + /* Release the lock */ + KeReleaseSpinLock(&HalpBusDatabaseSpinLock, OldIrql); + Status = STATUS_SUCCESS; + } + else + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + + /* Signal the event */ + KeSetEvent(&HalpBusDatabaseEvent, 0, FALSE); + + /* Re-page the function */ + MmUnlockPagableImageSection(CodeHandle); + + /* Free all allocations */ + if (Bus) ExFreePool(Bus); + if (InterfaceArray) ExFreePool(InterfaceArray); + if (InterfaceBusNumberArray) ExFreePool(InterfaceBusNumberArray); + if (ConfigArray) ExFreePool(ConfigArray); + if (ConfigBusNumberArray) ExFreePool(ConfigBusNumberArray); + + /* And we're done */ + DPRINT1("Bus handler has been registered: %p\n", *ReturnedBusHandler); + return Status; +} +#endif + +VOID +NTAPI +HalpInitBusHandler(VOID) +{ + /* Setup the bus lock */ + KeInitializeSpinLock(&HalpBusDatabaseSpinLock); + + /* Setup the bus event */ + KeInitializeEvent(&HalpBusDatabaseEvent, SynchronizationEvent, TRUE); + + /* Setup the bus configuration and bus table */ + HalpBusTable = HalpAllocateArray(0); + HalpConfigTable = HalpAllocateArray(0); + + /* Setup the bus list */ + InitializeListHead(&HalpAllBusHandlers); + + /* Setup the HAL Dispatch routines */ +#ifndef _MINIHAL_ + HalRegisterBusHandler = HaliRegisterBusHandler; + HalHandlerForBus = HaliHandlerForBus; + HalHandlerForConfigSpace = HaliHandlerForConfigSpace; + HalReferenceHandlerForBus = HaliReferenceHandlerForBus; + HalReferenceBusHandler = HaliReferenceBusHandler; + HalDereferenceBusHandler = HaliDereferenceBusHandler; +#endif + HalPciAssignSlotResources = HalpAssignSlotResources; + /* FIXME: Fix later */ +#if 0 + HalPciTranslateBusAddress = HaliTranslateBusAddress; + if (!HalFindBusAddressTranslation) HalFindBusAddressTranslation = HaliFindBusAddressTranslation; +#else + /* These should be written by the PCI driver later, but we give defaults */ + HalPciTranslateBusAddress = HalpTranslateBusAddress; + HalFindBusAddressTranslation = HalpFindBusAddressTranslation; +#endif +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/legacy/bus/cmosbus.c b/reactos/hal/halx86/generic/legacy/bus/cmosbus.c new file mode 100644 index 00000000000..279aebf9e20 --- /dev/null +++ b/reactos/hal/halx86/generic/legacy/bus/cmosbus.c @@ -0,0 +1,47 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/sysbus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +ULONG +NTAPI +HalpcGetCmosData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + DPRINT1("CMOS GetData\n"); + while (TRUE); + return 0; +} + +ULONG +NTAPI +HalpcSetCmosData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + DPRINT1("CMOS SetData\n"); + while (TRUE); + return 0; +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/legacy/bus/isabus.c b/reactos/hal/halx86/generic/legacy/bus/isabus.c new file mode 100644 index 00000000000..884e6d026bb --- /dev/null +++ b/reactos/hal/halx86/generic/legacy/bus/isabus.c @@ -0,0 +1,32 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/isabus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN +NTAPI +HalpTranslateIsaBusAddress(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + DPRINT1("ISA Translate\n"); + while (TRUE); + return FALSE; +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/bus/pcibus.c b/reactos/hal/halx86/generic/legacy/bus/pcibus.c similarity index 99% rename from reactos/hal/halx86/generic/bus/pcibus.c rename to reactos/hal/halx86/generic/legacy/bus/pcibus.c index ef3def412bd..f4d64e3b063 100644 --- a/reactos/hal/halx86/generic/bus/pcibus.c +++ b/reactos/hal/halx86/generic/legacy/bus/pcibus.c @@ -14,6 +14,8 @@ /* GLOBALS *******************************************************************/ +ULONG HalpBusType; + PCI_TYPE1_CFG_CYCLE_BITS HalpPciDebuggingDevice[2] = {{{{0}}}}; BOOLEAN HalpPCIConfigInitialized; diff --git a/reactos/hal/halx86/generic/bus/pcidata.c b/reactos/hal/halx86/generic/legacy/bus/pcidata.c similarity index 100% rename from reactos/hal/halx86/generic/bus/pcidata.c rename to reactos/hal/halx86/generic/legacy/bus/pcidata.c diff --git a/reactos/hal/halx86/generic/legacy/bus/sysbus.c b/reactos/hal/halx86/generic/legacy/bus/sysbus.c new file mode 100644 index 00000000000..ab8d2925c44 --- /dev/null +++ b/reactos/hal/halx86/generic/legacy/bus/sysbus.c @@ -0,0 +1,47 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/sysbus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN +NTAPI +HalpTranslateSystemBusAddress(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + DPRINT1("SYSTEM Translate\n"); + while (TRUE); + return FALSE; +} + +ULONG +NTAPI +HalpGetSystemInterruptVector(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + /* Get the root vector */ + DPRINT1("SYSTEM GetVector\n"); + while (TRUE); + return 0; +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/legacy/bussupp.c b/reactos/hal/halx86/generic/legacy/bussupp.c new file mode 100644 index 00000000000..831d27981d9 --- /dev/null +++ b/reactos/hal/halx86/generic/legacy/bussupp.c @@ -0,0 +1,488 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: hal/halx86/generic/legacy/bussupp.c + * PURPOSE: HAL Legacy Bus Support Code + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +PBUS_HANDLER +NTAPI +HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType, + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN INTERFACE_TYPE ParentBusInterfaceType, + IN ULONG ParentBusNumber, + IN ULONG BusSpecificData) +{ + PBUS_HANDLER Bus; + + /* Register the bus handler */ + HalRegisterBusHandler(InterfaceType, + BusDataType, + BusNumber, + ParentBusInterfaceType, + ParentBusNumber, + BusSpecificData, + NULL, + &Bus); + if (!Bus) return NULL; + + /* Check for a valid interface */ + if (InterfaceType != InterfaceTypeUndefined) + { + /* Allocate address ranges and zero them out */ + Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPool, + sizeof(SUPPORTED_RANGES), + ' laH'); + RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES)); + + /* Build the data structure */ + Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION; + Bus->BusAddresses->Dma.Limit = 7; + Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF; + Bus->BusAddresses->IO.Limit = 0xFFFF; + Bus->BusAddresses->IO.SystemAddressSpace = 1; + Bus->BusAddresses->PrefetchMemory.Base = 1; + } + + /* Return the bus address */ + return Bus; +} + +VOID +NTAPI +HalpRegisterInternalBusHandlers(VOID) +{ + PBUS_HANDLER Bus; + + /* Only do processor 1 */ + if (KeGetCurrentPrcb()->Number) return; + + /* Register root support */ + HalpInitBusHandler(); + + /* Allocate the system bus */ + Bus = HalpAllocateBusHandler(Internal, + ConfigurationSpaceUndefined, + 0, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering Internal Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; + } + + /* Allocate the CMOS bus */ + Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 0, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering CMOS Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpcGetCmosData; + Bus->SetBusData = HalpcSetCmosData; + } + + /* Allocate the CMOS bus */ + Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 1, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering CMOS Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpcGetCmosData; + Bus->SetBusData = HalpcSetCmosData; + } + + /* Allocate ISA bus */ + Bus = HalpAllocateBusHandler(Isa, + ConfigurationSpaceUndefined, + 0, + Internal, + 0, + 0); + DPRINT1("Registering ISA Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpNoBusData; + Bus->BusAddresses->Memory.Limit = 0xFFFFFF; + Bus->TranslateBusAddress = HalpTranslateIsaBusAddress; + } + + /* No support for EISA or MCA */ + ASSERT(HalpBusType == MACHINE_TYPE_ISA); +} + +VOID +NTAPI +HalpInitializePciBus(VOID) +{ + /* FIXME: Should do legacy PCI bus detection */ + + /* FIXME: Should detect chipset hacks */ + + /* FIXME: Should detect broken PCI hardware and apply hacks */ + + /* FIXME: Should build resource ranges */ +} + +VOID +NTAPI +HalpInitBusHandlers(VOID) +{ + /* Register the HAL Bus Handler support */ + HalpRegisterInternalBusHandlers(); +} + +VOID +NTAPI +HalpRegisterKdSupportFunctions(VOID) +{ + /* Register PCI Device Functions */ + KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging; + KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging; + + /* Register memory functions */ +#ifndef _MINIHAL_ + KdMapPhysicalMemory64 = HalpMapPhysicalMemory64; + KdUnmapVirtualAddress = HalpUnmapVirtualAddress; +#endif + + /* Register ACPI stub */ + KdCheckPowerButton = HalpCheckPowerButton; +} + +NTSTATUS +NTAPI +HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + BUS_HANDLER BusHandler; + PAGED_CODE(); + + /* Only PCI is supported */ + if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED; + + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call the PCI function */ + return HalpAssignPCISlotResources(&BusHandler, + &BusHandler, + RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + SlotNumber, + AllocatedResources); +} + +BOOLEAN +NTAPI +HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + /* Translation is easy */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + return TRUE; +} + +ULONG +NTAPI +HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + ULONG Vector = IRQ2VECTOR(BusInterruptLevel); + *Irql = (KIRQL)VECTOR2IRQL(Vector); + *Affinity = 0xFFFFFFFF; + return Vector; +} + +BOOLEAN +NTAPI +HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress, + IN OUT PULONG_PTR Context, + IN BOOLEAN NextBus) +{ + /* Make sure we have a context */ + if (!Context) return FALSE; + + /* If we have data in the context, then this shouldn't be a new lookup */ + if ((*Context) && (NextBus == TRUE)) return FALSE; + + /* Return bus data */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + + /* Set context value and return success */ + *Context = 1; + return TRUE; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources) +{ + /* Deprecated, return success */ + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +HalAssignSlotResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + /* Check the bus type */ + if (BusType != PCIBus) + { + /* Call our internal handler */ + return HalpAssignSlotResources(RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + BusType, + BusNumber, + SlotNumber, + AllocatedResources); + } + else + { + /* Call the PCI registered function */ + return HalPciAssignSlotResources(RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + PCIBus, + BusNumber, + SlotNumber, + AllocatedResources); + } +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetBusData(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length) +{ + /* Call the extended function */ + return HalGetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + BUS_HANDLER BusHandler; + + /* Look as the bus type */ + if (BusDataType == Cmos) + { + /* Call CMOS Function */ + return HalpGetCmosData(0, SlotNumber, Buffer, Length); + } + else if (BusDataType == EisaConfiguration) + { + /* FIXME: TODO */ + ASSERT(FALSE); + } + else if ((BusDataType == PCIConfiguration) && + (HalpPCIConfigInitialized) && + ((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus))) + { + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call PCI function */ + return HalpGetPCIData(&BusHandler, + &BusHandler, + *(PPCI_SLOT_NUMBER)&SlotNumber, + Buffer, + Offset, + Length); + } + + /* Invalid bus */ + return 0; +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + /* Call the system bus translator */ + return HalpGetSystemInterruptVector_Acpi(BusNumber, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalSetBusData(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length) +{ + /* Call the extended function */ + return HalSetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + BUS_HANDLER BusHandler; + + /* Look as the bus type */ + if (BusDataType == Cmos) + { + /* Call CMOS Function */ + return HalpSetCmosData(0, SlotNumber, Buffer, Length); + } + else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized)) + { + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call PCI function */ + return HalpSetPCIData(&BusHandler, + &BusHandler, + *(PPCI_SLOT_NUMBER)&SlotNumber, + Buffer, + Offset, + Length); + } + + /* Invalid bus */ + return 0; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + /* Look as the bus type */ + if (InterfaceType == PCIBus) + { + /* Call the PCI registered function */ + return HalPciTranslateBusAddress(PCIBus, + BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress); + } + else + { + /* Translation is easy */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + return TRUE; + } +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/legacy/halpcat.c b/reactos/hal/halx86/generic/legacy/halpcat.c index ea16403676e..0b85acd54ae 100644 --- a/reactos/hal/halx86/generic/legacy/halpcat.c +++ b/reactos/hal/halx86/generic/legacy/halpcat.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS HAL * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: hal/halx86/generic/acpi/halpcat.c + * FILE: hal/halx86/generic/legacy/halpcat.c * PURPOSE: HAL Legacy Support Code * PROGRAMMERS: ReactOS Portable Systems Group */ @@ -29,19 +29,6 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) return STATUS_NO_SUCH_DEVICE; } -VOID -NTAPI -HalpInitializePciBus(VOID) -{ - /* FIXME: Should do legacy PCI bus detection */ - - /* FIXME: Should detect chipset hacks */ - - /* FIXME: Should detect broken PCI hardware and apply hacks */ - - /* FIXME: Should build resource ranges */ -} - VOID NTAPI HalpBuildAddressMap(VOID) diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index a6ee63b3b88..0cd4e5aac43 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -7,14 +7,6 @@ - - bushndlr.c - isabus.c - halbus.c - pcibus.c - pcidata.c - sysbus.c - beep.c cmos.c display.c diff --git a/reactos/hal/halx86/hal_generic_acpi.rbuild b/reactos/hal/halx86/hal_generic_acpi.rbuild index 3784394b642..97501cb1823 100644 --- a/reactos/hal/halx86/hal_generic_acpi.rbuild +++ b/reactos/hal/halx86/hal_generic_acpi.rbuild @@ -10,7 +10,13 @@ halacpi.c halpnpdd.c + busemul.c + + + pcibus.c + + diff --git a/reactos/hal/halx86/hal_generic_pcat.rbuild b/reactos/hal/halx86/hal_generic_pcat.rbuild index e00ed5bdb4e..51f46eefc71 100644 --- a/reactos/hal/halx86/hal_generic_pcat.rbuild +++ b/reactos/hal/halx86/hal_generic_pcat.rbuild @@ -8,6 +8,15 @@ + + bushndlr.c + cmosbus.c + isabus.c + pcibus.c + pcidata.c + sysbus.c + + bussupp.c halpcat.c diff --git a/reactos/hal/halx86/hal_mini.rbuild b/reactos/hal/halx86/hal_mini.rbuild index a7baed44639..b2c8b718735 100644 --- a/reactos/hal/halx86/hal_mini.rbuild +++ b/reactos/hal/halx86/hal_mini.rbuild @@ -9,13 +9,16 @@ - - bushndlr.c - isabus.c - halbus.c - pcibus.c - pcidata.c - sysbus.c + + + bushndlr.c + cmosbus.c + isabus.c + pcibus.c + pcidata.c + sysbus.c + + bussupp.c beep.c bios.c diff --git a/reactos/hal/halx86/include/bus.h b/reactos/hal/halx86/include/bus.h index 03840227411..e8e6ef16f86 100644 --- a/reactos/hal/halx86/include/bus.h +++ b/reactos/hal/halx86/include/bus.h @@ -205,6 +205,8 @@ typedef struct _HAL_BUS_HANDLER /* FUNCTIONS *****************************************************************/ +/* SHARED (Fake PCI-BUS HANDLER) */ + VOID NTAPI HalpPCISynchronizeType1( @@ -277,34 +279,6 @@ HalpWritePCIConfig( IN ULONG Length ); -ULONG -NTAPI -HalpGetSystemInterruptVector( - ULONG BusNumber, - ULONG BusInterruptLevel, - ULONG BusInterruptVector, - PKIRQL Irql, - PKAFFINITY Affinity -); - -ULONG -NTAPI -HalpGetCmosData( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length -); - -ULONG -NTAPI -HalpSetCmosData( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length -); - ULONG NTAPI HalpGetPCIData( @@ -340,6 +314,36 @@ HalpAssignPCISlotResources( IN OUT PCM_RESOURCE_LIST *pAllocatedResources ); +/* NON-LEGACY */ + +ULONG +NTAPI +HalpGetSystemInterruptVector_Acpi( + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity +); + +ULONG +NTAPI +HalpGetCmosData( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length +); + +ULONG +NTAPI +HalpSetCmosData( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length +); + VOID NTAPI HalpInitializePciBus( @@ -352,12 +356,6 @@ HalpInitializePciStubs( VOID ); -VOID -NTAPI -HalpInitBusHandler( - VOID -); - BOOLEAN NTAPI HalpTranslateBusAddress( @@ -397,6 +395,78 @@ HalpRegisterPciDebuggingDeviceInfo( VOID ); +/* LEGACY */ + +VOID +NTAPI +HalpInitBusHandler( + VOID +); + +ULONG +NTAPI +HalpNoBusData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +ULONG +NTAPI +HalpcGetCmosData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +ULONG +NTAPI +HalpcSetCmosData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +BOOLEAN +NTAPI +HalpTranslateSystemBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress +); + +BOOLEAN +NTAPI +HalpTranslateIsaBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress +); + +ULONG +NTAPI +HalpGetSystemInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity +); + extern ULONG HalpBusType; extern BOOLEAN HalpPCIConfigInitialized; extern BUS_HANDLER HalpFakePciBusHandler; diff --git a/reactos/hal/halx86/include/halp.h b/reactos/hal/halx86/include/halp.h index 6edb85570d7..aa36554c7ec 100644 --- a/reactos/hal/halx86/include/halp.h +++ b/reactos/hal/halx86/include/halp.h @@ -765,6 +765,12 @@ KeUpdateSystemTime( IN KIRQL OldIrql ); +VOID +NTAPI +HalpInitBusHandlers( + VOID +); + #ifdef _M_AMD64 #define KfLowerIrql KeLowerIrql #ifndef CONFIG_SMP From 88c29ff4f2a681574506a5bf8bcb98a17b0c01eb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 01:24:15 +0000 Subject: [PATCH 285/292] [MSAFD] - Validate that we found the corresponding socket information in our socket information list - Fixes a crash in Firefox 2 when it tries to call accept() with a closed socket svn path=/trunk/; revision=47650 --- reactos/dll/win32/msafd/misc/dllmain.c | 52 ++++++++++++++++++++++++++ reactos/dll/win32/msafd/misc/event.c | 12 ++++++ reactos/dll/win32/msafd/misc/sndrcv.c | 25 +++++++++++++ 3 files changed, 89 insertions(+) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index c8da9744592..1ea4ce7002c 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -440,6 +440,12 @@ WSPCloseSocket(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } if (Socket->HelperEvents & WSH_NOTIFY_CLOSE) { @@ -635,6 +641,12 @@ WSPBind(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + HeapFree(GlobalHeap, 0, BindData); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set up Address in TDI Format */ BindData->Address.TAAddressCount = 1; @@ -728,6 +740,11 @@ WSPListen(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } if (Socket->SharedData.Listening) return 0; @@ -1072,6 +1089,12 @@ WSPAccept(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return INVALID_SOCKET; + } /* If this is non-blocking, make sure there's something for us to accept */ FD_ZERO(&ReadSet); @@ -1428,6 +1451,12 @@ WSPConnect(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Bind us First */ if (Socket->SharedData.State == SocketOpen) @@ -1644,6 +1673,12 @@ WSPShutdown(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set AFD Disconnect Type */ switch (HowTo) @@ -1718,6 +1753,12 @@ WSPGetSockName(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate a buffer for the address */ TdiAddressSize = @@ -1806,6 +1847,12 @@ WSPGetPeerName(IN SOCKET s, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(s); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate a buffer for the address */ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + *NameLength; @@ -1883,6 +1930,11 @@ WSPIoctl(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } switch( dwIoControlCode ) { diff --git a/reactos/dll/win32/msafd/misc/event.c b/reactos/dll/win32/msafd/misc/event.c index d79fe20019e..a1dc8766148 100644 --- a/reactos/dll/win32/msafd/misc/event.c +++ b/reactos/dll/win32/msafd/misc/event.c @@ -36,6 +36,12 @@ WSPEventSelect( /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set Socket to Non-Blocking */ BlockMode = 1; @@ -152,6 +158,12 @@ WSPEnumNetworkEvents( /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } EnumReq.Event = hEventObject; diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index 7f27fd43eb0..db26a367101 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -29,6 +29,11 @@ WSPAsyncSelect(IN SOCKET Handle, /* Get the Socket Structure associated to this Socket */ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate the Async Data Structure to pass on to the Thread later */ AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); @@ -111,6 +116,11 @@ WSPRecv(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -261,6 +271,11 @@ WSPRecvFrom(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -399,6 +414,11 @@ WSPSend(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -523,6 +543,11 @@ WSPSendTo(SOCKET Handle, /* Get the Socket Structure associate to this Socket */ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Bind us First */ if (Socket->SharedData.State == SocketOpen) From d19620d1ab20a214cc1e0e4c7b282a5d967f5bba Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 01:38:15 +0000 Subject: [PATCH 286/292] [AFD] - It is legal to send a NULL event object pointer to AFD (this is sent by msafd to cancel an existing event select) svn path=/trunk/; revision=47651 --- reactos/drivers/network/afd/afd/select.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/network/afd/afd/select.c b/reactos/drivers/network/afd/afd/select.c index d201a8c26a9..dd334d343a8 100644 --- a/reactos/drivers/network/afd/afd/select.c +++ b/reactos/drivers/network/afd/afd/select.c @@ -296,8 +296,11 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->EventSelect = NULL; else FCB->EventSelectTriggers = EventSelectInfo->Events; - } else - Status = STATUS_INVALID_PARAMETER; + } else { + FCB->EventSelect = NULL; + FCB->EventSelectTriggers = 0; + Status = STATUS_SUCCESS; + } AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); From e91cc9349b2b4c6622371dcb21bd880d5bade722 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 01:50:26 +0000 Subject: [PATCH 287/292] [MSAFD] - Fix 2 more callers who don't pass a valid lpErrno pointer - Check the return value of WSPSocket - Return WSAEWOULDBLOCK if there are no connections that can be accepted instead of silently returning 0 which is not INVALID_SOCKET so the caller treats it as a valid socket pointer and passes it to other functions which caused wide-spread mayhem since we never checked whether the socket handle the caller passed was valid until my last commit svn path=/trunk/; revision=47652 --- reactos/dll/win32/msafd/misc/dllmain.c | 13 ++++++++++--- reactos/dll/win32/msafd/misc/sndrcv.c | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index 1ea4ce7002c..f06b0a508d2 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -1102,12 +1102,17 @@ WSPAccept(SOCKET Handle, Timeout.tv_sec=0; Timeout.tv_usec=0; - WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL); + if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR) + { + NtClose(SockEvent); + return INVALID_SOCKET; + } if (ReadSet.fd_array[0] != Socket->Handle) { NtClose(SockEvent); - return 0; + *lpErrno = WSAEWOULDBLOCK; + return INVALID_SOCKET; } /* Send IOCTL */ @@ -1345,7 +1350,9 @@ WSPAccept(SOCKET Handle, &ProtocolInfo, GroupID, Socket->SharedData.CreateFlags, - NULL); + lpErrno); + if (AcceptSocket == INVALID_SOCKET) + return INVALID_SOCKET; /* Set up the Accept Structure */ AcceptData.ListenHandle = (HANDLE)AcceptSocket; diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index db26a367101..557fdae910e 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -51,7 +51,11 @@ WSPAsyncSelect(IN SOCKET Handle, /* Deactive WSPEventSelect */ if (Socket->SharedData.AsyncEvents) { - WSPEventSelect(Handle, NULL, 0, NULL); + if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR) + { + HeapFree(GetProcessHeap(), 0, AsyncData); + return SOCKET_ERROR; + } } /* Create the Asynch Thread if Needed */ From e2d5c9d92bf15a93c4d437ec202e3f51251b1bb7 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 7 Jun 2010 03:18:51 +0000 Subject: [PATCH 288/292] [HAL]: Kill debug spew. svn path=/trunk/; revision=47653 --- reactos/hal/halx86/generic/legacy/bus/bushndlr.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/reactos/hal/halx86/generic/legacy/bus/bushndlr.c b/reactos/hal/halx86/generic/legacy/bus/bushndlr.c index 6186d540ff4..7cb3a205cea 100644 --- a/reactos/hal/halx86/generic/legacy/bus/bushndlr.c +++ b/reactos/hal/halx86/generic/legacy/bus/bushndlr.c @@ -215,13 +215,11 @@ HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, { PHAL_BUS_HANDLER Bus, OldHandler = NULL; PHAL_BUS_HANDLER* BusEntry; - PVOID CodeHandle; + //PVOID CodeHandle; PARRAY InterfaceArray, InterfaceBusNumberArray, ConfigArray, ConfigBusNumberArray; PBUS_HANDLER ParentHandler; KIRQL OldIrql; NTSTATUS Status; - DPRINT1("HAL BUS REGISTRATION: %d.%d on bus %d with parent %d on bus %d\n", - InterfaceType, ConfigType, BusNumber, ParentBusType, ParentBusNumber); /* Make sure we have a valid handler */ ASSERT((InterfaceType != InterfaceTypeUndefined) || @@ -236,8 +234,8 @@ HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, /* Return the handler */ *ReturnedBusHandler = &Bus->Handler; - /* Don't page us out */ - CodeHandle = MmLockPagableDataSection(&HaliRegisterBusHandler); + /* FIXME: Fix the kernel first. Don't page us out */ + //CodeHandle = MmLockPagableDataSection(&HaliRegisterBusHandler); /* Synchronize with anyone else */ KeWaitForSingleObject(&HalpBusDatabaseEvent, @@ -367,8 +365,8 @@ HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, /* Signal the event */ KeSetEvent(&HalpBusDatabaseEvent, 0, FALSE); - /* Re-page the function */ - MmUnlockPagableImageSection(CodeHandle); + /* FIXME: Fix the kernel first. Re-page the function */ + //MmUnlockPagableImageSection(CodeHandle); /* Free all allocations */ if (Bus) ExFreePool(Bus); @@ -378,7 +376,6 @@ HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, if (ConfigBusNumberArray) ExFreePool(ConfigBusNumberArray); /* And we're done */ - DPRINT1("Bus handler has been registered: %p\n", *ReturnedBusHandler); return Status; } #endif From 07b14e926dc599fa9ca86fdbeec45ab32a334c83 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 7 Jun 2010 03:19:20 +0000 Subject: [PATCH 289/292] [HAL]: Add missing PCI Bus Handler support functions, used on non-ACPI systems (ISA-PCI support and such). svn path=/trunk/; revision=47654 --- .../hal/halx86/generic/legacy/bus/pcibus.c | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/reactos/hal/halx86/generic/legacy/bus/pcibus.c b/reactos/hal/halx86/generic/legacy/bus/pcibus.c index f4d64e3b063..fe49b731fcb 100644 --- a/reactos/hal/halx86/generic/legacy/bus/pcibus.c +++ b/reactos/hal/halx86/generic/legacy/bus/pcibus.c @@ -507,6 +507,55 @@ HalpSetPCIData(IN PBUS_HANDLER BusHandler, return Len; } +ULONG +NTAPI +HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + UNIMPLEMENTED; + while (TRUE); + return 0; +} + +VOID +NTAPI +HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData) +{ + UNIMPLEMENTED; + while (TRUE); +} + +VOID +NTAPI +HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData) +{ + UNIMPLEMENTED; + while (TRUE); +} + +NTSTATUS +NTAPI +HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER PciSlot, + OUT PSUPPORTED_RANGE *Range) +{ + UNIMPLEMENTED; + while (TRUE); + return STATUS_SUCCESS; +} + NTSTATUS NTAPI HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock, @@ -560,6 +609,18 @@ PciSize(ULONG Base, ULONG Mask) return Size; } +NTSTATUS +NTAPI +HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList) +{ + /* Not yet supported */ + DbgPrint("HAL: PCI Resource List Adjustment not implemented!"); + while (TRUE); + return STATUS_UNSUCCESSFUL; +} + NTSTATUS NTAPI HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler, @@ -1063,3 +1124,5 @@ HalpInitializePciStubs(VOID) HalpPCIConfigInitialized = TRUE; } +/* EOF */ + From adc324f5c9e0cb3c5d6761d52f969760c65e14cc Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 7 Jun 2010 03:23:48 +0000 Subject: [PATCH 290/292] [HAL]: Detect, initialize, and create bus handlers for, all PCI buses that are found on the machine. [HAL]: Detect PCI-to-PCI Bridges, Extended CardBus Addressing, read Chipset Hacks from Registry, and scan for IRQ lines used by PCI Devices. Scan for PCI-IDE controllers, broken Intel PCI Bridges/Controllers. Scan for OHCI and UHCI USB controllers. Warn the user that if any of these are found, the current HAL does not handle certain types of these devices (these checks are based on the ones the Legacy Windows HAL makes). svn path=/trunk/; revision=47655 --- reactos/hal/halx86/generic/legacy/bussupp.c | 483 +++++++++++++++++++- reactos/hal/halx86/include/bus.h | 46 ++ 2 files changed, 525 insertions(+), 4 deletions(-) diff --git a/reactos/hal/halx86/generic/legacy/bussupp.c b/reactos/hal/halx86/generic/legacy/bussupp.c index 831d27981d9..8d8f799c541 100644 --- a/reactos/hal/halx86/generic/legacy/bussupp.c +++ b/reactos/hal/halx86/generic/legacy/bussupp.c @@ -14,6 +14,9 @@ /* GLOBALS ********************************************************************/ +extern KSPIN_LOCK HalpPCIConfigLock; +ULONG HalpPciIrqMask; + /* PRIVATE FUNCTIONS **********************************************************/ PBUS_HANDLER @@ -137,17 +140,489 @@ HalpRegisterInternalBusHandlers(VOID) ASSERT(HalpBusType == MACHINE_TYPE_ISA); } +#ifndef _MINIHAL_ +NTSTATUS +NTAPI +HalpMarkChipsetDecode(BOOLEAN OverrideEnable) +{ + NTSTATUS Status; + UNICODE_STRING KeyString; + ULONG Data = OverrideEnable; + HANDLE KeyHandle, Handle; + + /* Open CCS key */ + RtlInitUnicodeString(&KeyString, + L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"); + Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE); + if (NT_SUCCESS(Status)) + { + /* Open PNP Bios key */ + RtlInitUnicodeString(&KeyString, L"Control\\Biosinfo\\PNPBios"); + Status = HalpOpenRegistryKey(&KeyHandle, + Handle, + &KeyString, + KEY_ALL_ACCESS, + TRUE); + + /* Close root key */ + ZwClose(Handle); + + /* Check if PNP BIOS key exists */ + if (NT_SUCCESS(Status)) + { + /* Set the override value */ + RtlInitUnicodeString(&KeyString, L"FullDecodeChipsetOverride"); + Status = ZwSetValueKey(KeyHandle, + &KeyString, + 0, + REG_DWORD, + &Data, + sizeof(Data)); + + /* Close subkey */ + ZwClose(KeyHandle); + } + } + + /* Return status */ + return Status; +} + +PBUS_HANDLER +NTAPI +HalpAllocateAndInitPciBusHandler(IN ULONG PciType, + IN ULONG BusNo, + IN BOOLEAN TestAllocation) +{ + PBUS_HANDLER Bus; + PPCIPBUSDATA BusData; + + /* Allocate the bus handler */ + Bus = HalpAllocateBusHandler(PCIBus, + PCIConfiguration, + BusNo, + Internal, + 0, + sizeof(PCIPBUSDATA)); + + /* Set it up */ + Bus->GetBusData = (PGETSETBUSDATA)HalpGetPCIData; + Bus->SetBusData = (PGETSETBUSDATA)HalpSetPCIData; + Bus->GetInterruptVector = (PGETINTERRUPTVECTOR)HalpGetPCIIntOnISABus; + Bus->AdjustResourceList = (PADJUSTRESOURCELIST)HalpAdjustPCIResourceList; + Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES)HalpAssignPCISlotResources; + Bus->BusAddresses->Dma.Limit = 0; + + /* Get our custom bus data */ + BusData = (PPCIPBUSDATA)Bus->BusData; + + /* Setup custom bus data */ + BusData->CommonData.Tag = PCI_DATA_TAG; + BusData->CommonData.Version = PCI_DATA_VERSION; + BusData->CommonData.ReadConfig = (PciReadWriteConfig)HalpReadPCIConfig; + BusData->CommonData.WriteConfig = (PciReadWriteConfig)HalpWritePCIConfig; + BusData->CommonData.Pin2Line = (PciPin2Line)HalpPCIPin2ISALine; + BusData->CommonData.Line2Pin = (PciLine2Pin)HalpPCIISALine2Pin; + BusData->MaxDevice = PCI_MAX_DEVICES; + BusData->GetIrqRange = (PciIrqRange)HalpGetISAFixedPCIIrq; + + /* Initialize the bitmap */ + RtlInitializeBitMap(&BusData->DeviceConfigured, BusData->ConfiguredBits, 256); + + /* Check the type of PCI bus */ + switch (PciType) + { + /* Type 1 PCI Bus */ + case 1: + + /* Copy the Type 1 handler data */ + RtlCopyMemory(&PCIConfigHandler, + &PCIConfigHandlerType1, + sizeof(PCIConfigHandler)); + + /* Set correct I/O Ports */ + BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT; + BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT; + break; + + /* Type 2 PCI Bus */ + case 2: + + /* Copy the Type 1 handler data */ + RtlCopyMemory(&PCIConfigHandler, + &PCIConfigHandlerType2, + sizeof (PCIConfigHandler)); + + /* Set correct I/O Ports */ + BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT; + BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT; + BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE; + + /* Only 16 devices supported, not 32 */ + BusData->MaxDevice = 16; + break; + + default: + + /* Invalid type */ + DbgPrint("HAL: Unnkown PCI type\n"); + } + + /* Return the bus handler */ + return Bus; +} + +BOOLEAN +NTAPI +HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler, + IN PCI_SLOT_NUMBER Slot) +{ + UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; + PPCI_COMMON_CONFIG PciHeader = (PVOID)DataBuffer; + ULONG i; + ULONG_PTR Address; + + /* Read the PCI header */ + HalpReadPCIConfig(BusHandler, Slot, PciHeader, 0, PCI_COMMON_HDR_LENGTH); + + /* Make sure it's a valid device */ + if ((PciHeader->VendorID == PCI_INVALID_VENDORID) || + (PCI_CONFIGURATION_TYPE(PciHeader) != PCI_DEVICE_TYPE)) + { + /* Bail out */ + return FALSE; + } + + /* Make sure interrupt numbers make sense */ + if (((PciHeader->u.type0.InterruptPin) && + (PciHeader->u.type0.InterruptPin > 4)) || + (PciHeader->u.type0.InterruptLine & 0x70)) + { + /* Bail out */ + return FALSE; + } + + /* Now scan PCI BARs */ + for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) + { + /* Check what kind of address it is */ + Address = PciHeader->u.type0.BaseAddresses[i]; + if (Address & PCI_ADDRESS_IO_SPACE) + { + /* Highest I/O port is 65535 */ + if (Address > 0xFFFF) return FALSE; + } + else + { + /* MMIO should be higher than 0x80000 */ + if ((Address > 0xF) && (Address < 0x80000)) return FALSE; + } + + /* Is this a 64-bit address? */ + if (!(Address & PCI_ADDRESS_IO_SPACE) && + ((Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)) + { + /* Check the next-next entry, since this one 64-bits wide */ + i++; + } + } + + /* Header, interrupt and address data all make sense */ + return TRUE; +} + +static BOOLEAN WarningsGiven[5]; + +NTSTATUS +NTAPI +HalpGetChipHacks(IN USHORT VendorId, + IN USHORT DeviceId, + IN UCHAR RevisionId, + IN PULONG HackFlags) +{ + /* Not yet implemented */ + if (!WarningsGiven[0]++) DbgPrint("HAL: Not checking for PCI Chipset Hacks. Your hardware may malfunction!\n"); + *HackFlags = 0; + return STATUS_UNSUCCESSFUL; +} + +BOOLEAN +NTAPI +HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo, + IN PPCI_COMMON_CONFIG PciData, + IN ULONG Flags) +{ + /* Not yet implemented */ + if (!WarningsGiven[1]++) DbgPrint("HAL: Not checking for PCI Cards with Extended Addressing. Your hardware may malfunction!\n"); + return FALSE; +} + +BOOLEAN +NTAPI +HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData) +{ + /* Not yet implemented */ + if (!WarningsGiven[2]++) DbgPrint("HAL: Not checking for PCI Cards that are IDE devices. Your hardware may malfunction!\n"); + return FALSE; +} + +BOOLEAN +NTAPI +HalpGetPciBridgeConfig(IN ULONG PciType, + IN PUCHAR MaxPciBus) +{ + /* Not yet implemented */ + if (!WarningsGiven[3]++) DbgPrint("HAL: Not checking for PCI-to-PCI Bridges. Your hardware may malfunction!\n"); + return FALSE; +} + +VOID +NTAPI +HalpFixupPciSupportedRanges(IN ULONG MaxBuses) +{ + /* Not yet implemented */ + if (!WarningsGiven[4]++) DbgPrint("HAL: Not adjusting Bridge-to-Child PCI Address Ranges. Your hardware may malfunction!\n"); +} +#endif + VOID NTAPI HalpInitializePciBus(VOID) { - /* FIXME: Should do legacy PCI bus detection */ +#ifndef _MINIHAL_ + PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo; + UCHAR PciType; + PCI_SLOT_NUMBER PciSlot; + ULONG i, j, k; + UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; + PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer; + PBUS_HANDLER BusHandler; + ULONG HackFlags; + BOOLEAN ExtendedAddressDecoding = FALSE; - /* FIXME: Should detect chipset hacks */ + /* Query registry information */ + PciRegistryInfo = HalpQueryPciRegistryInfo(); + if (!PciRegistryInfo) return; - /* FIXME: Should detect broken PCI hardware and apply hacks */ + /* Initialize the PCI configuration lock */ + KeInitializeSpinLock(&HalpPCIConfigLock); - /* FIXME: Should build resource ranges */ + /* Get the type and free the info structure */ + PciType = PciRegistryInfo->HardwareMechanism & 0xF; + + /* Check if this is a type 2 PCI bus with at least one bus */ + if ((PciRegistryInfo->NoBuses) && (PciType == 2)) + { + /* Setup the PCI slot */ + PciSlot.u.bits.Reserved = 0; + PciSlot.u.bits.FunctionNumber = 0; + + /* Loop all slots */ + for (i = 0; i < 32; i++) + { + /* Try to setup a Type 2 PCI slot */ + PciType = 2; + BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE); + if (!BusHandler) break; + + /* Now check if it's valid */ + if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; + + /* Heh, the BIOS lied... try Type 1 */ + PciType = 1; + BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE); + if (!BusHandler) break; + + /* Now check if it's valid */ + if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; + + /* Keep trying */ + PciType = 2; + } + + /* Now allocate the correct kind of handler */ + HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE); + } + + /* Okay, now loop all PCI bridges */ + do + { + /* Loop all PCI buses */ + for (i = 0; i < PciRegistryInfo->NoBuses; i++) + { + /* Check if we have a handler for it */ + if (!HalHandlerForBus(PCIBus, i)) + { + /* Allocate it */ + HalpAllocateAndInitPciBusHandler(PciType, i, FALSE); + } + } + /* Go to the next bridge */ + } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses)); + + /* Now build correct address range informaiton */ + HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses); + + /* Loop every bus */ + PciSlot.u.bits.Reserved = 0; + for (i = 0; i < PciRegistryInfo->NoBuses; i++) + { + /* Get the bus handler */ + BusHandler = HalHandlerForBus(PCIBus, i); + + /* Loop every device */ + for (j = 0; j < 32; j++) + { + /* Loop every function */ + PciSlot.u.bits.DeviceNumber = j; + for (k = 0; k < 8; k++) + { + /* Build the final slot structure */ + PciSlot.u.bits.FunctionNumber = k; + + /* Read the configuration information */ + HalpReadPCIConfig(BusHandler, + PciSlot, + PciData, + 0, + PCI_COMMON_HDR_LENGTH); + + /* Skip if this is an invalid function */ + if (PciData->VendorID == PCI_INVALID_VENDORID) continue; + + /* Check if this is a Cardbus bridge */ + if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE) + { + /* Not supported */ + DbgPrint("HAL: Your machine has a PCI Cardbus Bridge. This is not supported!\n"); + continue; + } + + /* Check if this is a PCI device */ + if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE) + { + /* Check if it has an interrupt pin and line registered */ + if ((PciData->u.type1.InterruptPin) && + (PciData->u.type1.InterruptLine)) + { + /* Check if this interrupt line is connected to the bus */ + if (PciData->u.type1.InterruptLine < 16) + { + /* Is this an IDE device? */ + DbgPrint("HAL: Found PCI device with IRQ line\n"); + if (!HalpIsIdeDevice(PciData)) + { + /* We'll mask out this interrupt then */ + DbgPrint("HAL: Device is not an IDE Device. Should be masking IRQ %d! This is not supported!\n", + PciData->u.type1.InterruptLine); + HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine); + } + } + } + } + + /* Check for broken Intel chips */ + if (PciData->VendorID == 0x8086) + { + /* Check for broken 82830 PCI controller */ + if ((PciData->DeviceID == 0x04A3) && + (PciData->RevisionID < 0x11)) + { + /* Skip */ + DbgPrint("HAL: Your machine has a broken Intel 82430 PCI Controller. This is not supported!\n"); + continue; + } + + /* Check for broken 82378 PCI-to-ISA Bridge */ + if ((PciData->DeviceID == 0x0484) && + (PciData->RevisionID <= 3)) + { + /* Skip */ + DbgPrint("HAL: Your machine has a broken Intel 82378 PCI-to-ISA Bridge. This is not supported!\n"); + continue; + } + + /* Check for broken 82450 PCI Bridge */ + if ((PciData->DeviceID == 0x84C4) && + (PciData->RevisionID <= 4)) + { + DbgPrint("HAL: Your machine has an Intel Orion 82450 PCI Bridge. This is not supported!\n"); + continue; + } + } + + /* Do we know this card? */ + if (!ExtendedAddressDecoding) + { + /* Check for it */ + if (HalpIsRecognizedCard(PciRegistryInfo, PciData, 1)) + { + /* We'll do chipset checks later */ + DbgPrint("HAL: Recognized a PCI Card with Extended Address Decoding. This is not supported!\n"); + ExtendedAddressDecoding = TRUE; + } + } + + /* Check if this is a USB controller */ + if ((PciData->BaseClass == PCI_CLASS_SERIAL_BUS_CTLR) && + (PciData->SubClass == PCI_SUBCLASS_SB_USB)) + { + /* Check if this is an OHCI controller */ + if (PciData->ProgIf == 0x10) + { + DbgPrint("HAL: Your machine has an OHCI (USB) PCI Expansion Card. This is not supported!\n"); + continue; + } + + /* Check for Intel UHCI controller */ + if (PciData->VendorID == 0x8086) + { + DbgPrint("HAL: Your machine has an Intel UHCI (USB) Controller. This is not supported!\n"); + continue; + } + + /* Check for VIA UHCI controller */ + if (PciData->VendorID == 0x1106) + { + DbgPrint("HAL: Your machine has a VIA UHCI (USB) Controller. This is not supported!\n"); + continue; + } + } + + /* Now check the registry for chipset hacks */ + if (NT_SUCCESS(HalpGetChipHacks(PciData->VendorID, + PciData->DeviceID, + PciData->RevisionID, + &HackFlags))) + { + /* Check for hibernate-disable */ + if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE) + { + DbgPrint("HAL: Your machine has a broken PCI device which is incompatible with hibernation. This is not supported!\n"); + continue; + } + + /* Check for USB controllers that generate SMIs */ + if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE) + { + DbgPrint("HAL: Your machine has a USB controller which generates SMIs. This is not supported!\n"); + continue; + } + } + } + } + } + + /* Initialize NMI Crash Flag */ + HalpGetNMICrashFlag(); + + /* Free the registry data */ + ExFreePool(PciRegistryInfo); + + /* Tell PnP if this hard supports correct decoding */ + HalpMarkChipsetDecode(ExtendedAddressDecoding); + DPRINT1("PCI BUS Setup complete\n"); +#endif } VOID diff --git a/reactos/hal/halx86/include/bus.h b/reactos/hal/halx86/include/bus.h index e8e6ef16f86..38cf406bf13 100644 --- a/reactos/hal/halx86/include/bus.h +++ b/reactos/hal/halx86/include/bus.h @@ -207,6 +207,16 @@ typedef struct _HAL_BUS_HANDLER /* SHARED (Fake PCI-BUS HANDLER) */ +extern PCI_CONFIG_HANDLER PCIConfigHandler; +extern PCI_CONFIG_HANDLER PCIConfigHandlerType1; +extern PCI_CONFIG_HANDLER PCIConfigHandlerType2; + +PPCI_REGISTRY_INFO_INTERNAL +NTAPI +HalpQueryPciRegistryInfo( + VOID +); + VOID NTAPI HalpPCISynchronizeType1( @@ -397,6 +407,42 @@ HalpRegisterPciDebuggingDeviceInfo( /* LEGACY */ +NTSTATUS +NTAPI +HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList); + +ULONG +NTAPI +HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); +VOID +NTAPI +HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); + +VOID +NTAPI +HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +NTSTATUS +NTAPI +HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER PciSlot, + OUT PSUPPORTED_RANGE *Range); + VOID NTAPI HalpInitBusHandler( From b2c96e402da107310196cb9d9ef40c6169034951 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 7 Jun 2010 05:40:08 +0000 Subject: [PATCH 291/292] [MSAFD] - Fix a bug in GetSocketStructure that resulted in us missing the last entry of the list - Remove an "optimization" which was supposed to find an unused socket entry (which it almost never did) but now just corrupts the linked list by trashing our NextSocket pointer svn path=/trunk/; revision=47656 --- reactos/dll/win32/msafd/misc/dllmain.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index f06b0a508d2..9b459b7d126 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -60,7 +60,7 @@ WSPSocket(int AddressFamily, ULONG SizeOfEA; PAFD_CREATE_PACKET AfdPacket; HANDLE Sock; - PSOCKET_INFORMATION Socket = NULL, PrevSocket = NULL; + PSOCKET_INFORMATION Socket = NULL; PFILE_FULL_EA_INFORMATION EABuffer = NULL; PHELPER_DATA HelperData; PVOID HelperDLLContext; @@ -260,17 +260,6 @@ WSPSocket(int AddressFamily, /* Save Handle */ Socket->Handle = (SOCKET)Sock; - /* XXX See if there's a structure we can reuse -- We need to do this - * more properly. */ - PrevSocket = GetSocketStructure( (SOCKET)Sock ); - - if( PrevSocket ) - { - RtlCopyMemory( PrevSocket, Socket, sizeof(*Socket) ); - RtlFreeHeap( GlobalHeap, 0, Socket ); - Socket = PrevSocket; - } - /* Save Group Info */ if (g != 0) { @@ -2325,15 +2314,8 @@ GetSocketStructure(SOCKET Handle) { PSOCKET_INFORMATION CurrentSocket; - if (!SocketListHead) - return NULL; - - /* This is a special case */ - if (SocketListHead->Handle == Handle) - return SocketListHead; - CurrentSocket = SocketListHead; - while (CurrentSocket->NextSocket) + while (CurrentSocket) { if (CurrentSocket->Handle == Handle) return CurrentSocket; From 7c5fd856eee994f929ac94989edacd279d6aec75 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 7 Jun 2010 13:37:43 +0000 Subject: [PATCH 292/292] [win32k] - Change the number of windowless timers from 1024 to 32768. - When destroying windowless timers, clear the bit number (IDEvent) in the bitmap so the bit number can be reused. - Only create a windowless timer if there is no windowless timer matching IDEvent. - Fixes case where applications create too many windowless timers and/or run out of windowless timers. svn path=/trunk/; revision=47658 --- .../subsystems/win32/win32k/ntuser/timer.c | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index ea3b509da5d..de8caeaafed 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -24,7 +24,7 @@ static LONG TimeLast = 0; #define MAX_ELAPSE_TIME 0x7FFFFFFF /* Windows 2000 has room for 32768 window-less timers */ -#define NUM_WINDOW_LESS_TIMERS 1024 +#define NUM_WINDOW_LESS_TIMERS 32768 static FAST_MUTEX Mutex; static RTL_BITMAP WindowLessTimersBitMap; @@ -94,6 +94,13 @@ RemoveTimer(PTIMER pTmr) { /* Set the flag, it will be removed when ready */ RemoveEntryList(&pTmr->ptmrList); + if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) + { + DPRINT("Clearing Bit %d)\n", pTmr->nID); + IntLockWindowlessTimerBitmap(); + RtlClearBit(&WindowLessTimersBitMap, pTmr->nID); + IntUnlockWindowlessTimerBitmap(); + } UserDereferenceObject(pTmr); Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer); } @@ -224,9 +231,15 @@ IntSetTimer( PWINDOW_OBJECT Window, Elapse = 10; } - if ((Window == NULL) && (!(Type & TMRF_SYSTEM))) + if ((Window) && (IDEvent == 0)) + IDEvent = 1; + + pTmr = FindTimer(Window, IDEvent, Type, FALSE); + + if ((!pTmr) && (Window == NULL) && (!(Type & TMRF_SYSTEM))) { IntLockWindowlessTimerBitmap(); + IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex); if (IDEvent == (UINT_PTR) -1) @@ -237,15 +250,11 @@ IntSetTimer( PWINDOW_OBJECT Window, return 0; } - HintIndex = ++IDEvent; - IntUnlockWindowlessTimerBitmap(); Ret = IDEvent; + //HintIndex = IDEvent + 1; + IntUnlockWindowlessTimerBitmap(); } - if ((Window) && (IDEvent == 0)) - IDEvent = 1; - - pTmr = FindTimer(Window, IDEvent, Type, FALSE); if (!pTmr) { pTmr = CreateTimer();