Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,23 @@
set(MODULE_NAME "TestInterlocked")
set(MODULE_PREFIX "TEST_INTERLOCKED")
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS TestInterlockedAccess.c TestInterlockedSList.c TestInterlockedDList.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
target_link_libraries(${MODULE_NAME} winpr)
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
foreach(test ${${MODULE_PREFIX}_TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")

View File

@@ -0,0 +1,200 @@
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
#include <winpr/interlocked.h>
int TestInterlockedAccess(int argc, char* argv[])
{
LONG* Addend = nullptr;
LONG* Target = nullptr;
LONG oldValue = 0;
LONG* Destination = nullptr;
LONGLONG oldValue64 = 0;
LONGLONG* Destination64 = nullptr;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
/* InterlockedIncrement */
Addend = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG));
if (!Addend)
{
printf("Failed to allocate memory\n");
return -1;
}
*Addend = 0;
for (int index = 0; index < 10; index++)
InterlockedIncrement(Addend);
if (*Addend != 10)
{
printf("InterlockedIncrement failure: Actual: %" PRId32 ", Expected: 10\n", *Addend);
return -1;
}
/* InterlockedDecrement */
for (int index = 0; index < 10; index++)
(void)InterlockedDecrement(Addend);
if (*Addend != 0)
{
printf("InterlockedDecrement failure: Actual: %" PRId32 ", Expected: 0\n", *Addend);
return -1;
}
/* InterlockedExchange */
Target = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG));
if (!Target)
{
printf("Failed to allocate memory\n");
return -1;
}
*Target = 0xAA;
oldValue = InterlockedExchange(Target, 0xFF);
if (oldValue != 0xAA)
{
printf("InterlockedExchange failure: Actual: 0x%08" PRIX32 ", Expected: 0xAA\n", oldValue);
return -1;
}
if (*Target != 0xFF)
{
printf("InterlockedExchange failure: Actual: 0x%08" PRIX32 ", Expected: 0xFF\n", *Target);
return -1;
}
/* InterlockedExchangeAdd */
*Addend = 25;
oldValue = InterlockedExchangeAdd(Addend, 100);
if (oldValue != 25)
{
printf("InterlockedExchangeAdd failure: Actual: %" PRId32 ", Expected: 25\n", oldValue);
return -1;
}
if (*Addend != 125)
{
printf("InterlockedExchangeAdd failure: Actual: %" PRId32 ", Expected: 125\n", *Addend);
return -1;
}
/* InterlockedCompareExchange (*Destination == Comparand) */
Destination = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG));
if (!Destination)
{
printf("Failed to allocate memory\n");
return -1;
}
*Destination = (LONG)0xAABBCCDDL;
oldValue = InterlockedCompareExchange(Destination, (LONG)0xCCDDEEFFL, (LONG)0xAABBCCDDL);
if (oldValue != (LONG)0xAABBCCDDL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32
", Expected: 0xAABBCCDD\n",
oldValue);
return -1;
}
if ((*Destination) != (LONG)0xCCDDEEFFL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32
", Expected: 0xCCDDEEFF\n",
*Destination);
return -1;
}
/* InterlockedCompareExchange (*Destination != Comparand) */
*Destination = (LONG)0xAABBCCDDL;
oldValue = InterlockedCompareExchange(Destination, -857870593L, 0x66778899L);
if (oldValue != (LONG)0xAABBCCDDL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32
", Expected: 0xAABBCCDD\n",
oldValue);
return -1;
}
if ((*Destination) != (LONG)0xAABBCCDDL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32
", Expected: 0xAABBCCDD\n",
*Destination);
return -1;
}
/* InterlockedCompareExchange64 (*Destination == Comparand) */
Destination64 = winpr_aligned_malloc(sizeof(LONGLONG), sizeof(LONGLONG));
if (!Destination64)
{
printf("Failed to allocate memory\n");
return -1;
}
*Destination64 = 0x66778899AABBCCDD;
oldValue64 =
InterlockedCompareExchange64(Destination64, 0x0899AABBCCDDEEFFLL, 0x66778899AABBCCDD);
if (oldValue64 != 0x66778899AABBCCDD)
{
printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64
", Expected: 0x66778899AABBCCDD\n",
oldValue64);
return -1;
}
if ((*Destination64) != 0x0899AABBCCDDEEFFLL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64
", Expected: 0x0899AABBCCDDEEFFLL\n",
*Destination64);
return -1;
}
/* InterlockedCompareExchange64 (*Destination != Comparand) */
*Destination64 = 0x66778899AABBCCDDLL;
oldValue64 = InterlockedCompareExchange64(Destination64, 0x0899AABBCCDDEEFFLL, 12345);
if (oldValue64 != 0x66778899AABBCCDDLL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64
", Expected: 0x66778899AABBCCDD\n",
oldValue64);
return -1;
}
if (*Destination64 != 0x66778899AABBCCDDLL)
{
printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64
", Expected: 0x66778899AABBCCDD\n",
*Destination64);
return -1;
}
winpr_aligned_free(Addend);
winpr_aligned_free(Target);
winpr_aligned_free(Destination);
winpr_aligned_free(Destination64);
return 0;
}

