Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
84a4219
Update print statement from 'Hello' to 'Goodbye'
WINDROID-EMU Feb 17, 2026
064383a
Wine Update error handling for PROT_EXEC in virtual.c
WINDROID-EMU Feb 19, 2026
512fcb5
Add missing HEAP_INFORMATION_CLASS constants for x86_64 compilation
WINDROID-EMU Mar 28, 2026
9c1e092
Implement ThreadIdealProcessor support in NtSetInformationThread and …
WINDROID-EMU Mar 29, 2026
319bfb8
Fix request_max_size structure to accommodate larger protocol requests
WINDROID-EMU Mar 29, 2026
f20e43b
FSR: Move FidelityFX Super Resolution from Android driver to X11 driver
WINDROID-EMU Apr 1, 2026
b39a36e
Refactor esync.c for improved performance and clarity
WINDROID-EMU Apr 3, 2026
0aecc34
Align structures to 64 bytes and optimize locks
WINDROID-EMU Apr 3, 2026
5c356a0
Optimize esync for gaming performance
WINDROID-EMU Apr 3, 2026
a27ef98
Reject D3D12 interface queries to prevent crashes
WINDROID-EMU Apr 3, 2026
99ee4ea
Windroid-Wine: Melhorias no FSR, Media Foundation e Colorimetria
WINDROID-EMU Apr 7, 2026
6df630b
Add video format constants and clean up code
WINDROID-EMU Apr 7, 2026
0f91477
Add profile and level checks for H264 format
WINDROID-EMU Apr 7, 2026
ecf53e5
Comment out error handling for STATUS_INVALID_HANDLE
WINDROID-EMU Apr 10, 2026
d55d1f3
Comment out error handling in server.c
WINDROID-EMU Apr 10, 2026
53a0182
Refactor esync structures and optimize inline functions
WINDROID-EMU Apr 13, 2026
a3aab1a
Add ntdll workaround to release reserved low memory on 32-bit.
WINDROID-EMU Apr 21, 2026
a710003
Add WINE_HEAP_ZERO_MEMORY hook for process heap creation.
WINDROID-EMU Apr 21, 2026
9cf9dc6
Match TLS allocation layout for ThreadLocalStoragePointer.
WINDROID-EMU Apr 21, 2026
f5ddc47
Fix WINE_HEAP_ZERO_MEMORY env read before process heap initialization.
WINDROID-EMU Apr 21, 2026
b231e5a
winex11.drv: Implement auto-scaling Native FSR Support (FShack-like)
WINDROID-EMU Apr 22, 2026
e9b7149
winex11.drv: Implement Smart FSR scaling with Aspect Ratio matching a…
WINDROID-EMU Apr 22, 2026
8f5b365
opengl: Fix FSR RCAS math and implement real-time sharpness adjustment
WINDROID-EMU Apr 22, 2026
bdb8268
winex11.drv: Refine FSR implementation with accurate EASU/RCAS shader…
WINDROID-EMU Apr 23, 2026
bcb95f5
ntdll: Implementar HideWineExports e spoofing de ProcessDebugPort par…
WINDROID-EMU Apr 23, 2026
36d3b24
winex11.drv: Fix FSR rendering artifacts and OpenGL state management
WINDROID-EMU Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,844 changes: 2,377 additions & 2,467 deletions dlls/combase/combase.c

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions dlls/dxgi/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IWineDXGIDevice *ifa
return S_OK;
}

/* HACK: Reject D3D12 interface queries explicitly to prevent games from
* crashing when they QueryInterface for D3D12CommandQueue (used by D3D9On12)
* and try to use the NULL pointer without checking the return value.
* GUID 0ec870a6-5d7e-4c22-8cfc-5baae07616ed = ID3D12CommandQueue */
if (IsEqualGUID(riid, &IID_ID3D12CommandQueue))
{
WARN("Rejecting ID3D12CommandQueue query - D3D9On12 not supported.\n");
*object = NULL;
return E_NOINTERFACE;
}

