1 /*
2  * Windows APIs that are different for each system.
3  *   We use pointers to the entry points so that a
4  *   single binary will run on all Windows systems.
5  *
6  *     Kern Sibbald MMIII
7  */
8 /*
9    Copyright (C) 2003-2006 Kern Sibbald
10 
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as amended with additional clauses defined in the
14    file LICENSE in the main source directory.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19    the file LICENSE for additional details.
20 
21  */
22 
23 #include "apc.h"
24 #include "winapi.h"
25 
26 /* Platform version info */
27 OSVERSIONINFO g_os_version_info;
28 OSVERSION g_os_version;
29 
30 /* API Pointers */
31 t_OpenProcessToken      p_OpenProcessToken = NULL;
32 t_AdjustTokenPrivileges p_AdjustTokenPrivileges = NULL;
33 t_LookupPrivilegeValue  p_LookupPrivilegeValue = NULL;
34 t_SetProcessShutdownParameters p_SetProcessShutdownParameters = NULL;
35 t_CreateFileA   p_CreateFileA = NULL;
36 t_CreateDirectoryA   p_CreateDirectoryA;
37 t_GetFileAttributesA    p_GetFileAttributesA = NULL;
38 t_GetFileAttributesExA  p_GetFileAttributesExA = NULL;
39 t_SetFileAttributesA    p_SetFileAttributesA = NULL;
40 t_FindFirstFileA p_FindFirstFileA = NULL;
41 t_FindNextFileA p_FindNextFileA = NULL;
42 t_SetCurrentDirectoryA p_SetCurrentDirectoryA = NULL;
43 t_GetCurrentDirectoryA p_GetCurrentDirectoryA = NULL;
44 
45 void
InitWinAPIWrapper()46 InitWinAPIWrapper()
47 {
48    HMODULE hLib = LoadLibraryA("KERNEL32.DLL");
49    if (hLib) {
50       /* create file calls */
51       p_CreateFileA = (t_CreateFileA)
52           GetProcAddress(hLib, "CreateFileA");
53 
54       p_CreateDirectoryA = (t_CreateDirectoryA)
55           GetProcAddress(hLib, "CreateDirectoryA");
56 
57       /* attribute calls */
58       p_GetFileAttributesA = (t_GetFileAttributesA)
59           GetProcAddress(hLib, "GetFileAttributesA");
60       p_GetFileAttributesExA = (t_GetFileAttributesExA)
61           GetProcAddress(hLib, "GetFileAttributesExA");
62       p_SetFileAttributesA = (t_SetFileAttributesA)
63           GetProcAddress(hLib, "SetFileAttributesA");
64       /* process calls */
65       p_SetProcessShutdownParameters = (t_SetProcessShutdownParameters)
66           GetProcAddress(hLib, "SetProcessShutdownParameters");
67 
68       /* find files */
69       p_FindFirstFileA = (t_FindFirstFileA)
70           GetProcAddress(hLib, "FindFirstFileA");
71       p_FindNextFileA = (t_FindNextFileA)
72           GetProcAddress(hLib, "FindNextFileA");
73       /* set and get directory */
74       p_SetCurrentDirectoryA = (t_SetCurrentDirectoryA)
75           GetProcAddress(hLib, "SetCurrentDirectoryA");
76       p_GetCurrentDirectoryA = (t_GetCurrentDirectoryA)
77           GetProcAddress(hLib, "GetCurrentDirectoryA");
78 
79       FreeLibrary(hLib);
80    }
81 
82    hLib = LoadLibraryA("ADVAPI32.DLL");
83    if (hLib) {
84       p_OpenProcessToken = (t_OpenProcessToken)
85          GetProcAddress(hLib, "OpenProcessToken");
86       p_AdjustTokenPrivileges = (t_AdjustTokenPrivileges)
87          GetProcAddress(hLib, "AdjustTokenPrivileges");
88       p_LookupPrivilegeValue = (t_LookupPrivilegeValue)
89          GetProcAddress(hLib, "LookupPrivilegeValueA");
90       FreeLibrary(hLib);
91    }
92 
93    // Get the current OS version
94    memset(&g_os_version_info, 0, sizeof(g_os_version_info));
95    g_os_version_info.dwOSVersionInfoSize = sizeof(g_os_version_info);
96    GetVersionEx(&g_os_version_info);
97 
98    // Convert OS version to ordered enumeration
99    if (g_os_version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
100    {
101       // VER_PLATFORM_WIN32_WINDOWS...
102       //
103       //   WINDOWS 95: 4.0
104       //   WINDOWS 98: 4.10
105       //   WINDOWS ME: 4.90
106       //
107       switch (g_os_version_info.dwMinorVersion)
108       {
109       case 0:
110          g_os_version = WINDOWS_95;
111          break;
112       case 10:
113          g_os_version = WINDOWS_98;
114          break;
115       default:
116       case 90:
117          g_os_version = WINDOWS_ME;
118          break;
119       }
120    }
121    else // if (g_os_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
122    {
123       // VER_PLATFORM_WIN32_NT...
124       //
125       //   WINDOWS NT:    4.0
126       //   WINDOWS 2000:  5.0
127       //   WINDOWS XP:    5.1
128       //   WINDOWS 2003:  5.2
129       //   WINDOWS VISTA: 6.0
130       //
131       switch (g_os_version_info.dwMajorVersion)
132       {
133       case 4:
134          g_os_version = WINDOWS_NT;
135          break;
136       case 5:
137          switch (g_os_version_info.dwMinorVersion)
138          {
139          case 0:
140             g_os_version = WINDOWS_2000;
141             break;
142          case 1:
143             g_os_version = WINDOWS_XP;
144             break;
145          default:
146          case 2:
147             g_os_version = WINDOWS_2003;
148             break;
149          }
150          break;
151       default:
152       case 6:
153          g_os_version = WINDOWS_VISTA;
154          break;
155       }
156    }
157 }
158 
159 // Add the requested access to the given kernel object handle
GrantAccess(HANDLE h,ACCESS_MASK access,TRUSTEE_TYPE type,LPTSTR name)160 BOOL GrantAccess(HANDLE h, ACCESS_MASK access, TRUSTEE_TYPE type, LPTSTR name)
161 {
162    DWORD rc;
163 
164    // Obtain current DACL from object
165    ACL *dacl;
166    SECURITY_DESCRIPTOR *sd;
167    rc = GetSecurityInfo(h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
168                         NULL, NULL, &dacl, NULL, &sd);
169    if (rc != ERROR_SUCCESS)
170       return false;
171 
172    // Add requested access to DACL
173    EXPLICIT_ACCESS ea;
174    ea.grfAccessPermissions = access;
175    ea.grfAccessMode = GRANT_ACCESS;
176    ea.grfInheritance = NO_INHERITANCE;
177    ea.Trustee.pMultipleTrustee = FALSE;
178    ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
179    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
180    ea.Trustee.TrusteeType = type;
181    ea.Trustee.ptstrName = name;
182    ACL *newdacl;
183    rc = SetEntriesInAcl(1, &ea, dacl, &newdacl);
184    if (rc != ERROR_SUCCESS) {
185       LocalFree(sd);
186       return false;
187    }
188 
189    // Set new DACL on object
190    rc = SetSecurityInfo(h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
191                         NULL, NULL, newdacl, NULL);
192 
193    // Done with structs
194    LocalFree(newdacl);
195    LocalFree(sd);
196 
197    return rc == ERROR_SUCCESS;
198 }
199