mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-30 21:33:34 +08:00
libwinpr-nt: implement NtCurrentTeb()
This commit is contained in:
parent
c878200e00
commit
68ec10a9d9
@ -498,7 +498,7 @@ BOOL tf_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
if (strncmp(client->settings->ChannelDefArray[i].Name, "rdpdbg", 6) == 0)
|
||||
{
|
||||
context->debug_channel = WTSVirtualChannelOpenEx(context->vcm, "rdpdbg", 0);
|
||||
context->debug_channel = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdbg", 0);
|
||||
|
||||
if (context->debug_channel != NULL)
|
||||
{
|
||||
@ -580,7 +580,7 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
{
|
||||
if (context->debug_channel)
|
||||
{
|
||||
WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test2", 5, NULL);
|
||||
WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test2", 5, NULL);
|
||||
}
|
||||
}
|
||||
else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */
|
||||
|
77
winpr/include/winpr/nt.h
Normal file
77
winpr/include/winpr/nt.h
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Native System Services
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_NT_H
|
||||
#define WINPR_NT_H
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
typedef struct _PEB PEB;
|
||||
typedef struct _PEB* PPEB;
|
||||
|
||||
typedef struct _TEB TEB;
|
||||
typedef struct _TEB* PTEB;
|
||||
|
||||
/**
|
||||
* Process Environment Block
|
||||
*/
|
||||
|
||||
struct _THREAD_BLOCK_ID
|
||||
{
|
||||
DWORD ThreadId;
|
||||
TEB* ThreadEnvironmentBlock;
|
||||
};
|
||||
typedef struct _THREAD_BLOCK_ID THREAD_BLOCK_ID;
|
||||
|
||||
struct _PEB
|
||||
{
|
||||
DWORD ThreadCount;
|
||||
DWORD ThreadArraySize;
|
||||
THREAD_BLOCK_ID* Threads;
|
||||
};
|
||||
|
||||
/*
|
||||
* Thread Environment Block
|
||||
*/
|
||||
|
||||
struct _TEB
|
||||
{
|
||||
PEB* ProcessEnvironmentBlock;
|
||||
|
||||
DWORD LastErrorValue;
|
||||
PVOID TlsSlots[64];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API PTEB NtCurrentTeb(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_NT_H */
|
||||
|
@ -31,10 +31,20 @@ add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib")
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
|
||||
MODULE winpr
|
||||
MODULES winpr-nt)
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
|
||||
else()
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
@ -23,25 +23,12 @@
|
||||
|
||||
#include <winpr/error.h>
|
||||
|
||||
/**
|
||||
* api-ms-win-core-errorhandling-l1-1-1.dll:
|
||||
*
|
||||
* GetErrorMode
|
||||
* SetErrorMode
|
||||
* GetLastError
|
||||
* SetLastError
|
||||
* RestoreLastError
|
||||
* RaiseException
|
||||
* UnhandledExceptionFilter
|
||||
* SetUnhandledExceptionFilter
|
||||
* AddVectoredExceptionHandler
|
||||
* RemoveVectoredExceptionHandler
|
||||
* AddVectoredContinueHandler
|
||||
* RemoveVectoredContinueHandler
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <winpr/nt.h>
|
||||
|
||||
UINT GetErrorMode(void)
|
||||
{
|
||||
return 0;
|
||||
@ -54,12 +41,12 @@ UINT SetErrorMode(UINT uMode)
|
||||
|
||||
DWORD GetLastError(VOID)
|
||||
{
|
||||
return 0;
|
||||
return NtCurrentTeb()->LastErrorValue;
|
||||
}
|
||||
|
||||
VOID SetLastError(DWORD dwErrCode)
|
||||
{
|
||||
|
||||
NtCurrentTeb()->LastErrorValue = dwErrCode;
|
||||
}
|
||||
|
||||
VOID RestoreLastError(DWORD dwErrCode)
|
||||
|
3
winpr/libwinpr/error/test/.gitignore
vendored
Normal file
3
winpr/libwinpr/error/test/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
TestError
|
||||
TestError.c
|
||||
|
31
winpr/libwinpr/error/test/CMakeLists.txt
Normal file
31
winpr/libwinpr/error/test/CMakeLists.txt
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
set(MODULE_NAME "TestError")
|
||||
set(MODULE_PREFIX "TEST_ERROR")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestErrorSetLastError.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-synch winpr-thread winpr-error)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
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")
|
||||
|
89
winpr/libwinpr/error/test/TestErrorSetLastError.c
Normal file
89
winpr/libwinpr/error/test/TestErrorSetLastError.c
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
|
||||
#include <winpr/error.h>
|
||||
|
||||
static int status = 0;
|
||||
|
||||
static DWORD errors[4] =
|
||||
{
|
||||
ERROR_INVALID_DATA,
|
||||
ERROR_BROKEN_PIPE,
|
||||
ERROR_INVALID_NAME,
|
||||
ERROR_BAD_ARGUMENTS
|
||||
};
|
||||
|
||||
static void* test_error_thread(void* arg)
|
||||
{
|
||||
int id;
|
||||
DWORD error;
|
||||
|
||||
id = (int) (size_t) arg;
|
||||
|
||||
error = errors[id];
|
||||
|
||||
SetLastError(error);
|
||||
|
||||
Sleep(10);
|
||||
|
||||
error = GetLastError();
|
||||
|
||||
if (error != errors[id])
|
||||
{
|
||||
printf("GetLastError() failure (thread %d): Expected: 0x%04X, Actual: 0x%04X\n",
|
||||
id, errors[id], error);
|
||||
|
||||
if (!status)
|
||||
status = -1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int TestErrorSetLastError(int argc, char* argv[])
|
||||
{
|
||||
DWORD error;
|
||||
HANDLE threads[4];
|
||||
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
|
||||
error = GetLastError();
|
||||
|
||||
if (error != ERROR_ACCESS_DENIED)
|
||||
{
|
||||
printf("GetLastError() failure: Expected: 0x%04X, Actual: 0x%04X\n",
|
||||
ERROR_ACCESS_DENIED, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 0, 0, NULL);
|
||||
threads[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 1, 0, NULL);
|
||||
threads[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 2, 0, NULL);
|
||||
threads[3] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 3, 0, NULL);
|
||||
|
||||
WaitForSingleObject(threads[0], INFINITE);
|
||||
WaitForSingleObject(threads[1], INFINITE);
|
||||
WaitForSingleObject(threads[2], INFINITE);
|
||||
WaitForSingleObject(threads[3], INFINITE);
|
||||
|
||||
CloseHandle(threads[0]);
|
||||
CloseHandle(threads[1]);
|
||||
CloseHandle(threads[2]);
|
||||
CloseHandle(threads[3]);
|
||||
|
||||
error = GetLastError();
|
||||
|
||||
if (error != ERROR_ACCESS_DENIED)
|
||||
{
|
||||
printf("GetLastError() failure: Expected: 0x%04X, Actual: 0x%04X\n",
|
||||
ERROR_ACCESS_DENIED, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
53
winpr/libwinpr/nt/CMakeLists.txt
Normal file
53
winpr/libwinpr/nt/CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-nt cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(MODULE_NAME "winpr-nt")
|
||||
set(MODULE_PREFIX "WINPR_NT")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
nt.c)
|
||||
|
||||
if(MSVC AND (NOT MONOLITHIC_BUILD))
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)
|
||||
endif()
|
||||
|
||||
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
SOURCES ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib")
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${CMAKE_DL_LIBS})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES SunOS)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rt)
|
||||
endif()
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
else()
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
8
winpr/libwinpr/nt/ModuleOptions.cmake
Normal file
8
winpr/libwinpr/nt/ModuleOptions.cmake
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
set(MINWIN_LAYER "0")
|
||||
set(MINWIN_GROUP "none")
|
||||
set(MINWIN_MAJOR_VERSION "0")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "nt")
|
||||
set(MINWIN_LONG_NAME "Windows Native System Services")
|
||||
set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}")
|
3
winpr/libwinpr/nt/module.def
Normal file
3
winpr/libwinpr/nt/module.def
Normal file
@ -0,0 +1,3 @@
|
||||
LIBRARY "libwinpr-nt"
|
||||
EXPORTS
|
||||
|
205
winpr/libwinpr/nt/nt.c
Normal file
205
winpr/libwinpr/nt/nt.c
Normal file
@ -0,0 +1,205 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Native System Services
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/nt.h>
|
||||
|
||||
/**
|
||||
* NtXxx Routines:
|
||||
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff557720/
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
/**
|
||||
* The current implementation of NtCurrentTeb() is not the most efficient
|
||||
* but it's a starting point. Beware of potential performance bottlenecks
|
||||
* caused by multithreaded usage of SetLastError/GetLastError.
|
||||
*/
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static PPEB g_ProcessEnvironmentBlock = NULL;
|
||||
|
||||
static void NtThreadEnvironmentBlockFree(PTEB teb);
|
||||
static void NtProcessEnvironmentBlockFree(PPEB peb);
|
||||
|
||||
static PTEB NtThreadEnvironmentBlockNew()
|
||||
{
|
||||
PTEB teb = NULL;
|
||||
pthread_key_t key;
|
||||
|
||||
teb = (PTEB) malloc(sizeof(TEB));
|
||||
|
||||
if (teb)
|
||||
{
|
||||
ZeroMemory(teb, sizeof(TEB));
|
||||
|
||||
/**
|
||||
* We are not really using the key, but it provides an automatic way
|
||||
* of calling NtThreadEnvironmentBlockFree on thread termination for
|
||||
* the current Thread Environment Block.
|
||||
*/
|
||||
|
||||
pthread_key_create(&key, (void (*)(void*)) NtThreadEnvironmentBlockFree);
|
||||
pthread_setspecific(key, (void*) teb);
|
||||
}
|
||||
|
||||
return teb;
|
||||
}
|
||||
|
||||
static void NtThreadEnvironmentBlockFree(PTEB teb)
|
||||
{
|
||||
DWORD index;
|
||||
PPEB peb = NULL;
|
||||
|
||||
peb = teb->ProcessEnvironmentBlock;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
for (index = 0; index < peb->ThreadArraySize; index++)
|
||||
{
|
||||
if (peb->Threads[index].ThreadEnvironmentBlock == teb)
|
||||
{
|
||||
peb->Threads[index].ThreadId = 0;
|
||||
peb->Threads[index].ThreadEnvironmentBlock = NULL;
|
||||
peb->ThreadCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!peb->ThreadCount)
|
||||
{
|
||||
NtProcessEnvironmentBlockFree(peb);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
free(teb);
|
||||
}
|
||||
|
||||
static PPEB NtProcessEnvironmentBlockNew()
|
||||
{
|
||||
PPEB peb = NULL;
|
||||
|
||||
peb = (PPEB) malloc(sizeof(PEB));
|
||||
|
||||
if (peb)
|
||||
{
|
||||
ZeroMemory(peb, sizeof(PEB));
|
||||
|
||||
peb->ThreadCount = 0;
|
||||
peb->ThreadArraySize = 64;
|
||||
peb->Threads = (THREAD_BLOCK_ID*) malloc(sizeof(THREAD_BLOCK_ID) * peb->ThreadArraySize);
|
||||
|
||||
if (peb->Threads)
|
||||
{
|
||||
ZeroMemory(peb->Threads, sizeof(THREAD_BLOCK_ID) * peb->ThreadArraySize);
|
||||
}
|
||||
}
|
||||
|
||||
return peb;
|
||||
}
|
||||
|
||||
static void NtProcessEnvironmentBlockFree(PPEB peb)
|
||||
{
|
||||
if (peb)
|
||||
{
|
||||
free(peb->Threads);
|
||||
free(peb);
|
||||
}
|
||||
|
||||
g_ProcessEnvironmentBlock = NULL;
|
||||
}
|
||||
|
||||
PPEB NtCurrentPeb(void)
|
||||
{
|
||||
PPEB peb = NULL;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
if (!g_ProcessEnvironmentBlock)
|
||||
g_ProcessEnvironmentBlock = NtProcessEnvironmentBlockNew();
|
||||
|
||||
peb = g_ProcessEnvironmentBlock;
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
return peb;
|
||||
}
|
||||
|
||||
PTEB NtCurrentTeb(void)
|
||||
{
|
||||
DWORD index;
|
||||
int freeIndex;
|
||||
DWORD ThreadId;
|
||||
PPEB peb = NULL;
|
||||
PTEB teb = NULL;
|
||||
|
||||
peb = NtCurrentPeb();
|
||||
|
||||
ThreadId = (DWORD) pthread_self();
|
||||
|
||||
freeIndex = -1;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
for (index = 0; index < peb->ThreadArraySize; index++)
|
||||
{
|
||||
if (!peb->Threads[index].ThreadId)
|
||||
{
|
||||
if (freeIndex < 0)
|
||||
freeIndex = (int) index;
|
||||
}
|
||||
|
||||
if (peb->Threads[index].ThreadId == ThreadId)
|
||||
{
|
||||
teb = peb->Threads[index].ThreadEnvironmentBlock;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!teb)
|
||||
{
|
||||
if (freeIndex >= 0)
|
||||
{
|
||||
teb = NtThreadEnvironmentBlockNew();
|
||||
peb->Threads[freeIndex].ThreadEnvironmentBlock = teb;
|
||||
peb->Threads[freeIndex].ThreadId = ThreadId;
|
||||
peb->ThreadCount++;
|
||||
|
||||
teb->ProcessEnvironmentBlock = peb;
|
||||
teb->LastErrorValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
return teb;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
3
winpr/libwinpr/nt/test/.gitignore
vendored
Normal file
3
winpr/libwinpr/nt/test/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
TestNt
|
||||
TestNt.c
|
||||
|
32
winpr/libwinpr/nt/test/CMakeLists.txt
Normal file
32
winpr/libwinpr/nt/test/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
set(MODULE_NAME "TestNt")
|
||||
set(MODULE_PREFIX "TEST_NT")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestNtCreateFile.c
|
||||
TestNtCurrentTeb.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-nt)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
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")
|
||||
|
8
winpr/libwinpr/nt/test/TestNtCreateFile.c
Normal file
8
winpr/libwinpr/nt/test/TestNtCreateFile.c
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#include <winpr/nt.h>
|
||||
|
||||
int TestNtCreateFile(int argc, char* argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
20
winpr/libwinpr/nt/test/TestNtCurrentTeb.c
Normal file
20
winpr/libwinpr/nt/test/TestNtCurrentTeb.c
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <winpr/nt.h>
|
||||
|
||||
int TestNtCurrentTeb(int argc, char* argv[])
|
||||
{
|
||||
PTEB teb;
|
||||
|
||||
teb = NtCurrentTeb();
|
||||
|
||||
if (!teb)
|
||||
{
|
||||
printf("NtCurrentTeb() returned NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user