if (device->child_layer)
{
TRACE("Forwarding to child layer %p.\n", device->child_layer);
Expand Down
23 changes: 23 additions & 0 deletions dlls/kernel32/tests/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,10 @@ static void test_tls_links(void)
TEB *teb = NtCurrentTeb(), *thread_teb;
THREAD_BASIC_INFORMATION tbi;
NTSTATUS status;
ULONG i, count;
HANDLE thread;
SIZE_T size;
void **ptr;

ok(!!teb->ThreadLocalStoragePointer, "got NULL.\n");

Expand All @@ -1728,6 +1731,26 @@ static void test_tls_links(void)
ResumeThread(thread);
WaitForSingleObject(test_tls_links_started, INFINITE);

if (!is_old_loader_struct())
{
ptr = teb->ThreadLocalStoragePointer;
count = (ULONG_PTR)ptr[-2];
size = HeapSize(GetProcessHeap(), 0, ptr - 2);
ok(size == (count + 2) * sizeof(void *), "got count %lu, size %Iu.\n", count, size);

for (i = 0; i < count; ++i)
{
if (!ptr[i]) continue;
size = HeapSize(GetProcessHeap(), 0, (void **)ptr[i] - 2);
ok(size && size < 100000, "got %Iu.\n", size);
}

ptr = thread_teb->ThreadLocalStoragePointer;
count = (ULONG_PTR)ptr[-2];
size = HeapSize(GetProcessHeap(), 0, ptr - 2);
ok(size == (count + 2) * sizeof(void *), "got count %lu, size %Iu.\n", count, size);
}

ok(!!thread_teb->ThreadLocalStoragePointer, "got NULL.\n");
ok(!teb->TlsLinks.Flink, "got %p.\n", teb->TlsLinks.Flink);
ok(!teb->TlsLinks.Blink, "got %p.\n", teb->TlsLinks.Blink);
Expand Down
72 changes: 65 additions & 7 deletions dlls/mfplat/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"

#include "initguid.h"
Expand Down Expand Up @@ -87,6 +86,7 @@ struct mft_registration
UINT32 input_types_count;
MFT_REGISTER_TYPE_INFO *output_types;
UINT32 output_types_count;
DWORD merit;
BOOL local;
};

Expand Down Expand Up @@ -1103,6 +1103,31 @@ static void mft_get_reg_flags(const WCHAR *clsidW, const WCHAR *nameW, DWORD *fl
RegCloseKey(hmft);
}

static void mft_get_reg_merit(const WCHAR *clsidW, DWORD *merit)
{
DWORD ret, reg_type, size;
HKEY hroot, hmft;

*merit = 0;

if (RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &hroot))
return;

ret = RegOpenKeyW(hroot, clsidW, &hmft);
RegCloseKey(hroot);
if (ret)
return;

reg_type = 0;
size = sizeof(*merit);
if (!RegQueryValueExW(hmft, L"Merit", NULL, &reg_type, (BYTE *)merit, &size) && reg_type == REG_DWORD)
{
/* Merit found */
}

RegCloseKey(hmft);
}

static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category, UINT32 flags,
IMFPluginControl *plugin_control, const MFT_REGISTER_TYPE_INFO *input_type,
const MFT_REGISTER_TYPE_INFO *output_type)
Expand Down Expand Up @@ -1131,6 +1156,7 @@ static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category,
goto next;

mft_get_reg_flags(clsidW, L"MFTFlags", &mft.flags);
mft_get_reg_merit(clsidW, &mft.merit);

if (output_type)
mft_get_reg_type_info_internal(clsidW, L"OutputTypes", &mft.output_types, &mft.output_types_count);
Expand Down Expand Up @@ -1237,28 +1263,60 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF

if (flags & MFT_ENUM_FLAG_SORTANDFILTER)
{
/* Local registrations. */
/* Preferred transforms. */
LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry)
{
if (mft->local)
if (!mft->factory && mft_is_preferred(plugin_control, &mft->clsid))
{
list_remove(&mft->entry);
list_add_tail(&mfts_sorted, &mft->entry);
}
}

/* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */

/* Preferred transforms. */
/* Local registrations. */
LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry)
{
if (!mft->factory && mft_is_preferred(plugin_control, &mft->clsid))
if (mft->local)
{
list_remove(&mft->entry);
list_add_tail(&mfts_sorted, &mft->entry);
}
}

/* Sorted by merit value. */
{
struct mft_registration **array;
unsigned int i, j, count = list_count(&mfts);

if (count > 1 && (array = malloc(count * sizeof(*array))))
{
i = 0;
LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry)
array[i++] = mft;

/* Simple bubble sort for merit (count is usually small) */
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (array[j]->merit < array[j+1]->merit)
{
struct mft_registration *tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}

for (i = 0; i < count; i++)
{
list_remove(&array[i]->entry);
list_add_tail(&mfts_sorted, &array[i]->entry);
}
free(array);
}
}

