1 /* Bluefish HTML Editor
2  * win32utils.c - non-portable win32 support functions
3  *
4  * Copyright (C) 2014 Olivier Sessink
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifdef WIN32
21 
22 #include "bluefish.h"
23 #include "win32utils.h"
24 
25 gboolean
isadmin_win32()26 isadmin_win32()
27 {
28 	BOOL bRet;
29 	PACL pACL;
30 	DWORD dwLen, dwStatus;
31 	PSID psidAdmin;
32 	HANDLE hTok, hItok;
33 	PRIVILEGE_SET ps;
34 	PSECURITY_DESCRIPTOR psdAdmin;
35 
36 	GENERIC_MAPPING gmap = {ACCESS_READ, ACCESS_WRITE, 0, ACCESS_READ | ACCESS_WRITE};
37 	SID_IDENTIFIER_AUTHORITY SSidAuth = {SECURITY_NT_AUTHORITY};
38 
39 	if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hTok)) {
40 		if (GetLastError() != ERROR_NO_TOKEN)
41 			return FALSE;
42 		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hTok))
43 			return FALSE;
44 	}
45 
46 	if (!DuplicateToken(hTok, SecurityImpersonation, &hItok))
47 		return FALSE;
48 
49 	if (!AllocateAndInitializeSid(&SSidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin))
50 		return FALSE;
51 
52 	if (!(psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH)))
53 		return FALSE;
54 
55 	if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
56 		return FALSE;
57 
58 	dwLen = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
59 	if (!(pACL = (PACL)LocalAlloc(LPTR, dwLen)))
60 		return FALSE;
61 
62 	if (!InitializeAcl(pACL, dwLen, ACL_REVISION2))
63 		return FALSE;
64 
65 	if (!AddAccessAllowedAce(pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE, psidAdmin))
66 		return FALSE;
67 
68 	if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
69 		return FALSE;
70 
71 	SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
72 	SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);
73 
74 	if (!IsValidSecurityDescriptor(psdAdmin))
75 		return FALSE;
76 
77 	dwLen = sizeof(PRIVILEGE_SET);
78 	if (!AccessCheck(psdAdmin, hItok, ACCESS_READ, &gmap, &ps, &dwLen, &dwStatus, &bRet)) {
79 		bRet = FALSE;
80 		g_print("ERROR: %lu\n", GetLastError());
81 	}
82 
83 	if (pACL) LocalFree(pACL);
84  	if (psdAdmin) LocalFree(psdAdmin);
85 	if (psidAdmin) FreeSid(psidAdmin);
86 	if (hItok) CloseHandle(hItok);
87 	if (hTok) CloseHandle(hTok);
88 
89 	return (gboolean)bRet;
90 }
91 
92 gint
getauthlevel_win32()93 getauthlevel_win32()
94 {
95 	DWORD dwSize;
96 	HKEY regchk;
97 	gchar buffer[128];
98 	if (isadmin_win32()) {
99 		RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Bluefish", 0, KEY_READ, &regchk);
100 		dwSize = sizeof(buffer);
101 		RegQueryValueEx(regchk, "package", NULL, NULL, buffer, &dwSize);
102 		RegCloseKey(regchk);
103 		if (!g_strcmp0(PACKAGE, buffer))
104 			return AUTH_CLASSIC;
105 		else
106 			return AUTH_ADMIN;
107 	}
108 	else
109 		return AUTH_USER;
110 }
111 
112 gboolean
pythoncheck_win32()113 pythoncheck_win32()
114 {
115 	HKEY hPython;
116 	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath", 0, KEY_QUERY_VALUE, &hPython) == ERROR_SUCCESS) {
117 		RegCloseKey(hPython);
118 		return TRUE;
119 	} else
120 		if (RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath", 0, KEY_QUERY_VALUE, &hPython) == ERROR_SUCCESS) {
121 		RegCloseKey(hPython);
122 		return TRUE;
123 	} else if (g_file_test("python.exe", G_FILE_TEST_EXISTS)) {
124 		// For a possible bundled copy of Python for portable installations
125 		return TRUE;
126 	} else {
127 		return FALSE;
128 	}
129 }
130 
131 #endif
132