Index: reactos/dll/ntdll/def/ntdll.spec =================================================================== --- reactos/dll/ntdll/def/ntdll.spec (revision 73408) +++ reactos/dll/ntdll/def/ntdll.spec (working copy) @@ -776,8 +776,8 @@ 771 stdcall RtlMultiAppendUnicodeStringBuffer(ptr long ptr) 772 stdcall RtlMultiByteToUnicodeN(ptr long ptr ptr long) 773 stdcall RtlMultiByteToUnicodeSize(ptr str long) -# RtlMultipleAllocateHeap -# RtlMultipleFreeHeap +774 stdcall RtlMultipleAllocateHeap(ptr long long long ptr) +775 stdcall RtlMultipleFreeHeap(ptr long long ptr) 776 stdcall RtlNewInstanceSecurityObject(long long ptr ptr ptr ptr ptr long ptr ptr) 777 stdcall RtlNewSecurityGrantedAccess(long ptr ptr ptr ptr ptr) 778 stdcall RtlNewSecurityObject(ptr ptr ptr long ptr ptr) Index: reactos/sdk/include/ndk/rtlfuncs.h =================================================================== --- reactos/sdk/include/ndk/rtlfuncs.h (revision 73408) +++ reactos/sdk/include/ndk/rtlfuncs.h (working copy) @@ -972,9 +972,9 @@ _Must_inspect_result_ NTSYSAPI -NTSTATUS +ULONG NTAPI -RtlMultipleAllocateHeap ( +RtlMultipleAllocateHeap( _In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_ SIZE_T Size, @@ -983,9 +983,9 @@ ); NTSYSAPI -NTSTATUS +ULONG NTAPI -RtlMultipleFreeHeap ( +RtlMultipleFreeHeap( _In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_ ULONG Count, Index: reactos/sdk/lib/rtl/heap.c =================================================================== --- reactos/sdk/lib/rtl/heap.c (revision 73408) +++ reactos/sdk/lib/rtl/heap.c (working copy) @@ -4,6 +4,7 @@ * FILE: lib/rtl/heap.c * PURPOSE: RTL Heap backend allocator * PROGRAMMERS: Copyright 2010 Aleksey Bragin + * Copyright 2016 Katayama Hirofumi MZ */ /* Useful references: @@ -3955,7 +3956,8 @@ return STATUS_UNSUCCESSFUL; } -NTSTATUS +/* @implemented */ +ULONG NTAPI RtlMultipleAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, @@ -3963,11 +3965,36 @@ IN ULONG Count, OUT PVOID *Array) { - UNIMPLEMENTED; - return 0; + ULONG Index; + EXCEPTION_RECORD ExceptionRecord; + + for (Index = 0; Index < Count; ++Index) + { + Array[Index] = RtlAllocateHeap(HeapHandle, Flags, Size); + if (Array[Index] == NULL) + { + /* ERROR_NOT_ENOUGH_MEMORY */ + RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY); + + if (Flags & HEAP_GENERATE_EXCEPTIONS) + { + ExceptionRecord.ExceptionCode = STATUS_NO_MEMORY; + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.NumberParameters = 0; + ExceptionRecord.ExceptionFlags = 0; + + RtlRaiseException(&ExceptionRecord); + } + + break; + } + } + + return Index; } -NTSTATUS +/* @implemented */ +ULONG NTAPI RtlMultipleFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, @@ -3974,8 +4001,47 @@ IN ULONG Count, OUT PVOID *Array) { - UNIMPLEMENTED; - return 0; + ULONG Index; + EXCEPTION_RECORD ExceptionRecord; + + Flags &= ~HEAP_GENERATE_EXCEPTIONS; + + for (Index = 0; Index < Count; ++Index) + { + if (Array[Index] == NULL) + { + continue; + } + if (Array == NULL) + { + ExceptionRecord.ExceptionCode = STATUS_INVALID_PARAMETER; + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.NumberParameters = 0; + ExceptionRecord.ExceptionFlags = 0; + + RtlRaiseException(&ExceptionRecord); + } + + _SEH2_TRY + { + if (!RtlFreeHeap(HeapHandle, Flags, Array[Index])) + { + /* ERROR_INVALID_PARAMETER */ + RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER); + + break; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* ERROR_INVALID_PARAMETER */ + RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER); + break; + } + _SEH2_END; + } + + return Index; } /* EOF */ Index: rostests/apitests/kernel32/CMakeLists.txt =================================================================== --- rostests/apitests/kernel32/CMakeLists.txt (revision 73408) +++ rostests/apitests/kernel32/CMakeLists.txt (working copy) @@ -17,7 +17,8 @@ TunnelCache.c WideCharToMultiByte.c testlist.c - Mailslot.c) + Mailslot.c + heap.c) add_executable(kernel32_apitest ${SOURCE}) target_link_libraries(kernel32_apitest wine ${PSEH_LIB}) Index: rostests/apitests/kernel32/testlist.c =================================================================== --- rostests/apitests/kernel32/testlist.c (revision 73408) +++ rostests/apitests/kernel32/testlist.c (working copy) @@ -20,6 +20,7 @@ extern void func_TerminateProcess(void); extern void func_TunnelCache(void); extern void func_WideCharToMultiByte(void); +extern void func_heap(void); const struct test winetest_testlist[] = { @@ -40,6 +41,7 @@ { "TerminateProcess", func_TerminateProcess }, { "TunnelCache", func_TunnelCache }, { "WideCharToMultiByte", func_WideCharToMultiByte }, + { "heap", func_heap }, { 0, 0 } };