mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
Sync with trunk head (r48654)
svn path=/branches/reactos-yarotows/; revision=48660
This commit is contained in:
@@ -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++)
|
||||
|
||||
+15
-54
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<module name="faultrep" type="win32dll" baseaddress="${BASEADDRESS_FAULTREP}" installbase="system32" installname="faultrep.dll">
|
||||
<importlibrary definition="faultrep.spec" />
|
||||
<include base="fusion">.</include>
|
||||
<include base="faultrep">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__WINESRC__" />
|
||||
<library>wine</library>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
+112
-14
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
+17
-3
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <pci.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#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 */
|
||||
|
||||
+64
-21
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<file>close.c</file>
|
||||
<file>common.c</file>
|
||||
<file>create.c</file>
|
||||
<file>devctrl.c</file>
|
||||
<file>dirctl.c</file>
|
||||
<file>fcb.c</file>
|
||||
<file>finfo.c</file>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <debug.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<file>fsctl.c</file>
|
||||
<file>iface.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>pnp.c</file>
|
||||
<file>rw.c</file>
|
||||
<file>shutdown.c</file>
|
||||
<file>string.c</file>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+175
-178
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+46
-6
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
#include "initguid.h"
|
||||
#include <poclass.h>
|
||||
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#include <ioevent.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
+49
-22
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+26
-11
@@ -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:
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
+234
-28
@@ -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
|
||||
//
|
||||
|
||||
+26
-29
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
+89
-107
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+11
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -301,6 +301,8 @@ PspDeleteProcess(IN PVOID ObjectBody)
|
||||
/* Detach */
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
|
||||
RemoveEntryList(&Process->MmProcessLinks);
|
||||
|
||||
/* Completely delete the Address Space */
|
||||
MmDeleteProcessAddressSpace(Process);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user