1 #include "w32knapi.h"
2 
3 HINSTANCE g_hInstance;
4 HMODULE g_hModule = NULL;
5 PGDI_TABLE_ENTRY GdiHandleTable;
6 
7 static
8 PGDI_TABLE_ENTRY
9 MyGdiQueryTable()
10 {
11     PTEB pTeb = NtCurrentTeb();
12     PPEB pPeb = pTeb->ProcessEnvironmentBlock;
13     return pPeb->GdiSharedHandleTable;
14 }
15 
16 BOOL
17 IsHandleValid(HGDIOBJ hobj)
18 {
19     USHORT Index = (ULONG_PTR)hobj;
20     PGDI_TABLE_ENTRY pentry = &GdiHandleTable[Index];
21 
22     if (pentry->KernelData == NULL ||
23         pentry->KernelData < (PVOID)0x80000000 ||
24         (USHORT)pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
25     {
26         return FALSE;
27     }
28 
29     return TRUE;
30 }
31 
32 PVOID
33 GetHandleUserData(HGDIOBJ hobj)
34 {
35     USHORT Index = (ULONG_PTR)hobj;
36     PGDI_TABLE_ENTRY pentry = &GdiHandleTable[Index];
37 
38     if (pentry->KernelData == NULL ||
39         pentry->KernelData < (PVOID)0x80000000 ||
40         (USHORT)pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
41     {
42         return NULL;
43     }
44 
45     return pentry->UserData;
46 }
47 
48 
49 static DWORD WINAPI
50 IntSyscall(FARPROC proc, UINT cParams, PVOID pFirstParam)
51 {
52     DWORD retval;
53 
54 #ifdef __GNUC__
55     asm volatile
56     (
57         "pushfl;"               // Save flags
58         "movl %%ecx, %%eax;"
59         "shl $2, %%eax;"        // Calculate param size
60         "subl %%eax, %%esp;"    // Calculate new stack pos
61         "movl %%esp, %%edi;"    // Destination is stackpointer
62         "cld;"                  // Clear direction flag
63         "rep movsd;"            // Copy params to the stack
64         "call *%%edx;"          // Call function
65         "popfl;"                // Restore flags
66         : "=a" (retval)
67         : "S" (pFirstParam), "c" (cParams), "d"(proc)
68         : "%edi"
69     );
70 #else
71     __asm
72     {
73         pushf
74         mov eax, cParams
75         shl eax, 2
76         sub esp, eax
77         mov edi, esp
78         cld
79         rep movsd
80         call proc
81         mov retval, eax
82         popf
83     };
84 #endif
85 
86     return retval;
87 }
88 
89 DWORD
90 Syscall(LPWSTR pszFunction, int cParams, void* pParams)
91 {
92     char szFunctionName[MAX_PATH];
93     FARPROC proc;
94 
95     sprintf(szFunctionName, "%ls", pszFunction);
96     proc = (FARPROC)GetProcAddress(g_hModule, szFunctionName);
97     if (!proc)
98     {
99         printf("Couldn't find proc: %s\n", szFunctionName);
100         return FALSE;
101     }
102 
103     return IntSyscall(proc, cParams, pParams);
104 }
105 
106 BOOL
107 IsFunctionPresent(LPWSTR lpszFunction)
108 {
109     char szFunctionName[MAX_PATH];
110     sprintf(szFunctionName, "%ls", lpszFunction);
111     return (GetProcAddress(g_hModule, szFunctionName) != NULL);
112 }
113 
114 int APIENTRY
115 WinMain(HINSTANCE hInstance,
116         HINSTANCE hPrevInstance,
117         LPSTR     lpCmdLine,
118         int       nCmdShow)
119 {
120     g_hInstance = hInstance;
121 
122     printf("Win32k native API test\n");
123 
124     /* Convert to gui thread */
125     // IsGUIThread(TRUE); <- does not exists on win2k
126 
127     InitOsVersion();
128     printf("g_OsIdx = %d\n", g_OsIdx);
129 
130     g_hModule = LoadLibraryW(L"w32kdll.dll");
131     if (!g_hModule)
132     {
133         printf("w32kdll.dll not found!\n");
134         return -1;
135     }
136 
137     GdiHandleTable = MyGdiQueryTable();
138     if(!GdiHandleTable)
139     {
140         FreeLibrary(g_hModule);
141         printf("GdiHandleTable not found!\n");
142         return -1;
143     }
144 
145     printf("\n");
146 
147     return TestMain(L"w32knapi", L"win32k.sys Nt-Api");
148 }
149