313 lines
5.3 KiB
C++
313 lines
5.3 KiB
C++
|
#include "InstallerUtil.h"
|
||
|
#include "InstallerMain.h"
|
||
|
#include <stdio.h>
|
||
|
#include <windows.h>
|
||
|
|
||
|
int tstrcasecmp(const TCHAR *str1, const TCHAR *str2)
|
||
|
{
|
||
|
#if defined _UNICODE
|
||
|
return _wcsicmp(str1, str2);
|
||
|
#else
|
||
|
return _stricmp(str1, str2);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
size_t AnsiToUnicode(const char *str, wchar_t *buffer, size_t maxchars)
|
||
|
{
|
||
|
if (maxchars < 1)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
size_t total =
|
||
|
(size_t)MultiByteToWideChar(CP_UTF8,
|
||
|
0,
|
||
|
str,
|
||
|
-1,
|
||
|
buffer,
|
||
|
(int)maxchars);
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
bool IsWhiteSpaceA(const char *stream)
|
||
|
{
|
||
|
char c = *stream;
|
||
|
if (c & (1<<7))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return isspace(c) != 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int BreakStringA(const char *str, char *out, size_t maxchars)
|
||
|
{
|
||
|
const char *inptr = str;
|
||
|
while (*inptr != '\0' && IsWhiteSpaceA(inptr))
|
||
|
{
|
||
|
inptr++;
|
||
|
}
|
||
|
|
||
|
if (*inptr == '\0')
|
||
|
{
|
||
|
if (maxchars)
|
||
|
{
|
||
|
*out = '\0';
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const char *start, *end = NULL;
|
||
|
|
||
|
bool quoted = (*inptr == '"');
|
||
|
if (quoted)
|
||
|
{
|
||
|
inptr++;
|
||
|
start = inptr;
|
||
|
/* Read input until we reach a quote. */
|
||
|
while (*inptr != '\0' && *inptr != '"')
|
||
|
{
|
||
|
/* Update the end point, increment the stream. */
|
||
|
end = inptr++;
|
||
|
}
|
||
|
/* Read one more token if we reached an end quote */
|
||
|
if (*inptr == '"')
|
||
|
{
|
||
|
inptr++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
start = inptr;
|
||
|
/* Read input until we reach a space */
|
||
|
while (*inptr != '\0' && !IsWhiteSpaceA(inptr))
|
||
|
{
|
||
|
/* Update the end point, increment the stream. */
|
||
|
end = inptr++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Copy the string we found, if necessary */
|
||
|
if (end == NULL)
|
||
|
{
|
||
|
if (maxchars)
|
||
|
{
|
||
|
*out = '\0';
|
||
|
}
|
||
|
}
|
||
|
else if (maxchars)
|
||
|
{
|
||
|
char *outptr = out;
|
||
|
maxchars--;
|
||
|
for (const char *ptr=start;
|
||
|
(ptr <= end) && ((unsigned)(outptr - out) < (maxchars));
|
||
|
ptr++, outptr++)
|
||
|
{
|
||
|
*outptr = *ptr;
|
||
|
}
|
||
|
*outptr = '\0';
|
||
|
}
|
||
|
|
||
|
/* Consume more of the string until we reach non-whitespace */
|
||
|
while (*inptr != '\0' && IsWhiteSpaceA(inptr))
|
||
|
{
|
||
|
inptr++;
|
||
|
}
|
||
|
|
||
|
return (int)(inptr - str);
|
||
|
}
|
||
|
|
||
|
size_t UTIL_Format(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
size_t len;
|
||
|
|
||
|
va_start(ap, fmt);
|
||
|
len = UTIL_FormatArgs(buffer, count, fmt, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
if (len >= count)
|
||
|
{
|
||
|
len = count - 1;
|
||
|
buffer[len] = '\0';
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
size_t UTIL_FormatArgs(TCHAR *buffer, size_t count, const TCHAR *fmt, va_list ap)
|
||
|
{
|
||
|
size_t len = _vsntprintf(buffer, count, fmt, ap);
|
||
|
|
||
|
if (len >= count)
|
||
|
{
|
||
|
len = count - 1;
|
||
|
buffer[len] = '\0';
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
size_t UTIL_PathFormat(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
size_t len;
|
||
|
|
||
|
va_start(ap, fmt);
|
||
|
len = UTIL_FormatArgs(buffer, count, fmt, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
for (size_t i = 0; i < len; i++)
|
||
|
{
|
||
|
if (buffer[i] == '/')
|
||
|
{
|
||
|
buffer[i] = '\\';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
const TCHAR *GetFileFromPath(const TCHAR *path)
|
||
|
{
|
||
|
size_t len = _tcslen(path);
|
||
|
|
||
|
for (size_t i = len - 1;
|
||
|
i >= 0 && i < len;
|
||
|
i--)
|
||
|
{
|
||
|
if (path[i] == '\\' || path[i] == '/')
|
||
|
{
|
||
|
return &path[i+1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void GenerateErrorMessage(DWORD err, TCHAR *buffer, size_t maxchars)
|
||
|
{
|
||
|
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
||
|
NULL,
|
||
|
err,
|
||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||
|
buffer,
|
||
|
(DWORD)maxchars,
|
||
|
NULL) == 0)
|
||
|
{
|
||
|
UTIL_Format(buffer, maxchars, _T("Unknown error"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INT_PTR AskToExit(HWND hWnd)
|
||
|
{
|
||
|
TCHAR verify_exit[100];
|
||
|
|
||
|
if (LoadString(g_hInstance,
|
||
|
IDS_VERIFY_EXIT,
|
||
|
verify_exit,
|
||
|
sizeof(verify_exit) / sizeof(TCHAR)
|
||
|
) == 0)
|
||
|
{
|
||
|
return (INT_PTR)FALSE;
|
||
|
}
|
||
|
|
||
|
int val = MessageBox(
|
||
|
hWnd,
|
||
|
_T("Are you sure you want to exit?"),
|
||
|
_T("SourceMod Installer"),
|
||
|
MB_YESNO|MB_ICONQUESTION);
|
||
|
|
||
|
if (val == 0 || val == IDYES)
|
||
|
{
|
||
|
UpdateGlobalPosition(hWnd);
|
||
|
EndDialog(hWnd, NULL);
|
||
|
return (INT_PTR)TRUE;
|
||
|
}
|
||
|
|
||
|
return (INT_PTR)FALSE;
|
||
|
}
|
||
|
|
||
|
size_t UTIL_GetFileSize(const TCHAR *file_path)
|
||
|
{
|
||
|
HANDLE hFile;
|
||
|
|
||
|
if ((hFile = CreateFile(file_path,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL))
|
||
|
!= INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
LARGE_INTEGER size;
|
||
|
|
||
|
if (GetFileSizeEx(hFile, &size))
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
return (size_t)size.QuadPart;
|
||
|
}
|
||
|
|
||
|
CloseHandle(hFile);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
size_t UTIL_GetFolderSize(const TCHAR *basepath)
|
||
|
{
|
||
|
HANDLE hFind;
|
||
|
WIN32_FIND_DATA fd;
|
||
|
TCHAR search_path[MAX_PATH];
|
||
|
size_t total = 0;
|
||
|
|
||
|
UTIL_PathFormat(search_path,
|
||
|
sizeof(search_path) / sizeof(TCHAR),
|
||
|
_T("%s\\*.*"),
|
||
|
basepath);
|
||
|
|
||
|
if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|
||
|
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
|
||
|
{
|
||
|
UTIL_PathFormat(search_path,
|
||
|
sizeof(search_path) / sizeof(TCHAR),
|
||
|
_T("%s\\%s"),
|
||
|
basepath,
|
||
|
fd.cFileName);
|
||
|
total += UTIL_GetFolderSize(search_path);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UTIL_PathFormat(search_path,
|
||
|
sizeof(search_path) / sizeof(TCHAR),
|
||
|
_T("%s\\%s"),
|
||
|
basepath,
|
||
|
fd.cFileName);
|
||
|
|
||
|
total += UTIL_GetFileSize(search_path);
|
||
|
}
|
||
|
} while (FindNextFile(hFind, &fd));
|
||
|
|
||
|
FindClose(hFind);
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
#endif
|