2013-03-18 16:55:34 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2013 Birunthan Mohanathas
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "Util.h"
|
|
|
|
|
|
|
|
namespace Util {
|
|
|
|
|
|
|
|
//
|
|
|
|
// System functions.
|
|
|
|
//
|
|
|
|
|
|
|
|
bool IsSystem64Bit()
|
|
|
|
{
|
|
|
|
#ifdef _WIN64
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
BOOL system64 = FALSE;
|
|
|
|
|
|
|
|
typedef BOOL (WINAPI * FPIsWow64Process)(HANDLE hProcess, BOOL* Wow64Process);
|
|
|
|
auto isWow64Process = (FPIsWow64Process)GetProcAddress(
|
|
|
|
GetModuleHandle(L"kernel32"), "IsWow64Process");
|
|
|
|
if (isWow64Process)
|
|
|
|
{
|
|
|
|
isWow64Process(GetCurrentProcess(), &system64);
|
|
|
|
}
|
|
|
|
|
|
|
|
return system64;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Process functions.
|
|
|
|
//
|
|
|
|
|
|
|
|
bool IsProcessUserAdmin()
|
|
|
|
{
|
|
|
|
BOOL runningAsAdmin = FALSE;
|
|
|
|
|
|
|
|
// Allocate and initialize a SID of the administrators group.
|
2013-05-31 14:28:39 +00:00
|
|
|
PSID adminGroupSid = nullptr;
|
2013-03-18 16:55:34 +00:00
|
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
|
|
|
if (AllocateAndInitializeSid(
|
|
|
|
&NtAuthority,
|
|
|
|
2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
&adminGroupSid))
|
|
|
|
{
|
|
|
|
// Check if the primary access token of the process has the admin group SID.
|
2013-05-31 14:28:39 +00:00
|
|
|
if (!CheckTokenMembership(nullptr, adminGroupSid, &runningAsAdmin))
|
2013-03-18 16:55:34 +00:00
|
|
|
{
|
|
|
|
runningAsAdmin = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeSid(adminGroupSid);
|
2013-05-31 14:28:39 +00:00
|
|
|
adminGroupSid = nullptr;
|
2013-03-18 16:55:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return runningAsAdmin;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CanProcessUserElevate()
|
|
|
|
{
|
|
|
|
OSVERSIONINFO osvi = {sizeof(osvi)};
|
|
|
|
GetVersionEx(&osvi);
|
|
|
|
if (osvi.dwMajorVersion >= 6)
|
|
|
|
{
|
|
|
|
// Check if UAC is enabled with Vista and above.
|
|
|
|
BOOL uacEnabled = FALSE;
|
|
|
|
|
|
|
|
// First try with undocumented CheckElevationEnabled function.
|
|
|
|
// See: http://blog.airesoft.co.uk/2011/03/uaceen-nothing-yet/
|
|
|
|
typedef DWORD (WINAPI * FPCheckElevationEnabled)(BOOL* pResult);
|
|
|
|
auto checkElevationEnabled = (FPCheckElevationEnabled)GetProcAddress(
|
|
|
|
GetModuleHandle(L"kernel32"), "CheckElevationEnabled");
|
|
|
|
if (checkElevationEnabled && checkElevationEnabled(&uacEnabled) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return uacEnabled;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Try checking registry.
|
|
|
|
const WCHAR* subKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
|
|
|
|
DWORD data;
|
|
|
|
if (GetRegistryDword(HKEY_LOCAL_MACHINE, subKey, L"EnableLUA", &data) == ERROR_SUCCESS &&
|
|
|
|
data != 0)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// File and directory functions.
|
|
|
|
//
|
|
|
|
|
|
|
|
bool CopyDirectory(const WCHAR* fromPath, const WCHAR* toPath)
|
|
|
|
{
|
|
|
|
int fromPathLength = wcslen(fromPath);
|
|
|
|
int toPathLength = wcslen(toPath);
|
|
|
|
|
|
|
|
// SHFileOperation expects double null terminated strings.
|
|
|
|
WCHAR* from = (WCHAR*)malloc((fromPathLength + 2) * sizeof(WCHAR));
|
|
|
|
wcscpy(from, fromPath);
|
|
|
|
from[fromPathLength + 2] = L'\0';
|
|
|
|
|
|
|
|
WCHAR* to = (WCHAR*)malloc((toPathLength + 2) * sizeof(WCHAR));
|
|
|
|
wcscpy(to, toPath);
|
|
|
|
to[toPathLength + 2] = L'\0';
|
|
|
|
|
|
|
|
SHFILEOPSTRUCT fo =
|
|
|
|
{
|
2013-05-31 14:28:39 +00:00
|
|
|
nullptr,
|
2013-03-18 16:55:34 +00:00
|
|
|
FO_COPY,
|
|
|
|
from,
|
|
|
|
to,
|
|
|
|
FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOL copied = (SHFileOperation(&fo) == 0);
|
|
|
|
|
|
|
|
free(from);
|
|
|
|
free(to);
|
|
|
|
|
|
|
|
return copied;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreateShortcutFile(const WCHAR* filePath, const WCHAR* targetPath)
|
|
|
|
{
|
|
|
|
IShellLink* psl;
|
2013-05-31 14:28:39 +00:00
|
|
|
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
|
2013-03-18 16:55:34 +00:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
IPersistFile* ppf;
|
|
|
|
hr = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
psl->SetPath(filePath);
|
|
|
|
hr = ppf->Save(targetPath, TRUE);
|
|
|
|
|
|
|
|
ppf->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
psl->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCEEDED(hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsDirectoryWritable()
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Registry functions.
|
|
|
|
//
|
|
|
|
|
|
|
|
bool GetRegistryDword(HKEY rootKey, const WCHAR* subKey, const WCHAR* value, DWORD* data)
|
|
|
|
{
|
|
|
|
DWORD type;
|
|
|
|
DWORD dataSize = sizeof(DWORD);
|
|
|
|
return (SHGetValue(rootKey, subKey, value, &type, data, &dataSize) == ERROR_SUCCESS &&
|
|
|
|
type == REG_DWORD);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetRegistryString(HKEY rootKey, const WCHAR* subKey, const WCHAR* value, WCHAR* data, DWORD dataSize)
|
|
|
|
{
|
|
|
|
DWORD type;
|
|
|
|
return (SHGetValue(rootKey, subKey, value, &type, data, &dataSize) == ERROR_SUCCESS &&
|
|
|
|
type == REG_SZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SetRegistryData(DWORD type, HKEY rootKey, const WCHAR* subKey, const WCHAR* value, BYTE* data, DWORD dataSize)
|
|
|
|
{
|
|
|
|
BOOL result = FALSE;
|
|
|
|
HKEY regKey;
|
2013-05-31 14:28:39 +00:00
|
|
|
if (RegCreateKeyEx(rootKey, subKey, 0, 0, 0, KEY_SET_VALUE, nullptr, ®Key, nullptr) == ERROR_SUCCESS)
|
2013-03-18 16:55:34 +00:00
|
|
|
{
|
|
|
|
if (RegSetValueEx(regKey, value, 0, type, data, dataSize) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
result = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(regKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SetRegistryDword(HKEY rootKey, const WCHAR* subKey, const WCHAR* value, DWORD data)
|
|
|
|
{
|
|
|
|
return SetRegistryData(REG_DWORD, rootKey, subKey, value, (BYTE*)&data, sizeof(DWORD));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SetRegistryString(HKEY rootKey, const WCHAR* subKey, const WCHAR* value, const WCHAR* data)
|
|
|
|
{
|
|
|
|
DWORD dataSize = (wcslen(data) + 1) * sizeof(WCHAR);
|
|
|
|
return SetRegistryData(REG_SZ, rootKey, subKey, value, (BYTE*)data, dataSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Misc. functions.
|
|
|
|
//
|
|
|
|
|
|
|
|
bool DownloadFile(const WCHAR* url, const WCHAR* file)
|
|
|
|
{
|
|
|
|
bool result = false;
|
2013-05-31 14:28:39 +00:00
|
|
|
HINTERNET hNet = InternetOpen(L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
|
2013-03-18 16:55:34 +00:00
|
|
|
if (hNet)
|
|
|
|
{
|
2013-05-31 14:28:39 +00:00
|
|
|
HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
2013-03-18 16:55:34 +00:00
|
|
|
if (hFile)
|
|
|
|
{
|
2013-05-31 14:28:39 +00:00
|
|
|
HINTERNET hUrl = InternetOpenUrl(hNet, url, nullptr, 0, INTERNET_FLAG_RESYNCHRONIZE, 0);
|
2013-03-18 16:55:34 +00:00
|
|
|
if (hUrl)
|
|
|
|
{
|
|
|
|
const DWORD bufferSize = 8192;
|
|
|
|
BYTE* buffer = (BYTE*)malloc(bufferSize);
|
|
|
|
if (buffer)
|
|
|
|
{
|
|
|
|
DWORD readSize;
|
|
|
|
while (InternetReadFile(hUrl, buffer, bufferSize, &readSize))
|
|
|
|
{
|
|
|
|
if (readSize == 0)
|
|
|
|
{
|
|
|
|
// All data read.
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD writeSize;
|
2013-05-31 14:28:39 +00:00
|
|
|
if (!WriteFile(hFile, buffer, readSize, &writeSize, nullptr) ||
|
2013-03-18 16:55:34 +00:00
|
|
|
readSize != writeSize)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
InternetCloseHandle(hUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
CloseHandle(hFile);
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
DeleteFile(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
InternetCloseHandle(hNet);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Util
|