/* Append the rest. */
LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry)
{
Expand Down
53 changes: 30 additions & 23 deletions dlls/ntdll/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2578,37 +2578,44 @@ NTSTATUS WINAPI RtlQueryHeapInformation( HANDLE handle, HEAP_INFORMATION_CLASS i
/***********************************************************************
* RtlSetHeapInformation (NTDLL.@)
*/
NTSTATUS WINAPI RtlSetHeapInformation( HANDLE handle, HEAP_INFORMATION_CLASS info_class, void *info, SIZE_T size )
NTSTATUS WINAPI RtlSetHeapInformation(
HANDLE HeapHandle,
HEAP_INFORMATION_CLASS HeapInformationClass,
PVOID HeapInformation,
SIZE_T HeapInformationLength)
{
struct heap *heap;
ULONG flags;
TRACE("RtlSetHeapInformation(%p, %d, %p, %zu)\n",
HeapHandle, HeapInformationClass,
HeapInformation, HeapInformationLength);

TRACE( "handle %p, info_class %u, info %p, size %Iu.\n", handle, info_class, info, size );

switch (info_class)
switch (HeapInformationClass)
{
case HeapCompatibilityInformation:
{
ULONG compat_info;
case HeapCompatibilityInformation:
{
/* Compatibilidade com heaps (Low Fragmentation Heap etc.) */
if (HeapInformationLength < sizeof(ULONG))
return STATUS_INFO_LENGTH_MISMATCH;

/* Aceita valor mas não implementa totalmente */
return STATUS_SUCCESS;
}

if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
if (!(heap = unsafe_heap_from_handle( handle, 0, &flags ))) return STATUS_INVALID_HANDLE;
if (heap->flags & HEAP_NO_SERIALIZE) return STATUS_INVALID_PARAMETER;
case HeapEnableTerminationOnCorruption:
{
/* Ativa proteção contra corrupção de heap */
/* No Wine normalmente só ignoramos */
return STATUS_SUCCESS;
}

compat_info = *(ULONG *)info;
if (compat_info != HEAP_STD && compat_info != HEAP_LFH)
case HeapOptimizeResources:
{
FIXME( "HeapCompatibilityInformation %lu not implemented!\n", compat_info );
return STATUS_UNSUCCESSFUL;
/* Otimização de heap (stub seguro) */
return STATUS_SUCCESS;
}
if (InterlockedCompareExchange( &heap->compat_info, compat_info, HEAP_STD ) != HEAP_STD)
return STATUS_UNSUCCESSFUL;
return STATUS_SUCCESS;
}

default:
FIXME( "HEAP_INFORMATION_CLASS %u not implemented!\n", info_class );
return STATUS_SUCCESS;
default:
WARN("Classe de heap não implementada: %d\n", HeapInformationClass);
return STATUS_NOT_IMPLEMENTED;
}
}

Expand Down
61 changes: 49 additions & 12 deletions dlls/ntdll/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,34 @@ static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_H
return TRUE;
}

/*************************************************************************
* alloc_tls_memory
*
* Allocate memory for TLS vector or index with an extra data.
*/
static void *alloc_tls_memory( BOOL vector, ULONG_PTR size )
{
ULONG_PTR *ptr;

if (!(ptr = RtlAllocateHeap( GetProcessHeap(), vector ? HEAP_ZERO_MEMORY : 0, size + sizeof(void *) * 2 )))
return NULL;
ptr += 2;
if (vector) ptr[-2] = size / sizeof(void *);
else ptr[-2] = ptr[-1] = 0;
return ptr;
}

/*************************************************************************
* free_tls_memory
*
* Free TLS vector or index memory.
*/
static void free_tls_memory( void *ptr )
{
if (!ptr) return;
RtlFreeHeap( GetProcessHeap(), 0, (void **)ptr - 2 );
}

/*************************************************************************
* alloc_tls_slot
*
Expand Down Expand Up @@ -1336,7 +1364,7 @@ static BOOL alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod )
if (old_module_count < tls_module_count)
{
void **old = teb->ThreadLocalStoragePointer;
void **new = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, tls_module_count * sizeof(*new));
void **new = alloc_tls_memory( TRUE, tls_module_count * sizeof(*new) );

if (!new) return FALSE;
if (old) memcpy( new, old, old_module_count * sizeof(*new) );
Expand All @@ -1348,15 +1376,14 @@ static BOOL alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod )
/* FIXME: can't free old block here, should be freed at thread exit */
}

