]> wimlib.net Git - wimlib/blob - src/win32.c
Do not capture directory hard links
[wimlib] / src / win32.c
1 #include "config.h"
2
3 #if defined(__CYGWIN__) || defined(__WIN32__)
4 #include <windows.h>
5 #       ifdef ERROR
6 #               undef ERROR
7 #       endif
8
9 #include "wimlib_internal.h"
10
11
12 #ifdef ENABLE_ERROR_MESSAGES
13 void win32_error(u32 err_code)
14 {
15         char *buffer;
16         DWORD nchars;
17         nchars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
18                                 NULL, err_code, 0,
19                                 (char*)&buffer, 0, NULL);
20         if (nchars == 0) {
21                 ERROR("Error printing error message! "
22                       "Computer will self-destruct in 3 seconds.");
23         } else {
24                 ERROR("Win32 error: %s", buffer);
25                 LocalFree(buffer);
26         }
27 }
28 #else
29 #define win32_error(err_code)
30 #endif
31
32 void *win32_open_file_readonly(const void *path)
33 {
34         return CreateFileW((const wchar_t*)path,
35                            FILE_READ_DATA |
36                                FILE_READ_ATTRIBUTES |
37                                READ_CONTROL |
38                                ACCESS_SYSTEM_SECURITY,
39                            FILE_SHARE_READ,
40                            NULL, /* lpSecurityAttributes */
41                            OPEN_EXISTING,
42                            FILE_FLAG_BACKUP_SEMANTICS |
43                                FILE_FLAG_OPEN_REPARSE_POINT,
44                            NULL /* hTemplateFile */);
45 }
46
47 int win32_read_file(const char *filename,
48                     void *handle, u64 offset, size_t size, u8 *buf)
49 {
50         HANDLE h = handle;
51         DWORD err;
52         DWORD bytesRead;
53         LARGE_INTEGER liOffset = {.QuadPart = offset};
54
55         wimlib_assert(size <= 0xffffffff);
56
57         if (SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN))
58                 if (ReadFile(h, buf, size, &bytesRead, NULL) && bytesRead == size)
59                         return 0;
60         err = GetLastError();
61         ERROR("Error reading \"%s\"", filename);
62         win32_error(err);
63         return WIMLIB_ERR_READ;
64 }
65
66 void win32_close_file(void *handle)
67 {
68         CloseHandle((HANDLE)handle);
69 }
70
71 static bool win32_modify_privilege(const char *privilege, bool enable)
72 {
73         HANDLE hToken;
74         LUID luid;
75         TOKEN_PRIVILEGES newState;
76         bool ret = false;
77
78         DEBUG("%s privilege %s",
79               enable ? "Enabling" : "Disabling", privilege);
80
81         if (!OpenProcessToken(GetCurrentProcess(),
82                               TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
83                               &hToken))
84         {
85                 DEBUG("OpenProcessToken() failed");
86                 goto out;
87         }
88
89         if (!LookupPrivilegeValue(NULL, privilege, &luid)) {
90                 DEBUG("LookupPrivilegeValue() failed");
91                 goto out;
92         }
93
94         newState.PrivilegeCount = 1;
95         newState.Privileges[0].Luid = luid;
96         newState.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0);
97         ret = AdjustTokenPrivileges(hToken, FALSE, &newState, 0, NULL, NULL);
98         if (!ret)
99                 DEBUG("AdjustTokenPrivileges() failed");
100         CloseHandle(hToken);
101 out:
102         if (!ret) {
103                 DWORD err = GetLastError();
104                 win32_error(err);
105                 WARNING("Failed to %s privilege %s",
106                         enable ? "enable" : "disable", privilege);
107                 WARNING("The program will continue, but if permission issues are "
108                         "encountered, you may need to run this program as the administrator");
109         }
110         return ret;
111 }
112
113 bool win32_acquire_privilege(const char *privilege)
114 {
115         return win32_modify_privilege(privilege, true);
116 }
117
118 bool win32_release_privilege(const char *privilege)
119 {
120         return win32_modify_privilege(privilege, false);
121 }
122
123
124 #endif /* __CYGWIN__ || __WIN32__ */