]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/compat/winapi.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / compat / winapi.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2018 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Windows APIs that are different for each system.
21  *   We use pointers to the entry points so that a
22  *   single binary will run on all Windows systems.
23  *
24  *     Kern Sibbald MMIII
25  */
26
27 #include "bacula.h"
28
29
30 #ifdef HAVE_VSS64
31 /* 64 bit entrypoint name */
32 #define VSSVBACK_ENTRY "?CreateVssBackupComponents@@YAJPEAPEAVIVssBackupComponents@@@Z"
33 #define VSSVMETA_ENTRY "?CreateVssExamineWriterMetadata@@YAJPEAGPEAPEAVIVssExamineWriterMetadata@@@Z"
34 #else
35 /* 32 bit entrypoint name */
36 #define VSSVMETA_ENTRY "?CreateVssExamineWriterMetadata@@YGJPAGPAPAVIVssExamineWriterMetadata@@@Z"
37 #define VSSVBACK_ENTRY "?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z"
38 #endif
39
40
41 // init with win9x, but maybe set to NT in InitWinAPI
42 DWORD g_platform_id = VER_PLATFORM_WIN32_WINDOWS;
43 DWORD g_MinorVersion = 0;
44 DWORD g_MajorVersion = 0;
45
46 /* API Pointers */
47
48 t_OpenProcessToken      p_OpenProcessToken = NULL;
49 t_AdjustTokenPrivileges p_AdjustTokenPrivileges = NULL;
50 t_LookupPrivilegeValue  p_LookupPrivilegeValue = NULL;
51
52 t_SetProcessShutdownParameters p_SetProcessShutdownParameters = NULL;
53
54 t_CreateFileA           p_CreateFileA = NULL;
55 t_CreateFileW           p_CreateFileW = NULL;
56
57 t_OpenEncryptedFileRawA p_OpenEncryptedFileRawA = NULL;
58 t_OpenEncryptedFileRawW p_OpenEncryptedFileRawW = NULL;
59 t_ReadEncryptedFileRaw  p_ReadEncryptedFileRaw = NULL;
60 t_WriteEncryptedFileRaw p_WriteEncryptedFileRaw = NULL;
61 t_CloseEncryptedFileRaw p_CloseEncryptedFileRaw = NULL;
62
63
64 t_CreateDirectoryA      p_CreateDirectoryA;
65 t_CreateDirectoryW      p_CreateDirectoryW;
66
67 t_GetFileInformationByHandleEx p_GetFileInformationByHandleEx = NULL;
68
69 t_wunlink               p_wunlink = NULL;
70 t_wmkdir                p_wmkdir = NULL;
71
72 t_GetFileAttributesA    p_GetFileAttributesA = NULL;
73 t_GetFileAttributesW    p_GetFileAttributesW = NULL;
74
75 t_GetFileAttributesExA  p_GetFileAttributesExA = NULL;
76 t_GetFileAttributesExW  p_GetFileAttributesExW = NULL;
77
78 t_SetFileAttributesA    p_SetFileAttributesA = NULL;
79 t_SetFileAttributesW    p_SetFileAttributesW = NULL;
80 t_BackupRead            p_BackupRead = NULL;
81 t_BackupWrite           p_BackupWrite = NULL;
82 t_WideCharToMultiByte   p_WideCharToMultiByte = NULL;
83 t_MultiByteToWideChar   p_MultiByteToWideChar = NULL;
84
85 t_AttachConsole         p_AttachConsole = NULL;
86
87 t_FindFirstFileA        p_FindFirstFileA = NULL;
88 t_FindFirstFileW        p_FindFirstFileW = NULL;
89
90 t_FindNextFileA         p_FindNextFileA = NULL;
91 t_FindNextFileW         p_FindNextFileW = NULL;
92
93 t_SetCurrentDirectoryA  p_SetCurrentDirectoryA = NULL;
94 t_SetCurrentDirectoryW  p_SetCurrentDirectoryW = NULL;
95
96 t_GetCurrentDirectoryA  p_GetCurrentDirectoryA = NULL;
97 t_GetCurrentDirectoryW  p_GetCurrentDirectoryW = NULL;
98
99 t_GetVolumePathNameW    p_GetVolumePathNameW = NULL;
100 t_GetVolumeNameForVolumeMountPointW p_GetVolumeNameForVolumeMountPointW = NULL;
101
102 t_SHGetFolderPath       p_SHGetFolderPath = NULL;
103
104 t_CreateProcessA        p_CreateProcessA = NULL;
105 t_CreateProcessW        p_CreateProcessW = NULL;
106
107 t_CreateSymbolicLinkA   p_CreateSymbolicLinkA = NULL;
108 t_CreateSymbolicLinkW   p_CreateSymbolicLinkW = NULL;
109 t_InetPton              p_InetPton = NULL;
110 t_GetProcessMemoryInfo p_GetProcessMemoryInfo = NULL;
111 t_EmptyWorkingSet      p_EmptyWorkingSet = NULL;
112
113 HMODULE                vsslib = NULL;
114 t_CreateVssBackupComponents p_CreateVssBackupComponents = NULL;
115 t_VssFreeSnapshotProperties p_VssFreeSnapshotProperties = NULL;
116 t_CreateVssExamineWriterMetadata p_CreateVssExamineWriterMetadata;
117
118
119 static void atexit_handler()
120 {
121    CoUninitialize();
122 }
123
124 /* http://thrysoee.dk/InsideCOM+/ch18d.htm
125  * The COM+ security infrastructure is initialized on a per-process basis at
126  * start-up. The CoInitializeSecurity function sets the default security values
127  * for the process. If an application does not call CoInitializeSecurity, COM+
128  * calls the function automatically the first time an interface pointer is
129  * marshaled into or out of an apartment (or context) in the
130  * process. Attempting to call CoInitializeSecurity after marshaling takes
131  * place yields the infamous RPC_E_TOO_LATE error. Thus, programs that want to
132  * call CoInitializeSecurity explicitly are advised to do so immediately after
133  * calling CoInitializeEx. Note that CoInitializeSecurity is called only once per
134  * process, not in each thread that calls CoInitializeEx.
135 */
136 static void InitComInterface()
137 {
138    /* Setup ComSecurity */
139    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
140    if (FAILED(hr)) {
141       Dmsg1(0, "CoInitializeEx returned 0x%08X\n", hr);
142
143    } else {
144       // Initialize COM security
145       hr =
146          CoInitializeSecurity(
147             NULL,           //  Allow *all* VSS writers to communicate back!
148             -1,             //  Default COM authentication service
149             NULL,           //  Default COM authorization service
150             NULL,           //  reserved parameter
151             RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  //  Strongest COM authentication level
152             RPC_C_IMP_LEVEL_IDENTIFY,       //  Minimal impersonation abilities
153             NULL,            //  Default COM authentication settings
154             EOAC_NONE,       //  No special options
155             NULL             //  Reserved parameter
156             );
157       if (FAILED(hr)  && (hr != RPC_E_TOO_LATE)) {
158          Dmsg1(0, "CoInitializeSecurity returned 0x%08X\n", hr);
159       }
160       atexit(atexit_handler);
161    }
162 }
163
164 void
165 InitWinAPIWrapper()
166 {
167    OSVERSIONINFO osversioninfo = { sizeof(OSVERSIONINFO) };
168
169    // Get the current OS version
170    if (!GetVersionEx(&osversioninfo)) {
171       g_platform_id = 0;
172    } else {
173       g_platform_id = osversioninfo.dwPlatformId;
174       g_MinorVersion = osversioninfo.dwMinorVersion;
175       g_MajorVersion = osversioninfo.dwMajorVersion;
176    }
177
178    HMODULE hLib = LoadLibraryA("KERNEL32.DLL");
179    if (hLib) {
180       /* Might be defined in Kernel32.dll or PSAPI.DLL */
181       p_GetProcessMemoryInfo = (t_GetProcessMemoryInfo)
182          GetProcAddress(hLib, "K32GetProcessMemoryInfo");
183
184       /* Might be defined in Kernel32.dll or PSAPI.DLL */
185       p_EmptyWorkingSet = (t_EmptyWorkingSet)
186          GetProcAddress(hLib, "K32EmptyWorkingSet");
187
188       /* Not defined before win2008 */
189       p_CreateSymbolicLinkA = (t_CreateSymbolicLinkA)
190          GetProcAddress(hLib, "CreateSymbolicLinkA");
191       p_CreateSymbolicLinkW = (t_CreateSymbolicLinkW)
192          GetProcAddress(hLib, "CreateSymbolicLinkW");
193
194       /* create process calls */
195       p_CreateProcessA = (t_CreateProcessA)
196          GetProcAddress(hLib, "CreateProcessA");
197       p_CreateProcessW = (t_CreateProcessW)
198          GetProcAddress(hLib, "CreateProcessW");
199
200       /* create file calls */
201       p_CreateFileA = (t_CreateFileA)GetProcAddress(hLib, "CreateFileA");
202       p_CreateDirectoryA = (t_CreateDirectoryA)GetProcAddress(hLib, "CreateDirectoryA");
203
204       p_GetFileInformationByHandleEx = (t_GetFileInformationByHandleEx)
205          GetProcAddress(hLib, "GetFileInformationByHandleEx");
206
207       /* attribute calls */
208       p_GetFileAttributesA = (t_GetFileAttributesA)GetProcAddress(hLib, "GetFileAttributesA");
209       p_GetFileAttributesExA = (t_GetFileAttributesExA)GetProcAddress(hLib, "GetFileAttributesExA");
210       p_SetFileAttributesA = (t_SetFileAttributesA)GetProcAddress(hLib, "SetFileAttributesA");
211
212       /* process calls */
213       p_SetProcessShutdownParameters = (t_SetProcessShutdownParameters)
214           GetProcAddress(hLib, "SetProcessShutdownParameters");
215
216       /* char conversion calls */
217       p_WideCharToMultiByte = (t_WideCharToMultiByte)
218           GetProcAddress(hLib, "WideCharToMultiByte");
219       p_MultiByteToWideChar = (t_MultiByteToWideChar)
220           GetProcAddress(hLib, "MultiByteToWideChar");
221
222       /* find files */
223       p_FindFirstFileA = (t_FindFirstFileA)GetProcAddress(hLib, "FindFirstFileA");
224       p_FindNextFileA = (t_FindNextFileA)GetProcAddress(hLib, "FindNextFileA");
225
226       /* get and set directory */
227       p_GetCurrentDirectoryA = (t_GetCurrentDirectoryA)
228           GetProcAddress(hLib, "GetCurrentDirectoryA");
229       p_SetCurrentDirectoryA = (t_SetCurrentDirectoryA)
230           GetProcAddress(hLib, "SetCurrentDirectoryA");
231
232       if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS) {
233          p_CreateFileW = (t_CreateFileW)
234              GetProcAddress(hLib, "CreateFileW");
235          p_CreateDirectoryW = (t_CreateDirectoryW)
236              GetProcAddress(hLib, "CreateDirectoryW");
237
238          /* backup calls */
239          p_BackupRead = (t_BackupRead)GetProcAddress(hLib, "BackupRead");
240          p_BackupWrite = (t_BackupWrite)GetProcAddress(hLib, "BackupWrite");
241
242          p_GetFileAttributesW = (t_GetFileAttributesW)
243              GetProcAddress(hLib, "GetFileAttributesW");
244          p_GetFileAttributesExW = (t_GetFileAttributesExW)
245              GetProcAddress(hLib, "GetFileAttributesExW");
246          p_SetFileAttributesW = (t_SetFileAttributesW)
247              GetProcAddress(hLib, "SetFileAttributesW");
248          p_FindFirstFileW = (t_FindFirstFileW)
249              GetProcAddress(hLib, "FindFirstFileW");
250          p_FindNextFileW = (t_FindNextFileW)
251              GetProcAddress(hLib, "FindNextFileW");
252          p_GetCurrentDirectoryW = (t_GetCurrentDirectoryW)
253              GetProcAddress(hLib, "GetCurrentDirectoryW");
254          p_SetCurrentDirectoryW = (t_SetCurrentDirectoryW)
255              GetProcAddress(hLib, "SetCurrentDirectoryW");
256
257          /* some special stuff we need for VSS
258             but static linkage doesn't work on Win 9x */
259          p_GetVolumePathNameW = (t_GetVolumePathNameW)
260              GetProcAddress(hLib, "GetVolumePathNameW");
261          p_GetVolumeNameForVolumeMountPointW = (t_GetVolumeNameForVolumeMountPointW)
262              GetProcAddress(hLib, "GetVolumeNameForVolumeMountPointW");
263
264          p_AttachConsole = (t_AttachConsole)
265              GetProcAddress(hLib, "AttachConsole");
266       }
267    }
268
269    if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS) {
270       hLib = LoadLibraryA("MSVCRT.DLL");
271       if (hLib) {
272          /* unlink */
273          p_wunlink = (t_wunlink)
274          GetProcAddress(hLib, "_wunlink");
275          /* wmkdir */
276          p_wmkdir = (t_wmkdir)
277          GetProcAddress(hLib, "_wmkdir");
278       }
279
280       hLib = LoadLibraryA("ADVAPI32.DLL");
281       if (hLib) {
282          p_OpenProcessToken = (t_OpenProcessToken)
283             GetProcAddress(hLib, "OpenProcessToken");
284          p_AdjustTokenPrivileges = (t_AdjustTokenPrivileges)
285             GetProcAddress(hLib, "AdjustTokenPrivileges");
286          p_LookupPrivilegeValue = (t_LookupPrivilegeValue)
287             GetProcAddress(hLib, "LookupPrivilegeValueA");
288
289          p_OpenEncryptedFileRawA = (t_OpenEncryptedFileRawA)
290             GetProcAddress(hLib, "OpenEncryptedFileRawA");
291          p_OpenEncryptedFileRawW = (t_OpenEncryptedFileRawW)
292             GetProcAddress(hLib, "OpenEncryptedFileRawW");
293          p_ReadEncryptedFileRaw = (t_ReadEncryptedFileRaw)
294             GetProcAddress(hLib, "ReadEncryptedFileRaw");
295          p_WriteEncryptedFileRaw = (t_WriteEncryptedFileRaw)
296             GetProcAddress(hLib, "WriteEncryptedFileRaw");
297          p_CloseEncryptedFileRaw = (t_CloseEncryptedFileRaw)
298             GetProcAddress(hLib, "CloseEncryptedFileRaw");
299       }
300    }
301
302    hLib = LoadLibraryA("SHELL32.DLL");
303    if (hLib) {
304       p_SHGetFolderPath = (t_SHGetFolderPath)
305          GetProcAddress(hLib, "SHGetFolderPathA");
306    } else {
307       /* If SHELL32 isn't found try SHFOLDER for older systems */
308       hLib = LoadLibraryA("SHFOLDER.DLL");
309       if (hLib) {
310          p_SHGetFolderPath = (t_SHGetFolderPath)
311             GetProcAddress(hLib, "SHGetFolderPathA");
312       }
313    }
314    hLib = LoadLibraryA("WS2_32.DLL");
315    if (hLib) {
316       p_InetPton = (t_InetPton)GetProcAddress(hLib, "InetPtonA");
317    }
318    if (!p_GetProcessMemoryInfo) {
319       hLib = LoadLibraryA("PSAPI.DLL");
320       if (hLib) {
321          p_GetProcessMemoryInfo = (t_GetProcessMemoryInfo)GetProcAddress(hLib, "GetProcessMemoryInfo");
322          p_EmptyWorkingSet = (t_EmptyWorkingSet) GetProcAddress(hLib, "EmptyWorkingSet");
323       }
324    }
325
326    vsslib = LoadLibraryA("VSSAPI.DLL");
327    if (vsslib) {
328       p_CreateVssBackupComponents = (t_CreateVssBackupComponents)
329          GetProcAddress(vsslib, VSSVBACK_ENTRY);
330       p_VssFreeSnapshotProperties = (t_VssFreeSnapshotProperties)
331           GetProcAddress(vsslib, "VssFreeSnapshotProperties");
332       p_CreateVssExamineWriterMetadata = (t_CreateVssExamineWriterMetadata)
333           GetProcAddress(vsslib, VSSVMETA_ENTRY);
334    }
335
336    /* In recent version of windows, the function is in Kernel32 */
337    if (!p_GetFileInformationByHandleEx) {
338       hLib = LoadLibraryA("FileExtd.lib");
339       if (hLib) {
340          p_GetFileInformationByHandleEx = (t_GetFileInformationByHandleEx)
341             GetProcAddress(hLib, "GetFileInformationByHandleEx");
342       }
343    }
344
345    atexit(Win32ConvCleanupCache);
346
347    /* Setup Com Object security interface (called once per process) */
348    InitComInterface();
349 }