if (!(new_ptr = RtlAllocateHeap( GetProcessHeap(), 0, size + dir->SizeOfZeroFill ))) return -1;
if (!(new_ptr = alloc_tls_memory( FALSE, size + dir->SizeOfZeroFill ))) return -1;
memcpy( new_ptr, (void *)dir->StartAddressOfRawData, size );
memset( (char *)new_ptr + size, 0, dir->SizeOfZeroFill );

TRACE( "thread %04lx slot %lu: %lu/%lu bytes at %p\n",
HandleToULong(teb->ClientId.UniqueThread), i, size, dir->SizeOfZeroFill, new_ptr );

RtlFreeHeap( GetProcessHeap(), 0,
InterlockedExchangePointer( (void **)teb->ThreadLocalStoragePointer + i, new_ptr ));
free_tls_memory( InterlockedExchangePointer( (void **)teb->ThreadLocalStoragePointer + i, new_ptr ) );
}
if (thread) NtClose( thread );

Expand Down Expand Up @@ -1571,8 +1598,7 @@ static NTSTATUS alloc_thread_tls(void)
void **pointers;
UINT i, size;

if (!(pointers = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
tls_module_count * sizeof(*pointers) )))
if (!(pointers = alloc_tls_memory( TRUE, tls_module_count * sizeof(*pointers) )))
return STATUS_NO_MEMORY;

for (i = 0; i < tls_module_count; i++)
Expand All @@ -1583,10 +1609,10 @@ static NTSTATUS alloc_thread_tls(void)
size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
if (!size && !dir->SizeOfZeroFill) continue;

if (!(pointers[i] = RtlAllocateHeap( GetProcessHeap(), 0, size + dir->SizeOfZeroFill )))
if (!(pointers[i] = alloc_tls_memory( FALSE, size + dir->SizeOfZeroFill )))
{
while (i) RtlFreeHeap( GetProcessHeap(), 0, pointers[--i] );
RtlFreeHeap( GetProcessHeap(), 0, pointers );
while (i) free_tls_memory( pointers[--i] );
free_tls_memory( pointers );
return STATUS_NO_MEMORY;
}
memcpy( pointers[i], (void *)dir->StartAddressOfRawData, size );
Expand Down Expand Up @@ -3889,8 +3915,8 @@ void WINAPI LdrShutdownThread(void)
if (NtCurrentTeb()->Instrumentation[0])
((TEB *)NtCurrentTeb()->Instrumentation[0])->ThreadLocalStoragePointer = NULL;
#endif
for (i = 0; i < tls_module_count; i++) RtlFreeHeap( GetProcessHeap(), 0, pointers[i] );
RtlFreeHeap( GetProcessHeap(), 0, pointers );
for (i = 0; i < tls_module_count; i++) free_tls_memory( pointers[i] );
free_tls_memory( pointers );
}
RtlProcessFlsData( NtCurrentTeb()->FlsSlots, 2 );
NtCurrentTeb()->FlsSlots = NULL;
Expand Down Expand Up @@ -4340,14 +4366,25 @@ void loader_init( CONTEXT *context, void **entry )
ANSI_STRING ctrl_routine = RTL_CONSTANT_STRING( "CtrlRoutine" );
WINE_MODREF *kernel32;
PEB *peb = NtCurrentTeb()->Peb;
WCHAR env_heap_zero[16];
SIZE_T env_heap_zero_len = 0;
ULONG heap_flags = HEAP_GROWABLE;
unsigned int i;

peb->LdrData = &ldr;
peb->FastPebLock = &peb_lock;
peb->TlsBitmap = &tls_bitmap;
peb->TlsExpansionBitmap = &tls_expansion_bitmap;
peb->LoaderLock = &loader_section;
peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL );
if (!RtlQueryEnvironmentVariable( NULL, L"WINE_HEAP_ZERO_MEMORY",
ARRAY_SIZE(env_heap_zero), env_heap_zero,
ARRAY_SIZE(env_heap_zero), &env_heap_zero_len ) &&
env_heap_zero_len && env_heap_zero[0] == L'1')
{
ERR( "Enabling heap zero hack.\n" );
heap_flags |= HEAP_ZERO_MEMORY;
}
peb->ProcessHeap = RtlCreateHeap( heap_flags, NULL, 0, 0, NULL, NULL );

RtlInitializeBitMap( &tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8 );
RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
Expand Down
Loading