View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
#include <winpr/interlocked.h>
typedef struct
{
WINPR_LIST_ENTRY ItemEntry;
ULONG Signature;
} LIST_ITEM, *PLIST_ITEM;
int TestInterlockedDList(int argc, char* argv[])
{
ULONG Count = 0;
PLIST_ITEM pListItem = nullptr;
WINPR_PLIST_ENTRY pListHead = nullptr;
WINPR_PLIST_ENTRY pListEntry = nullptr;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
pListHead = (WINPR_PLIST_ENTRY)winpr_aligned_malloc(sizeof(WINPR_LIST_ENTRY),
MEMORY_ALLOCATION_ALIGNMENT);
if (!pListHead)
{
printf("Memory allocation failed.\n");
return -1;
}
InitializeListHead(pListHead);
if (!IsListEmpty(pListHead))
{
printf("Expected empty list\n");
return -1;
}
/* InsertHeadList / RemoveHeadList */
printf("InsertHeadList / RemoveHeadList\n");
for (Count = 1; Count <= 10; Count += 1)
{
pListItem =
(PLIST_ITEM)winpr_aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
pListItem->Signature = Count;
InsertHeadList(pListHead, &(pListItem->ItemEntry));
}
for (Count = 10; Count >= 1; Count -= 1)
{
pListEntry = RemoveHeadList(pListHead);
pListItem = (PLIST_ITEM)pListEntry;
winpr_aligned_free(pListItem);
}
/* InsertTailList / RemoveTailList */
printf("InsertTailList / RemoveTailList\n");
for (Count = 1; Count <= 10; Count += 1)
{
pListItem =
(PLIST_ITEM)winpr_aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
pListItem->Signature = Count;
InsertTailList(pListHead, &(pListItem->ItemEntry));
}
for (Count = 10; Count >= 1; Count -= 1)
{
pListEntry = RemoveTailList(pListHead);
pListItem = (PLIST_ITEM)pListEntry;
winpr_aligned_free(pListItem);
}
winpr_aligned_free(pListHead);
return 0;
}

View File

@@ -0,0 +1,95 @@
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
#include <winpr/interlocked.h>
#define ITEM_COUNT 23
typedef struct
{
WINPR_SLIST_ENTRY ItemEntry;
ULONG Signature;
} PROGRAM_ITEM, *PPROGRAM_ITEM;
int TestInterlockedSList(int argc, char* argv[])
{
int rc = -1;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
/* Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. */
WINPR_PSLIST_HEADER pListHead = (WINPR_PSLIST_HEADER)winpr_aligned_malloc(
sizeof(WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
if (!pListHead)
{
printf("Memory allocation failed.\n");
return -1;
}
InitializeSListHead(pListHead);
/* Insert 10 items into the list. */
for (ULONG Count = 0; Count < ITEM_COUNT; Count++)
{
PPROGRAM_ITEM pProgramItem =
(PPROGRAM_ITEM)winpr_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
if (!pProgramItem)
{
printf("Memory allocation failed.\n");
goto fail;
}
pProgramItem->Signature = Count + 1UL;
WINPR_PSLIST_ENTRY pFirstEntry =
InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry));
if (((Count == 0) && pFirstEntry) || ((Count != 0) && !pFirstEntry))
{
printf("Error: List is empty.\n");
winpr_aligned_free(pProgramItem);
goto fail;
}
}
/* Remove 10 items from the list and display the signature. */
for (ULONG Count = 0; Count < ITEM_COUNT; Count++)
{
WINPR_PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead);
if (!pListEntry)
{
printf("List is empty.\n");
goto fail;
}
PPROGRAM_ITEM pProgramItem = (PPROGRAM_ITEM)pListEntry;
printf("Signature is %" PRIu32 "\n", pProgramItem->Signature);
/*
* This example assumes that the SLIST_ENTRY structure is the
* first member of the structure. If your structure does not
* follow this convention, you must compute the starting address
* of the structure before calling the free function.
*/
winpr_aligned_free(pListEntry);
}
/* Flush the list and verify that the items are gone. */
WINPR_PSLIST_ENTRY pFirstEntry = InterlockedPopEntrySList(pListHead);
if (pFirstEntry)
{
printf("Error: List is not empty.\n");
goto fail;
}
rc = 0;
fail:
winpr_aligned_free(pListHead);
return rc;
}