1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*=====================================================================
6**
7** Source: test1.c (FreeLibraryAndExitThread)
8**
9** Purpose: Tests the PAL implementation of the FreeLibraryAndExitThread
10** function. FreeLibraryAndExitThread when run will exit the
11** process that it is called within, therefore we create a
12** thread to run the API. Then test for the existance of the
13** thread and access to the library.
14**
15**
16**===================================================================*/
17
18#include <palsuite.h>
19
20/*Define platform specific information*/
21
22/* SHLEXT is defined only for Unix variants */
23#if defined(SHLEXT)
24#define LibraryName "dlltest"SHLEXT
25#else
26#define LibraryName "dlltest"
27#endif
28
29#define TIMEOUT 60000
30
31BOOL PALAPI StartThreadTest();
32DWORD PALAPI CreateTestThread(LPVOID);
33BOOL PALAPI TestDll(HMODULE, int);
34
35int __cdecl main(int argc, char* argv[])
36{
37 /*Initialize the PAL*/
38 if ((PAL_Initialize(argc, argv)) != 0)
39 {
40 return (FAIL);
41 }
42
43 if (!StartThreadTest())
44 {
45 Fail("ERROR: FreeLibraryAndExitThread test failed.\n");
46 }
47
48 /*Terminate the PAL*/
49 PAL_Terminate();
50 return PASS;
51
52}
53
54
55BOOL PALAPI StartThreadTest()
56{
57 HMODULE hLib;
58 HANDLE hThread;
59 DWORD dwThreadId;
60 LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread;
61 LPVOID lpParameter = (LPVOID)lpStartAddress;
62 DWORD rc = -1;
63 /*Load library (DLL).*/
64 hLib = LoadLibrary(LibraryName);
65 if(hLib == NULL)
66 {
67 Trace("ERROR: Unable to load library %s\n", LibraryName);
68
69 return (FALSE);
70 }
71
72 /*Start the test thread*/
73 hThread = CreateThread(NULL,
74 (DWORD)0,
75 lpStartAddress,
76 hLib,
77 (DWORD)NULL,
78 &dwThreadId);
79 if(hThread == NULL)
80 {
81 Trace("ERROR:%u: Unable to create thread.\n",
82 GetLastError());
83
84 FreeLibrary(hLib);
85 return (FALSE);
86 }
87
88 /*Wait on thread.*/
89 rc = WaitForSingleObject(hThread, TIMEOUT);
90 if( rc != WAIT_OBJECT_0 )
91 {
92 Trace("ERROR:%u: hThread=0x%4.4lx not exited by "
93 "FreeLibraryAndExitThread, RC[%d]\n",
94 GetLastError(),
95 hThread, rc);
96
97// There is a possibility that the other thread might
98// still be using the library VSW:337893
99// FreeLibrary(hLib);
100 CloseHandle(hThread);
101 return (FALSE);
102 }
103
104 /*Test access to DLL.*/
105 if(!TestDll(hLib, 0))
106 {
107 Trace("ERROR: TestDll function returned FALSE "
108 "expected TRUE\n.");
109
110 CloseHandle(hThread);
111 return (FALSE);
112 }
113
114 FreeLibrary(hLib);
115 /*Clean-up thread.*/
116 CloseHandle(hThread);
117
118 return (TRUE);
119}
120
121BOOL PALAPI TestDll(HMODULE hLib, int testResult)
122{
123 int RetVal;
124 char FunctName[] = "DllTest";
125 FARPROC DllAddr;
126
127 /* Attempt to grab the proc address of the dll function.
128 * This one should succeed.*/
129 if(testResult == 1)
130 {
131 DllAddr = GetProcAddress(hLib, FunctName);
132 if(DllAddr == NULL)
133 {
134 Trace("ERROR: Unable to load function \"%s\" library \"%s\"\n",
135 FunctName,
136 LibraryName);
137 return (FALSE);
138 }
139 /* Run the function in the DLL,
140 * to ensure that the DLL was loaded properly.*/
141 RetVal = DllAddr();
142 if (RetVal != 1)
143 {
144 Trace("ERROR: Unable to receive correct information from DLL! "
145 ":expected \"1\", returned \"%d\"\n",
146 RetVal);
147 return (FALSE);
148 }
149 }
150
151 /* Attempt to grab the proc address of the dll function.
152 * This one should fail.*/
153 if(testResult == 0)
154 {
155 DllAddr = GetProcAddress(hLib, FunctName);
156 if(DllAddr != NULL)
157 {
158 Trace("ERROR: Able to load function \"%s\" from free'd"
159 " library \"%s\"\n",
160 FunctName,
161 LibraryName);
162 return (FALSE);
163 }
164 }
165 return (TRUE);
166}
167
168DWORD PALAPI CreateTestThread(LPVOID lpParam)
169{
170 /* Test access to DLL.*/
171 TestDll(lpParam, 1);
172
173 /*Free library and exit thread.*/
174 FreeLibraryAndExitThread(lpParam, (DWORD)0);
175
176 /* NOT REACHED */
177
178 /*Infinite loop, we should not get here.*/
179 while(1);
180
181 return (DWORD)0;
182}
183
184