diff --git a/base/applications/network/netstat/netstat.c b/base/applications/network/netstat/netstat.c index fbffe08db8e..d491d081813 100644 --- a/base/applications/network/netstat/netstat.c +++ b/base/applications/network/netstat/netstat.c @@ -237,12 +237,13 @@ BOOL DisplayOutput() ShowUdpStatistics(); return EXIT_SUCCESS; } - else //if (bDoShowAllCons) + else { _tprintf(_T("\nActive Connections\n")); _tprintf(_T("\n Proto Local Address Foreign Address State\n")); ShowTcpTable(); - ShowUdpTable(); + if (bDoShowAllCons) + ShowUdpTable(); } return EXIT_SUCCESS; } @@ -422,23 +423,24 @@ VOID ShowTcpTable() CHAR Remote[ADDRESSLEN]; /* Get the table of TCP endpoints */ - dwSize = 0; - error = GetTcpTable(NULL, &dwSize, TRUE); - if (error != ERROR_INSUFFICIENT_BUFFER) + dwSize = sizeof (MIB_TCPTABLE); + /* Should also work when we get new connections between 2 GetTcpTable() + * calls: */ + do + { + tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize); + error = GetTcpTable(tcpTable, &dwSize, TRUE); + if ( error != NO_ERROR ) + HeapFree(GetProcessHeap(), 0, tcpTable); + } + while ( error == ERROR_INSUFFICIENT_BUFFER ); + + if (error != NO_ERROR) { printf("Failed to snapshot TCP endpoints.\n"); DoFormatMessage(error); exit(EXIT_FAILURE); } - tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize); - error = GetTcpTable(tcpTable, &dwSize, TRUE ); - if (error) - { - printf("Failed to snapshot TCP endpoints table.\n"); - DoFormatMessage(error); - HeapFree(GetProcessHeap(), 0, tcpTable); - exit(EXIT_FAILURE); - } /* Dump the TCP table */ for (i = 0; i < tcpTable->dwNumEntries; i++) diff --git a/dll/ntdll/ldr/utils.c b/dll/ntdll/ldr/utils.c index 14512194832..fcbd21f800d 100644 --- a/dll/ntdll/ldr/utils.c +++ b/dll/ntdll/ldr/utils.c @@ -88,10 +88,10 @@ static __inline LONG LdrpDecrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); } LoadCount = Module->LoadCount; - if (Module->LoadCount > 0 && Module->LoadCount != LDRP_PROCESS_CREATION_TIME) - { + if (Module->LoadCount > 0 && Module->LoadCount != LDRP_PROCESS_CREATION_TIME) + { Module->LoadCount--; - } + } if (!Locked) { RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); @@ -107,10 +107,10 @@ static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); } LoadCount = Module->LoadCount; - if (Module->LoadCount != LDRP_PROCESS_CREATION_TIME) - { + if (Module->LoadCount != LDRP_PROCESS_CREATION_TIME) + { Module->LoadCount++; - } + } if (!Locked) { RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); @@ -1388,7 +1388,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, ULONG Count, ProtectSize, OldProtect, OldProtect2; PVOID Page, ProtectPage, ProtectPage2; PUSHORT TypeOffset; - ULONG_PTR Delta; + LONG_PTR Delta; NTSTATUS Status; if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) @@ -3464,54 +3464,15 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey, } -PIMAGE_BASE_RELOCATION NTAPI -LdrProcessRelocationBlock(IN ULONG_PTR Address, - IN ULONG Count, - IN PUSHORT TypeOffset, - IN LONG_PTR Delta) +PIMAGE_BASE_RELOCATION +NTAPI +LdrProcessRelocationBlock( + IN ULONG_PTR Address, + IN ULONG Count, + IN PUSHORT TypeOffset, + IN LONG_PTR Delta) { - SHORT Offset; - USHORT Type; - USHORT i; - PUSHORT ShortPtr; - PULONG LongPtr; - - for (i = 0; i < Count; i++) - { - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - - switch (Type) - { - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset); - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset); - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)((ULONG_PTR)Address + Offset); - *LongPtr += Delta; - break; - - case IMAGE_REL_BASED_HIGHADJ: - case IMAGE_REL_BASED_MIPS_JMPADDR: - default: - DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); - return NULL; - } - - TypeOffset++; - } - - return (PIMAGE_BASE_RELOCATION)TypeOffset; + return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta); } NTSTATUS diff --git a/dll/win32/faultrep/faultrep.rbuild b/dll/win32/faultrep/faultrep.rbuild index aeeb3afeca5..0c886fc2038 100644 --- a/dll/win32/faultrep/faultrep.rbuild +++ b/dll/win32/faultrep/faultrep.rbuild @@ -1,6 +1,6 @@ - . + . include/reactos/wine wine diff --git a/dll/win32/gdi32/objects/text.c b/dll/win32/gdi32/objects/text.c index d64e01262f2..b84e948abad 100644 --- a/dll/win32/gdi32/objects/text.c +++ b/dll/win32/gdi32/objects/text.c @@ -173,7 +173,7 @@ GetTextExtentPointW( LPSIZE lpSize ) { - return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 1); + return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0); } @@ -299,7 +299,7 @@ GetTextExtentExPointI(HDC hdc, LPINT alpDx, LPSIZE lpSize) { - return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,1); + return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,GTEF_INDICES); } /* @@ -312,7 +312,7 @@ GetTextExtentPointI(HDC hdc, int cgi, LPSIZE lpSize) { - return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,2); + return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,GTEF_INDICES); } /* diff --git a/dll/win32/iphlpapi/iphlpapi_main.c b/dll/win32/iphlpapi/iphlpapi_main.c index 717fd2dee67..ebb73ad6017 100644 --- a/dll/win32/iphlpapi/iphlpapi_main.c +++ b/dll/win32/iphlpapi/iphlpapi_main.c @@ -1747,7 +1747,7 @@ static int TcpTableSorter(const void *a, const void *b) */ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) { - DWORD ret = NO_ERROR; + DWORD ret = ERROR_NO_DATA; TRACE("pTcpTable %p, pdwSize %p, bOrder %d\n", pTcpTable, pdwSize, (DWORD)bOrder); @@ -1764,18 +1764,31 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) ret = ERROR_INSUFFICIENT_BUFFER; } else { - PMIB_TCPTABLE pTcpTable = getTcpTable(); - if (pTcpTable) + PMIB_TCPTABLE pOurTcpTable = getTcpTable(); + if (pOurTcpTable) { size = sizeof(MIB_TCPTABLE); - if (pTcpTable->dwNumEntries > 1) - size += (pTcpTable->dwNumEntries - 1) * sizeof(MIB_TCPROW); - *pdwSize = size; + if (pOurTcpTable->dwNumEntries > 1) + size += (pOurTcpTable->dwNumEntries - 1) * sizeof(MIB_TCPROW); + + if (*pdwSize < size) + { + *pdwSize = size; - if (bOrder) - qsort(pTcpTable->table, pTcpTable->dwNumEntries, - sizeof(MIB_TCPROW), TcpTableSorter); - ret = NO_ERROR; + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + memcpy(pTcpTable, pOurTcpTable, size); + + if (bOrder) + qsort(pTcpTable->table, pTcpTable->dwNumEntries, + sizeof(MIB_TCPROW), TcpTableSorter); + + ret = NO_ERROR; + } + + free(pOurTcpTable); } } } diff --git a/dll/win32/iphlpapi/iphlpapi_private.h b/dll/win32/iphlpapi/iphlpapi_private.h index 2cb747f2a80..6ba198a301c 100644 --- a/dll/win32/iphlpapi/iphlpapi_private.h +++ b/dll/win32/iphlpapi/iphlpapi_private.h @@ -139,6 +139,7 @@ LONG OpenChildKeyRead( HANDLE RegHandle, PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ); void ConsumeChildKeyName( PWCHAR Name ); PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ); +PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ); void ConsumeRegValueString( PWCHAR NameServer ); BOOL isInterface( TDIEntityID *if_maybe ); BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ); diff --git a/dll/win32/iphlpapi/registry.c b/dll/win32/iphlpapi/registry.c index 64b0f1f98bb..e83fde95281 100644 --- a/dll/win32/iphlpapi/registry.c +++ b/dll/win32/iphlpapi/registry.c @@ -66,25 +66,123 @@ void ConsumeChildKeyName( PWCHAR Name ) { if (Name) HeapFree( GetProcessHeap(), 0, Name ); } -PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) { - PWCHAR Name; - DWORD ReturnedSize = 0; +PVOID QueryRegistryValue(HANDLE RegHandle, PWCHAR ValueName, LPDWORD RegistryType, LPDWORD Length) +{ + PVOID ReadValue = NULL; + DWORD Error; - if (RegQueryValueExW( RegHandle, ValueName, NULL, NULL, NULL, - &ReturnedSize ) != 0) { - return 0; - } else { - Name = malloc( ReturnedSize); - RegQueryValueExW( RegHandle, ValueName, NULL, NULL, (PVOID)Name, - &ReturnedSize ); - return Name; - } + *Length = 0; + *RegistryType = REG_NONE; + + while (TRUE) + { + Error = RegQueryValueExW(RegHandle, ValueName, NULL, RegistryType, ReadValue, Length); + if (Error == ERROR_SUCCESS) + { + if (ReadValue) break; + } + else if (Error == ERROR_MORE_DATA) + { + HeapFree(GetProcessHeap(), 0, ReadValue); + } + else break; + + ReadValue = HeapAlloc(GetProcessHeap(), 0, *Length); + if (!ReadValue) return NULL; + } + + if (Error != ERROR_SUCCESS) + { + if (ReadValue) HeapFree(GetProcessHeap(), 0, ReadValue); + + *Length = 0; + *RegistryType = REG_NONE; + ReadValue = NULL; + } + + return ReadValue; +} + +PWCHAR TerminateReadString(PWCHAR String, DWORD Length) +{ + PWCHAR TerminatedString; + + TerminatedString = HeapAlloc(GetProcessHeap(), 0, Length + sizeof(WCHAR)); + if (TerminatedString == NULL) + return NULL; + + memcpy(TerminatedString, String, Length); + + TerminatedString[Length / sizeof(WCHAR)] = UNICODE_NULL; + + return TerminatedString; +} + +PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) +{ + PWCHAR String, TerminatedString; + DWORD Type, Length; + + String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length); + if (!String) return NULL; + if (Type != REG_SZ) + { + DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_SZ); + //HeapFree(GetProcessHeap(), 0, String); + //return NULL; + } + + TerminatedString = TerminateReadString(String, Length); + HeapFree(GetProcessHeap(), 0, String); + if (!TerminatedString) return NULL; + + return TerminatedString; } void ConsumeRegValueString( PWCHAR Value ) { - if (Value) free(Value); + if (Value) HeapFree(GetProcessHeap(), 0, Value); } PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ) { - return 0; /* FIXME if needed */ + PWCHAR String, TerminatedString, Tmp; + PWCHAR *Table; + DWORD Type, Length, i, j; + + String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length); + if (!String) return NULL; + if (Type != REG_MULTI_SZ) + { + DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_MULTI_SZ); + //HeapFree(GetProcessHeap(), 0, String); + //return NULL; + } + + TerminatedString = TerminateReadString(String, Length); + HeapFree(GetProcessHeap(), 0, String); + if (!TerminatedString) return NULL; + + for (Tmp = TerminatedString, i = 0; *Tmp; Tmp++, i++) while (*Tmp) Tmp++; + + Table = HeapAlloc(GetProcessHeap(), 0, (i + 1) * sizeof(PWCHAR)); + if (!Table) + { + HeapFree(GetProcessHeap(), 0, TerminatedString); + return NULL; + } + + for (Tmp = TerminatedString, j = 0; *Tmp; Tmp++, j++) + { + PWCHAR Orig = Tmp; + + for (i = 0; *Tmp; i++, Tmp++); + + Table[j] = HeapAlloc(GetProcessHeap(), 0, i * sizeof(WCHAR)); + memcpy(Table[j], Orig, i * sizeof(WCHAR)); + } + + Table[j] = NULL; + + HeapFree(GetProcessHeap(), 0, TerminatedString); + + return Table; } diff --git a/dll/win32/user32/windows/window.c b/dll/win32/user32/windows/window.c index 5f2826a0cdf..468536ee290 100644 --- a/dll/win32/user32/windows/window.c +++ b/dll/win32/user32/windows/window.c @@ -342,18 +342,6 @@ CreateWindowExA(DWORD dwExStyle, POINT mPos[2]; UINT id = 0; HWND top_child; - PWND WndParent; - PCLS pcls; - - if(!(WndParent = ValidateHwnd(hWndParent)) || - !(pcls = DesktopPtrToUser(WndParent->pcls))) - return 0; - - if (pcls->fnid != FNID_MDICLIENT) - { - ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent); - return 0; - } /* lpParams of WM_[NC]CREATE is different for MDI children. * MDICREATESTRUCT members have the originally passed values. @@ -466,24 +454,6 @@ CreateWindowExW(DWORD dwExStyle, POINT mPos[2]; UINT id = 0; HWND top_child; - PWND WndParent; - PCLS pcls; - - WndParent = ValidateHwnd(hWndParent); - - if(!WndParent) - return 0; - - pcls = DesktopPtrToUser(WndParent->pcls); - - if(!pcls) - return 0; - - if (pcls->fnid != FNID_MDICLIENT) - { - ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent); - return 0; - } /* lpParams of WM_[NC]CREATE is different for MDI children. * MDICREATESTRUCT members have the originally passed values. diff --git a/drivers/bus/acpi/busmgr/bus.c b/drivers/bus/acpi/busmgr/bus.c index 9860055873a..0c46bb8a339 100644 --- a/drivers/bus/acpi/busmgr/bus.c +++ b/drivers/bus/acpi/busmgr/bus.c @@ -463,8 +463,19 @@ acpi_bus_generate_event_dpc(PKDPC Dpc, PVOID SystemArgument1, PVOID SystemArgument2) { - struct acpi_bus_event *event = SystemArgument1; + struct acpi_bus_event *event; + struct acpi_device *device = SystemArgument1; + ULONG_PTR TypeData = (ULONG_PTR)SystemArgument2; KIRQL OldIrql; + + event = ExAllocatePool(NonPagedPool,sizeof(struct acpi_bus_event)); + if (!event) + return; + + sprintf(event->device_class, "%s", device->pnp.device_class); + sprintf(event->bus_id, "%s", device->pnp.bus_id); + event->type = (TypeData & 0xFF000000) >> 24; + event->data = (TypeData & 0x00FFFFFF); KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); list_add_tail(&event->node, &acpi_bus_event_list); @@ -479,7 +490,7 @@ acpi_bus_generate_event ( UINT8 type, int data) { - struct acpi_bus_event *event = NULL; + ULONG_PTR TypeData = 0; DPRINT("acpi_bus_generate_event"); @@ -489,18 +500,14 @@ acpi_bus_generate_event ( /* drop event on the floor if no one's listening */ if (!event_is_open) return_VALUE(0); + + /* Data shouldn't even get near 24 bits */ + ASSERT(!(data & 0xFF000000)); + + TypeData = data; + TypeData |= type << 24; - event = ExAllocatePool(NonPagedPool,sizeof(struct acpi_bus_event)); - if (!event) - return_VALUE(-4); - - sprintf(event->device_class, "%s", device->pnp.device_class); - sprintf(event->bus_id, "%s", device->pnp.bus_id); - event->type = type; - event->data = data; - - if (!KeInsertQueueDpc(&event_dpc, event, NULL)) - ExFreePool(event); + KeInsertQueueDpc(&event_dpc, device, (PVOID)TypeData); return_VALUE(0); } diff --git a/drivers/bus/acpi/buspdo.c b/drivers/bus/acpi/buspdo.c index d5129ffa5f5..7d167b7742c 100644 --- a/drivers/bus/acpi/buspdo.c +++ b/drivers/bus/acpi/buspdo.c @@ -727,6 +727,7 @@ Bus_PDO_QueryResources( case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: case ACPI_RESOURCE_TYPE_MEMORY24: case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: case ACPI_RESOURCE_TYPE_IO: { NumberOfResources++; @@ -1044,6 +1045,22 @@ Bus_PDO_QueryResources( ResourceDescriptor->u.Memory.Start.QuadPart = mem32_data->Minimum; ResourceDescriptor->u.Memory.Length = mem32_data->AddressLength; + ResourceDescriptor++; + break; + } + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + { + ACPI_RESOURCE_FIXED_MEMORY32 *memfixed32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data; + ResourceDescriptor->Type = CmResourceTypeMemory; + ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; + ResourceDescriptor->Flags = 0; + if (memfixed32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) + ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; + else + ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; + ResourceDescriptor->u.Memory.Start.QuadPart = memfixed32_data->Address; + ResourceDescriptor->u.Memory.Length = memfixed32_data->AddressLength; + ResourceDescriptor++; break; } @@ -1142,6 +1159,7 @@ Bus_PDO_QueryResourceRequirements( case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: case ACPI_RESOURCE_TYPE_MEMORY24: case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: case ACPI_RESOURCE_TYPE_IO: { NumberOfResources++; @@ -1479,6 +1497,24 @@ Bus_PDO_QueryResourceRequirements( RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem32_data->Maximum; RequirementDescriptor->u.Memory.Length = mem32_data->AddressLength; + RequirementDescriptor++; + break; + } + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + { + ACPI_RESOURCE_FIXED_MEMORY32 *fixedmem32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data; + RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; + RequirementDescriptor->Type = CmResourceTypeMemory; + RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; + RequirementDescriptor->Flags = 0; + if (fixedmem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) + RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; + else + RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; + RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = fixedmem32_data->Address; + RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = fixedmem32_data->Address; + RequirementDescriptor->u.Memory.Length = fixedmem32_data->AddressLength; + RequirementDescriptor++; break; } diff --git a/drivers/bus/pcix/debug.c b/drivers/bus/pcix/debug.c index f3a9930a880..8f1ed81616b 100644 --- a/drivers/bus/pcix/debug.c +++ b/drivers/bus/pcix/debug.c @@ -49,6 +49,26 @@ PCHAR PoCodes[] = "QUERY_POWER", }; +PCHAR SystemPowerStates[] = +{ + "Unspecified", + "Working", + "Sleeping1", + "Sleeping2", + "Sleeping3", + "Hibernate", + "Shutdown" +}; + +PCHAR DevicePowerStates[] = +{ + "Unspecified", + "D0", + "D1", + "D2", + "D3" +}; + ULONG PciBreakOnPdoPowerIrp, PciBreakOnFdoPowerIrp; ULONG PciBreakOnPdoPnpIrp, PciBreakOnFdoPnpIrp; @@ -194,4 +214,131 @@ PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData) } } +VOID +NTAPI +PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps) +{ + ULONG i; + + /* Dump the capabilities */ + DPRINT1("Capabilities\n Lock:%d, Eject:%d, Remove:%d, Dock:%d, UniqueId:%d\n", + DeviceCaps->LockSupported, + DeviceCaps->EjectSupported, + DeviceCaps->Removable, + DeviceCaps->DockDevice, + DeviceCaps->UniqueID); + DbgPrint(" SilentInstall:%d, RawOk:%d, SurpriseOk:%d\n", + DeviceCaps->SilentInstall, + DeviceCaps->RawDeviceOK, + DeviceCaps->SurpriseRemovalOK); + DbgPrint(" Address %08x, UINumber %08x, Latencies D1 %d, D2 %d, D3 %d\n", + DeviceCaps->Address, + DeviceCaps->UINumber, + DeviceCaps->D1Latency, + DeviceCaps->D2Latency, + DeviceCaps->D3Latency); + + /* Dump and convert the wake levels */ + DbgPrint(" System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [", + SystemPowerStates[min(DeviceCaps->SystemWake, PowerSystemMaximum)], + DevicePowerStates[min(DeviceCaps->DeviceWake, PowerDeviceMaximum)]); + + /* Dump and convert the power state mappings */ + for (i = PowerSystemWorking; i < PowerSystemMaximum; i++) + DbgPrint(" %s", DevicePowerStates[DeviceCaps->DeviceState[i]]); + + /* Finish the dump */ + DbgPrint(" ]\n"); +} + +PCHAR +NTAPI +PciDebugCmResourceTypeToText(IN UCHAR Type) +{ + /* What kind of resource it this? */ + switch (Type) + { + /* Pick the correct identifier string based on the type */ + case CmResourceTypeDeviceSpecific: return "CmResourceTypeDeviceSpecific"; + case CmResourceTypePort: return "CmResourceTypePort"; + case CmResourceTypeInterrupt: return "CmResourceTypeInterrupt"; + case CmResourceTypeMemory: return "CmResourceTypeMemory"; + case CmResourceTypeDma: return "CmResourceTypeDma"; + case CmResourceTypeBusNumber: return "CmResourceTypeBusNumber"; + case CmResourceTypeConfigData: return "CmResourceTypeConfigData"; + case CmResourceTypeDevicePrivate: return "CmResourceTypeDevicePrivate"; + case CmResourceTypePcCardConfig: return "CmResourceTypePcCardConfig"; + default: return "*** INVALID RESOURCE TYPE ***"; + } +} + +VOID +NTAPI +PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor) +{ + ULONG i; + PULONG Data; + + /* Print out the header */ + DPRINT1(" IoResource Descriptor dump: Descriptor @0x%x\n", Descriptor); + DPRINT1(" Option = 0x%x\n", Descriptor->Option); + DPRINT1(" Type = %d (%s)\n", Descriptor->Type, PciDebugCmResourceTypeToText(Descriptor->Type)); + DPRINT1(" ShareDisposition = %d\n", Descriptor->ShareDisposition); + DPRINT1(" Flags = 0x%04X\n", Descriptor->Flags); + + /* Loop private data */ + Data = (PULONG)&Descriptor->u.DevicePrivate; + for (i = 0; i < 6; i += 3) + { + /* Dump it in 32-bit triplets */ + DPRINT1(" Data[%d] = %08x %08x %08x\n", i, Data[0], Data[1], Data[2]); + } +} + +VOID +NTAPI +PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements) +{ + ULONG AlternativeLists; + PIO_RESOURCE_LIST List; + ULONG Count; + PIO_RESOURCE_DESCRIPTOR Descriptor; + + /* Make sure there's a list */ + if (!Requirements) return; + + /* Grab the main list and the alternates as well */ + AlternativeLists = Requirements->AlternativeLists; + List = Requirements->List; + + /* Print out the initial header*/ + DPRINT1(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n"); + DPRINT1(" InterfaceType %d\n", Requirements->InterfaceType); + DPRINT1(" BusNumber 0x%x\n", Requirements->BusNumber); + DPRINT1(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n", + Requirements->SlotNumber, + Requirements->SlotNumber, + ((PCI_SLOT_NUMBER*)&Requirements->SlotNumber)->u.bits.DeviceNumber, + ((PCI_SLOT_NUMBER*)&Requirements->SlotNumber)->u.bits.FunctionNumber); + DPRINT1(" AlternativeLists %d\n", AlternativeLists); + + /* Scan alternative lists */ + while (AlternativeLists--) + { + /* Get the descriptor array, and the count of descriptors */ + Descriptor = List->Descriptors; + Count = List->Count; + + /* Print out each descriptor */ + DPRINT1("\n List[%d].Count = %d\n", AlternativeLists, Count); + while (Count--) PciDebugPrintIoResource(Descriptor++); + + /* Should've reached a new list now */ + List = (PIO_RESOURCE_LIST)Descriptor; + } + + /* Terminate the dump */ + DPRINT1("\n"); +} + /* EOF */ diff --git a/drivers/bus/pcix/enum.c b/drivers/bus/pcix/enum.c index a4d53dd9fec..4e17a7f700a 100644 --- a/drivers/bus/pcix/enum.c +++ b/drivers/bus/pcix/enum.c @@ -14,6 +14,8 @@ /* GLOBALS ********************************************************************/ +PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements; + PCI_CONFIGURATOR PciConfigurators[] = { { @@ -47,6 +49,345 @@ PCI_CONFIGURATOR PciConfigurators[] = /* FUNCTIONS ******************************************************************/ +PIO_RESOURCE_REQUIREMENTS_LIST +NTAPI +PciAllocateIoRequirementsList(IN ULONG Count, + IN ULONG BusNumber, + IN ULONG SlotNumber) +{ + SIZE_T Size; + PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; + + /* Calculate the final size of the list, including each descriptor */ + Size = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); + if (Count > 1) Size = sizeof(IO_RESOURCE_DESCRIPTOR) * (Count - 1) + + sizeof(IO_RESOURCE_REQUIREMENTS_LIST); + + /* Allocate the list */ + RequirementsList = ExAllocatePoolWithTag(PagedPool, Size, 'BicP'); + if (!RequirementsList) return NULL; + + /* Initialize it */ + RtlZeroMemory(RequirementsList, Size); + RequirementsList->AlternativeLists = 1; + RequirementsList->BusNumber = BusNumber; + RequirementsList->SlotNumber = SlotNumber; + RequirementsList->InterfaceType = PCIBus; + RequirementsList->ListSize = Size; + RequirementsList->List[0].Count = Count; + RequirementsList->List[0].Version = 1; + RequirementsList->List[0].Revision = 1; + + /* Return it */ + return RequirementsList; +} + +PCM_RESOURCE_LIST +NTAPI +PciAllocateCmResourceList(IN ULONG Count, + IN ULONG BusNumber) +{ + SIZE_T Size; + PCM_RESOURCE_LIST ResourceList; + + /* Calculate the final size of the list, including each descriptor */ + Size = sizeof(CM_RESOURCE_LIST); + if (Count > 1) Size = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count - 1) + + sizeof(CM_RESOURCE_LIST); + + /* Allocate the list */ + ResourceList = ExAllocatePoolWithTag(PagedPool, Size, 'BicP'); + if (!ResourceList) return NULL; + + /* Initialize it */ + RtlZeroMemory(ResourceList, Size); + ResourceList->Count = 1; + ResourceList->List[0].BusNumber = BusNumber; + ResourceList->List[0].InterfaceType = PCIBus; + ResourceList->List[0].PartialResourceList.Version = 1; + ResourceList->List[0].PartialResourceList.Revision = 1; + ResourceList->List[0].PartialResourceList.Count = Count; + + /* Return it */ + return ResourceList; +} + +NTSTATUS +NTAPI +PciQueryResources(IN PPCI_PDO_EXTENSION PdoExtension, + OUT PCM_RESOURCE_LIST *Buffer) +{ + PPCI_FUNCTION_RESOURCES PciResources; + BOOLEAN HaveVga, HaveMemSpace, HaveIoSpace; + USHORT BridgeControl, PciCommand; + ULONG Count, i; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, Resource, LastResource; + PCM_RESOURCE_LIST ResourceList; + UCHAR InterruptLine; + PAGED_CODE(); + + /* Assume failure */ + Count = 0; + HaveVga = FALSE; + *Buffer = NULL; + + /* Make sure there's some resources to query */ + PciResources = PdoExtension->Resources; + if (!PciResources) return STATUS_SUCCESS; + + /* Read the decodes */ + PciReadDeviceConfig(PdoExtension, + &PciCommand, + FIELD_OFFSET(PCI_COMMON_HEADER, Command), + sizeof(USHORT)); + + /* Check which ones are turned on */ + HaveIoSpace = PciCommand & PCI_ENABLE_IO_SPACE; + HaveMemSpace = PciCommand & PCI_ENABLE_MEMORY_SPACE; + + /* Loop maximum possible descriptors */ + for (i = 0; i < 7; i++) + { + /* Check if the decode for this descriptor is actually turned on */ + Partial = &PciResources->Current[i]; + if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) || + ((HaveIoSpace) && (Partial->Type == CmResourceTypePort))) + { + /* One more fully active descriptor */ + Count++; + } + } + + /* If there's an interrupt pin associated, check at least one decode is on */ + if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace))) + { + /* Read the interrupt line for the pin, add a descriptor if it's valid */ + InterruptLine = PdoExtension->AdjustedInterruptLine; + if ((InterruptLine) && (InterruptLine != -1)) Count++; + } + + /* Check for PCI bridge */ + if (PdoExtension->HeaderType == PCI_BRIDGE_TYPE) + { + /* Read bridge settings, check if VGA is present */ + PciReadDeviceConfig(PdoExtension, + &BridgeControl, + FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.BridgeControl), + sizeof(USHORT)); + if (BridgeControl & PCI_ENABLE_BRIDGE_VGA) + { + /* Remember for later */ + HaveVga = TRUE; + + /* One memory descriptor for 0xA0000, plus the two I/O port ranges */ + if (HaveMemSpace) Count++; + if (HaveIoSpace) Count += 2; + } + } + + /* If there's no descriptors in use, there's no resources, so return */ + if (!Count) return STATUS_SUCCESS; + + /* Allocate a resource list to hold the resources */ + ResourceList = PciAllocateCmResourceList(Count, + PdoExtension->ParentFdoExtension->BaseBus); + if (!ResourceList) return STATUS_INSUFFICIENT_RESOURCES; + + /* This is where the descriptors will be copied into */ + Resource = ResourceList->List[0].PartialResourceList.PartialDescriptors; + LastResource = Resource + Count + 1; + + /* Loop maximum possible descriptors */ + for (i = 0; i < 7; i++) + { + /* Check if the decode for this descriptor is actually turned on */ + Partial = &PciResources->Current[i]; + if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) || + ((HaveIoSpace) && (Partial->Type == CmResourceTypePort))) + { + /* Copy the descriptor into the resource list */ + *Resource++ = *Partial; + } + } + + /* Check if earlier the code detected this was a PCI bridge with VGA on it */ + if (HaveVga) + { + /* Are the memory decodes enabled? */ + if (HaveMemSpace) + { + /* Build a memory descriptor for a 128KB framebuffer at 0xA0000 */ + Resource->Flags = CM_RESOURCE_MEMORY_READ_WRITE; + Resource->u.Generic.Start.HighPart = 0; + Resource->Type = CmResourceTypeMemory; + Resource->u.Generic.Start.LowPart = 0xA0000; + Resource->u.Generic.Length = 0x20000; + Resource++; + } + + /* Are the I/O decodes enabled? */ + if (HaveIoSpace) + { + /* Build an I/O descriptor for the graphic ports at 0x3B0 */ + Resource->Type = CmResourceTypePort; + Resource->Flags = CM_RESOURCE_PORT_POSITIVE_DECODE | CM_RESOURCE_PORT_10_BIT_DECODE; + Resource->u.Port.Start.QuadPart = 0x3B0u; + Resource->u.Port.Length = 0xC; + Resource++; + + /* Build an I/O descriptor for the graphic ports at 0x3C0 */ + Resource->Type = CmResourceTypePort; + Resource->Flags = CM_RESOURCE_PORT_POSITIVE_DECODE | CM_RESOURCE_PORT_10_BIT_DECODE; + Resource->u.Port.Start.QuadPart = 0x3C0u; + Resource->u.Port.Length = 0x20; + Resource++; + } + } + + /* If there's an interrupt pin associated, check at least one decode is on */ + if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace))) + { + /* Read the interrupt line for the pin, check if it's valid */ + InterruptLine = PdoExtension->AdjustedInterruptLine; + if ((InterruptLine) && (InterruptLine != -1)) + { + /* Make sure there's still space */ + ASSERT(Resource < LastResource); + + /* Add the interrupt descriptor */ + Resource->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + Resource->Type = CmResourceTypeInterrupt; + Resource->ShareDisposition = CmResourceShareShared; + Resource->u.Interrupt.Affinity = -1; + Resource->u.Interrupt.Level = InterruptLine; + Resource->u.Interrupt.Vector = InterruptLine; + } + } + + /* Return the resouce list */ + *Buffer = ResourceList; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PciQueryTargetDeviceRelations(IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_RELATIONS *pDeviceRelations) +{ + PDEVICE_RELATIONS DeviceRelations; + PAGED_CODE(); + + /* If there were existing relations, free them */ + if (*pDeviceRelations) ExFreePoolWithTag(*pDeviceRelations, 0); + + /* Allocate a new structure for the relations */ + DeviceRelations = ExAllocatePoolWithTag(NonPagedPool, + sizeof(DEVICE_RELATIONS), + 'BicP'); + if (!DeviceRelations) return STATUS_INSUFFICIENT_RESOURCES; + + /* Only one relation: the PDO */ + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = PdoExtension->PhysicalDeviceObject; + ObReferenceObject(DeviceRelations->Objects[0]); + + /* Return the new relations */ + *pDeviceRelations = DeviceRelations; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PciQueryEjectionRelations(IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_RELATIONS *pDeviceRelations) +{ + /* Not yet implemented */ + UNIMPLEMENTED; + while (TRUE); +} + +NTSTATUS +NTAPI +PciBuildRequirementsList(IN PPCI_PDO_EXTENSION PdoExtension, + IN PPCI_COMMON_HEADER PciData, + OUT PIO_RESOURCE_REQUIREMENTS_LIST* Buffer) +{ + PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; + { + /* There aren't, so use the zero descriptor */ + RequirementsList = PciZeroIoResourceRequirements; + + /* Does it actually exist yet? */ + if (!PciZeroIoResourceRequirements) + { + /* Allocate it, and use it for future use */ + RequirementsList = PciAllocateIoRequirementsList(0, 0, 0); + PciZeroIoResourceRequirements = RequirementsList; + if (!PciZeroIoResourceRequirements) return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Return the zero requirements list to the caller */ + *Buffer = RequirementsList; + DPRINT1("PCI - build resource reqs - early out, 0 resources\n"); + return STATUS_SUCCESS; + } + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PciQueryRequirements(IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList) +{ + NTSTATUS Status; + PCI_COMMON_HEADER PciHeader; + PAGED_CODE(); + + /* Check if the PDO has any resources, or at least an interrupt pin */ + if ((PdoExtension->Resources) || (PdoExtension->InterruptPin)) + { + /* Read the current PCI header */ + PciReadDeviceConfig(PdoExtension, &PciHeader, 0, PCI_COMMON_HDR_LENGTH); + + /* Use it to build a list of requirements */ + Status = PciBuildRequirementsList(PdoExtension, &PciHeader, RequirementsList); + if (!NT_SUCCESS(Status)) return Status; + + /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */ + if ((PciHeader.VendorID == 0xE11) && + (PciHeader.DeviceID == 0xA0F7) && + (PciHeader.RevisionID == 17) && + (ExIsProcessorFeaturePresent(PF_PAE_ENABLED))) + { + /* Have not tested this on eVb's machine yet */ + UNIMPLEMENTED; + while (TRUE); + } + + /* Check if the requirements are actually the zero list */ + if (*RequirementsList == PciZeroIoResourceRequirements) + { + /* A simple NULL will sufficie for the PnP Manager */ + *RequirementsList = NULL; + DPRINT1("Returning NULL requirements list\n"); + } + else + { + /* Otherwise, print out the requirements list */ + PciDebugPrintIoResReqList(*RequirementsList); + } + } + else + { + /* There aren't any resources, so simply return NULL */ + DPRINT1("PciQueryRequirements returning NULL requirements list\n"); + *RequirementsList = NULL; + } + + /* This call always succeeds (but maybe with no requirements) */ + return STATUS_SUCCESS; +} + /* * 7. The IO/MEM/Busmaster decodes are disabled for the device. * 8. The PCI bus driver sets the operating mode bits of the Programming diff --git a/drivers/bus/pcix/fdo.c b/drivers/bus/pcix/fdo.c index 256df1a3f4d..bfad380aca4 100644 --- a/drivers/bus/pcix/fdo.c +++ b/drivers/bus/pcix/fdo.c @@ -295,9 +295,23 @@ PciFdoIrpQueryCapabilities(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PDEVICE_CAPABILITIES Capabilities; + PAGED_CODE(); + ASSERT_FDO(DeviceExtension); + + /* Get the capabilities */ + Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities; + + /* Inherit wake levels and power mappings from the higher-up capabilities */ + DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake; + DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake; + RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping, + Capabilities->DeviceState, + sizeof(DeviceExtension->PowerState.SystemStateMapping)); + + /* Dump the capabilities and return success */ + PciDebugDumpQueryCapabilities(Capabilities); + return STATUS_SUCCESS; } NTSTATUS diff --git a/drivers/bus/pcix/pci.h b/drivers/bus/pcix/pci.h index 93a5f140276..866784ac87f 100644 --- a/drivers/bus/pcix/pci.h +++ b/drivers/bus/pcix/pci.h @@ -79,6 +79,11 @@ // #define PCI_VERIFIER_CODES 0x04 +// +// PCI ID Buffer ANSI Strings +// +#define MAX_ANSI_STRINGS 0x08 + // // Device Extension, Interface, Translator and Arbiter Signatures // @@ -410,6 +415,19 @@ typedef struct _PCI_VERIFIER_DATA PCHAR DebuggerMessageText; } PCI_VERIFIER_DATA, *PPCI_VERIFIER_DATA; +// +// PCI ID Buffer Descriptor +// +typedef struct _PCI_ID_BUFFER +{ + ULONG Count; + ANSI_STRING Strings[MAX_ANSI_STRINGS]; + ULONG StringSize[MAX_ANSI_STRINGS]; + ULONG TotalLength; + PCHAR CharBuffer; + CHAR BufferData[256]; +} PCI_ID_BUFFER, *PPCI_ID_BUFFER; + // // PCI Configuration Callbacks // @@ -1111,6 +1129,20 @@ PciDecodeEnable( OUT PUSHORT Command ); +NTSTATUS +NTAPI +PciQueryBusInformation( + IN PPCI_PDO_EXTENSION PdoExtension, + IN PPNP_BUS_INFORMATION* Buffer +); + +NTSTATUS +NTAPI +PciQueryCapabilities( + IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_CAPABILITIES DeviceCapability +); + // // Configuration Routines // @@ -1217,6 +1249,18 @@ PciDebugDumpCommonConfig( IN PPCI_COMMON_HEADER PciData ); +VOID +NTAPI +PciDebugDumpQueryCapabilities( + IN PDEVICE_CAPABILITIES DeviceCaps +); + +VOID +NTAPI +PciDebugPrintIoResReqList( + IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements +); + // // Interface Support // @@ -1452,6 +1496,34 @@ PciQueryDeviceRelations( IN OUT PDEVICE_RELATIONS *pDeviceRelations ); +NTSTATUS +NTAPI +PciQueryResources( + IN PPCI_PDO_EXTENSION PdoExtension, + OUT PCM_RESOURCE_LIST *Buffer +); + +NTSTATUS +NTAPI +PciQueryTargetDeviceRelations( + IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_RELATIONS *pDeviceRelations +); + +NTSTATUS +NTAPI +PciQueryEjectionRelations( + IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_RELATIONS *pDeviceRelations +); + +NTSTATUS +NTAPI +PciQueryRequirements( + IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList +); + // // Identification Functions // @@ -1462,6 +1534,23 @@ PciGetDeviceDescriptionMessage( IN UCHAR SubClass ); +NTSTATUS +NTAPI +PciQueryDeviceText( + IN PPCI_PDO_EXTENSION PdoExtension, + IN DEVICE_TEXT_TYPE QueryType, + IN ULONG Locale, + OUT PWCHAR *Buffer +); + +NTSTATUS +NTAPI +PciQueryId( + IN PPCI_PDO_EXTENSION DeviceExtension, + IN BUS_QUERY_ID_TYPE QueryType, + OUT PWCHAR *Buffer +); + // // CardBUS Support // @@ -1627,6 +1716,8 @@ extern PWATCHDOG_TABLE WdTable; extern PPCI_HACK_ENTRY PciHackTable; extern BOOLEAN PciAssignBusNumbers; extern BOOLEAN PciEnableNativeModeATA; +extern PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable; +extern BOOLEAN PciRunningDatacenter; /* Exported by NTOS, should this go in the NDK? */ extern NTSYSAPI BOOLEAN InitSafeBootMode; diff --git a/drivers/bus/pcix/pci/id.c b/drivers/bus/pcix/pci/id.c index c1d711b086f..9db7d703fb0 100644 --- a/drivers/bus/pcix/pci/id.c +++ b/drivers/bus/pcix/pci/id.c @@ -11,6 +11,7 @@ #include #define NDEBUG #include +#include "stdio.h" /* GLOBALS ********************************************************************/ @@ -107,4 +108,354 @@ PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, return Message; } +VOID +NTAPI +PciInitIdBuffer(IN PPCI_ID_BUFFER IdBuffer) +{ + /* Initialize the sizes to zero and the pointer to the start of the buffer */ + IdBuffer->TotalLength = 0; + IdBuffer->Count = 0; + IdBuffer->CharBuffer = IdBuffer->BufferData; +} + +ULONG +NTAPI +PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer, + IN PCCH Format, + ...) +{ + ULONG Size, Length; + PANSI_STRING AnsiString; + va_list va; + va_start(va, Format); + ASSERT(IdBuffer->Count < MAX_ANSI_STRINGS); + + /* Do the actual string formatting into the character buffer */ + vsprintf(IdBuffer->CharBuffer, Format, va); + + /* Initialize the ANSI_STRING that will hold this string buffer */ + AnsiString = &IdBuffer->Strings[IdBuffer->Count]; + RtlInitAnsiString(AnsiString, IdBuffer->CharBuffer); + + /* Calculate the final size of the string, in Unicode */ + Size = RtlAnsiStringToUnicodeSize(AnsiString); + + /* Update hte buffer with the size,and update the character pointer */ + IdBuffer->StringSize[IdBuffer->Count] = Size; + IdBuffer->TotalLength += Size; + Length = AnsiString->Length + sizeof(ANSI_NULL); + IdBuffer->CharBuffer += Length; + + /* Move to the next string for next time */ + IdBuffer->Count++; + + /* Return the length */ + return Length; +} + +ULONG +NTAPI +PciIdPrintfAppend(IN PPCI_ID_BUFFER IdBuffer, + IN PCCH Format, + ...) +{ + ULONG NextId, Size, Length, MaxLength; + PANSI_STRING AnsiString; + va_list va; + va_start(va, Format); + ASSERT(IdBuffer->Count); + + /* Choose the next static ANSI_STRING to use */ + NextId = IdBuffer->Count - 1; + + /* Max length is from the end of the buffer up until the current pointer */ + MaxLength = (PCHAR)(IdBuffer + 1) - IdBuffer->CharBuffer; + + /* Do the actual append, and return the length this string took */ + Length = vsprintf(IdBuffer->CharBuffer - 1, Format, va); + ASSERT(Length < MaxLength); + + /* Select the static ANSI_STRING, and update its length information */ + AnsiString = &IdBuffer->Strings[NextId]; + AnsiString->Length += Length; + AnsiString->MaximumLength += Length; + + /* Calculate the final size of the string, in Unicode */ + Size = RtlAnsiStringToUnicodeSize(AnsiString); + + /* Update the buffer with the size, and update the character pointer */ + IdBuffer->StringSize[NextId] = Size; + IdBuffer->TotalLength += Size; + IdBuffer->CharBuffer += Length; + + /* Return the size */ + return Size; +} + +NTSTATUS +NTAPI +PciQueryId(IN PPCI_PDO_EXTENSION DeviceExtension, + IN BUS_QUERY_ID_TYPE QueryType, + OUT PWCHAR *Buffer) +{ + ULONG SubsysId; + CHAR VendorString[22]; + PPCI_PDO_EXTENSION PdoExtension; + PPCI_FDO_EXTENSION ParentExtension; + PWCHAR StringBuffer; + ULONG i, Size; + NTSTATUS Status; + PANSI_STRING NextString; + UNICODE_STRING DestinationString; + PCI_ID_BUFFER IdBuffer; + PAGED_CODE(); + + /* Assume failure */ + Status = STATUS_SUCCESS; + *Buffer = NULL; + + /* Start with the genric vendor string, which is the vendor ID + device ID */ + sprintf(VendorString, + "PCI\\VEN_%04X&DEV_%04X", + DeviceExtension->VendorId, + DeviceExtension->DeviceId); + + /* Initialize the PCI ID Buffer */ + PciInitIdBuffer(&IdBuffer); + + /* Build the subsystem ID as shown in PCI ID Strings */ + SubsysId = DeviceExtension->SubsystemVendorId | (DeviceExtension->SubsystemId << 16); + + /* Check what the caller is requesting */ + switch (QueryType) + { + case BusQueryDeviceID: + + /* A single ID, the vendor string + the revision ID */ + PciIdPrintf(&IdBuffer, + "%s&SUBSYS_%08X&REV_%02X", + VendorString, + SubsysId, + DeviceExtension->RevisionId); + break; + + case BusQueryHardwareIDs: + + /* First the vendor string + the subsystem ID + the revision ID */ + PciIdPrintf(&IdBuffer, + "%s&SUBSYS_%08X&REV_%02X", + VendorString, + SubsysId, + DeviceExtension->RevisionId); + + /* Next, without the revision */ + PciIdPrintf(&IdBuffer, + "%s&SUBSYS_%08X", + VendorString, + SubsysId); + + /* Next, the vendor string + the base class + sub class + progif */ + PciIdPrintf(&IdBuffer, + "%s&CC_%02X%02X%02X", + VendorString, + DeviceExtension->BaseClass, + DeviceExtension->SubClass, + DeviceExtension->ProgIf); + + /* Next, without the progif */ + PciIdPrintf(&IdBuffer, + "%s&CC_%02X%02X", + VendorString, + DeviceExtension->BaseClass, + DeviceExtension->SubClass); + + /* And finally, a terminator */ + PciIdPrintf(&IdBuffer, "\0"); + break; + + case BusQueryCompatibleIDs: + + /* First, the vendor + revision ID only */ + PciIdPrintf(&IdBuffer, + "%s&REV_%02X", + VendorString, + DeviceExtension->RevisionId); + + /* Next, the vendor string alone */ + PciIdPrintf(&IdBuffer, "%s", VendorString); + + /* Next, the vendor ID + the base class + the sub class + progif */ + PciIdPrintf(&IdBuffer, + "PCI\\VEN_%04X&CC_%02X%02X%02X", + DeviceExtension->VendorId, + DeviceExtension->BaseClass, + DeviceExtension->SubClass, + DeviceExtension->ProgIf); + + /* Now without the progif */ + PciIdPrintf(&IdBuffer, + "PCI\\VEN_%04X&CC_%02X%02X", + DeviceExtension->VendorId, + DeviceExtension->BaseClass, + DeviceExtension->SubClass); + + /* And then just the vendor ID itself */ + PciIdPrintf(&IdBuffer, + "PCI\\VEN_%04X", + DeviceExtension->VendorId); + + /* Then the base class + subclass + progif, without any vendor */ + PciIdPrintf(&IdBuffer, + "PCI\\CC_%02X%02X%02X", + DeviceExtension->BaseClass, + DeviceExtension->SubClass, + DeviceExtension->ProgIf); + + /* Next, without the progif */ + PciIdPrintf(&IdBuffer, + "PCI\\CC_%02X%02X", + DeviceExtension->BaseClass, + DeviceExtension->SubClass); + + /* And finally, a terminator */ + PciIdPrintf(&IdBuffer, "\0"); + break; + + case BusQueryInstanceID: + + /* Start with a terminator */ + PciIdPrintf(&IdBuffer, "\0"); + + /* And then encode the device and function number */ + PciIdPrintfAppend(&IdBuffer, + "%02X", + (DeviceExtension->Slot.u.bits.DeviceNumber << 3) | + DeviceExtension->Slot.u.bits.FunctionNumber); + + /* Loop every parent until the root */ + ParentExtension = DeviceExtension->ParentFdoExtension; + while (!PCI_IS_ROOT_FDO(ParentExtension)) + { + /* And encode the parent's device and function number as well */ + PdoExtension = ParentExtension->PhysicalDeviceObject->DeviceExtension; + PciIdPrintfAppend(&IdBuffer, + "%02X", + (PdoExtension->Slot.u.bits.DeviceNumber << 3) | + PdoExtension->Slot.u.bits.FunctionNumber); + } + break; + + default: + + /* Unknown query type */ + DPRINT1("PciQueryId expected ID type = %d\n", QueryType); + return STATUS_NOT_SUPPORTED; + } + + /* Something should've been generated if this has been reached */ + ASSERT(IdBuffer.Count > 0); + + /* Allocate the final string buffer to hold the ID */ + StringBuffer = ExAllocatePoolWithTag(PagedPool, IdBuffer.TotalLength, 'BicP'); + if (!StringBuffer) return STATUS_INSUFFICIENT_RESOURCES; + + /* Build the UNICODE_STRING structure for it */ + DPRINT1("PciQueryId(%d)\n", QueryType); + DestinationString.Buffer = StringBuffer; + DestinationString.MaximumLength = IdBuffer.TotalLength; + + /* Loop every ID in the buffer */ + for (i = 0; i < IdBuffer.Count; i++) + { + /* Select the ANSI_STRING for the ID */ + NextString = &IdBuffer.Strings[i]; + DPRINT1(" <- \"%s\"\n", NextString->Buffer); + + /* Convert it to a UNICODE_STRING */ + Status = RtlAnsiStringToUnicodeString(&DestinationString, NextString, FALSE); + ASSERT(NT_SUCCESS(Status)); + + /* Add it into the final destination buffer */ + Size = IdBuffer.StringSize[i]; + DestinationString.MaximumLength -= Size; + DestinationString.Buffer += (Size / sizeof(WCHAR)); + } + + /* Return the buffer to the caller and return status (should be success) */ + *Buffer = StringBuffer; + return Status; +} + +NTSTATUS +NTAPI +PciQueryDeviceText(IN PPCI_PDO_EXTENSION PdoExtension, + IN DEVICE_TEXT_TYPE QueryType, + IN ULONG Locale, + OUT PWCHAR *Buffer) +{ + PWCHAR MessageBuffer, LocationBuffer; + ULONG Length; + NTSTATUS Status; + + /* Check what the caller is requesting */ + switch (QueryType) + { + case DeviceTextDescription: + + /* Get the message from the resource section */ + MessageBuffer = PciGetDeviceDescriptionMessage(PdoExtension->BaseClass, + PdoExtension->SubClass); + + /* Return it to the caller, and select proper status code */ + *Buffer = MessageBuffer; + Status = MessageBuffer ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED; + break; + + case DeviceTextLocationInformation: + + /* Get the message from the resource section */ + MessageBuffer = PciGetDescriptionMessage(0x10000, &Length); + if (!MessageBuffer) + { + /* It should be there, but fail if it wasn't found for some reason */ + Status = STATUS_NOT_SUPPORTED; + break; + } + + /* Add space for a null-terminator, and allocate the buffer */ + Length += 2 * sizeof(UNICODE_NULL); + LocationBuffer = ExAllocatePoolWithTag(PagedPool, + Length * sizeof(WCHAR), + 'BicP'); + *Buffer = LocationBuffer; + + /* Check if the allocation succeeded */ + if (LocationBuffer) + { + /* Build the location string based on bus, function, and device */ + swprintf(LocationBuffer, + MessageBuffer, + PdoExtension->ParentFdoExtension->BaseBus, + PdoExtension->Slot.u.bits.FunctionNumber, + PdoExtension->Slot.u.bits.DeviceNumber); + } + + /* Free the original string from the resource section */ + ExFreePoolWithTag(MessageBuffer, 0); + + /* Select the correct status */ + Status = LocationBuffer ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; + break; + + default: + + /* Anything else is unsupported */ + Status = STATUS_NOT_SUPPORTED; + break; + } + + /* Return whether or not a device text string was indeed found */ + return Status; +} + /* EOF */ diff --git a/drivers/bus/pcix/pdo.c b/drivers/bus/pcix/pdo.c index 2e2bd57bc1f..8ed578c1251 100644 --- a/drivers/bus/pcix/pdo.c +++ b/drivers/bus/pcix/pdo.c @@ -200,9 +200,32 @@ PciPdoIrpQueryDeviceRelations(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + NTSTATUS Status; + PAGED_CODE(); + + /* Are ejection relations being queried? */ + if (IoStackLocation->Parameters.QueryDeviceRelations.Type == EjectionRelations) + { + /* Call the worker function */ + Status = PciQueryEjectionRelations(DeviceExtension, + (PDEVICE_RELATIONS*)&Irp-> + IoStatus.Information); + } + else if (IoStackLocation->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) + { + /* The only other relation supported is the target device relation */ + Status = PciQueryTargetDeviceRelations(DeviceExtension, + (PDEVICE_RELATIONS*)&Irp-> + IoStatus.Information); + } + else + { + /* All other relations are unsupported */ + Status = STATUS_NOT_SUPPORTED; + } + + /* Return either the result of the worker function, or unsupported status */ + return Status; } NTSTATUS @@ -211,9 +234,12 @@ PciPdoIrpQueryCapabilities(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryCapabilities(DeviceExtension, + IoStackLocation-> + Parameters.DeviceCapabilities.Capabilities); } NTSTATUS @@ -222,9 +248,11 @@ PciPdoIrpQueryResources(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryResources(DeviceExtension, + (PCM_RESOURCE_LIST*)&Irp->IoStatus.Information); } NTSTATUS @@ -233,9 +261,12 @@ PciPdoIrpQueryResourceRequirements(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryRequirements(DeviceExtension, + (PIO_RESOURCE_REQUIREMENTS_LIST*)&Irp-> + IoStatus.Information); } NTSTATUS @@ -244,9 +275,15 @@ PciPdoIrpQueryDeviceText(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryDeviceText(DeviceExtension, + IoStackLocation-> + Parameters.QueryDeviceText.DeviceTextType, + IoStackLocation-> + Parameters.QueryDeviceText.LocaleId, + (PWCHAR*)&Irp->IoStatus.Information); } NTSTATUS @@ -255,9 +292,12 @@ PciPdoIrpQueryId(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryId(DeviceExtension, + IoStackLocation->Parameters.QueryId.IdType, + (PWCHAR*)&Irp->IoStatus.Information); } NTSTATUS @@ -266,9 +306,12 @@ PciPdoIrpQueryBusInformation(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PAGED_CODE(); + + /* Call the worker function */ + return PciQueryBusInformation(DeviceExtension, + (PPNP_BUS_INFORMATION*)&Irp-> + IoStatus.Information); } NTSTATUS diff --git a/drivers/bus/pcix/utils.c b/drivers/bus/pcix/utils.c index f450a261a74..031b732c669 100644 --- a/drivers/bus/pcix/utils.c +++ b/drivers/bus/pcix/utils.c @@ -1306,4 +1306,455 @@ PciDecodeEnable(IN PPCI_PDO_EXTENSION PdoExtension, } } +NTSTATUS +NTAPI +PciQueryBusInformation(IN PPCI_PDO_EXTENSION PdoExtension, + IN PPNP_BUS_INFORMATION* Buffer) +{ + PPNP_BUS_INFORMATION BusInfo; + + /* Allocate a structure for the bus information */ + BusInfo = ExAllocatePoolWithTag(PagedPool, + sizeof(PNP_BUS_INFORMATION), + 'BicP'); + if (!BusInfo) return STATUS_INSUFFICIENT_RESOURCES; + + /* Write the correct GUID and bus type identifier, and fill the bus number */ + BusInfo->BusTypeGuid = GUID_BUS_TYPE_PCI; + BusInfo->LegacyBusType = PCIBus; + BusInfo->BusNumber = PdoExtension->ParentFdoExtension->BaseBus; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PciDetermineSlotNumber(IN PPCI_PDO_EXTENSION PdoExtension, + OUT PULONG SlotNumber) +{ + PPCI_FDO_EXTENSION ParentExtension; + ULONG ResultLength; + NTSTATUS Status; + PSLOT_INFO SlotInfo; + + /* Check if a $PIR from the BIOS is used (legacy IRQ routing) */ + ParentExtension = PdoExtension->ParentFdoExtension; + DPRINT1("Slot lookup for %d.%d.%d\n", + ParentExtension ? ParentExtension->BaseBus : -1, + PdoExtension->Slot.u.bits.DeviceNumber, + PdoExtension->Slot.u.bits.FunctionNumber); + if ((PciIrqRoutingTable) && (ParentExtension)) + { + /* Read every slot information entry */ + SlotInfo = &PciIrqRoutingTable->Slot[0]; + DPRINT1("PIR$ %p is %lx bytes, slot 0 is at: %lx\n", + PciIrqRoutingTable, PciIrqRoutingTable->TableSize, SlotInfo); + while (SlotInfo < (PSLOT_INFO)((ULONG_PTR)PciIrqRoutingTable + + PciIrqRoutingTable->TableSize)) + { + DPRINT1("Slot Info: %d.%d->#%d\n", + SlotInfo->BusNumber, + SlotInfo->DeviceNumber, + SlotInfo->SlotNumber); + + /* Check if this slot information matches the PDO being queried */ + if ((ParentExtension->BaseBus == SlotInfo->BusNumber) && + (PdoExtension->Slot.u.bits.DeviceNumber == SlotInfo->DeviceNumber >> 3) && + (SlotInfo->SlotNumber)) + { + /* We found it, return it and return success */ + *SlotNumber = SlotInfo->SlotNumber; + return STATUS_SUCCESS; + } + + /* Try the next slot */ + SlotInfo++; + } + } + + /* Otherwise, grab the parent FDO and check if it's the root */ + if (PCI_IS_ROOT_FDO(ParentExtension)) + { + /* The root FDO doesn't have a slot number */ + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* Otherwise, query the slot/UI address/number as a device property */ + Status = IoGetDeviceProperty(ParentExtension->PhysicalDeviceObject, + DevicePropertyUINumber, + sizeof(ULONG), + SlotNumber, + &ResultLength); + } + + /* Return the status of this endeavour */ + return Status; +} + +NTSTATUS +NTAPI +PciGetDeviceCapabilities(IN PDEVICE_OBJECT DeviceObject, + IN OUT PDEVICE_CAPABILITIES DeviceCapability) +{ + PIRP Irp; + NTSTATUS Status; + KEVENT Event; + PDEVICE_OBJECT AttachedDevice; + PIO_STACK_LOCATION IoStackLocation; + IO_STATUS_BLOCK IoStatusBlock; + PAGED_CODE(); + + /* Zero out capabilities and set undefined values to start with */ + RtlZeroMemory(DeviceCapability, sizeof(DEVICE_CAPABILITIES)); + DeviceCapability->Size = sizeof(DEVICE_CAPABILITIES); + DeviceCapability->Version = 1; + DeviceCapability->Address = -1; + DeviceCapability->UINumber = -1; + + /* Build the wait event for the IOCTL */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + + /* Find the device the PDO is attached to */ + AttachedDevice = IoGetAttachedDeviceReference(DeviceObject); + + /* And build an IRP for it */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + AttachedDevice, + NULL, + 0, + NULL, + &Event, + &IoStatusBlock); + if (!Irp) + { + /* The IRP failed, fail the request as well */ + ObDereferenceObject(AttachedDevice); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Set default status */ + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + /* Get a stack location in this IRP */ + IoStackLocation = IoGetNextIrpStackLocation(Irp); + ASSERT(IoStackLocation); + + /* Initialize it as a query capabilities IRP, with no completion routine */ + RtlZeroMemory(IoStackLocation, sizeof(IO_STACK_LOCATION)); + IoStackLocation->MajorFunction = IRP_MJ_PNP; + IoStackLocation->MinorFunction = IRP_MN_QUERY_CAPABILITIES; + IoStackLocation->Parameters.DeviceCapabilities.Capabilities = DeviceCapability; + IoSetCompletionRoutine(Irp, NULL, NULL, FALSE, FALSE, FALSE); + + /* Send the IOCTL to the driver */ + Status = IoCallDriver(AttachedDevice, Irp); + if (Status == STATUS_PENDING) + { + /* Wait for a response and update the actual status */ + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = Irp->IoStatus.Status; + } + + /* Done, dereference the attached device and return the final result */ + ObDereferenceObject(AttachedDevice); + return Status; +} + +NTSTATUS +NTAPI +PciQueryPowerCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, + IN PDEVICE_CAPABILITIES DeviceCapability) +{ + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status; + DEVICE_CAPABILITIES AttachedCaps; + DEVICE_POWER_STATE NewPowerState, DevicePowerState, DeviceWakeLevel, DeviceWakeState; + SYSTEM_POWER_STATE SystemWakeState, DeepestWakeState, CurrentState; + + /* Nothing is known at first */ + DeviceWakeState = PowerDeviceUnspecified; + SystemWakeState = DeepestWakeState = PowerSystemUnspecified; + + /* Get the PCI capabilities for the parent PDO */ + DeviceObject = PdoExtension->ParentFdoExtension->PhysicalDeviceObject; + Status = PciGetDeviceCapabilities(DeviceObject, &AttachedCaps); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if there's not an existing device state for S0 */ + if (!AttachedCaps.DeviceState[PowerSystemWorking]) + { + /* Set D0<->S0 mapping */ + AttachedCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0; + } + + /* Check if there's not an existing device state for S3 */ + if (!AttachedCaps.DeviceState[PowerSystemShutdown]) + { + /* Set D3<->S3 mapping */ + AttachedCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3; + } + + /* Check for a PDO with broken, or no, power capabilities */ + if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS) + { + /* Unknown wake device states */ + DeviceCapability->DeviceWake = PowerDeviceUnspecified; + DeviceCapability->SystemWake = PowerSystemUnspecified; + + /* No device state support */ + DeviceCapability->DeviceD1 = FALSE; + DeviceCapability->DeviceD2 = FALSE; + + /* No waking from any low-power device state is supported */ + DeviceCapability->WakeFromD0 = FALSE; + DeviceCapability->WakeFromD1 = FALSE; + DeviceCapability->WakeFromD2 = FALSE; + DeviceCapability->WakeFromD3 = FALSE; + + /* For the rest, copy whatever the parent PDO had */ + RtlCopyMemory(DeviceCapability->DeviceState, + AttachedCaps.DeviceState, + sizeof(DeviceCapability->DeviceState)); + return STATUS_SUCCESS; + } + + /* The PCI Device has power capabilities, so read which ones are supported */ + DeviceCapability->DeviceD1 = PdoExtension->PowerCapabilities.Support.D1; + DeviceCapability->DeviceD2 = PdoExtension->PowerCapabilities.Support.D2; + DeviceCapability->WakeFromD0 = PdoExtension->PowerCapabilities.Support.PMED0; + DeviceCapability->WakeFromD1 = PdoExtension->PowerCapabilities.Support.PMED1; + DeviceCapability->WakeFromD2 = PdoExtension->PowerCapabilities.Support.PMED2; + + /* Can the attached device wake from D3? */ + if (AttachedCaps.DeviceWake != PowerDeviceD3) + { + /* It can't, so check if this PDO supports hot D3 wake */ + DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot; + } + else + { + /* It can, is this the root bus? */ + if (PCI_IS_ROOT_FDO(PdoExtension->ParentFdoExtension)) + { + /* This is the root bus, so just check if it supports hot D3 wake */ + DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot; + } + else + { + /* Take the minimums? -- need to check with briang at work */ + UNIMPLEMENTED; + } + } + + /* Now loop each system power state to determine its device state mapping */ + for (CurrentState = PowerSystemWorking; + CurrentState < PowerSystemMaximum; + CurrentState++) + { + /* Read the current mapping from the attached device */ + DevicePowerState = AttachedCaps.DeviceState[CurrentState]; + NewPowerState = DevicePowerState; + + /* The attachee suports D1, but this PDO does not */ + if ((NewPowerState == PowerDeviceD1) && + !(PdoExtension->PowerCapabilities.Support.D1)) + { + /* Fall back to D2 */ + NewPowerState = PowerDeviceD2; + } + + /* The attachee supports D2, but this PDO does not */ + if ((NewPowerState == PowerDeviceD2) && + !(PdoExtension->PowerCapabilities.Support.D2)) + { + /* Fall back to D3 */ + NewPowerState = PowerDeviceD3; + } + + /* Set the mapping based on the best state supported */ + DeviceCapability->DeviceState[CurrentState] = NewPowerState; + + /* Check if sleep states are being processed, and a mapping was found */ + if ((CurrentState < PowerSystemHibernate) && + (NewPowerState != PowerDeviceUnspecified)) + { + /* Save this state as being the deepest one found until now */ + DeepestWakeState = CurrentState; + } + + /* + * Finally, check if the computed sleep state is within the states that + * this device can wake the system from, and if it's higher or equal to + * the sleep state mapping that came from the attachee, assuming that it + * had a valid mapping to begin with. + * + * It this is the case, then make sure that the computed sleep state is + * matched by the device's ability to actually wake from that state. + * + * For devices that support D3, the PCI device only needs Hot D3 as long + * as the attachee's state is less than D3. Otherwise, if the attachee + * might also be at D3, this would require a Cold D3 wake, so check that + * the device actually support this. + */ + if ((CurrentState < AttachedCaps.SystemWake) && + (NewPowerState >= DevicePowerState) && + (DevicePowerState != PowerDeviceUnspecified) && + (((NewPowerState == PowerDeviceD0) && (DeviceCapability->WakeFromD0)) || + ((NewPowerState == PowerDeviceD1) && (DeviceCapability->WakeFromD1)) || + ((NewPowerState == PowerDeviceD2) && (DeviceCapability->WakeFromD2)) || + ((NewPowerState == PowerDeviceD3) && + (PdoExtension->PowerCapabilities.Support.PMED3Hot) && + ((DevicePowerState < PowerDeviceD3) || + (PdoExtension->PowerCapabilities.Support.PMED3Cold))))) + { + /* The mapping is valid, so this will be the lowest wake state */ + SystemWakeState = CurrentState; + DeviceWakeState = NewPowerState; + } + } + + /* Read the current wake level */ + DeviceWakeLevel = PdoExtension->PowerState.DeviceWakeLevel; + + /* Check if the attachee's wake levels are valid, and the PDO's is higher */ + if ((AttachedCaps.SystemWake != PowerSystemUnspecified) && + (AttachedCaps.DeviceWake != PowerDeviceUnspecified) && + (DeviceWakeLevel != PowerDeviceUnspecified) && + (DeviceWakeLevel >= AttachedCaps.DeviceWake)) + { + /* Inherit the system wake from the attachee, and this PDO's wake level */ + DeviceCapability->SystemWake = AttachedCaps.SystemWake; + DeviceCapability->DeviceWake = DeviceWakeLevel; + + /* Now check if the wake level is D0, but the PDO doesn't support it */ + if ((DeviceCapability->DeviceWake == PowerDeviceD0) && + !(DeviceCapability->WakeFromD0)) + { + /* Bump to D1 */ + DeviceCapability->DeviceWake = PowerDeviceD1; + } + + /* Now check if the wake level is D1, but the PDO doesn't support it */ + if ((DeviceCapability->DeviceWake == PowerDeviceD1) && + !(DeviceCapability->WakeFromD1)) + { + /* Bump to D2 */ + DeviceCapability->DeviceWake = PowerDeviceD2; + } + + /* Now check if the wake level is D2, but the PDO doesn't support it */ + if ((DeviceCapability->DeviceWake == PowerDeviceD2) && + !(DeviceCapability->WakeFromD2)) + { + /* Bump it to D3 */ + DeviceCapability->DeviceWake = PowerDeviceD3; + } + + /* Now check if the wake level is D3, but the PDO doesn't support it */ + if ((DeviceCapability->DeviceWake == PowerDeviceD3) && + !(DeviceCapability->WakeFromD3)) + { + /* Then no valid wake state exists */ + DeviceCapability->DeviceWake = PowerDeviceUnspecified; + DeviceCapability->SystemWake = PowerSystemUnspecified; + } + + /* Check if no valid wake state was found */ + if ((DeviceCapability->DeviceWake == PowerDeviceUnspecified) || + (DeviceCapability->SystemWake == PowerSystemUnspecified)) + { + /* Check if one was computed earlier */ + if ((SystemWakeState != PowerSystemUnspecified) && + (DeviceWakeState != PowerDeviceUnspecified)) + { + /* Use the wake state that had been computed earlier */ + DeviceCapability->DeviceWake = DeviceWakeState; + DeviceCapability->SystemWake = SystemWakeState; + + /* If that state was D3, then the device supports Hot/Cold D3 */ + if (DeviceWakeState == PowerDeviceD3) DeviceCapability->WakeFromD3 = TRUE; + } + } + + /* + * Finally, check for off states (lower than S3, such as hibernate) and + * make sure that the device both supports waking from D3 as well as + * supports a Cold wake + */ + if ((DeviceCapability->SystemWake > PowerSystemSleeping3) && + ((DeviceCapability->DeviceWake != PowerDeviceD3) || + !(PdoExtension->PowerCapabilities.Support.PMED3Cold))) + { + /* It doesn't, so pick the computed lowest wake state from earlier */ + DeviceCapability->SystemWake = DeepestWakeState; + } + + /* Set the PCI Specification mandated maximum latencies for transitions */ + DeviceCapability->D1Latency = 0; + DeviceCapability->D2Latency = 2; + DeviceCapability->D3Latency = 100; + + /* Sanity check */ + ASSERT(DeviceCapability->DeviceState[PowerSystemWorking] == PowerDeviceD0); + } + else + { + /* No valid sleep states, no latencies to worry about */ + DeviceCapability->D1Latency = 0; + DeviceCapability->D2Latency = 0; + DeviceCapability->D3Latency = 0; + } + + /* This function always succeeds, even without power management support */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PciQueryCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, + IN OUT PDEVICE_CAPABILITIES DeviceCapability) +{ + NTSTATUS Status; + + /* A PDO ID is never unique, and its address is its function and device */ + DeviceCapability->UniqueID = FALSE; + DeviceCapability->Address = PdoExtension->Slot.u.bits.FunctionNumber | + (PdoExtension->Slot.u.bits.DeviceNumber << 16); + + /* Check for host bridges */ + if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) && + (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST)) + { + /* Raw device opens to a host bridge are acceptable */ + DeviceCapability->RawDeviceOK = TRUE; + } + else + { + /* Otherwise, other PDOs cannot be directly opened */ + DeviceCapability->RawDeviceOK = FALSE; + } + + /* PCI PDOs are pretty fixed things */ + DeviceCapability->LockSupported = FALSE; + DeviceCapability->EjectSupported = FALSE; + DeviceCapability->Removable = FALSE; + DeviceCapability->DockDevice = FALSE; + + /* The slot number is stored as a device property, go query it */ + PciDetermineSlotNumber(PdoExtension, &DeviceCapability->UINumber); + + /* Finally, query and power capabilities and convert them for PnP usage */ + Status = PciQueryPowerCapabilities(PdoExtension, DeviceCapability); + + /* Dump the capabilities if it all worked, and return the status */ + if (NT_SUCCESS(Status)) PciDebugDumpQueryCapabilities(DeviceCapability); + return Status; +} + /* EOF */ diff --git a/drivers/filesystems/cdfs/cdfs.c b/drivers/filesystems/cdfs/cdfs.c index 28eb370766b..172282eff77 100644 --- a/drivers/filesystems/cdfs/cdfs.c +++ b/drivers/filesystems/cdfs/cdfs.c @@ -95,6 +95,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject, CdfsQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = CdfsSetVolumeInformation; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = + CdfsDeviceControl; DriverObject->DriverUnload = NULL; diff --git a/drivers/filesystems/cdfs/cdfs.h b/drivers/filesystems/cdfs/cdfs.h index 3b114efdfee..905a34e0c75 100644 --- a/drivers/filesystems/cdfs/cdfs.h +++ b/drivers/filesystems/cdfs/cdfs.h @@ -277,13 +277,17 @@ CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN OUT PULONG pOutputBufferSize, IN BOOLEAN Override); - /* create.c */ NTSTATUS NTAPI CdfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp); +/* devctrl.c */ + +NTSTATUS NTAPI +CdfsDeviceControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp); /* dirctl.c */ diff --git a/drivers/filesystems/cdfs/cdfs.rbuild b/drivers/filesystems/cdfs/cdfs.rbuild index 2aed0e891db..ef0edec3bba 100644 --- a/drivers/filesystems/cdfs/cdfs.rbuild +++ b/drivers/filesystems/cdfs/cdfs.rbuild @@ -10,6 +10,7 @@ close.c common.c create.c + devctrl.c dirctl.c fcb.c finfo.c diff --git a/drivers/filesystems/cdfs/common.c b/drivers/filesystems/cdfs/common.c index 3a3722e5a74..dd47a78a964 100644 --- a/drivers/filesystems/cdfs/common.c +++ b/drivers/filesystems/cdfs/common.c @@ -197,8 +197,11 @@ CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread()); IoSetDeviceToVerify(PsGetCurrentThread(), NULL); - NewStatus = IoVerifyVolume(DeviceToVerify, FALSE); - DPRINT1("IoVerifyVolume() returned (Status %lx)\n", NewStatus); + if (DeviceToVerify) + { + NewStatus = IoVerifyVolume(DeviceToVerify, FALSE); + DPRINT1("IoVerifyVolume() returned (Status %lx)\n", NewStatus); + } } DPRINT("Returning Status %x\n", Status); diff --git a/drivers/filesystems/cdfs/devctrl.c b/drivers/filesystems/cdfs/devctrl.c new file mode 100644 index 00000000000..cee4ba58aca --- /dev/null +++ b/drivers/filesystems/cdfs/devctrl.c @@ -0,0 +1,64 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/filesystems/cdfs/devctrl.c + * PURPOSE: CDROM (ISO 9660) filesystem driver + * PROGRAMMER: Pierre Schweitzer + * + */ + +/* INCLUDES *****************************************************************/ + +#include "cdfs.h" + +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS NTAPI +CdfsDeviceControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + NTSTATUS Status; + PVCB Vcb = NULL; + PFILE_OBJECT FileObject; + PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); + + FileObject = Stack->FileObject; + Irp->IoStatus.Information = 0; + + /* FIXME: HACK, it means that CD has changed */ + if (!FileObject) + { + DPRINT1("FIXME: CdfsDeviceControl called without FileObject!\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_DEVICE_REQUEST; + } + + /* Only support such operations on volume */ + if (!(FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_PARAMETER; + } + + if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_DISK_TYPE) + { + /* We should handle this one, but we don't! */ + Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + { + /* Pass it to storage driver */ + IoSkipCurrentIrpStackLocation(Irp); + Vcb = (PVCB)Stack->DeviceObject->DeviceExtension; + Status = IoCallDriver(Vcb->StorageDevice, Irp); + } + + return Status; +} diff --git a/drivers/filesystems/cdfs/dirctl.c b/drivers/filesystems/cdfs/dirctl.c index 12399883234..0160c922321 100644 --- a/drivers/filesystems/cdfs/dirctl.c +++ b/drivers/filesystems/cdfs/dirctl.c @@ -376,13 +376,15 @@ CdfsGetNameInformation(PFCB Fcb, DPRINT("CdfsGetNameInformation() called\n"); Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR); - if ((sizeof (FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength) + if ((sizeof(FILE_NAMES_INFORMATION) + Length) > BufferLength) return(STATUS_BUFFER_OVERFLOW); Info->FileNameLength = Length; Info->NextEntryOffset = - ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, 4); - memcpy(Info->FileName, Fcb->ObjectName, Length); + ROUND_UP(sizeof(FILE_NAMES_INFORMATION) + Length, sizeof(ULONG)); + RtlCopyMemory(Info->FileName, Fcb->ObjectName, Length); + + // Info->FileIndex=; return(STATUS_SUCCESS); } @@ -399,31 +401,27 @@ CdfsGetDirectoryInformation(PFCB Fcb, DPRINT("CdfsGetDirectoryInformation() called\n"); Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR); - if ((sizeof (FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength) + if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength) return(STATUS_BUFFER_OVERFLOW); Info->FileNameLength = Length; Info->NextEntryOffset = - ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, 4); - memcpy(Info->FileName, Fcb->ObjectName, Length); + ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) + Length, sizeof(ULONG)); + RtlCopyMemory(Info->FileName, Fcb->ObjectName, Length); /* Convert file times */ CdfsDateTimeToSystemTime(Fcb, &Info->CreationTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastAccessTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastWriteTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->ChangeTime); + Info->LastWriteTime = Info->CreationTime; + Info->ChangeTime = Info->CreationTime; /* Convert file flags */ CdfsFileFlagsToAttributes(Fcb, &Info->FileAttributes); if (CdfsFCBIsDirectory(Fcb)) { - Info->EndOfFile.QuadPart = 0LL; - Info->AllocationSize.QuadPart = 0LL; + Info->EndOfFile.QuadPart = 0; + Info->AllocationSize.QuadPart = 0; } else { @@ -450,23 +448,19 @@ CdfsGetFullDirectoryInformation(PFCB Fcb, DPRINT("CdfsGetFullDirectoryInformation() called\n"); Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR); - if ((sizeof (FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength) + if ((sizeof (FILE_FULL_DIR_INFORMATION) + Length) > BufferLength) return(STATUS_BUFFER_OVERFLOW); Info->FileNameLength = Length; Info->NextEntryOffset = - ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, 4); - memcpy(Info->FileName, Fcb->ObjectName, Length); + ROUND_UP(sizeof(FILE_FULL_DIR_INFORMATION) + Length, sizeof(ULONG)); + RtlCopyMemory(Info->FileName, Fcb->ObjectName, Length); /* Convert file times */ CdfsDateTimeToSystemTime(Fcb, &Info->CreationTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastAccessTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastWriteTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->ChangeTime); + Info->LastWriteTime = Info->CreationTime; + Info->ChangeTime = Info->CreationTime; /* Convert file flags */ CdfsFileFlagsToAttributes(Fcb, @@ -474,8 +468,8 @@ CdfsGetFullDirectoryInformation(PFCB Fcb, if (CdfsFCBIsDirectory(Fcb)) { - Info->EndOfFile.QuadPart = 0LL; - Info->AllocationSize.QuadPart = 0LL; + Info->EndOfFile.QuadPart = 0; + Info->AllocationSize.QuadPart = 0; } else { @@ -508,18 +502,14 @@ CdfsGetBothDirectoryInformation(PFCB Fcb, Info->FileNameLength = Length; Info->NextEntryOffset = - ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, 4); - memcpy(Info->FileName, Fcb->ObjectName, Length); + ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG)); + RtlCopyMemory(Info->FileName, Fcb->ObjectName, Length); /* Convert file times */ CdfsDateTimeToSystemTime(Fcb, &Info->CreationTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastAccessTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->LastWriteTime); - CdfsDateTimeToSystemTime(Fcb, - &Info->ChangeTime); + Info->LastWriteTime = Info->CreationTime; + Info->ChangeTime = Info->CreationTime; /* Convert file flags */ CdfsFileFlagsToAttributes(Fcb, @@ -527,8 +517,8 @@ CdfsGetBothDirectoryInformation(PFCB Fcb, if (CdfsFCBIsDirectory(Fcb)) { - Info->EndOfFile.QuadPart = 0LL; - Info->AllocationSize.QuadPart = 0LL; + Info->EndOfFile.QuadPart = 0; + Info->AllocationSize.QuadPart = 0; } else { @@ -542,8 +532,9 @@ CdfsGetBothDirectoryInformation(PFCB Fcb, Info->EaSize = 0; /* Copy short name */ + ASSERT(Fcb->ShortNameU.Length / sizeof(WCHAR) <= 12); Info->ShortNameLength = Fcb->ShortNameU.Length; - memcpy(Info->ShortName, Fcb->ShortNameU.Buffer, Fcb->ShortNameU.Length); + RtlCopyMemory(Info->ShortName, Fcb->ShortNameU.Buffer, Fcb->ShortNameU.Length); return(STATUS_SUCCESS); } @@ -584,6 +575,15 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, Stack->Parameters.QueryDirectory.FileInformationClass; FileIndex = Stack->Parameters.QueryDirectory.FileIndex; + /* Determine Buffer for result */ + if (Irp->MdlAddress) + { + Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); + } + else + { + Buffer = Irp->UserBuffer; + } if (SearchPattern != NULL) { @@ -596,13 +596,8 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, { return STATUS_INSUFFICIENT_RESOURCES; } - - Ccb->DirectorySearchPattern.Length = SearchPattern->Length; Ccb->DirectorySearchPattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR); - - memcpy(Ccb->DirectorySearchPattern.Buffer, - SearchPattern->Buffer, - SearchPattern->Length); + RtlCopyUnicodeString(&Ccb->DirectorySearchPattern, SearchPattern); Ccb->DirectorySearchPattern.Buffer[SearchPattern->Length / sizeof(WCHAR)] = 0; } } @@ -625,24 +620,14 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, /* Determine directory index */ if (Stack->Flags & SL_INDEX_SPECIFIED) { - Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart; - Ccb->Offset = 0; + Ccb->Entry = Stack->Parameters.QueryDirectory.FileIndex; + Ccb->Offset = Ccb->CurrentByteOffset.u.LowPart; } else if (First || (Stack->Flags & SL_RESTART_SCAN)) { Ccb->Entry = 0; Ccb->Offset = 0; } - - /* Determine Buffer for result */ - if (Irp->MdlAddress) - { - Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); - } - else - { - Buffer = Irp->UserBuffer; - } DPRINT("Buffer = %p tofind = %wZ\n", Buffer, &Ccb->DirectorySearchPattern); TempFcb.ObjectName = TempFcb.PathName; diff --git a/drivers/filesystems/cdfs/fcb.c b/drivers/filesystems/cdfs/fcb.c index a7dd385aa46..12bee1dd753 100644 --- a/drivers/filesystems/cdfs/fcb.c +++ b/drivers/filesystems/cdfs/fcb.c @@ -233,7 +233,6 @@ CdfsFCBInitializeCache(PVCB Vcb, PFCB Fcb) { PFILE_OBJECT FileObject; - NTSTATUS Status; PCCB newCCB; FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); @@ -241,7 +240,7 @@ CdfsFCBInitializeCache(PVCB Vcb, newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB); if (newCCB == NULL) { - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(newCCB, sizeof(CCB)); @@ -256,7 +255,6 @@ CdfsFCBInitializeCache(PVCB Vcb, Fcb->FileObject = FileObject; Fcb->DevExt = Vcb; - Status = STATUS_SUCCESS; CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), FALSE, @@ -266,7 +264,7 @@ CdfsFCBInitializeCache(PVCB Vcb, ObDereferenceObject(FileObject); Fcb->Flags |= FCB_CACHE_INITIALIZED; - return(Status); + return STATUS_SUCCESS; } @@ -434,6 +432,9 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb, } memset(newCCB, 0, sizeof(CCB)); + FileObject->ReadAccess = TRUE; + FileObject->WriteAccess = FALSE; + FileObject->DeleteAccess = FALSE; FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; diff --git a/drivers/filesystems/cdfs/fsctl.c b/drivers/filesystems/cdfs/fsctl.c index dd0e065a055..c0433db4768 100644 --- a/drivers/filesystems/cdfs/fsctl.c +++ b/drivers/filesystems/cdfs/fsctl.c @@ -359,7 +359,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject, Vpb->SerialNumber = CdInfo.SerialNumber; Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength; - RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR)); + RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength); RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO)); NewDeviceObject->Vpb = DeviceToMount->Vpb; diff --git a/drivers/filesystems/fastfat/create.c b/drivers/filesystems/fastfat/create.c index f643104c947..514084ee3f1 100644 --- a/drivers/filesystems/fastfat/create.c +++ b/drivers/filesystems/fastfat/create.c @@ -125,7 +125,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) ExReleaseResourceLite (&DeviceExt->DirResource); FileOffset.QuadPart = 0; - if (CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) + if (CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry)) { while (TRUE) { @@ -155,7 +155,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) { CcUnpinData(Context); FileOffset.u.LowPart += PAGE_SIZE; - if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) + if (!CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry)) { Context = NULL; break; diff --git a/drivers/filesystems/fastfat/direntry.c b/drivers/filesystems/fastfat/direntry.c index 1a1577c452d..060102973c6 100644 --- a/drivers/filesystems/fastfat/direntry.c +++ b/drivers/filesystems/fastfat/direntry.c @@ -66,7 +66,7 @@ FATIsDirectoryEmpty(PVFATFCB Fcb) CcUnpinData(Context); } - if (!CcMapData(Fcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&FatDirEntry)) + if (!CcMapData(Fcb->FileObject, &FileOffset, sizeof(FAT_DIR_ENTRY), TRUE, &Context, (PVOID*)&FatDirEntry)) { return TRUE; } @@ -120,7 +120,7 @@ FATXIsDirectoryEmpty(PVFATFCB Fcb) CcUnpinData(Context); } - if (!CcMapData(Fcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&FatXDirEntry)) + if (!CcMapData(Fcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY), TRUE, &Context, (PVOID*)&FatXDirEntry)) { return TRUE; } diff --git a/drivers/filesystems/fastfat/dirwr.c b/drivers/filesystems/fastfat/dirwr.c index a1da379004b..0e948addc67 100644 --- a/drivers/filesystems/fastfat/dirwr.c +++ b/drivers/filesystems/fastfat/dirwr.c @@ -638,7 +638,7 @@ FATDelEntry( CcUnpinData(Context); } Offset.u.LowPart = (i * sizeof(FAT_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE; - CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE, + CcPinRead(pFcb->parentFcb->FileObject, &Offset, sizeof(FAT_DIR_ENTRY), TRUE, &Context, (PVOID*)&pDirEntry); } pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))].Filename[0] = 0xe5; @@ -689,7 +689,7 @@ FATXDelEntry( DPRINT("delete entry: %d\n", StartIndex); Offset.u.HighPart = 0; Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE; - if (!CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE, + if (!CcPinRead(pFcb->parentFcb->FileObject, &Offset, sizeof(FATX_DIR_ENTRY), TRUE, &Context, (PVOID*)&pDirEntry)) { DPRINT1("CcPinRead(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE); diff --git a/drivers/filesystems/fastfat/fcb.c b/drivers/filesystems/fastfat/fcb.c index 1bfc51cec39..bfdeb18605b 100644 --- a/drivers/filesystems/fastfat/fcb.c +++ b/drivers/filesystems/fastfat/fcb.c @@ -474,7 +474,7 @@ vfatMakeFCBFromDirEntry( if (vfatFCBIsDirectory(rcFCB)) { ULONG FirstCluster, CurrentCluster; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; Size = 0; FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry); if (FirstCluster == 1) @@ -484,7 +484,7 @@ vfatMakeFCBFromDirEntry( else if (FirstCluster != 0) { CurrentCluster = FirstCluster; - while (CurrentCluster != 0xffffffff) + while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) { Size += vcb->FatInfo.BytesPerCluster; Status = NextCluster (vcb, FirstCluster, &CurrentCluster, FALSE); diff --git a/drivers/filesystems/fastfat/iface.c b/drivers/filesystems/fastfat/iface.c index 6bf97159deb..de9bb165a33 100644 --- a/drivers/filesystems/fastfat/iface.c +++ b/drivers/filesystems/fastfat/iface.c @@ -100,6 +100,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest; + DriverObject->MajorFunction[IRP_MJ_PNP] = VfatBuildRequest; DriverObject->DriverUnload = NULL; diff --git a/drivers/filesystems/fastfat/misc.c b/drivers/filesystems/fastfat/misc.c index 688086acec2..71d94b5acb7 100644 --- a/drivers/filesystems/fastfat/misc.c +++ b/drivers/filesystems/fastfat/misc.c @@ -127,6 +127,8 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext) return VfatCleanup(IrpContext); case IRP_MJ_FLUSH_BUFFERS: return VfatFlush(IrpContext); + case IRP_MJ_PNP: + return VfatPnp(IrpContext); default: DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; diff --git a/drivers/filesystems/fastfat/pnp.c b/drivers/filesystems/fastfat/pnp.c new file mode 100644 index 00000000000..b77c04ce142 --- /dev/null +++ b/drivers/filesystems/fastfat/pnp.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/filesystems/fastfat/pnp.c + * PURPOSE: VFAT Filesystem + * PROGRAMMER: Pierre Schweitzer + * + */ + +/* INCLUDES *****************************************************************/ + +#define NDEBUG +#include "vfat.h" + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext) +{ + PVCB Vcb = NULL; + NTSTATUS Status; + + /* PRECONDITION */ + ASSERT(IrpContext); + + switch (IrpContext->Stack->MinorFunction) + { + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_SURPRISE_REMOVAL: + case IRP_MN_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + Status = STATUS_NOT_IMPLEMENTED; + IrpContext->Irp->IoStatus.Status = Status; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + break; + default: + IoSkipCurrentIrpStackLocation(IrpContext->Irp); + Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension; + Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp); + } + + VfatFreeIrpContext(IrpContext); + + return Status; +} diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h index e9c37da3d63..3521d31a36d 100644 --- a/drivers/filesystems/fastfat/vfat.h +++ b/drivers/filesystems/fastfat/vfat.h @@ -775,5 +775,8 @@ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb); +/* --------------------------------------------------------------- pnp.c */ + +NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext); /* EOF */ diff --git a/drivers/filesystems/fastfat/vfatfs.rbuild b/drivers/filesystems/fastfat/vfatfs.rbuild index 56ca836973c..a8e81d2c2c3 100644 --- a/drivers/filesystems/fastfat/vfatfs.rbuild +++ b/drivers/filesystems/fastfat/vfatfs.rbuild @@ -21,6 +21,7 @@ fsctl.c iface.c misc.c + pnp.c rw.c shutdown.c string.c diff --git a/drivers/filesystems/fastfat/volume.c b/drivers/filesystems/fastfat/volume.c index d91e44fa99c..4a014b37882 100644 --- a/drivers/filesystems/fastfat/volume.c +++ b/drivers/filesystems/fastfat/volume.c @@ -229,7 +229,7 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject, /* Search existing volume entry on disk */ FileOffset.QuadPart = 0; - if (CcPinRead(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) + if (CcPinRead(pRootFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry)) { while (TRUE) { @@ -250,13 +250,13 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject, Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry); if ((DirIndex % EntriesPerPage) == 0) { - CcUnpinData(Context); - FileOffset.u.LowPart += PAGE_SIZE; - if (!CcPinRead(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) - { - Context = NULL; - break; - } + CcUnpinData(Context); + FileOffset.u.LowPart += PAGE_SIZE; + if (!CcPinRead(pRootFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry)) + { + Context = NULL; + break; + } } } if (Context) diff --git a/drivers/input/i8042prt/mouse.c b/drivers/input/i8042prt/mouse.c index 11838134667..efa73093244 100644 --- a/drivers/input/i8042prt/mouse.c +++ b/drivers/input/i8042prt/mouse.c @@ -49,7 +49,7 @@ i8042MouQueuePacket( DeviceExtension->MouseComplete = TRUE; DeviceExtension->MouseInBuffer++; - if (DeviceExtension->MouseInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize) + if (DeviceExtension->MouseInBuffer >= DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize) { WARN_(I8042PRT, "Mouse buffer overflow\n"); DeviceExtension->MouseInBuffer--; diff --git a/drivers/network/tcpip/datalink/lan.c b/drivers/network/tcpip/datalink/lan.c index 2d449550bb0..3883235b6a0 100644 --- a/drivers/network/tcpip/datalink/lan.c +++ b/drivers/network/tcpip/datalink/lan.c @@ -569,9 +569,7 @@ VOID NTAPI ProtocolBindAdapter( * SystemSpecific1: Pointer to a registry path with protocol-specific configuration information * SystemSpecific2: Unused & must not be touched */ -{ - /* XXX confirm that this is still true, or re-word the following comment */ - /* we get to ignore BindContext because we will never pend an operation with NDIS */ +{ TI_DbgPrint(DEBUG_DATALINK, ("Called with registry path %wZ for %wZ\n", SystemSpecific1, DeviceName)); *Status = LANRegisterAdapter(DeviceName, SystemSpecific1); } @@ -952,10 +950,13 @@ BOOLEAN BindAdapter( OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ParameterHandle; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo; + WCHAR Buffer[150]; UNICODE_STRING IPAddress = RTL_CONSTANT_STRING(L"IPAddress"); UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask"); UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway"); UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP"); + UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"); + UNICODE_STRING TcpipRegistryPath; UNICODE_STRING RegistryDataU; ANSI_STRING RegistryDataA; @@ -1009,9 +1010,19 @@ BOOLEAN BindAdapter( TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n", &IF->Description)); + + TcpipRegistryPath.MaximumLength = sizeof(WCHAR) * 150; + TcpipRegistryPath.Length = 0; + TcpipRegistryPath.Buffer = Buffer; + + RtlAppendUnicodeStringToString(&TcpipRegistryPath, + &Prefix); + + RtlAppendUnicodeStringToString(&TcpipRegistryPath, + &IF->Name); InitializeObjectAttributes(&ObjectAttributes, - RegistryPath, + &TcpipRegistryPath, OBJ_CASE_INSENSITIVE, 0, NULL); @@ -1019,6 +1030,7 @@ BOOLEAN BindAdapter( AddrInitIPv4(&DefaultMask, 0); Status = ZwOpenKey(&ParameterHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status)) { IF->Unicast = DefaultMask; @@ -1040,7 +1052,7 @@ BOOLEAN BindAdapter( KeyValueInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG), &Unused); - if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) != 0) + if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) == 0) { RegistryDataU.MaximumLength = 16 + sizeof(WCHAR); RegistryDataU.Buffer = (PWCHAR)KeyValueInfo->Data; diff --git a/drivers/network/tcpip/tcpip/fileobjs.c b/drivers/network/tcpip/tcpip/fileobjs.c index 70357fced9a..98cc4062d0d 100644 --- a/drivers/network/tcpip/tcpip/fileobjs.c +++ b/drivers/network/tcpip/tcpip/fileobjs.c @@ -379,9 +379,15 @@ NTSTATUS FileCloseAddress( LockObject(AddrFile, &OldIrql); /* We have to close this connection because we started it */ if( AddrFile->Listener ) + { + AddrFile->Listener->AddressFile = NULL; TCPClose( AddrFile->Listener ); + } if( AddrFile->Connection ) + { + AddrFile->Connection->AddressFile = NULL; DereferenceObject( AddrFile->Connection ); + } UnlockObject(AddrFile, OldIrql); DereferenceObject(AddrFile); diff --git a/drivers/network/tcpip/tcpip/ninfo.c b/drivers/network/tcpip/tcpip/ninfo.c index 293eb19a027..f78d4b40062 100644 --- a/drivers/network/tcpip/tcpip/ninfo.c +++ b/drivers/network/tcpip/tcpip/ninfo.c @@ -21,15 +21,21 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI KIRQL OldIrql; UINT RtCount = CountFIBs(IF); UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount; - PFIB_ENTRY RCache = - ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), - RCacheCur = RCache; - PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ), - RtCurrent = RouteEntries; + PFIB_ENTRY RCache, RCacheCur; + PIPROUTE_ENTRY RouteEntries, RtCurrent; UINT i; - TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d, RCache = %08x\n", - RtCount, RCache)); + TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d\n", + RtCount)); + + if (RtCount == 0) + return InfoCopyOut(NULL, 0, NULL, BufferSize); + + RouteEntries = ExAllocatePool( NonPagedPool, Size ); + RtCurrent = RouteEntries; + + RCache = ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ); + RCacheCur = RCache; if( !RCache || !RouteEntries ) { if( RCache ) ExFreePool( RCache ); diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index b1475afb4d0..daffb9b1fd5 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -5456,6 +5456,8 @@ typedef struct _IO_COMPLETION_CONTEXT { #define IRP_DEFER_IO_COMPLETION 0x00000800 #define IRP_OB_QUERY_NAME 0x00001000 #define IRP_HOLD_DEVICE_QUEUE 0x00002000 +#define IRP_RETRY_IO_COMPLETION 0x00004000 +#define IRP_CLASS_CACHE_OPERATION 0x00008000 #define IRP_QUOTA_CHARGED 0x01 #define IRP_ALLOCATED_MUST_SUCCEED 0x02 diff --git a/include/ndk/ldrfuncs.h b/include/ndk/ldrfuncs.h index 8943a099ad2..743d213b87e 100644 --- a/include/ndk/ldrfuncs.h +++ b/include/ndk/ldrfuncs.h @@ -109,4 +109,13 @@ LdrVerifyMappedImageMatchesChecksum( IN ULONG FileLength ); +PIMAGE_BASE_RELOCATION +NTAPI +LdrProcessRelocationBlockLongLong( + IN ULONG_PTR Address, + IN ULONG Count, + IN PUSHORT TypeOffset, + IN LONGLONG Delta +); + #endif diff --git a/include/psdk/ntddvdeo.h b/include/psdk/ntddvdeo.h index 2aa4774382e..6bf65a42a17 100644 --- a/include/psdk/ntddvdeo.h +++ b/include/psdk/ntddvdeo.h @@ -468,6 +468,15 @@ typedef struct _ENG_EVENT ULONG fFlags; } ENG_EVENT, *PENG_EVENT; +typedef struct _DISPLAY_BRIGHTNESS { + UCHAR ucDisplayPolicy; + UCHAR ucACBrightness; + UCHAR ucDCBrightness; +} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS; + +#define DISPLAYPOLICY_AC 0x00000001 +#define DISPLAYPOLICY_DC 0x00000002 +#define DISPLAYPOLICY_BOTH 0x00000003 #ifdef __cplusplus } diff --git a/include/psdk/ntdef.h b/include/psdk/ntdef.h index aaf5182d9d3..be71648f18b 100644 --- a/include/psdk/ntdef.h +++ b/include/psdk/ntdef.h @@ -194,7 +194,7 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1300) #define TYPE_ALIGNMENT(t) __alignof(t) #else -#define TYPE_ALIGNMENT(t) FIELD_OFFSET( struct { char x; t test; }, test ) +#define TYPE_ALIGNMENT(t) FIELD_OFFSET(struct { char x; t test; }, test) #endif /* Calling Conventions */ @@ -219,7 +219,7 @@ #else #define DECLSPEC_ADDRSAFE #endif -#endif +#endif /* DECLSPEC_ADDRSAFE */ #if !defined(_NTSYSTEM_) #define NTSYSAPI DECLSPEC_IMPORT @@ -235,14 +235,14 @@ /* Inlines */ #ifndef FORCEINLINE -#if (_MSC_VER >= 1200) +#if defined(_MSC_VER) && (_MSC_VER >= 1200) #define FORCEINLINE __forceinline -#elif (_MSC_VER) +#elif defined(_MSC_VER) #define FORCEINLINE __inline -#else +#else /* __GNUC__ */ #define FORCEINLINE extern __inline__ __attribute__((always_inline)) #endif -#endif +#endif /* FORCEINLINE */ #ifndef DECLSPEC_NOINLINE #if (_MSC_VER >= 1300) @@ -252,7 +252,7 @@ #else #define DECLSPEC_NOINLINE #endif -#endif +#endif /* DECLSPEC_NOINLINE */ #if !defined(_M_CEE_PURE) #define NTAPI_INLINE NTAPI @@ -265,11 +265,11 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(MIDL_PASS) #define DECLSPEC_ALIGN(x) __declspec(align(x)) #elif defined(__GNUC__) -#define DECLSPEC_ALIGN(x) __attribute__((aligned(x))) +#define DECLSPEC_ALIGN(x) __attribute__ ((__aligned__ (x))) #else #define DECLSPEC_ALIGN(x) #endif -#endif +#endif /* DECLSPEC_ALIGN */ /* Use to silence unused variable warnings when it is intentional */ #define UNREFERENCED_PARAMETER(P) {(P)=(P);} @@ -507,7 +507,7 @@ typedef struct _STRING64 { #define MAKELCID(lgid, srtid) ((ULONG)((((ULONG)((USHORT)(srtid))) << 16) | \ ((ULONG)((USHORT)(lgid))))) -#define MAKESORTLCID(lgid, srtid, ver) \ +#define MAKESORTLCID(lgid, srtid, ver) \ ((ULONG)((MAKELCID(lgid, srtid)) | \ (((ULONG)((USHORT)(ver))) << 20))) #define LANGIDFROMLCID(lcid) ((USHORT)(lcid)) @@ -549,9 +549,9 @@ typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES; /* Product Types */ typedef enum _NT_PRODUCT_TYPE { - NtProductWinNt = 1, - NtProductLanManNt, - NtProductServer + NtProductWinNt = 1, + NtProductLanManNt, + NtProductServer } NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE; typedef enum _EVENT_TYPE { @@ -560,8 +560,8 @@ typedef enum _EVENT_TYPE { } EVENT_TYPE; typedef enum _TIMER_TYPE { - NotificationTimer, - SynchronizationTimer + NotificationTimer, + SynchronizationTimer } TIMER_TYPE; typedef enum _WAIT_TYPE { @@ -571,25 +571,23 @@ typedef enum _WAIT_TYPE { /* Doubly Linked Lists */ typedef struct _LIST_ENTRY { - struct _LIST_ENTRY *Flink; - struct _LIST_ENTRY *Blink; + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY; -typedef struct LIST_ENTRY32 -{ - ULONG Flink; - ULONG Blink; +typedef struct LIST_ENTRY32 { + ULONG Flink; + ULONG Blink; } LIST_ENTRY32, *PLIST_ENTRY32; -typedef struct LIST_ENTRY64 -{ - ULONGLONG Flink; - ULONGLONG Blink; +typedef struct LIST_ENTRY64 { + ULONGLONG Flink; + ULONGLONG Blink; } LIST_ENTRY64, *PLIST_ENTRY64; /* Singly Linked Lists */ typedef struct _SINGLE_LIST_ENTRY { - struct _SINGLE_LIST_ENTRY *Next; + struct _SINGLE_LIST_ENTRY *Next; } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; typedef struct _PROCESSOR_NUMBER { @@ -603,10 +601,10 @@ struct _EXCEPTION_RECORD; typedef EXCEPTION_DISPOSITION (NTAPI *PEXCEPTION_ROUTINE)( - IN struct _EXCEPTION_RECORD *ExceptionRecord, - IN PVOID EstablisherFrame, - IN OUT struct _CONTEXT *ContextRecord, - IN OUT PVOID DispatcherContext); + struct _EXCEPTION_RECORD *ExceptionRecord, + PVOID EstablisherFrame, + struct _CONTEXT *ContextRecord, + PVOID DispatcherContext); typedef struct _GROUP_AFFINITY { KAFFINITY Mask; @@ -650,155 +648,154 @@ typedef struct _GROUP_AFFINITY { /* C_ASSERT Definition */ #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1] +#define VER_WORKSTATION_NT 0x40000000 +#define VER_SERVER_NT 0x80000000 +#define VER_SUITE_SMALLBUSINESS 0x00000001 +#define VER_SUITE_ENTERPRISE 0x00000002 +#define VER_SUITE_BACKOFFICE 0x00000004 +#define VER_SUITE_COMMUNICATIONS 0x00000008 +#define VER_SUITE_TERMINAL 0x00000010 +#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020 +#define VER_SUITE_EMBEDDEDNT 0x00000040 +#define VER_SUITE_DATACENTER 0x00000080 +#define VER_SUITE_SINGLEUSERTS 0x00000100 +#define VER_SUITE_PERSONAL 0x00000200 +#define VER_SUITE_BLADE 0x00000400 +#define VER_SUITE_EMBEDDED_RESTRICTED 0x00000800 +#define VER_SUITE_SECURITY_APPLIANCE 0x00001000 +#define VER_SUITE_STORAGE_SERVER 0x00002000 +#define VER_SUITE_COMPUTE_SERVER 0x00004000 +#define VER_SUITE_WH_SERVER 0x00008000 + /* Primary language IDs. */ -#define LANG_NEUTRAL 0x00 -#define LANG_INVARIANT 0x7f +#define LANG_NEUTRAL 0x00 +#define LANG_INVARIANT 0x7f -#define LANG_AFRIKAANS 0x36 -#define LANG_ALBANIAN 0x1c -#define LANG_ALSATIAN 0x84 -#define LANG_AMHARIC 0x5e -#define LANG_ARABIC 0x01 -#define LANG_ARMENIAN 0x2b -#define LANG_ASSAMESE 0x4d -#define LANG_AZERI 0x2c -#define LANG_BASHKIR 0x6d -#define LANG_BASQUE 0x2d -#define LANG_BELARUSIAN 0x23 -#define LANG_BENGALI 0x45 -#define LANG_BRETON 0x7e -#define LANG_BOSNIAN 0x1a -#define LANG_BOSNIAN_NEUTRAL 0x781a -#define LANG_BULGARIAN 0x02 -#define LANG_CATALAN 0x03 -#define LANG_CHINESE 0x04 -#define LANG_CHINESE_SIMPLIFIED 0x04 -#define LANG_CHINESE_TRADITIONAL 0x7c04 -#define LANG_CORSICAN 0x83 -#define LANG_CROATIAN 0x1a -#define LANG_CZECH 0x05 -#define LANG_DANISH 0x06 -#define LANG_DARI 0x8c -#define LANG_DIVEHI 0x65 -#define LANG_DUTCH 0x13 -#define LANG_ENGLISH 0x09 -#define LANG_ESTONIAN 0x25 -#define LANG_FAEROESE 0x38 -#define LANG_FARSI 0x29 -#define LANG_FILIPINO 0x64 -#define LANG_FINNISH 0x0b -#define LANG_FRENCH 0x0c -#define LANG_FRISIAN 0x62 -#define LANG_GALICIAN 0x56 -#define LANG_GEORGIAN 0x37 -#define LANG_GERMAN 0x07 -#define LANG_GREEK 0x08 -#define LANG_GREENLANDIC 0x6f -#define LANG_GUJARATI 0x47 -#define LANG_HAUSA 0x68 -#define LANG_HEBREW 0x0d -#define LANG_HINDI 0x39 -#define LANG_HUNGARIAN 0x0e -#define LANG_ICELANDIC 0x0f -#define LANG_IGBO 0x70 -#define LANG_INDONESIAN 0x21 -#define LANG_INUKTITUT 0x5d -#define LANG_IRISH 0x3c -#define LANG_ITALIAN 0x10 -#define LANG_JAPANESE 0x11 -#define LANG_KANNADA 0x4b -#define LANG_KASHMIRI 0x60 -#define LANG_KAZAK 0x3f -#define LANG_KHMER 0x53 -#define LANG_KICHE 0x86 -#define LANG_KINYARWANDA 0x87 -#define LANG_KONKANI 0x57 -#define LANG_KOREAN 0x12 -#define LANG_KYRGYZ 0x40 -#define LANG_LAO 0x54 -#define LANG_LATVIAN 0x26 -#define LANG_LITHUANIAN 0x27 -#define LANG_LOWER_SORBIAN 0x2e -#define LANG_LUXEMBOURGISH 0x6e -#define LANG_MACEDONIAN 0x2f -#define LANG_MALAY 0x3e -#define LANG_MALAYALAM 0x4c -#define LANG_MALTESE 0x3a -#define LANG_MANIPURI 0x58 -#define LANG_MAORI 0x81 -#define LANG_MAPUDUNGUN 0x7a -#define LANG_MARATHI 0x4e -#define LANG_MOHAWK 0x7c -#define LANG_MONGOLIAN 0x50 -#define LANG_NEPALI 0x61 -#define LANG_NORWEGIAN 0x14 -#define LANG_OCCITAN 0x82 -#define LANG_ORIYA 0x48 -#define LANG_PASHTO 0x63 -#define LANG_PERSIAN 0x29 -#define LANG_POLISH 0x15 -#define LANG_PORTUGUESE 0x16 -#define LANG_PUNJABI 0x46 -#define LANG_QUECHUA 0x6b -#define LANG_ROMANIAN 0x18 -#define LANG_ROMANSH 0x17 -#define LANG_RUSSIAN 0x19 -#define LANG_SAMI 0x3b -#define LANG_SANSKRIT 0x4f -#define LANG_SERBIAN 0x1a -#define LANG_SERBIAN_NEUTRAL 0x7c1a -#define LANG_SINDHI 0x59 -#define LANG_SINHALESE 0x5b -#define LANG_SLOVAK 0x1b -#define LANG_SLOVENIAN 0x24 -#define LANG_SOTHO 0x6c -#define LANG_SPANISH 0x0a -#define LANG_SWAHILI 0x41 -#define LANG_SWEDISH 0x1d -#define LANG_SYRIAC 0x5a -#define LANG_TAJIK 0x28 -#define LANG_TAMAZIGHT 0x5f -#define LANG_TAMIL 0x49 -#define LANG_TATAR 0x44 -#define LANG_TELUGU 0x4a -#define LANG_THAI 0x1e -#define LANG_TIBETAN 0x51 -#define LANG_TIGRIGNA 0x73 -#define LANG_TSWANA 0x32 -#define LANG_TURKISH 0x1f -#define LANG_TURKMEN 0x42 -#define LANG_UIGHUR 0x80 -#define LANG_UKRAINIAN 0x22 -#define LANG_UPPER_SORBIAN 0x2e -#define LANG_URDU 0x20 -#define LANG_UZBEK 0x43 -#define LANG_VIETNAMESE 0x2a -#define LANG_WELSH 0x52 -#define LANG_WOLOF 0x88 -#define LANG_XHOSA 0x34 -#define LANG_YAKUT 0x85 -#define LANG_YI 0x78 -#define LANG_YORUBA 0x6a -#define LANG_ZULU 0x35 - -#define VER_WORKSTATION_NT 0x40000000 -#define VER_SERVER_NT 0x80000000 - -#define VER_SUITE_SMALLBUSINESS 1 -#define VER_SUITE_ENTERPRISE 2 -#define VER_SUITE_BACKOFFICE 4 -#define VER_SUITE_COMMUNICATIONS 8 -#define VER_SUITE_TERMINAL 16 -#define VER_SUITE_SMALLBUSINESS_RESTRICTED 32 -#define VER_SUITE_EMBEDDEDNT 64 -#define VER_SUITE_DATACENTER 128 -#define VER_SUITE_SINGLEUSERTS 256 -#define VER_SUITE_PERSONAL 512 -#define VER_SUITE_BLADE 1024 -#define VER_SUITE_EMBEDDED_RESTRICTED 2048 -#define VER_SUITE_SECURITY_APPLIANCE 4096 -#define VER_SUITE_STORAGE_SERVER 8192 -#define VER_SUITE_COMPUTE_SERVER 16384 -#define VER_SUITE_WH_SERVER 32768 +#define LANG_AFRIKAANS 0x36 +#define LANG_ALBANIAN 0x1c +#define LANG_ALSATIAN 0x84 +#define LANG_AMHARIC 0x5e +#define LANG_ARABIC 0x01 +#define LANG_ARMENIAN 0x2b +#define LANG_ASSAMESE 0x4d +#define LANG_AZERI 0x2c +#define LANG_BASHKIR 0x6d +#define LANG_BASQUE 0x2d +#define LANG_BELARUSIAN 0x23 +#define LANG_BENGALI 0x45 +#define LANG_BRETON 0x7e +#define LANG_BOSNIAN 0x1a +#define LANG_BOSNIAN_NEUTRAL 0x781a +#define LANG_BULGARIAN 0x02 +#define LANG_CATALAN 0x03 +#define LANG_CHINESE 0x04 +#define LANG_CHINESE_SIMPLIFIED 0x04 +#define LANG_CHINESE_TRADITIONAL 0x7c04 +#define LANG_CORSICAN 0x83 +#define LANG_CROATIAN 0x1a +#define LANG_CZECH 0x05 +#define LANG_DANISH 0x06 +#define LANG_DARI 0x8c +#define LANG_DIVEHI 0x65 +#define LANG_DUTCH 0x13 +#define LANG_ENGLISH 0x09 +#define LANG_ESTONIAN 0x25 +#define LANG_FAEROESE 0x38 +#define LANG_FARSI 0x29 +#define LANG_FILIPINO 0x64 +#define LANG_FINNISH 0x0b +#define LANG_FRENCH 0x0c +#define LANG_FRISIAN 0x62 +#define LANG_GALICIAN 0x56 +#define LANG_GEORGIAN 0x37 +#define LANG_GERMAN 0x07 +#define LANG_GREEK 0x08 +#define LANG_GREENLANDIC 0x6f +#define LANG_GUJARATI 0x47 +#define LANG_HAUSA 0x68 +#define LANG_HEBREW 0x0d +#define LANG_HINDI 0x39 +#define LANG_HUNGARIAN 0x0e +#define LANG_ICELANDIC 0x0f +#define LANG_IGBO 0x70 +#define LANG_INDONESIAN 0x21 +#define LANG_INUKTITUT 0x5d +#define LANG_IRISH 0x3c +#define LANG_ITALIAN 0x10 +#define LANG_JAPANESE 0x11 +#define LANG_KANNADA 0x4b +#define LANG_KASHMIRI 0x60 +#define LANG_KAZAK 0x3f +#define LANG_KHMER 0x53 +#define LANG_KICHE 0x86 +#define LANG_KINYARWANDA 0x87 +#define LANG_KONKANI 0x57 +#define LANG_KOREAN 0x12 +#define LANG_KYRGYZ 0x40 +#define LANG_LAO 0x54 +#define LANG_LATVIAN 0x26 +#define LANG_LITHUANIAN 0x27 +#define LANG_LOWER_SORBIAN 0x2e +#define LANG_LUXEMBOURGISH 0x6e +#define LANG_MACEDONIAN 0x2f +#define LANG_MALAY 0x3e +#define LANG_MALAYALAM 0x4c +#define LANG_MALTESE 0x3a +#define LANG_MANIPURI 0x58 +#define LANG_MAORI 0x81 +#define LANG_MAPUDUNGUN 0x7a +#define LANG_MARATHI 0x4e +#define LANG_MOHAWK 0x7c +#define LANG_MONGOLIAN 0x50 +#define LANG_NEPALI 0x61 +#define LANG_NORWEGIAN 0x14 +#define LANG_OCCITAN 0x82 +#define LANG_ORIYA 0x48 +#define LANG_PASHTO 0x63 +#define LANG_PERSIAN 0x29 +#define LANG_POLISH 0x15 +#define LANG_PORTUGUESE 0x16 +#define LANG_PUNJABI 0x46 +#define LANG_QUECHUA 0x6b +#define LANG_ROMANIAN 0x18 +#define LANG_ROMANSH 0x17 +#define LANG_RUSSIAN 0x19 +#define LANG_SAMI 0x3b +#define LANG_SANSKRIT 0x4f +#define LANG_SERBIAN 0x1a +#define LANG_SERBIAN_NEUTRAL 0x7c1a +#define LANG_SINDHI 0x59 +#define LANG_SINHALESE 0x5b +#define LANG_SLOVAK 0x1b +#define LANG_SLOVENIAN 0x24 +#define LANG_SOTHO 0x6c +#define LANG_SPANISH 0x0a +#define LANG_SWAHILI 0x41 +#define LANG_SWEDISH 0x1d +#define LANG_SYRIAC 0x5a +#define LANG_TAJIK 0x28 +#define LANG_TAMAZIGHT 0x5f +#define LANG_TAMIL 0x49 +#define LANG_TATAR 0x44 +#define LANG_TELUGU 0x4a +#define LANG_THAI 0x1e +#define LANG_TIBETAN 0x51 +#define LANG_TIGRIGNA 0x73 +#define LANG_TSWANA 0x32 +#define LANG_TURKISH 0x1f +#define LANG_TURKMEN 0x42 +#define LANG_UIGHUR 0x80 +#define LANG_UKRAINIAN 0x22 +#define LANG_UPPER_SORBIAN 0x2e +#define LANG_URDU 0x20 +#define LANG_UZBEK 0x43 +#define LANG_VIETNAMESE 0x2a +#define LANG_WELSH 0x52 +#define LANG_WOLOF 0x88 +#define LANG_XHOSA 0x34 +#define LANG_YAKUT 0x85 +#define LANG_YI 0x78 +#define LANG_YORUBA 0x6a +#define LANG_ZULU 0x35 #endif /* _NTDEF_ */ diff --git a/include/psdk/wingdi.h b/include/psdk/wingdi.h index 641aeb31684..550ef68c626 100644 --- a/include/psdk/wingdi.h +++ b/include/psdk/wingdi.h @@ -3022,6 +3022,7 @@ BOOL WINAPI GetCharWidth32A(HDC,UINT,UINT,LPINT); BOOL WINAPI GetCharWidth32W(HDC,UINT,UINT,LPINT); BOOL WINAPI GetCharWidthA(HDC,UINT,UINT,LPINT); BOOL WINAPI GetCharWidthW(HDC,UINT,UINT,LPINT); +BOOL WINAPI GetCharWidthI(HDC,UINT,UINT,LPWORD,LPINT); BOOL WINAPI GetCharWidthFloatA(HDC,UINT,UINT,PFLOAT); BOOL WINAPI GetCharWidthFloatW(HDC,UINT,UINT,PFLOAT); int WINAPI GetClipBox(HDC,LPRECT); @@ -3097,9 +3098,11 @@ int WINAPI GetTextCharset(HDC); int WINAPI GetTextCharsetInfo(HDC,LPFONTSIGNATURE,DWORD); COLORREF WINAPI GetTextColor(HDC); BOOL WINAPI GetTextExtentExPointA(HDC,LPCSTR,int,int,LPINT,LPINT,LPSIZE); -BOOL WINAPI GetTextExtentExPointW( HDC,LPCWSTR,int,int,LPINT,LPINT,LPSIZE ); +BOOL WINAPI GetTextExtentExPointW(HDC,LPCWSTR,int,int,LPINT,LPINT,LPSIZE); +BOOL WINAPI GetTextExtentExPointI(HDC,LPWORD,int,int,LPINT,LPINT,LPSIZE); BOOL WINAPI GetTextExtentPointA(HDC,LPCSTR,int,LPSIZE); BOOL WINAPI GetTextExtentPointW(HDC,LPCWSTR,int,LPSIZE); +BOOL WINAPI GetTextExtentPointI(HDC,LPWORD,int,LPSIZE); BOOL WINAPI GetTextExtentPoint32A(HDC,LPCSTR,int,LPSIZE); BOOL WINAPI GetTextExtentPoint32W( HDC,LPCWSTR,int,LPSIZE); int WINAPI GetTextFaceA(HDC,int,LPSTR); diff --git a/include/reactos/mc/bugcodes.mc b/include/reactos/mc/bugcodes.mc index f59d7f0d7f3..bb0b556f564 100644 --- a/include/reactos/mc/bugcodes.mc +++ b/include/reactos/mc/bugcodes.mc @@ -1311,6 +1311,16 @@ restart your computer, press F8 to select Advanced Startup Options, and then select Safe Mode. . +MessageId=0xC6 +Severity=Success +Facility=System +SymbolicName=DRIVER_CAUGHT_MODIFYING_FREED_POOL +Language=English +A device driver attempting to corrupt the system has been caught. +The faulty driver currently on the kernel stack must be replaced +with a working version. +. + MessageId=0xC8 Severity=Success Facility=System diff --git a/include/reactos/win32k/ntgdityp.h b/include/reactos/win32k/ntgdityp.h index 1aedf765dbc..667060b87d6 100644 --- a/include/reactos/win32k/ntgdityp.h +++ b/include/reactos/win32k/ntgdityp.h @@ -192,6 +192,9 @@ typedef DWORD LFTYPE; #define GCABCW_NOFLOAT 0x0001 #define GCABCW_INDICES 0x0002 +// NtGdiGetTextExtent* flags (reactos own) +#define GTEF_INDICES 0x1 + /* CAPS1 support */ #define CAPS1 94 //#define C1_TRANSPARENT 0x0001 diff --git a/include/xdk/iotypes.h b/include/xdk/iotypes.h index 55673244e1a..9e1446c2245 100644 --- a/include/xdk/iotypes.h +++ b/include/xdk/iotypes.h @@ -1793,6 +1793,9 @@ $if (_WDMDDK_) #define IRP_DEFER_IO_COMPLETION 0x00000800 #define IRP_OB_QUERY_NAME 0x00001000 #define IRP_HOLD_DEVICE_QUEUE 0x00002000 +/* The following 2 are missing in latest WDK */ +#define IRP_RETRY_IO_COMPLETION 0x00004000 +#define IRP_CLASS_CACHE_OPERATION 0x00008000 #define IRP_QUOTA_CHARGED 0x01 #define IRP_ALLOCATED_MUST_SUCCEED 0x02 diff --git a/lib/drivers/ip/transport/tcp/tcp.c b/lib/drivers/ip/transport/tcp/tcp.c index e8ea9bb290f..e980f6b1e15 100644 --- a/lib/drivers/ip/transport/tcp/tcp.c +++ b/lib/drivers/ip/transport/tcp/tcp.c @@ -35,20 +35,20 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) Connection, Connection->SocketContext)); /* Things that can happen when we try the initial connection */ - if( Connection->SignalState & SEL_CONNECT ) { + if( Connection->SignalState & (SEL_CONNECT | SEL_FIN) ) { while (!IsListEmpty(&Connection->ConnectRequest)) { Entry = RemoveHeadList( &Connection->ConnectRequest ); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Bucket->Status = STATUS_SUCCESS; + Bucket->Status = (Connection->SignalState & SEL_CONNECT) ? STATUS_SUCCESS : STATUS_CANCELLED; Bucket->Information = 0; InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } } - if( Connection->SignalState & SEL_ACCEPT ) { + if( Connection->SignalState & (SEL_ACCEPT | SEL_FIN) ) { /* Handle readable on a listening socket -- * TODO: Implement filtering */ @@ -90,7 +90,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) } /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ ) { + if( Connection->SignalState & (SEL_READ | SEL_FIN) ) { TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", IsListEmpty(&Connection->ReceiveRequest) ? "empty" : "nonempty")); @@ -145,7 +145,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) } } } - if( Connection->SignalState & SEL_WRITE ) { + if( Connection->SignalState & (SEL_WRITE | SEL_FIN) ) { TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", IsListEmpty(&Connection->SendRequest) ? "empty" : "nonempty")); @@ -234,7 +234,10 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) /* If the socket is dead, remove the reference we added for oskit */ if (Connection->SignalState & SEL_FIN) + { + Connection->SocketContext = NULL; DereferenceObject(Connection); + } } VOID ConnectionFree(PVOID Object) { @@ -663,17 +666,15 @@ NTSTATUS TCPClose KIRQL OldIrql; NTSTATUS Status; PVOID Socket; + PADDRESS_FILE AddressFile = NULL; + PCONNECTION_ENDPOINT AddressConnection = NULL; - /* We don't rely on SocketContext == NULL for socket - * closure anymore but we still need it to determine - * if we caused the closure - */ LockObject(Connection, &OldIrql); Socket = Connection->SocketContext; Connection->SocketContext = NULL; /* Don't try to close again if the other side closed us already */ - if (!(Connection->SignalState & SEL_FIN)) + if (Socket) { /* We need to close here otherwise oskit will never indicate * SEL_FIN and we will never fully close the connection */ @@ -693,11 +694,26 @@ NTSTATUS TCPClose } if (Connection->AddressFile) - DereferenceObject(Connection->AddressFile); + { + LockObjectAtDpcLevel(Connection->AddressFile); + if (Connection->AddressFile->Connection == Connection) + { + AddressConnection = Connection->AddressFile->Connection; + Connection->AddressFile->Connection = NULL; + } + UnlockObjectFromDpcLevel(Connection->AddressFile); + + AddressFile = Connection->AddressFile; + Connection->AddressFile = NULL; + } UnlockObject(Connection, OldIrql); DereferenceObject(Connection); + if (AddressConnection) + DereferenceObject(AddressConnection); + if (AddressFile) + DereferenceObject(AddressFile); return Status; } diff --git a/lib/drivers/oskittcp/oskittcp/interface.c b/lib/drivers/oskittcp/oskittcp/interface.c index 3c589e7b255..1959e679ac8 100644 --- a/lib/drivers/oskittcp/oskittcp/interface.c +++ b/lib/drivers/oskittcp/oskittcp/interface.c @@ -114,6 +114,12 @@ void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ) DbgPrint ( line ); } +void InitializeSocketFlags(struct socket *so) +{ + so->so_state |= SS_NBIO; + so->so_options |= SO_DONTROUTE; +} + /* From uipc_syscalls.c */ int OskitTCPSocket( void *context, @@ -128,7 +134,7 @@ int OskitTCPSocket( void *context, int error = socreate(domain, &so, type, proto); if( !error ) { so->so_connection = context; - so->so_state |= SS_NBIO; + InitializeSocketFlags(so); *aso = so; } OSKUnlock(); @@ -170,7 +176,7 @@ int OskitTCPRecv( void *connection, &tcp_flags ); OSKUnlock(); - *OutLen = Len - uio.uio_resid; + if (error == 0) *OutLen = Len - uio.uio_resid; return error; } @@ -317,7 +323,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, error = sosend( socket, NULL, &uio, NULL, NULL, 0 ); OSKUnlock(); - *OutLen = Len - uio.uio_resid; + if (error == 0) *OutLen = Len - uio.uio_resid; return error; } @@ -399,7 +405,8 @@ int OskitTCPAccept( void *socket, if (error) goto out; - so->so_state |= SS_NBIO | SS_ISCONNECTED; + InitializeSocketFlags(so); + so->so_state |= SS_ISCONNECTED; so->so_q = so->so_q0 = NULL; so->so_qlen = so->so_q0len = 0; so->so_head = 0; diff --git a/lib/drivers/oskittcp/oskittcp/route.c b/lib/drivers/oskittcp/oskittcp/route.c index 8ba57da7e3e..59311a4648c 100644 --- a/lib/drivers/oskittcp/oskittcp/route.c +++ b/lib/drivers/oskittcp/oskittcp/route.c @@ -106,6 +106,7 @@ rtalloc1(dst, report, ignflags) int report; u_long ignflags; { +#ifndef __REACTOS__ register struct radix_node_head *rnh = rt_tables[dst->sa_family]; register struct rtentry *rt; register struct radix_node *rn; @@ -142,6 +143,9 @@ rtalloc1(dst, report, ignflags) } splx(s); return (newrt); +#else + return NULL; +#endif } void diff --git a/lib/drivers/oskittcp/oskittcp/tcp_input.c b/lib/drivers/oskittcp/oskittcp/tcp_input.c index 1811476e9cf..39116abf15f 100644 --- a/lib/drivers/oskittcp/oskittcp/tcp_input.c +++ b/lib/drivers/oskittcp/oskittcp/tcp_input.c @@ -84,6 +84,7 @@ struct inpcbinfo tcbinfo; * Set DELACK for segments received in order, but ack immediately * when segments are out of order (so fast retransmit can work). */ +#ifdef TCP_ACK_HACK #define TCP_REASS(tp, ti, m, so, flags) { \ if ((ti)->ti_seq == (tp)->rcv_nxt && \ (tp)->seg_next == (struct tcpiphdr *)(tp) && \ @@ -103,6 +104,24 @@ struct inpcbinfo tcbinfo; tp->t_flags |= TF_ACKNOW; \ } \ } +#else +#define TCP_REASS(tp, ti, m, so, flags) { \ + if ((ti)->ti_seq == (tp)->rcv_nxt && \ + (tp)->seg_next == (struct tcpiphdr *)(tp) && \ + (tp)->t_state == TCPS_ESTABLISHED) { \ + tp->t_flags |= TF_DELACK; \ + (tp)->rcv_nxt += (ti)->ti_len; \ + flags = (ti)->ti_flags & TH_FIN; \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ + sbappend(&(so)->so_rcv, (m)); \ + sorwakeup(so); \ + } else { \ + (flags) = tcp_reass((tp), (ti), (m)); \ + tp->t_flags |= TF_ACKNOW; \ + } \ +} +#endif #ifndef TUBA_INCLUDE int @@ -573,6 +592,7 @@ findpcb: */ sbappend(&so->so_rcv, m); sorwakeup(so); +#ifdef TCP_ACK_HACK /* * If this is a short packet, then ACK now - with Nagel * congestion avoidance sender won't send more until @@ -584,6 +604,9 @@ findpcb: } else { tp->t_flags |= TF_DELACK; } +#else + tp->t_flags |= TF_DELACK; +#endif return; } } @@ -1950,31 +1973,26 @@ tcp_mss(tp, offer) struct tcpcb *tp; int offer; { +#ifndef __REACTOS__ register struct rtentry *rt; struct ifnet *ifp = NULL; - register int rtt, mss; + struct rmxp_tao *taop; + register int rtt; +#endif + register int mss; u_long bufsize; struct inpcb *inp; struct socket *so; - struct rmxp_tao *taop; int origoffer = offer; inp = tp->t_inpcb; - if ((rt = tcp_rtlookup(inp)) == NULL) { + so = inp->inp_socket; #ifndef __REACTOS__ + if ((rt = tcp_rtlookup(inp)) == NULL) { tp->t_maxopd = tp->t_maxseg = tcp_mssdflt; -#else - if (offer < tcp_mssdflt) - tp->t_maxopd = tp->t_maxseg = tcp_mssdflt; - else - tp->t_maxopd = tp->t_maxseg = min(offer, tcp_mssopt(tp)); -#endif return; } -#ifndef __REACTOS__ ifp = rt->rt_ifp; -#endif - so = inp->inp_socket; taop = rmx_taop(rt->rt_rmx); /* @@ -1983,6 +2001,7 @@ tcp_mss(tp, offer) */ if (offer == -1) offer = taop->tao_mssopt; +#endif /* * Offer == 0 means that there was no MSS on the SYN segment, * in this case we use tcp_mssdflt. @@ -1997,6 +2016,7 @@ tcp_mss(tp, offer) * funny things may happen in tcp_output. */ offer = max(offer, 64); +#ifndef __REACTOS__ taop->tao_mssopt = offer; /* @@ -2037,6 +2057,10 @@ tcp_mss(tp, offer) if (!in_localaddr(inp->inp_faddr)) mss = min(mss, tcp_mssdflt); } +#else + mss = tcp_mssopt(tp); + mss = min(mss, tcp_mssdflt); +#endif mss = min(mss, offer); /* * maxopd stores the maximum length of data AND options @@ -2074,7 +2098,7 @@ tcp_mss(tp, offer) * number of mss units; if the mss is larger than * the socket buffer, decrease the mss. */ -#ifdef RTV_SPIPE +#if defined(RTV_SPIPE) && !defined(__REACTOS__) if ((bufsize = rt->rt_rmx.rmx_sendpipe) == 0) #endif bufsize = so->so_snd.sb_hiwat; @@ -2088,7 +2112,7 @@ tcp_mss(tp, offer) } tp->t_maxseg = mss; -#ifdef RTV_RPIPE +#if defined(RTV_RPIPE) && !defined(__REACTOS__) if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0) #endif bufsize = so->so_rcv.sb_hiwat; @@ -2098,12 +2122,15 @@ tcp_mss(tp, offer) bufsize = sb_max; (void)sbreserve(&so->so_rcv, bufsize); } +#ifndef __REACTOS__ /* * Don't force slow-start on local network. */ if (!in_localaddr(inp->inp_faddr)) +#endif tp->snd_cwnd = mss; +#ifndef __REACTOS__ if (rt->rt_rmx.rmx_ssthresh) { /* * There's some sort of gateway or interface @@ -2114,6 +2141,7 @@ tcp_mss(tp, offer) tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh); tcpstat.tcps_usedssthresh++; } +#endif } /* diff --git a/lib/drivers/oskittcp/oskittcp/tcp_subr.c b/lib/drivers/oskittcp/oskittcp/tcp_subr.c index 4632b688ef1..b9c215140e2 100644 --- a/lib/drivers/oskittcp/oskittcp/tcp_subr.c +++ b/lib/drivers/oskittcp/oskittcp/tcp_subr.c @@ -560,6 +560,7 @@ struct rtentry * tcp_rtlookup(inp) struct inpcb *inp; { +#ifndef __REACTOS__ struct route *ro; struct rtentry *rt; @@ -576,7 +577,10 @@ tcp_rtlookup(inp) rt = ro->ro_rt; } } - return rt; + return rt; +#else + return NULL; +#endif } /* diff --git a/lib/drivers/oskittcp/oskittcp/uipc_socket2.c b/lib/drivers/oskittcp/oskittcp/uipc_socket2.c index d565910f289..4155922d804 100644 --- a/lib/drivers/oskittcp/oskittcp/uipc_socket2.c +++ b/lib/drivers/oskittcp/oskittcp/uipc_socket2.c @@ -118,8 +118,10 @@ soisconnected(so) wakeup(so, (caddr_t)&head->so_timeo); } else { wakeup(so, (caddr_t)&so->so_timeo); +#ifndef __REACTOS__ sorwakeup(so); sowwakeup(so); +#endif } } @@ -131,8 +133,10 @@ soisdisconnecting(so) so->so_state &= ~SS_ISCONNECTING; so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); wakeup(so, (caddr_t)&so->so_timeo); +#ifndef __REACTOS__ sowwakeup(so); sorwakeup(so); +#endif } void @@ -144,8 +148,10 @@ soisdisconnected(so) so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); wakeup(so, (caddr_t)&so->so_timeo); +#ifndef __REACTOS__ sowwakeup(so); sorwakeup(so); +#endif } /* @@ -192,7 +198,9 @@ sonewconn1(head, connstatus) return ((struct socket *)0); } if (connstatus) { +#ifndef __REACTOS__ sorwakeup(head); +#endif wakeup(head, (caddr_t)&head->so_timeo); so->so_state |= connstatus; } diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c index b44b58976b2..18dd8aa2b10 100644 --- a/ntoskrnl/ex/init.c +++ b/ntoskrnl/ex/init.c @@ -815,6 +815,51 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock) } } +VOID +NTAPI +ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG PagesToDestroy, + IN TYPE_OF_MEMORY MemoryType) +{ + PLIST_ENTRY ListEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor; + + DPRINT1("Burn RAM amount: %d pages\n", PagesToDestroy); + + /* Loop the memory descriptors, beginning at the end */ + for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink; + ListEntry != &LoaderBlock->MemoryDescriptorListHead; + ListEntry = ListEntry->Blink) + { + /* Get the memory descriptor structure */ + MemDescriptor = CONTAINING_RECORD(ListEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Is memory free there or is it temporary? */ + if (MemDescriptor->MemoryType == LoaderFree || + MemDescriptor->MemoryType == LoaderFirmwareTemporary) + { + /* Check if the descriptor has more pages than we want */ + if (MemDescriptor->PageCount > PagesToDestroy) + { + /* Change block's page count, ntoskrnl doesn't care much */ + MemDescriptor->PageCount -= PagesToDestroy; + break; + } + else + { + /* Change block type */ + MemDescriptor->MemoryType = MemoryType; + PagesToDestroy -= MemDescriptor->PageCount; + + /* Check if we are done */ + if (PagesToDestroy == 0) break; + } + } + } +} + VOID NTAPI ExpInitializeExecutive(IN ULONG Cpu, @@ -919,12 +964,7 @@ ExpInitializeExecutive(IN ULONG Cpu, { /* Read the number of pages we'll use */ PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); - if (PerfMem) - { - /* FIXME: TODO */ - DPRINT1("Burnable memory support not yet present." - "/BURNMEM option ignored.\n"); - } + if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad); } } } diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index bec9be6d1b4..5f2998debdf 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -1073,7 +1073,7 @@ IopParseDevice( IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, - IN OUT PVOID Context OPTIONAL, + IN OUT PVOID Context, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object ); diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index a7154de564d..346d9c08a54 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -435,6 +435,9 @@ typedef struct _MMFREE_POOL_ENTRY struct _MMFREE_POOL_ENTRY *Owner; } MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY; +/* Signature of a freed block */ +#define MM_FREE_POOL_SIGNATURE 'ARM3' + /* Paged pool information */ typedef struct _MM_PAGED_POOL_INFO { diff --git a/ntoskrnl/include/internal/po.h b/ntoskrnl/include/internal/po.h index 01ddf3b5c37..ef4ee1a5ff1 100644 --- a/ntoskrnl/include/internal/po.h +++ b/ntoskrnl/include/internal/po.h @@ -6,6 +6,7 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ +#include "initguid.h" #include // diff --git a/ntoskrnl/io/iomgr/device.c b/ntoskrnl/io/iomgr/device.c index ec6de6c770a..88e5ba4fa67 100644 --- a/ntoskrnl/io/iomgr/device.c +++ b/ntoskrnl/io/iomgr/device.c @@ -671,7 +671,6 @@ IopGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, { NTSTATUS Status; IO_STACK_LOCATION Stack = {0}; - IO_STATUS_BLOCK IoStatusBlock; PDEVICE_RELATIONS DeviceRelations; PDEVICE_OBJECT DeviceObject = NULL; @@ -682,19 +681,17 @@ IopGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, if (!DeviceObject) return STATUS_NO_SUCH_DEVICE; /* Define input parameters */ + Stack.MajorFunction = IRP_MJ_PNP; + Stack.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS; Stack.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation; Stack.FileObject = FileObject; /* Call the driver to query all relations (IRP_MJ_PNP) */ - Status = IopInitiatePnpIrp(DeviceObject, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_RELATIONS, - &Stack); + Status = IopSynchronousCall(DeviceObject, + &Stack, + (PVOID)&DeviceRelations); if (!NT_SUCCESS(Status)) return Status; - /* Get returned pointer to DEVICE_RELATIONS */ - DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; - /* Make sure it's not NULL and contains only one object */ ASSERT(DeviceRelations); ASSERT(DeviceRelations->Count == 1); diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c index dcc086eb659..0a52f2aaf8d 100644 --- a/ntoskrnl/io/iomgr/deviface.c +++ b/ntoskrnl/io/iomgr/deviface.c @@ -731,11 +731,6 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid, } KeyName.Length = KeyName.MaximumLength = (USHORT)bip->DataLength - 4 * sizeof(WCHAR); KeyName.Buffer = &((PWSTR)bip->Data)[4]; - if (KeyName.Length && KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] == UNICODE_NULL) - { - /* Remove trailing NULL */ - KeyName.Length -= sizeof(WCHAR); - } /* Add new symbolic link to symbolic link list */ if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) > ReturnBuffer.MaximumLength) @@ -1232,6 +1227,7 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; ULONG LinkedValue; + GUID DeviceGuid; if (SymbolicLinkName == NULL) return STATUS_INVALID_PARAMETER_1; @@ -1309,13 +1305,20 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, DPRINT1("IoGetDeviceObjectPointer() failed with status 0x%08lx\n", Status); return Status; } + + Status = RtlGUIDFromString(&GuidString, &DeviceGuid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlGUIDFromString() failed with status 0x%08lx\n", Status); + return Status; + } EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL : &GUID_DEVICE_INTERFACE_REMOVAL; IopNotifyPlugPlayNotification( PhysicalDeviceObject, EventCategoryDeviceInterfaceChange, EventGuid, - &GuidString, + &DeviceGuid, (PVOID)SymbolicLinkName); ObDereferenceObject(FileObject); diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c index b6a63d9af66..46060f470b2 100644 --- a/ntoskrnl/io/iomgr/file.c +++ b/ntoskrnl/io/iomgr/file.c @@ -171,7 +171,7 @@ IopParseDevice(IN PVOID ParseObject, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, - IN OUT PVOID Context OPTIONAL, + IN OUT PVOID Context, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object) { diff --git a/ntoskrnl/io/iomgr/iofunc.c b/ntoskrnl/io/iomgr/iofunc.c index c40e7c9d789..22e8710a4e3 100644 --- a/ntoskrnl/io/iomgr/iofunc.c +++ b/ntoskrnl/io/iomgr/iofunc.c @@ -11,6 +11,7 @@ /* INCLUDES *****************************************************************/ #include +#include #define NDEBUG #include #include "internal/io_i.h" @@ -1175,6 +1176,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, Irp->RequestorMode = PreviousMode; Irp->UserIosb = IoStatusBlock; Irp->UserEvent = Event; + Irp->UserBuffer = Buffer; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; @@ -3222,12 +3224,13 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, PFILE_OBJECT FileObject; PIRP Irp; PIO_STACK_LOCATION StackPtr; - PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT DeviceObject, TargetDeviceObject; PKEVENT Event = NULL; BOOLEAN LocalEvent = FALSE; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status; IO_STATUS_BLOCK KernelIosb; + TARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure; PAGED_CODE(); IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle); @@ -3276,6 +3279,10 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, NULL); if (!NT_SUCCESS(Status)) return Status; + /* Get target device for notification */ + Status = IoGetRelatedTargetDevice(FileObject, &TargetDeviceObject); + if (!NT_SUCCESS(Status)) TargetDeviceObject = NULL; + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -3289,6 +3296,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, if (!Event) { ObDereferenceObject(FileObject); + if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent(Event, SynchronizationEvent, FALSE); @@ -3303,7 +3311,11 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, /* Allocate the IRP */ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, Event); + if (!Irp) + { + if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject); + return IopCleanupFailedIrp(FileObject, NULL, Event); + } /* Set up the IRP */ Irp->RequestorMode = PreviousMode; @@ -3338,6 +3350,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, { /* Allocating failed, clean up and return the exception code */ IopCleanupAfterException(FileObject, Irp, NULL, Event); + if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; @@ -3370,6 +3383,17 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, IoStatusBlock); } + if (TargetDeviceObject && NT_SUCCESS(Status)) + { + /* Time to report change */ + NotificationStructure.Version = 1; + NotificationStructure.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION); + NotificationStructure.Event = GUID_IO_VOLUME_NAME_CHANGE; + NotificationStructure.FileObject = NULL; + NotificationStructure.NameBufferOffset = - 1; + Status = IoReportTargetDeviceChange(TargetDeviceObject, &NotificationStructure); + } + /* Return status */ return Status; } diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c index a578e89731a..55d316adf55 100644 --- a/ntoskrnl/io/iomgr/irp.c +++ b/ntoskrnl/io/iomgr/irp.c @@ -18,6 +18,8 @@ #undef IoCallDriver #undef IoCompleteRequest +PIRP IopDeadIrp; + /* PRIVATE FUNCTIONS ********************************************************/ VOID @@ -112,10 +114,9 @@ IopAbortInterruptedIrp(IN PKEVENT EventObject, VOID NTAPI -IopRemoveThreadIrp(VOID) +IopDisassociateThreadIrp(VOID) { - KIRQL OldIrql; - PIRP DeadIrp; + KIRQL OldIrql, LockIrql; PETHREAD IrpThread; PLIST_ENTRY IrpEntry; PIO_ERROR_LOG_PACKET ErrorLogEntry; @@ -134,36 +135,41 @@ IopRemoveThreadIrp(VOID) return; } + /* Ensure no one will come disturb */ + LockIrql = KeAcquireQueuedSpinLock(LockQueueIoCompletionLock); + /* Get the misbehaving IRP */ IrpEntry = IrpThread->IrpList.Flink; - DeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry); + IopDeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry); IOTRACE(IO_IRP_DEBUG, "%s - Deassociating IRP %p for %p\n", __FUNCTION__, - DeadIrp, + IopDeadIrp, IrpThread); /* Don't cancel the IRP if it's already been completed far */ - if (DeadIrp->CurrentLocation == (DeadIrp->StackCount + 2)) + if (IopDeadIrp->CurrentLocation == (IopDeadIrp->StackCount + 2)) { /* Return */ + KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql); KeLowerIrql(OldIrql); return; } /* Disown the IRP! */ - DeadIrp->Tail.Overlay.Thread = NULL; + IopDeadIrp->Tail.Overlay.Thread = NULL; RemoveHeadList(&IrpThread->IrpList); - InitializeListHead(&DeadIrp->ThreadListEntry); + InitializeListHead(&IopDeadIrp->ThreadListEntry); /* Get the stack location and check if it's valid */ - IoStackLocation = IoGetCurrentIrpStackLocation(DeadIrp); - if (DeadIrp->CurrentLocation <= DeadIrp->StackCount) + IoStackLocation = IoGetCurrentIrpStackLocation(IopDeadIrp); + if (IopDeadIrp->CurrentLocation <= IopDeadIrp->StackCount) { /* Get the device object */ DeviceObject = IoStackLocation->DeviceObject; } + KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql); /* Lower IRQL now, since we have the pointers we need */ KeLowerIrql(OldIrql); @@ -176,7 +182,7 @@ IopRemoveThreadIrp(VOID) if (ErrorLogEntry) { /* Write the entry */ - ErrorLogEntry->ErrorCode = 0xBAADF00D; /* FIXME */ + ErrorLogEntry->ErrorCode = IO_DRIVER_CANCEL_TIMEOUT; IoWriteErrorLogEntry(ErrorLogEntry); } } @@ -982,14 +988,12 @@ NTAPI IoCancelIrp(IN PIRP Irp) { KIRQL OldIrql; - KIRQL IrqlAtEntry; PDRIVER_CANCEL CancelRoutine; IOTRACE(IO_IRP_DEBUG, "%s - Canceling IRP %p\n", __FUNCTION__, Irp); ASSERT(Irp->Type == IO_TYPE_IRP); - IrqlAtEntry = KeGetCurrentIrql(); /* Acquire the cancel lock and cancel the IRP */ IoAcquireCancelSpinLock(&OldIrql); @@ -1005,7 +1009,7 @@ IoCancelIrp(IN PIRP Irp) /* It is, bugcheck */ KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP, (ULONG_PTR)Irp, - 0, + (ULONG_PTR)CancelRoutine, 0, 0); } @@ -1013,7 +1017,6 @@ IoCancelIrp(IN PIRP Irp) /* Set the cancel IRQL And call the routine */ Irp->CancelIrql = OldIrql; CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp); - ASSERT(IrqlAtEntry == KeGetCurrentIrql()); return TRUE; } @@ -1034,6 +1037,11 @@ IoCancelThreadIo(IN PETHREAD Thread) LARGE_INTEGER Interval; PLIST_ENTRY ListHead, NextEntry; PIRP Irp; + PAGED_CODE(); + + /* Windows isn't using given thread, but using current. */ + Thread = PsGetCurrentThread(); + IOTRACE(IO_IRP_DEBUG, "%s - Canceling IRPs for Thread %p\n", __FUNCTION__, @@ -1077,7 +1085,7 @@ IoCancelThreadIo(IN PETHREAD Thread) { /* Print out a message and remove the IRP */ DPRINT1("Broken driver did not complete!\n"); - IopRemoveThreadIrp(); + IopDisassociateThreadIrp(); } /* Raise the IRQL Again */ @@ -1415,7 +1423,6 @@ IofCompleteRequest(IN PIRP Irp, else { /* The IRP just got canceled... does a thread still own it? */ - Thread = Irp->Tail.Overlay.Thread; if (Thread) { /* Yes! There is still hope! Initialize the APC */ @@ -1576,7 +1583,7 @@ IoGetPagingIoPriority(IN PIRP Irp) Flags = Irp->Flags; /* Check what priority it has */ - if (Flags & 0x8000) // FIXME: Undocumented flag + if (Flags & IRP_CLASS_CACHE_OPERATION) { /* High priority */ Priority = IoPagingPriorityHigh; @@ -1604,7 +1611,12 @@ NTAPI IoGetRequestorProcess(IN PIRP Irp) { /* Return the requestor process */ - return Irp->Tail.Overlay.Thread->ThreadsProcess; + if (Irp->Tail.Overlay.Thread) + { + return Irp->Tail.Overlay.Thread->ThreadsProcess; + } + + return NULL; } /* @@ -1614,8 +1626,15 @@ ULONG NTAPI IoGetRequestorProcessId(IN PIRP Irp) { + PEPROCESS Process; + /* Return the requestor process' id */ - return PtrToUlong(IoGetRequestorProcess(Irp)->UniqueProcessId); + if ((Process = IoGetRequestorProcess(Irp))) + { + return PtrToUlong(Process->UniqueProcessId); + } + + return 0; } /* @@ -1626,9 +1645,17 @@ NTAPI IoGetRequestorSessionId(IN PIRP Irp, OUT PULONG pSessionId) { + PEPROCESS Process; + /* Return the session */ - *pSessionId = IoGetRequestorProcess(Irp)->Session; - return STATUS_SUCCESS; + if ((Process = IoGetRequestorProcess(Irp))) + { + *pSessionId = Process->Session; + return STATUS_SUCCESS; + } + + *pSessionId = (ULONG)-1; + return STATUS_UNSUCCESSFUL; } /* diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index e0ad64b7c72..35e8efcc080 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -64,6 +64,13 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, { PDEVICE_OBJECT Fdo; NTSTATUS Status; + + if (!DriverObject) + { + /* Special case for bus driven devices */ + DeviceNode->Flags |= DNF_ADDED; + return STATUS_SUCCESS; + } if (!DriverObject->DriverExtension->AddDevice) { @@ -1897,11 +1904,15 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, { /* We don't need to worry about loading the driver because we're * being driven in raw mode so our parent must be loaded to get here */ - Status = IopStartDevice(DeviceNode); - if (!NT_SUCCESS(Status)) + Status = IopInitializeDevice(DeviceNode, NULL); + if (NT_SUCCESS(Status)) { - DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n", - &DeviceNode->InstancePath, Status); + Status = IopStartDevice(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n", + &DeviceNode->InstancePath, Status); + } } } else @@ -2610,6 +2621,7 @@ IopUpdateRootKey(VOID) OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hEnum, hRoot, hHalAcpiDevice, hHalAcpiId, hLogConf; NTSTATUS Status; + ULONG Disposition; InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateKey(&hEnum, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, 0, NULL); @@ -2636,13 +2648,16 @@ IopUpdateRootKey(VOID) if (!NT_SUCCESS(Status)) return Status; InitializeObjectAttributes(&ObjectAttributes, &HalAcpiId, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hHalAcpiDevice, NULL); - Status = ZwCreateKey(&hHalAcpiId, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, 0, NULL); + Status = ZwCreateKey(&hHalAcpiId, KEY_CREATE_SUB_KEY | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0, &Disposition); ZwClose(hHalAcpiDevice); if (!NT_SUCCESS(Status)) - return Status; - Status = ZwSetValueKey(hHalAcpiId, &DeviceDescU, 0, REG_SZ, HalAcpiDeviceDesc.Buffer, HalAcpiDeviceDesc.MaximumLength); - if (NT_SUCCESS(Status)) - Status = ZwSetValueKey(hHalAcpiId, &HardwareIDU, 0, REG_MULTI_SZ, HalAcpiHardwareID.Buffer, HalAcpiHardwareID.MaximumLength); + return Status; + if (Disposition == REG_CREATED_NEW_KEY) + { + Status = ZwSetValueKey(hHalAcpiId, &DeviceDescU, 0, REG_SZ, HalAcpiDeviceDesc.Buffer, HalAcpiDeviceDesc.MaximumLength); + if (NT_SUCCESS(Status)) + Status = ZwSetValueKey(hHalAcpiId, &HardwareIDU, 0, REG_MULTI_SZ, HalAcpiHardwareID.Buffer, HalAcpiHardwareID.MaximumLength); + } if (NT_SUCCESS(Status)) { InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hHalAcpiId, NULL); @@ -3310,8 +3325,8 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, ASSERT(EnumeratorNameEnd); /* This is the format of the returned data */ - PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * 2, - &DeviceNode->ChildBusNumber); + PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR), + DeviceInstanceName); case DevicePropertyAddress: diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 18d75ab4eb7..165b0b06f59 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -132,12 +132,25 @@ PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject, ASSERT(NotificationStructure != NULL); ASSERT(DeviceObject != NULL); + if (SyncEvent) + { + ASSERT(SyncStatus); + *SyncStatus = STATUS_PENDING; + } + /* That call is totally wrong but notifications handler must be fixed first */ IopNotifyPlugPlayNotification(DeviceObject, EventCategoryTargetDeviceChange, &GUID_PNP_CUSTOM_NOTIFICATION, NotificationStructure, NULL); + + if (SyncEvent) + { + KeSetEvent(SyncEvent, IO_NO_INCREMENT, FALSE); + *SyncStatus = STATUS_SUCCESS; + } + return STATUS_SUCCESS; } diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index 30eb071c2d1..bc7e01864b0 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1413,6 +1413,8 @@ KdbEnterDebuggerException( /* Delete the temporary breakpoint which was used to step over or into the instruction. */ KdbpDeleteBreakPoint(-1, BreakPoint); + TrapFrame->Eip--; + if (--KdbNumSingleSteps > 0) { if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) || @@ -1681,8 +1683,11 @@ continue_execution: /* Clear dr6 status flags. */ TrapFrame->Dr6 &= ~0x0000e00f; - /* Skip the current instruction */ - Context->Eip++; + if (!(KdbEnteredOnSingleStep && KdbSingleStepOver)) + { + /* Skip the current instruction */ + Context->Eip++; + } } return ContinueType; diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 59aac80d99a..f97ea6962b9 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -1050,21 +1050,24 @@ MiCheckForConflictingNode( IN PMM_AVL_TABLE Table ); -NTSTATUS +TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeDownTree( IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, - OUT PULONG_PTR Base + OUT PULONG_PTR Base, + OUT PMMADDRESS_NODE *Parent ); VOID NTAPI MiInsertNode( + IN PMM_AVL_TABLE Table, IN PMMADDRESS_NODE NewNode, - IN PMM_AVL_TABLE Table + PMMADDRESS_NODE Parent, + TABLE_SEARCH_RESULT Result ); VOID diff --git a/ntoskrnl/mm/ARM3/mminit.c b/ntoskrnl/mm/ARM3/mminit.c index 9f9f1b4c974..e7bb328d784 100644 --- a/ntoskrnl/mm/ARM3/mminit.c +++ b/ntoskrnl/mm/ARM3/mminit.c @@ -831,8 +831,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Check for bad RAM */ case LoaderBad: - DPRINT1("You have damaged RAM modules. Stopping boot\n"); - while (TRUE); + DPRINT1("You either have specified /BURNMEMORY or damaged RAM modules.\n"); break; /* Check for free RAM */ diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c index 2570d790e19..8627cdeebe3 100644 --- a/ntoskrnl/mm/ARM3/pagfault.c +++ b/ntoskrnl/mm/ARM3/pagfault.c @@ -620,10 +620,28 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction, return STATUS_SUCCESS; } - // - // We don't implement prototype PTEs - // - ASSERT(TempPte.u.Soft.Prototype == 0); + /* Check one kind of prototype PTE */ + if (TempPte.u.Soft.Prototype) + { + /* The one used for protected pool... */ + ASSERT(MmProtectFreedNonPagedPool == TRUE); + + /* Make sure protected pool is on, and that this is a pool address */ + if ((MmProtectFreedNonPagedPool) && + (((Address >= MmNonPagedPoolStart) && + (Address < (PVOID)((ULONG_PTR)MmNonPagedPoolStart + + MmSizeOfNonPagedPoolInBytes))) || + ((Address >= MmNonPagedPoolExpansionStart) && + (Address < MmNonPagedPoolEnd)))) + { + /* Bad boy, bad boy, whatcha gonna do, whatcha gonna do when ARM3 comes for you! */ + KeBugCheckEx(DRIVER_CAUGHT_MODIFYING_FREED_POOL, + (ULONG_PTR)Address, + StoreInstruction, + Mode, + 4); + } + } // // We don't implement transition PTEs diff --git a/ntoskrnl/mm/ARM3/pool.c b/ntoskrnl/mm/ARM3/pool.c index 57409b02ad1..39736ffdb5b 100644 --- a/ntoskrnl/mm/ARM3/pool.c +++ b/ntoskrnl/mm/ARM3/pool.c @@ -31,6 +31,150 @@ BOOLEAN MmProtectFreedNonPagedPool; /* PRIVATE FUNCTIONS **********************************************************/ +VOID +NTAPI +MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, + IN ULONG PageCount) +{ + PMMPTE PointerPte, LastPte; + MMPTE TempPte; + + /* If pool is physical, can't protect PTEs */ + if (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) return; + + /* Get PTE pointers and loop */ + PointerPte = MiAddressToPte(VirtualAddress); + LastPte = PointerPte + PageCount; + do + { + /* Capture the PTE for safety */ + TempPte = *PointerPte; + + /* Mark it as an invalid PTE, set proto bit to recognize it as pool */ + TempPte.u.Hard.Valid = 0; + TempPte.u.Soft.Prototype = 1; + MI_WRITE_INVALID_PTE(PointerPte, TempPte); + } while (++PointerPte < LastPte); + + /* Flush the TLB */ + KeFlushEntireTb(TRUE, TRUE); +} + +BOOLEAN +NTAPI +MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, + IN ULONG PageCount) +{ + PMMPTE PointerPte; + MMPTE TempPte; + PFN_NUMBER UnprotectedPages = 0; + + /* If pool is physical, can't protect PTEs */ + if (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) return FALSE; + + /* Get, and capture the PTE */ + PointerPte = MiAddressToPte(VirtualAddress); + TempPte = *PointerPte; + + /* Loop protected PTEs */ + while ((TempPte.u.Hard.Valid == 0) && (TempPte.u.Soft.Prototype == 1)) + { + /* Unprotect the PTE */ + TempPte.u.Hard.Valid = 1; + TempPte.u.Soft.Prototype = 0; + MI_WRITE_VALID_PTE(PointerPte, TempPte); + + /* One more page */ + if (++UnprotectedPages == PageCount) break; + + /* Capture next PTE */ + TempPte = *(++PointerPte); + } + + /* Return if any pages were unprotected */ + return UnprotectedPages ? TRUE : FALSE; +} + +VOID +FORCEINLINE +MiProtectedPoolUnProtectLinks(IN PLIST_ENTRY Links, + OUT PVOID* PoolFlink, + OUT PVOID* PoolBlink) +{ + BOOLEAN Safe; + PVOID PoolVa; + + /* Initialize variables */ + *PoolFlink = *PoolBlink = NULL; + + /* Check if the list has entries */ + if (IsListEmpty(Links) == FALSE) + { + /* We are going to need to forward link to do an insert */ + PoolVa = Links->Flink; + + /* So make it safe to access */ + Safe = MiUnProtectFreeNonPagedPool(PoolVa, 1); + if (Safe) PoolFlink = PoolVa; + } + + /* Are we going to need a backward link too? */ + if (Links != Links->Blink) + { + /* Get the head's backward link for the insert */ + PoolVa = Links->Blink; + + /* Make it safe to access */ + Safe = MiUnProtectFreeNonPagedPool(PoolVa, 1); + if (Safe) PoolBlink = PoolVa; + } +} + +VOID +FORCEINLINE +MiProtectedPoolProtectLinks(IN PVOID PoolFlink, + IN PVOID PoolBlink) +{ + /* Reprotect the pages, if they got unprotected earlier */ + if (PoolFlink) MiProtectFreeNonPagedPool(PoolFlink, 1); + if (PoolBlink) MiProtectFreeNonPagedPool(PoolBlink, 1); +} + +VOID +NTAPI +MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry, + IN BOOLEAN Critical) +{ + PVOID PoolFlink, PoolBlink; + + /* Make the list accessible */ + MiProtectedPoolUnProtectLinks(ListHead, &PoolFlink, &PoolBlink); + + /* Now insert in the right position */ + Critical ? InsertHeadList(ListHead, Entry) : InsertTailList(ListHead, Entry); + + /* And reprotect the pages containing the free links */ + MiProtectedPoolProtectLinks(PoolFlink, PoolBlink); +} + +VOID +NTAPI +MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry) +{ + PVOID PoolFlink, PoolBlink; + + /* Make the list accessible */ + MiProtectedPoolUnProtectLinks(Entry, &PoolFlink, &PoolBlink); + + /* Now remove */ + RemoveEntryList(Entry); + + /* And reprotect the pages containing the free links */ + if (PoolFlink) MiProtectFreeNonPagedPool(PoolFlink, 1); + if (PoolBlink) MiProtectFreeNonPagedPool(PoolBlink, 1); +} + VOID NTAPI MiInitializeNonPagedPoolThresholds(VOID) @@ -154,6 +298,7 @@ MiInitializeNonPagedPool(VOID) FreeEntry = MmNonPagedPoolStart; FirstEntry = FreeEntry; FreeEntry->Size = PoolPages; + FreeEntry->Signature = MM_FREE_POOL_SIGNATURE; FreeEntry->Owner = FirstEntry; // @@ -172,6 +317,7 @@ MiInitializeNonPagedPool(VOID) // FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE); FreeEntry->Owner = FirstEntry; + FreeEntry->Signature = MM_FREE_POOL_SIGNATURE; } // @@ -245,7 +391,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // // Handle paged pool // - if (PoolType == PagedPool) + if ((PoolType & BASE_POOL_TYPE_MASK) == PagedPool) { // // Lock the paged pool mutex @@ -471,10 +617,18 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, NextEntry = NextHead->Flink; while (NextEntry != NextHead) { + /* Is freed non paged pool enabled */ + if (MmProtectFreedNonPagedPool) + { + /* We need to be able to touch this page, unprotect it */ + MiUnProtectFreeNonPagedPool(NextEntry, 0); + } + // // Grab the entry and see if it can handle our allocation // FreeEntry = CONTAINING_RECORD(NextEntry, MMFREE_POOL_ENTRY, List); + ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE); if (FreeEntry->Size >= SizeInPages) { // @@ -488,23 +642,31 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, BaseVa = (PVOID)((ULONG_PTR)FreeEntry + (FreeEntry->Size << PAGE_SHIFT)); - // - // This is not a free page segment anymore - // - RemoveEntryList(&FreeEntry->List); + /* Remove the item from the list, depending if pool is protected */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolRemoveEntryList(&FreeEntry->List) : + RemoveEntryList(&FreeEntry->List); // // However, check if its' still got space left // if (FreeEntry->Size != 0) { - // - // Insert it back into a different list, based on its pages - // + /* Check which list to insert this entry into */ i = FreeEntry->Size - 1; if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1; - InsertTailList (&MmNonPagedPoolFreeListHead[i], - &FreeEntry->List); + + /* Insert the entry into the free list head, check for prot. pool */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolInsertList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List, TRUE) : + InsertTailList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List); + + /* Is freed non paged pool protected? */ + if (MmProtectFreedNonPagedPool) + { + /* Protect the freed pool! */ + MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size); + } } // @@ -554,6 +716,13 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // Try the next free page entry // NextEntry = FreeEntry->List.Flink; + + /* Is freed non paged pool protected? */ + if (MmProtectFreedNonPagedPool) + { + /* Protect the freed pool! */ + MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size); + } } } while (++NextHead < LastHead); @@ -755,12 +924,21 @@ MiFreePoolPages(IN PVOID StartingVa) } else { + /* Sanity check */ + ASSERT((ULONG_PTR)StartingVa + NumberOfPages <= (ULONG_PTR)MmNonPagedPoolEnd); + + /* Check if protected pool is enabled */ + if (MmProtectFreedNonPagedPool) + { + /* The freed block will be merged, it must be made accessible */ + MiUnProtectFreeNonPagedPool(MiPteToAddress(PointerPte), 0); + } + // // Otherwise, our entire allocation must've fit within the initial non // paged pool, or the expansion nonpaged pool, so get the PFN entry of // the next allocation // - ASSERT((ULONG_PTR)StartingVa + NumberOfPages <= (ULONG_PTR)MmNonPagedPoolEnd); if (PointerPte->u.Hard.Valid == 1) { // @@ -789,13 +967,16 @@ MiFreePoolPages(IN PVOID StartingVa) // FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa + (NumberOfPages << PAGE_SHIFT)); + ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE); ASSERT(FreeEntry->Owner == FreeEntry); - // - // Consume this entry's pages, and remove it from its free list - // + /* Consume this entry's pages */ FreePages += FreeEntry->Size; - RemoveEntryList (&FreeEntry->List); + + /* Remove the item from the list, depending if pool is protected */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolRemoveEntryList(&FreeEntry->List) : + RemoveEntryList(&FreeEntry->List); } // @@ -819,6 +1000,15 @@ MiFreePoolPages(IN PVOID StartingVa) // Otherwise, get the PTE for the page right before our allocation // PointerPte -= NumberOfPages + 1; + + /* Check if protected pool is enabled */ + if (MmProtectFreedNonPagedPool) + { + /* The freed block will be merged, it must be made accessible */ + MiUnProtectFreeNonPagedPool(MiPteToAddress(PointerPte), 0); + } + + /* Check if this is valid pool, or a guard page */ if (PointerPte->u.Hard.Valid == 1) { // @@ -846,8 +1036,16 @@ MiFreePoolPages(IN PVOID StartingVa) // Get the free entry descriptor for that given page range // FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa - PAGE_SIZE); + ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE); FreeEntry = FreeEntry->Owner; + /* Check if protected pool is enabled */ + if (MmProtectFreedNonPagedPool) + { + /* The freed block will be merged, it must be made accessible */ + MiUnProtectFreeNonPagedPool(FreeEntry, 0); + } + // // Check if the entry is small enough to be indexed on a free list // If it is, we'll want to re-insert it, since we're about to @@ -855,10 +1053,10 @@ MiFreePoolPages(IN PVOID StartingVa) // if (FreeEntry->Size < (MI_MAX_FREE_PAGE_LISTS - 1)) { - // - // Remove the list from where it is now - // - RemoveEntryList(&FreeEntry->List); + /* Remove the item from the list, depending if pool is protected */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolRemoveEntryList(&FreeEntry->List) : + RemoveEntryList(&FreeEntry->List); // // Update its size @@ -871,10 +1069,10 @@ MiFreePoolPages(IN PVOID StartingVa) i = (ULONG)(FreeEntry->Size - 1); if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1; - // - // Do it - // - InsertTailList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List); + /* Insert the entry into the free list head, check for prot. pool */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolInsertList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List, TRUE) : + InsertTailList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List); } else { @@ -902,10 +1100,10 @@ MiFreePoolPages(IN PVOID StartingVa) i = FreeEntry->Size - 1; if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1; - // - // And insert us - // - InsertTailList (&MmNonPagedPoolFreeListHead[i], &FreeEntry->List); + /* Insert the entry into the free list head, check for prot. pool */ + MmProtectFreedNonPagedPool ? + MiProtectedPoolInsertList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List, TRUE) : + InsertTailList(&MmNonPagedPoolFreeListHead[i], &FreeEntry->List); } // @@ -924,10 +1122,18 @@ MiFreePoolPages(IN PVOID StartingVa) // // Link back to the parent free entry, and keep going // - NextEntry->Owner = FreeEntry; + NextEntry->Owner = FreeEntry; + NextEntry->Signature = MM_FREE_POOL_SIGNATURE; NextEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + PAGE_SIZE); } while (NextEntry != LastEntry); + /* Is freed non paged pool protected? */ + if (MmProtectFreedNonPagedPool) + { + /* Protect the freed pool! */ + MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size); + } + // // We're done, release the lock and let the caller know how much we freed // diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c index 816c7d191ea..a2280a00cf2 100644 --- a/ntoskrnl/mm/ARM3/procsup.c +++ b/ntoskrnl/mm/ARM3/procsup.c @@ -55,6 +55,8 @@ MiCreatePebOrTeb(IN PEPROCESS Process, ULONG RandomCoeff; ULONG_PTR StartAddress, EndAddress; LARGE_INTEGER CurrentTime; + TABLE_SEARCH_RESULT Result = TableFoundNode; + PMMADDRESS_NODE Parent; /* Allocate a VAD */ Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV'); @@ -93,26 +95,29 @@ MiCreatePebOrTeb(IN PEPROCESS Process, StartAddress -= RandomCoeff; EndAddress = StartAddress + ROUND_TO_PAGES(Size) - 1; - /* See if this VA range can be obtained */ - if (!MiCheckForConflictingNode(StartAddress >> PAGE_SHIFT, - EndAddress >> PAGE_SHIFT, - &Process->VadRoot)) - { - /* No conflict, use this address */ - *Base = StartAddress; - goto AfterFound; - } + /* Try to find something below the random upper margin */ + Result = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), + EndAddress, + PAGE_SIZE, + &Process->VadRoot, + Base, + &Parent); + } + + /* Check for success. TableFoundNode means nothing free. */ + if (Result == TableFoundNode) + { + /* For TEBs, or if a PEB location couldn't be found, scan the VAD root */ + Result = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), + (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1, + PAGE_SIZE, + &Process->VadRoot, + Base, + &Parent); + /* Bail out, if still nothing free was found */ + if (Result == TableFoundNode) return STATUS_NO_MEMORY; } - /* For TEBs, or if a PEB location couldn't be found, scan the VAD root */ - Status = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), - (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1, - PAGE_SIZE, - &Process->VadRoot, - Base); - ASSERT(NT_SUCCESS(Status)); - -AfterFound: /* Validate that it came from the VAD ranges */ ASSERT(*Base >= (ULONG_PTR)MI_LOWEST_VAD_ADDRESS); @@ -121,6 +126,7 @@ AfterFound: Vad->EndingVpn = ((*Base) + Size - 1) >> PAGE_SHIFT; Vad->u3.Secured.StartVpn = *Base; Vad->u3.Secured.EndVpn = (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1); + Vad->u1.Parent = NULL; /* FIXME: Should setup VAD bitmap */ Status = STATUS_SUCCESS; @@ -131,8 +137,8 @@ AfterFound: /* Insert the VAD */ ASSERT(Vad->EndingVpn >= Vad->StartingVpn); Process->VadRoot.NodeHint = Vad; - MiInsertNode((PVOID)Vad, &Process->VadRoot); - + MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); + /* Release the working set */ MiUnlockProcessWorkingSet(Process, Thread); @@ -1158,18 +1164,9 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process) /* Remove this VAD from the tree */ ASSERT(VadTree->NumberGenericTableElements >= 1); - DPRINT("Removing node for VAD: %lx %lx\n", Vad->StartingVpn, Vad->EndingVpn); MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree); DPRINT("Moving on: %d\n", VadTree->NumberGenericTableElements); - /* Check if this VAD was the hint */ - if (VadTree->NodeHint == Vad) - { - /* Get a new hint, unless we're empty now, in which case nothing */ - VadTree->NodeHint = VadTree->BalancedRoot.RightChild; - if (!VadTree->NumberGenericTableElements) VadTree->NodeHint = NULL; - } - /* Only PEB/TEB VADs supported for now */ ASSERT(Vad->u.VadFlags.PrivateMemory == 1); ASSERT(Vad->u.VadFlags.VadType == VadNone); diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index b9fce2d56e9..8a86c91ed22 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -1135,9 +1135,9 @@ CheckDllState: ImageFileDirectory->Length); /* Now add the import name and null-terminate it */ - RtlAppendStringToString((PSTRING)&DllName, - (PSTRING)&NameString); - DllName.Buffer[(DllName.MaximumLength - 1) / sizeof(WCHAR)] = UNICODE_NULL; + RtlAppendUnicodeStringToString(&DllName, + &NameString); + DllName.Buffer[DllName.Length / sizeof(WCHAR)] = UNICODE_NULL; /* Load the image */ Status = MmLoadSystemImage(&DllName, diff --git a/ntoskrnl/mm/ARM3/vadnode.c b/ntoskrnl/mm/ARM3/vadnode.c index c6f8be6ff86..a9aa209dd84 100644 --- a/ntoskrnl/mm/ARM3/vadnode.c +++ b/ntoskrnl/mm/ARM3/vadnode.c @@ -4,6 +4,7 @@ * FILE: ntoskrnl/mm/ARM3/vadnode.c * PURPOSE: ARM Memory Manager VAD Node Algorithms * PROGRAMMERS: ReactOS Portable Systems Group + * Timo Kreuzer (timo.kreuzer@reactos.org) */ /* INCLUDES *******************************************************************/ @@ -92,19 +93,14 @@ MiCheckForConflictingNode(IN ULONG_PTR StartVpn, VOID NTAPI -MiInsertNode(IN PMMADDRESS_NODE NewNode, - IN PMM_AVL_TABLE Table) +MiInsertNode( + IN PMM_AVL_TABLE Table, + IN PMMADDRESS_NODE NewNode, + PMMADDRESS_NODE Parent, + TABLE_SEARCH_RESULT Result) { - PMMADDRESS_NODE NodeOrParent = NULL; - TABLE_SEARCH_RESULT Result; - - /* Find the node's parent, and where to insert this node */ - Result = RtlpFindAvlTableNodeOrParent(Table, - (PVOID)NewNode->StartingVpn, - &NodeOrParent); - /* Insert it into the tree */ - RtlpInsertAvlTreeNode(Table, NewNode, NodeOrParent, Result); + RtlpInsertAvlTreeNode(Table, NewNode, Parent, Result); } VOID @@ -112,11 +108,21 @@ NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table) { + DPRINT("Removing address node: %lx %lx\n", Node->StartingVpn, Node->EndingVpn); + /* Call the AVL code */ RtlpDeleteAvlTreeNode(Table, Node); /* Decrease element count */ Table->NumberGenericTableElements--; + + /* Check if this node was the hint */ + if (Table->NodeHint == Node) + { + /* Get a new hint, unless we're empty now, in which case nothing */ + if (!Table->NumberGenericTableElements) Table->NodeHint = NULL; + else Table->NodeHint = Table->BalancedRoot.RightChild; + } } PMMADDRESS_NODE @@ -155,17 +161,18 @@ MiGetPreviousNode(IN PMMADDRESS_NODE Node) return NULL; } -NTSTATUS +TABLE_SEARCH_RESULT NTAPI -MiFindEmptyAddressRangeDownTree(IN SIZE_T Length, - IN ULONG_PTR BoundaryAddress, - IN ULONG_PTR Alignment, - IN PMM_AVL_TABLE Table, - OUT PULONG_PTR Base) +MiFindEmptyAddressRangeDownTree( + IN SIZE_T Length, + IN ULONG_PTR BoundaryAddress, + IN ULONG_PTR Alignment, + IN PMM_AVL_TABLE Table, + OUT PULONG_PTR Base, + OUT PMMADDRESS_NODE *Parent) { - PMMADDRESS_NODE Node, PreviousNode; - ULONG_PTR CandidateAddress, EndAddress; - ULONG AlignEndVpn, CandidateVpn, BoundaryVpn, LowestVpn, StartVpn, EndVpn; + PMMADDRESS_NODE Node, LowestNode, Child; + ULONG LowVpn, HighVpn; PFN_NUMBER PageCount; /* Sanity checks */ @@ -174,107 +181,82 @@ MiFindEmptyAddressRangeDownTree(IN SIZE_T Length, /* Compute page length, make sure the boundary address is valid */ Length = PAGE_ROUND_UP(Length); + PageCount = Length >> PAGE_SHIFT; if ((BoundaryAddress + 1) < Length) return STATUS_NO_MEMORY; - - /* Compute the highest address to start at */ - CandidateAddress = ROUND_UP(BoundaryAddress + 1 - Length, Alignment); /* Check if the table is empty */ - if (!Table->NumberGenericTableElements) + if (Table->NumberGenericTableElements == 0) { /* Tree is empty, the candidate address is already the best one */ - *Base = CandidateAddress; - return STATUS_SUCCESS; + *Base = ROUND_DOWN(BoundaryAddress + 1 - Length, Alignment); + return TableEmptyTree; } - /* Starting from the root, go down until the right-most child */ - Node = RtlRightChildAvl(&Table->BalancedRoot); - while (RtlRightChildAvl(Node)) Node = RtlRightChildAvl(Node); + /* Calculate the initial upper margin */ + HighVpn = BoundaryAddress >> PAGE_SHIFT; - /* Get the aligned ending address of this VPN */ - EndAddress = ROUND_UP((Node->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1), - Alignment); + /* Starting from the root, go down until the right-most child, + trying to stay below the boundary. */ + LowestNode = Node = RtlRightChildAvl(&Table->BalancedRoot); + while ( (Child = RtlRightChildAvl(Node)) && + Child->EndingVpn < HighVpn ) Node = Child; - /* Can we fit the address without overflowing into the node? */ - if ((EndAddress < BoundaryAddress) && - ((BoundaryAddress - EndAddress) > Length)) + /* Now loop the Vad nodes */ + while (Node) + { + /* Keep track of the lowest node */ + LowestNode = Node; + + /* Calculate the lower margin */ + LowVpn = ROUND_UP(Node->EndingVpn + 1, Alignment >> PAGE_SHIFT); + + /* Check if the current bounds are suitable */ + if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount)) + { + /* There is enough space to add our node */ + LowVpn = HighVpn - PageCount; + *Base = LowVpn << PAGE_SHIFT; + + /* Can we use the current node as parent? */ + Child = RtlRightChildAvl(Node); + if (!Child) + { + /* Node has no right child, so use it as parent */ + *Parent = Node; + return TableInsertAsRight; + } + else + { + /* Node has a right child, find most left grand child */ + Node = Child; + while ((Child = RtlLeftChildAvl(Node))) Node = Child; + *Parent = Node; + return TableInsertAsLeft; + } + } + + /* Update the upper margin if neccessary */ + if (Node->StartingVpn < HighVpn) HighVpn = Node->StartingVpn; + + /* Go to the next lower node */ + Node = MiGetPreviousNode(Node); + } + + /* Check if there's enough space before the lowest Vad */ + LowVpn = ROUND_UP((ULONG_PTR)MI_LOWEST_VAD_ADDRESS, Alignment) >> PAGE_SHIFT; + if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount)) { /* There is enough space to add our address */ - *Base = ROUND_UP(BoundaryAddress - Length, Alignment); - return STATUS_SUCCESS; - } - - PageCount = Length >> PAGE_SHIFT; - CandidateVpn = CandidateAddress >> PAGE_SHIFT; - BoundaryVpn = BoundaryAddress >> PAGE_SHIFT; - LowestVpn = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS >> PAGE_SHIFT; - - PreviousNode = MiGetPreviousNode(Node); - - StartVpn = Node->StartingVpn; - EndVpn = PreviousNode ? PreviousNode->EndingVpn : 0; - AlignEndVpn = ROUND_UP(EndVpn + 1, Alignment >> PAGE_SHIFT); - - /* Loop until a gap is found */ - for (PageCount = Length >> PAGE_SHIFT, - CandidateVpn = CandidateAddress >> PAGE_SHIFT, - BoundaryVpn = BoundaryAddress >> PAGE_SHIFT, - LowestVpn = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS >> PAGE_SHIFT, - PreviousNode = MiGetPreviousNode(Node), - StartVpn = Node->StartingVpn, - EndVpn = PreviousNode ? PreviousNode->EndingVpn : 0, - AlignEndVpn = ROUND_UP(EndVpn + 1, Alignment >> PAGE_SHIFT); - PreviousNode; - Node = PreviousNode, - PreviousNode = MiGetPreviousNode(Node), - StartVpn = Node->StartingVpn, - EndVpn = PreviousNode ? PreviousNode->EndingVpn : 0, - AlignEndVpn = ROUND_UP(EndVpn + 1, Alignment >> PAGE_SHIFT)) - { - /* Can we fit the address without overflowing into the node? */ - if ((StartVpn < CandidateVpn) && ((StartVpn - AlignEndVpn) >= PageCount)) - { - /* Check if we can get our candidate address */ - if ((CandidateVpn > EndVpn) && (BoundaryVpn < StartVpn)) - { - /* Use it */ - *Base = CandidateAddress; - return STATUS_SUCCESS; - } - - /* Otherwise, can we fit it by changing the start address? */ - if (StartVpn > AlignEndVpn) - { - /* It'll fit, compute the new base address for that to work */ - *Base = ROUND_UP((StartVpn << PAGE_SHIFT) - Length, Alignment); - return STATUS_SUCCESS; - } - } - - PreviousNode = MiGetPreviousNode(Node); - StartVpn = Node->StartingVpn; - EndVpn = PreviousNode ? PreviousNode->EndingVpn : 0; - AlignEndVpn = ROUND_UP(EndVpn + 1, Alignment >> PAGE_SHIFT); + LowVpn = HighVpn - PageCount; + *Base = LowVpn << PAGE_SHIFT; + *Parent = LowestNode; + return TableInsertAsLeft; } - /* See if we could squeeze into the last descriptor */ - if ((StartVpn > LowestVpn) && ((StartVpn - LowestVpn) >= PageCount)) - { - /* Check if we can try our candidate address */ - if (BoundaryVpn < StartVpn) - { - /* Use it */ - *Base = CandidateAddress; - return STATUS_SUCCESS; - } - - /* Otherwise, change the base address to what's needed to fit in */ - *Base = ROUND_UP((StartVpn << PAGE_SHIFT) - Length, Alignment); - return STATUS_SUCCESS; - } - /* No address space left at all */ - return STATUS_NO_MEMORY; + *Base = 0; + *Parent = NULL; + return TableFoundNode; } /* EOF */ diff --git a/ntoskrnl/po/events.c b/ntoskrnl/po/events.c index 8417f2760cc..efbcc104d61 100644 --- a/ntoskrnl/po/events.c +++ b/ntoskrnl/po/events.c @@ -79,6 +79,15 @@ PopGetSysButtonCompletion( if (SysButton & SYS_BUTTON_LID) DbgPrint(" LID"); if (SysButton == 0) DbgPrint(" WAKE"); DbgPrint(" )\n"); + + if (SysButton & SYS_BUTTON_POWER) + { + /* FIXME: Read registry for the action we should perform here */ + DPRINT1("Initiating shutdown after power button event\n"); + + ZwShutdownSystem(ShutdownNoReboot); + } + } /* Allocate a new workitem to send the next IOCTL_GET_SYS_BUTTON_EVENT */ diff --git a/ntoskrnl/po/power.c b/ntoskrnl/po/power.c index e8d37b855fd..d745d76e777 100644 --- a/ntoskrnl/po/power.c +++ b/ntoskrnl/po/power.c @@ -136,7 +136,7 @@ PoInitSystem(IN ULONG BootPhase) /* Check if this is phase 1 init */ if (BootPhase == 1) { - /* Registry power button notification */ + /* Register power button notification */ IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVICE_SYS_BUTTON, @@ -145,6 +145,16 @@ PoInitSystem(IN ULONG BootPhase) PopAddRemoveSysCapsCallback, NULL, &NotificationEntry); + + /* Register lid notification */ + IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, + PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, + (PVOID)&GUID_DEVICE_LID, + IopRootDeviceNode-> + PhysicalDeviceObject->DriverObject, + PopAddRemoveSysCapsCallback, + NULL, + &NotificationEntry); return TRUE; } diff --git a/ntoskrnl/ps/kill.c b/ntoskrnl/ps/kill.c index b1ea95fb361..c1f9ce33cb6 100644 --- a/ntoskrnl/ps/kill.c +++ b/ntoskrnl/ps/kill.c @@ -301,6 +301,8 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Detach */ KeUnstackDetachProcess(&ApcState); + RemoveEntryList(&Process->MmProcessLinks); + /* Completely delete the Address Space */ MmDeleteProcessAddressSpace(Process); } diff --git a/ntoskrnl/ps/process.c b/ntoskrnl/ps/process.c index fea26c938c0..0c557c3699e 100644 --- a/ntoskrnl/ps/process.c +++ b/ntoskrnl/ps/process.c @@ -469,14 +469,14 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, if (Parent != PsInitialSystemProcess) { /* It's not, so acquire the process rundown */ - if (ExAcquireRundownProtection(&Process->RundownProtect)) + if (ExAcquireRundownProtection(&Parent->RundownProtect)) { /* If the parent has a section, use it */ SectionObject = Parent->SectionObject; if (SectionObject) ObReferenceObject(SectionObject); /* Release process rundown */ - ExReleaseRundownProtection(&Process->RundownProtect); + ExReleaseRundownProtection(&Parent->RundownProtect); } /* If we don't have a section object */ diff --git a/subsystems/win32/win32k/eng/mouse.c b/subsystems/win32/win32k/eng/mouse.c index 55e2f782ce2..02bb965e6bf 100644 --- a/subsystems/win32/win32k/eng/mouse.c +++ b/subsystems/win32/win32k/eng/mouse.c @@ -195,6 +195,9 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) pgp->Enabled = TRUE; + /* Check if we have any mouse pointer */ + if (!pgp->psurfSave) return; + /* Calculate pointer coordinates */ pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x; pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y; @@ -299,88 +302,74 @@ EngSetPointerShape( { PDEVOBJ *ppdev; GDIPOINTER *pgp; - LONG lDelta; - HBITMAP hbmp; - RECTL rcl; + LONG lDelta = 0; + HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL; + PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL; + RECTL rectl; + SIZEL sizel = {0, 0}; ASSERT(pso); ppdev = GDIDEV(pso); pgp = &ppdev->Pointer; + /* Do we have any bitmap at all? */ + if (psoColor || psoMask) + { + /* Get the size of the new pointer */ if (psoColor) { - pgp->Size.cx = psoColor->sizlBitmap.cx; - pgp->Size.cy = psoColor->sizlBitmap.cy; - if (psoMask) - { - // CHECKME: Is this really required? if we have a color surface, - // we only need the AND part of the mask. - /* Check if the sizes match as they should */ - if (psoMask->sizlBitmap.cx != psoColor->sizlBitmap.cx || - psoMask->sizlBitmap.cy != psoColor->sizlBitmap.cy * 2) - { - DPRINT("Sizes of mask (%ld,%ld) and color (%ld,%ld) don't match\n", - psoMask->sizlBitmap.cx, psoMask->sizlBitmap.cy, - psoColor->sizlBitmap.cx, psoColor->sizlBitmap.cy); -// return SPS_ERROR; + sizel.cx = psoColor->sizlBitmap.cx; + sizel.cy = psoColor->sizlBitmap.cy; } - } - } - else if (psoMask) + else// if (psoMask) { - pgp->Size.cx = psoMask->sizlBitmap.cx; - pgp->Size.cy = psoMask->sizlBitmap.cy / 2; + sizel.cx = psoMask->sizlBitmap.cx; + sizel.cy = psoMask->sizlBitmap.cy / 2; } - IntHideMousePointer(ppdev, pso); + rectl.left = 0; + rectl.top = 0; + rectl.right = sizel.cx; + rectl.bottom = sizel.cy; - if (pgp->psurfColor) + /* Calculate lDelta for our surfaces. */ + lDelta = DIB_GetDIBWidthBytes(sizel.cx, + BitsPerFormat(pso->iBitmapFormat)); + + /* Create a bitmap for saving the pixels under the cursor. */ + hbmSave = EngCreateBitmap(sizel, + lDelta, + pso->iBitmapFormat, + BMF_TOPDOWN | BMF_NOZEROINIT, + NULL); + psurfSave = SURFACE_ShareLockSurface(hbmSave); + if (!psurfSave) goto failure; + } + + if (psoColor) { - EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); - SURFACE_ShareUnlockSurface(pgp->psurfColor); - pgp->psurfColor = NULL; - } + /* Color bitmap must have the same format as the dest surface */ + if (psoColor->iBitmapFormat != pso->iBitmapFormat) goto failure; - if (pgp->psurfMask) - { - EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); - SURFACE_ShareUnlockSurface(pgp->psurfMask); - pgp->psurfMask = NULL; - } - - if (pgp->psurfSave != NULL) - { - EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr); - SURFACE_ShareUnlockSurface(pgp->psurfSave); - pgp->psurfSave = NULL; - } - - /* See if we are being asked to hide the pointer. */ - if (psoMask == NULL && psoColor == NULL) - { - return SPS_ACCEPT_NOEXCLUDE; - } - - pgp->HotSpot.x = xHot; - pgp->HotSpot.y = yHot; - - /* Calculate lDelta for our surfaces. */ - lDelta = DIB_GetDIBWidthBytes(pgp->Size.cx, - BitsPerFormat(pso->iBitmapFormat)); - - rcl.left = 0; - rcl.top = 0; - rcl.right = pgp->Size.cx; - rcl.bottom = pgp->Size.cy; - - /* Create surface for saving the pixels under the cursor. */ - hbmp = EngCreateBitmap(pgp->Size, + /* Create a bitmap to copy the color bitmap to */ + hbmColor = EngCreateBitmap(psoColor->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); - pgp->psurfSave = SURFACE_ShareLockSurface(hbmp); + psurfColor = SURFACE_ShareLockSurface(hbmColor); + if (!psurfColor) goto failure; + + /* Now copy the given bitmap */ + rectl.bottom = psoColor->sizlBitmap.cy; + IntEngCopyBits(&psurfColor->SurfObj, + psoColor, + NULL, + pxlo, + &rectl, + (POINTL*)&rectl); + } /* Create a mask surface */ if (psoMask) @@ -388,15 +377,16 @@ EngSetPointerShape( EXLATEOBJ exlo; PPALETTE ppal; - hbmp = EngCreateBitmap(psoMask->sizlBitmap, + /* Create a bitmap for the mask */ + hbmMask = EngCreateBitmap(psoMask->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); - pgp->psurfMask = SURFACE_ShareLockSurface(hbmp); + psurfMask = SURFACE_ShareLockSurface(hbmMask); + if (!psurfMask) goto failure; - if(pgp->psurfMask) - { + /* Initialize an EXLATEOBJ */ ppal = PALETTE_LockPalette(ppdev->devinfo.hpalDefault); EXLATEOBJ_vInitialize(&exlo, &gpalMono, @@ -405,49 +395,62 @@ EngSetPointerShape( RGB(0xff,0xff,0xff), RGB(0,0,0)); - rcl.bottom = psoMask->sizlBitmap.cy; - IntEngCopyBits(&pgp->psurfMask->SurfObj, + /* Copy the mask bitmap */ + rectl.bottom = psoMask->sizlBitmap.cy; + IntEngCopyBits(&psurfMask->SurfObj, psoMask, NULL, &exlo.xlo, - &rcl, - (POINTL*)&rcl); + &rectl, + (POINTL*)&rectl); + /* Cleanup */ EXLATEOBJ_vCleanup(&exlo); - if (ppal) - PALETTE_UnlockPalette(ppal); + if (ppal) PALETTE_UnlockPalette(ppal); } - } - else + + /* Hide mouse pointer */ + IntHideMousePointer(ppdev, pso); + + /* Free old color bitmap */ + if (pgp->psurfColor) { + EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); + SURFACE_ShareUnlockSurface(pgp->psurfColor); + pgp->psurfColor = NULL; + } + + /* Free old mask bitmap */ + if (pgp->psurfMask) + { + EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); + SURFACE_ShareUnlockSurface(pgp->psurfMask); pgp->psurfMask = NULL; } - /* Create a color surface */ - if (psoColor) + /* Free old save bitmap */ + if (pgp->psurfSave) { - hbmp = EngCreateBitmap(psoColor->sizlBitmap, - lDelta, - pso->iBitmapFormat, - BMF_TOPDOWN | BMF_NOZEROINIT, - NULL); - pgp->psurfColor = SURFACE_ShareLockSurface(hbmp); - if (pgp->psurfColor) - { - rcl.bottom = psoColor->sizlBitmap.cy; - IntEngCopyBits(&pgp->psurfColor->SurfObj, - psoColor, - NULL, - pxlo, - &rcl, - (POINTL*)&rcl); + EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr); + SURFACE_ShareUnlockSurface(pgp->psurfSave); + pgp->psurfSave = NULL; } - } - else + + /* See if we are being asked to hide the pointer. */ + if (psoMask == NULL && psoColor == NULL) { - pgp->psurfColor = NULL; + /* We're done */ + return SPS_ACCEPT_NOEXCLUDE; } + /* Now set the new cursor */ + pgp->psurfColor = psurfColor; + pgp->psurfMask = psurfMask; + pgp->psurfSave = psurfSave; + pgp->HotSpot.x = xHot; + pgp->HotSpot.y = yHot; + pgp->Size = sizel; + if (x != -1) { ppdev->ptlPointer.x = x; @@ -469,6 +472,17 @@ EngSetPointerShape( } return SPS_ACCEPT_NOEXCLUDE; + +failure: + /* Cleanup surfaces */ + if (hbmMask) EngDeleteSurface(hbmMask); + if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); + if (hbmColor) EngDeleteSurface(hbmColor); + if (psurfColor) SURFACE_ShareUnlockSurface(psurfColor); + if (hbmSave) EngDeleteSurface(hbmSave); + if (psurfSave) SURFACE_ShareUnlockSurface(psurfSave); + + return SPS_ERROR; } /* diff --git a/subsystems/win32/win32k/include/text.h b/subsystems/win32/win32k/include/text.h index a9a05779055..9dc6510fd6e 100644 --- a/subsystems/win32/win32k/include/text.h +++ b/subsystems/win32/win32k/include/text.h @@ -96,7 +96,7 @@ INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristi ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL); INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *); BOOL FASTCALL ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS); -BOOL FASTCALL TextIntGetTextExtentPoint(PDC,PTEXTOBJ,LPCWSTR,INT,ULONG,LPINT,LPINT,LPSIZE); +BOOL FASTCALL TextIntGetTextExtentPoint(PDC,PTEXTOBJ,LPCWSTR,INT,ULONG,LPINT,LPINT,LPSIZE,FLONG); BOOL FASTCALL ftGdiGetTextMetricsW(HDC,PTMW_INTERNAL); DWORD FASTCALL IntGetFontLanguageInfo(PDC); INT FASTCALL ftGdiGetTextCharsetInfo(PDC,PFONTSIGNATURE,DWORD); diff --git a/subsystems/win32/win32k/ntuser/message.c b/subsystems/win32/win32k/ntuser/message.c index c4006eddc8e..87cce90d8ab 100644 --- a/subsystems/win32/win32k/ntuser/message.c +++ b/subsystems/win32/win32k/ntuser/message.c @@ -579,14 +579,20 @@ co_IntTranslateMouseMessage( return TRUE; } + *HitTest = HTCLIENT; + UserRefObjectCo(Window, &Ref); if ( ThreadQueue == Window->pti->MessageQueue && ThreadQueue->CaptureWindow != Window->hSelf) { /* only send WM_NCHITTEST messages if we're not capturing the window! */ - *HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0, - MAKELONG(Msg->pt.x, Msg->pt.y)); + if (Remove ) + { + *HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0, + MAKELONG(Msg->pt.x, Msg->pt.y)); + } + /* else we are going to see this message again, but then with Remove == TRUE */ if (*HitTest == (USHORT)HTTRANSPARENT) { @@ -626,10 +632,6 @@ co_IntTranslateMouseMessage( } } } - else - { - *HitTest = HTCLIENT; - } if ( gspv.bMouseClickLock && ( (Msg->message == WM_LBUTTONUP) || @@ -801,6 +803,8 @@ co_IntPeekMessage( PUSER_MESSAGE Msg, */ CheckMessages: + HitTest = HTNOWHERE; + Present = FALSE; KeQueryTickCount(&LargeTickCount); diff --git a/subsystems/win32/win32k/ntuser/msgqueue.c b/subsystems/win32/win32k/ntuser/msgqueue.c index dc315b5ccaf..b7cba1d7dd0 100644 --- a/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/subsystems/win32/win32k/ntuser/msgqueue.c @@ -350,6 +350,10 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win PWINDOW_OBJECT CaptureWindow = NULL; HWND hCaptureWin; + /* FIXME: Mouse message can be sent before the Desktop is up and running in which case ScopeWin (Desktop) is 0. + Is this the best fix? */ + if (ScopeWin == 0) return FALSE; + ASSERT_REFS_CO(ScopeWin); /* diff --git a/subsystems/win32/win32k/ntuser/timer.c b/subsystems/win32/win32k/ntuser/timer.c index 984b206a6b8..2f4e2189f3f 100644 --- a/subsystems/win32/win32k/ntuser/timer.c +++ b/subsystems/win32/win32k/ntuser/timer.c @@ -30,7 +30,7 @@ static LONG TimeLast = 0; static FAST_MUTEX Mutex; static RTL_BITMAP WindowLessTimersBitMap; static PVOID WindowLessTimersBitMapBuffer; -static ULONG HintIndex = 0; +static ULONG HintIndex = 1; ERESOURCE TimerLock; @@ -97,9 +97,11 @@ RemoveTimer(PTIMER pTmr) RemoveEntryList(&pTmr->ptmrList); if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) { - DPRINT("Clearing Bit %d)\n", pTmr->nID); + UINT_PTR IDEvent; + + IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID; IntLockWindowlessTimerBitmap(); - RtlClearBit(&WindowLessTimersBitMap, pTmr->nID); + RtlClearBit(&WindowLessTimersBitMap, IDEvent); IntUnlockWindowlessTimerBitmap(); } UserDereferenceObject(pTmr); @@ -155,7 +157,7 @@ FindSystemTimer(PMSG pMsg) break; pLE = pTmr->ptmrList.Flink; - pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); + pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); TimerLeave(); @@ -200,7 +202,7 @@ IntSetTimer( PWINDOW_OBJECT Window, INT Type) { PTIMER pTmr; - UINT Ret= IDEvent; + UINT Ret = IDEvent; LARGE_INTEGER DueTime; DueTime.QuadPart = (LONGLONG)(-5000000); @@ -227,8 +229,10 @@ IntSetTimer( PWINDOW_OBJECT Window, Elapse = 10; } + /* Passing an IDEvent of 0 and the SetTimer returns 1. + It will create the timer with an ID of 0 */ if ((Window) && (IDEvent == 0)) - IDEvent = 1; + Ret = 1; pTmr = FindTimer(Window, IDEvent, Type); @@ -243,11 +247,13 @@ IntSetTimer( PWINDOW_OBJECT Window, IntUnlockWindowlessTimerBitmap(); DPRINT1("Unable to find a free window-less timer id\n"); SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); + ASSERT(FALSE); return 0; } + IDEvent = NUM_WINDOW_LESS_TIMERS - IDEvent; Ret = IDEvent; - //HintIndex = IDEvent + 1; + IntUnlockWindowlessTimerBitmap(); } @@ -271,7 +277,7 @@ IntSetTimer( PWINDOW_OBJECT Window, pTmr->cmsRate = Elapse; pTmr->pfn = TimerFunc; pTmr->nID = IDEvent; - pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode. + pTmr->flags = Type|TMRF_INIT; } else { @@ -319,6 +325,7 @@ SystemTimerSet( PWINDOW_OBJECT Window, if (Window && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess()) { SetLastWin32Error(ERROR_ACCESS_DENIED); + DPRINT("SysemTimerSet: Access Denied!\n"); return 0; } return IntSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM); @@ -509,9 +516,6 @@ IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) DPRINT("IntKillTimer Window %x id %p systemtimer %s\n", Window, IDEvent, SystemTimer ? "TRUE" : "FALSE"); - if ((Window) && (IDEvent == 0)) - IDEvent = 1; - pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0); if (pTmr) @@ -532,7 +536,7 @@ InitTimerImpl(VOID) ExInitializeFastMutex(&Mutex); BitmapBytes = ROUND_UP(NUM_WINDOW_LESS_TIMERS, sizeof(ULONG) * 8) / 8; - WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(PagedPool, BitmapBytes, TAG_TIMERBMP); + WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(NonPagedPool, BitmapBytes, TAG_TIMERBMP); if (WindowLessTimersBitMapBuffer == NULL) { return STATUS_UNSUCCESSFUL; diff --git a/subsystems/win32/win32k/objects/cliprgn.c b/subsystems/win32/win32k/objects/cliprgn.c index 1f8fe7982ec..ae988ae1ec7 100644 --- a/subsystems/win32/win32k/objects/cliprgn.c +++ b/subsystems/win32/win32k/objects/cliprgn.c @@ -95,11 +95,7 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn) dc->fs &= ~DC_FLAG_DIRTY_RAO; - if (dc->prgnVis == NULL) - { - dc->prgnVis = IntSysCreateRectpRgn(0, 0, 0, 0); - GDIOBJ_CopyOwnership(hdc, ((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr); - } + ASSERT (dc->prgnVis != NULL); retval = NtGdiCombineRgn(((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr, hrgn, 0, RGN_COPY); if ( retval != ERROR ) diff --git a/subsystems/win32/win32k/objects/coord.c b/subsystems/win32/win32k/objects/coord.c index 7310dcb1adc..12cb42a024b 100644 --- a/subsystems/win32/win32k/objects/coord.c +++ b/subsystems/win32/win32k/objects/coord.c @@ -886,6 +886,46 @@ IntMirrorWindowOrg(PDC dc) return; } +VOID +NTAPI +DC_vSetLayout( + IN PDC pdc, + IN LONG wox, + IN DWORD dwLayout) +{ + PDC_ATTR pdcattr = pdc->pdcattr; + + pdcattr->dwLayout = dwLayout; + + if (!(dwLayout & LAYOUT_ORIENTATIONMASK)) return; + + if (dwLayout & LAYOUT_RTL) + { + pdcattr->iMapMode = MM_ANISOTROPIC; + } + + pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy; + pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x; + + if (wox == -1) + IntMirrorWindowOrg(pdc); + else + pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x; + + if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT; + + if (pdc->dclevel.flPath & DCPATH_CLOCKWISE) + pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; + else + pdc->dclevel.flPath |= DCPATH_CLOCKWISE; + + pdcattr->flXform |= (PAGE_EXTENTS_CHANGED | + INVALIDATE_ATTRIBUTES | + DEVICE_TO_WORLD_INVALID); + +// DC_UpdateXforms(pdc); +} + // NtGdiSetLayout // // The default is left to right. This function changes it to right to left, which @@ -901,53 +941,22 @@ NtGdiSetLayout( IN LONG wox, IN DWORD dwLayout) { - PDC dc; + PDC pdc; PDC_ATTR pdcattr; DWORD oLayout; - dc = DC_LockDc(hdc); - if (!dc) + pdc = DC_LockDc(hdc); + if (!pdc) { SetLastWin32Error(ERROR_INVALID_HANDLE); return GDI_ERROR; } - pdcattr = dc->pdcattr; + pdcattr = pdc->pdcattr; - pdcattr->dwLayout = dwLayout; oLayout = pdcattr->dwLayout; + DC_vSetLayout(pdc, wox, dwLayout); - if (!(dwLayout & LAYOUT_ORIENTATIONMASK)) - { - DC_UnlockDc(dc); - return oLayout; - } - - if (dwLayout & LAYOUT_RTL) - { - pdcattr->iMapMode = MM_ANISOTROPIC; - } - - pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy; - pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x; - - if (wox == -1) - IntMirrorWindowOrg(dc); - else - pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x; - - if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT; - - if (dc->dclevel.flPath & DCPATH_CLOCKWISE) - dc->dclevel.flPath &= ~DCPATH_CLOCKWISE; - else - dc->dclevel.flPath |= DCPATH_CLOCKWISE; - - pdcattr->flXform |= (PAGE_EXTENTS_CHANGED | - INVALIDATE_ATTRIBUTES | - DEVICE_TO_WORLD_INVALID); - -// DC_UpdateXforms(dc); - DC_UnlockDc(dc); + DC_UnlockDc(pdc); return oLayout; } diff --git a/subsystems/win32/win32k/objects/font.c b/subsystems/win32/win32k/objects/font.c index a0837e1d24a..520f256b312 100644 --- a/subsystems/win32/win32k/objects/font.c +++ b/subsystems/win32/win32k/objects/font.c @@ -75,7 +75,7 @@ GreGetKerningPairs( return Count; } - +#if 0 DWORD FASTCALL GreGetCharacterPlacementW( @@ -90,13 +90,14 @@ GreGetCharacterPlacementW( if (!pgcpw) { - if (GreGetTextExtentW( hdc, pwsz, nCount, &Size, 1)) + if (GreGetTextExtentW( hdc, pwsz, nCount, &Size, 0)) return MAKELONG(Size.cx, Size.cy); return 0; } UNIMPLEMENTED; return 0; } +#endif INT FASTCALL @@ -167,7 +168,7 @@ IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height) DC_UnlockDc(pdc); return 0; } - Good = TextIntGetTextExtentPoint(pdc, TextObj, alphabet, 52, 0, NULL, 0, &sz); + Good = TextIntGetTextExtentPoint(pdc, TextObj, alphabet, 52, 0, NULL, 0, &sz, 0); TEXTOBJ_UnlockText(TextObj); DC_UnlockDc(pdc); diff --git a/subsystems/win32/win32k/objects/freetype.c b/subsystems/win32/win32k/objects/freetype.c index 20ad506d170..83f53fab758 100644 --- a/subsystems/win32/win32k/objects/freetype.c +++ b/subsystems/win32/win32k/objects/freetype.c @@ -2123,7 +2123,8 @@ TextIntGetTextExtentPoint(PDC dc, ULONG MaxExtent, LPINT Fit, LPINT Dx, - LPSIZE Size) + LPSIZE Size, + FLONG fl) { PFONTGDI FontGDI; FT_Face face; @@ -2195,7 +2196,11 @@ TextIntGetTextExtentPoint(PDC dc, for (i = 0; i < Count; i++) { - glyph_index = FT_Get_Char_Index(face, *String); + if (fl & GTEF_INDICES) + glyph_index = *String; + else + glyph_index = FT_Get_Char_Index(face, *String); + if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight))) { @@ -4254,16 +4259,17 @@ NtGdiGetGlyphIndicesW( IntLockFreeType; face = FontGDI->face; + if (DefChar == 0xffff && FT_IS_SFNT(face)) + { + TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0); + } + for (i = 0; i < cwc; i++) { - Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); + Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); // FIXME: unsafe! if (Buffer[i] == 0) { - if (DefChar == 0xffff && FT_IS_SFNT(face)) - { - TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); - DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0); - } Buffer[i] = DefChar; } } diff --git a/subsystems/win32/win32k/objects/print.c b/subsystems/win32/win32k/objects/print.c index bf21047292f..6377c5e9cae 100644 --- a/subsystems/win32/win32k/objects/print.c +++ b/subsystems/win32/win32k/objects/print.c @@ -87,23 +87,6 @@ NtGdiEscape(HDC hDC, return ret; } -INT -APIENTRY -IntEngExtEscape( - SURFOBJ *Surface, - INT Escape, - INT InSize, - LPVOID InData, - INT OutSize, - LPVOID OutData) -{ - if (Escape == QUERYESCSUPPORT) - return FALSE; - - DPRINT1("IntEngExtEscape is unimplemented. - Keep going and have a nice day\n"); - return -1; -} - INT APIENTRY IntGdiExtEscape( @@ -117,22 +100,14 @@ IntGdiExtEscape( SURFACE *psurf = dc->dclevel.pSurface; INT Result; - /* FIXME - Handle psurf == NULL !!!!!! */ - - if ( NULL == dc->ppdev->DriverFunctions.Escape ) + if (!dc->ppdev->DriverFunctions.Escape) { - Result = IntEngExtEscape( - &psurf->SurfObj, - Escape, - InSize, - (PVOID)((ULONG_PTR)InData), - OutSize, - (PVOID)OutData); + Result = 0; } else { Result = dc->ppdev->DriverFunctions.Escape( - &psurf->SurfObj, + psurf ? &psurf->SurfObj : NULL, Escape, InSize, (PVOID)InData, diff --git a/subsystems/win32/win32k/objects/text.c b/subsystems/win32/win32k/objects/text.c index 07cf12dcf21..b39ee850b39 100644 --- a/subsystems/win32/win32k/objects/text.c +++ b/subsystems/win32/win32k/objects/text.c @@ -15,6 +15,7 @@ /** Functions *****************************************************************/ +#if 0 /* flOpts : GetTextExtentPoint32W = 0 @@ -60,7 +61,8 @@ GreGetTextExtentW( 0, NULL, 0, - psize); + psize, + flOpts); TEXTOBJ_UnlockText(TextObj); } else @@ -123,7 +125,8 @@ GreGetTextExtentExW( MaxExtent, (LPINT)Fit, (LPINT)Dx, - pSize); + pSize, + fl); TEXTOBJ_UnlockText(TextObj); } else @@ -132,6 +135,7 @@ GreGetTextExtentExW( DC_UnlockDc(pdc); return Result; } +#endif DWORD APIENTRY @@ -347,7 +351,8 @@ NtGdiGetTextExtentExW( MaxExtent, NULL == UnsafeFit ? NULL : &Fit, Dx, - &Size); + &Size, + fl); TEXTOBJ_UnlockText(TextObj); } else @@ -420,7 +425,7 @@ NtGdiGetTextExtent(HDC hdc, LPSIZE psize, UINT flOpts) { - return NtGdiGetTextExtentExW(hdc, lpwsz, cwc, 0, NULL, NULL, psize, 0); + return NtGdiGetTextExtentExW(hdc, lpwsz, cwc, 0, NULL, NULL, psize, flOpts); } BOOL