add syscall list for windows 2000 SP4, so GreatLord can do testing
[reactos.git] / rostests / apitests / w32knapi / w32knapi.c
1 #include "w32knapi.h"
2
3 HINSTANCE g_hInstance;
4 HMODULE g_hModule = NULL;
5 INT g_nOs;
6 PSYSCALL_ENTRY g_SyscallTable;
7
8 BOOL
9 InitOsVersion()
10 {
11 OSVERSIONINFOW osv;
12 LPWSTR pszRos;
13
14 osv.dwOSVersionInfoSize = sizeof(osv);
15 GetVersionExW(&osv);
16 pszRos = osv.szCSDVersion + wcslen(osv.szCSDVersion) + 1;
17 /* make sure the string is zero terminated */
18 osv.szCSDVersion[127] = 0;
19 /* Is ReactOS? */
20 if (wcsstr(pszRos, L"ReactOS") != NULL)
21 {
22 printf("Running on %ls\n", pszRos);
23 g_hModule = LoadLibraryW(L"w32kdll.dll");
24 if (!g_hModule)
25 {
26 printf("w32kdll.dll not found!\n");
27 return FALSE;
28 }
29 g_nOs = OS_REACTOS;
30 return TRUE;
31 }
32
33 if (osv.dwPlatformId != VER_PLATFORM_WIN32_NT)
34 {
35 printf("Unsupported OS\n");
36 return FALSE;
37 }
38
39 if (osv.dwMajorVersion == 5 && osv.dwMinorVersion == 1 && osv.dwBuildNumber == 2600)
40 {
41 printf("Running on Windows XP, build 2600\n");
42 g_nOs = OS_WINDOWS;
43 g_SyscallTable = SyscallTable_XP_2600;
44 return TRUE;
45 }
46
47 if (osv.dwMajorVersion == 5 && osv.dwMinorVersion == 0 && osv.dwBuildNumber == 2195)
48 {
49 printf("Running on Windows 2000, build 2195\n");
50 g_nOs = OS_WINDOWS;
51 g_SyscallTable = SyscallTable_2K_2195;
52 return TRUE;
53 }
54
55 printf("Unsupported OS\n");
56
57 return FALSE;
58 }
59
60 static PSYSCALL_ENTRY
61 GetSyscallEntry(LPWSTR lpszFunction)
62 {
63 INT i;
64
65 for (i = 0; g_SyscallTable[i].lpszFunction != NULL; i++)
66 {
67 if (wcscmp(g_SyscallTable[i].lpszFunction, lpszFunction) == 0)
68 {
69 return &g_SyscallTable[i];
70 }
71 }
72 return NULL;
73 }
74
75 static DWORD STDCALL
76 WinSyscall(INT nSyscalNum, PVOID pFirstParam)
77 {
78 DWORD ret;
79 asm volatile ("int $0x2e\n" : "=a"(ret): "a" (nSyscalNum), "d" (pFirstParam));
80 return ret;
81 }
82
83 static DWORD STDCALL
84 RosSyscall(FARPROC proc, UINT cParams, PVOID pFirstParam)
85 {
86 DWORD ret;
87
88 asm volatile
89 (
90 "pushfl;" // Save flags
91 "movl %%ecx, %%eax;"
92 "shl $2, %%eax;" // Calculate param size
93 "subl %%eax, %%esp;" // Calculate new stack pos
94 "movl %%esp, %%edi;" // Destination is stackpointer
95 "cld;" // Clear direction flag
96 "rep movsd;" // Copy params to the stack
97 "call *%%edx;" // Call function
98 "popfl;" // Restore flags
99 : "=a" (ret)
100 : "S" (pFirstParam), "c" (cParams), "d"(proc)
101 : "%edi"
102 );
103
104 return ret;
105 }
106
107 DWORD
108 Syscall(LPWSTR pszFunction, int cParams, void* pParams)
109 {
110 if (g_nOs == OS_REACTOS)
111 {
112 char szFunctionName[MAX_PATH];
113
114 sprintf(szFunctionName, "%ls", pszFunction);
115 FARPROC proc = (FARPROC)GetProcAddress(g_hModule, szFunctionName);
116 if (!proc)
117 {
118 printf("Couldn't find proc: %s\n", szFunctionName);
119 return FALSE;
120 }
121
122 return RosSyscall(proc, cParams, pParams);
123 }
124 else
125 {
126 PSYSCALL_ENTRY pEntry = GetSyscallEntry(pszFunction);
127 return WinSyscall(pEntry->nSyscallNum, pParams);
128 }
129 }
130
131 BOOL
132 IsFunctionPresent(LPWSTR lpszFunction)
133 {
134 if (g_nOs == OS_REACTOS)
135 {
136 char szFunctionName[MAX_PATH];
137 sprintf(szFunctionName, "%ls", lpszFunction);
138 return (GetProcAddress(g_hModule, szFunctionName) != NULL);
139 }
140
141 return (GetSyscallEntry(lpszFunction) != NULL);
142 }
143
144 int APIENTRY
145 WinMain(HINSTANCE hInstance,
146 HINSTANCE hPrevInstance,
147 LPSTR lpCmdLine,
148 int nCmdShow)
149 {
150 g_hInstance = hInstance;
151
152
153 printf("Win32k native API test\n");
154
155 /* Convert to gui thread */
156 IsGUIThread(TRUE);
157
158 if (!InitOsVersion())
159 {
160 return 0;
161 }
162
163 printf("\n");
164
165 return TestMain(L"w32knapi", L"win32k.sys Nt-Api");
166 }