tools/installer/InstallerUtil.cpp
author David Anderson <dvander@alliedmods.net>
Wed Jan 07 04:06:18 2009 -0500 (2009-01-07)
changeset 2513 527bad3cb6f9
parent 2289 44045ead61cd
permissions -rw-r--r--
Cleaned up SourceForts entries in sdktools.games.txt (bug 3492).
     1 #include "InstallerUtil.h"
     2 #include "InstallerMain.h"
     3 #include <stdio.h>
     4 #include <windows.h>
     5 
     6 int tstrcasecmp(const TCHAR *str1, const TCHAR *str2)
     7 {
     8 #if defined _UNICODE
     9 	return _wcsicmp(str1, str2);
    10 #else
    11 	return _stricmp(str1, str2);
    12 #endif
    13 }
    14 
    15 size_t AnsiToUnicode(const char *str, wchar_t *buffer, size_t maxchars)
    16 {
    17 	if (maxchars < 1)
    18 	{
    19 		return 0;
    20 	}
    21 
    22 	size_t total = 
    23 		(size_t)MultiByteToWideChar(CP_UTF8,
    24 		0,
    25 		str,
    26 		-1,
    27 		buffer,
    28 		(int)maxchars);
    29 
    30 	return total;
    31 }
    32 
    33 bool IsWhiteSpaceA(const char *stream)
    34 {
    35 	char c = *stream;
    36 	if (c & (1<<7))
    37 	{
    38 		return false;
    39 	}
    40 	else
    41 	{
    42 		return isspace(c) != 0;
    43 	}
    44 }
    45 
    46 int BreakStringA(const char *str, char *out, size_t maxchars)
    47 {
    48 	const char *inptr = str;
    49 	while (*inptr != '\0' && IsWhiteSpaceA(inptr))
    50 	{
    51 		inptr++;
    52 	}
    53 
    54 	if (*inptr == '\0')
    55 	{
    56 		if (maxchars)
    57 		{
    58 			*out = '\0';
    59 		}
    60 		return -1;
    61 	}
    62 
    63 	const char *start, *end = NULL;
    64 
    65 	bool quoted = (*inptr == '"');
    66 	if (quoted)
    67 	{
    68 		inptr++;
    69 		start = inptr;
    70 		/* Read input until we reach a quote. */
    71 		while (*inptr != '\0' && *inptr != '"')
    72 		{
    73 			/* Update the end point, increment the stream. */
    74 			end = inptr++;
    75 		}
    76 		/* Read one more token if we reached an end quote */
    77 		if (*inptr == '"')
    78 		{
    79 			inptr++;
    80 		}
    81 	}
    82 	else
    83 	{
    84 		start = inptr;
    85 		/* Read input until we reach a space */
    86 		while (*inptr != '\0' && !IsWhiteSpaceA(inptr))
    87 		{
    88 			/* Update the end point, increment the stream. */
    89 			end = inptr++;
    90 		}
    91 	}
    92 
    93 	/* Copy the string we found, if necessary */
    94 	if (end == NULL)
    95 	{
    96 		if (maxchars)
    97 		{
    98 			*out = '\0';
    99 		}
   100 	}
   101 	else if (maxchars)
   102 	{
   103 		char *outptr = out;
   104 		maxchars--;
   105 		for (const char *ptr=start;
   106 			(ptr <= end) && ((unsigned)(outptr - out) < (maxchars));
   107 			ptr++, outptr++)
   108 			{
   109 			*outptr = *ptr;
   110 		}
   111 		*outptr = '\0';
   112 	}
   113 
   114 	/* Consume more of the string until we reach non-whitespace */
   115 	while (*inptr != '\0' && IsWhiteSpaceA(inptr))
   116 	{
   117 		inptr++;
   118 	}
   119 
   120 	return (int)(inptr - str);
   121 }
   122 
   123 size_t UTIL_Format(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
   124 {
   125 	va_list ap;
   126 	size_t len;
   127 	
   128 	va_start(ap, fmt);
   129 	len = UTIL_FormatArgs(buffer, count, fmt, ap);
   130 	va_end(ap);
   131 
   132 	if (len >= count)
   133 	{
   134 		len = count - 1;
   135 		buffer[len] = '\0';
   136 	}
   137 
   138 	return len;
   139 }
   140 
   141 size_t UTIL_FormatArgs(TCHAR *buffer, size_t count, const TCHAR *fmt, va_list ap)
   142 {
   143 	size_t len = _vsntprintf(buffer, count, fmt, ap);
   144 
   145 	if (len >= count)
   146 	{
   147 		len = count - 1;
   148 		buffer[len] = '\0';
   149 	}
   150 
   151 	return len;
   152 }
   153 
   154 size_t UTIL_PathFormat(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
   155 {
   156 	va_list ap;
   157 	size_t len;
   158 
   159 	va_start(ap, fmt);
   160 	len = UTIL_FormatArgs(buffer, count, fmt, ap);
   161 	va_end(ap);
   162 
   163 	for (size_t i = 0; i < len; i++)
   164 	{
   165 		if (buffer[i] == '/')
   166 		{
   167 			buffer[i] = '\\';
   168 		}
   169 	}
   170 
   171 	return len;
   172 }
   173 
   174 const TCHAR *GetFileFromPath(const TCHAR *path)
   175 {
   176 	size_t len = _tcslen(path);
   177 
   178 	for (size_t i = len - 1;
   179 		 i >= 0 && i < len;
   180 		 i--)
   181 	{
   182 		if (path[i] == '\\' || path[i] == '/')
   183 		{
   184 			return &path[i+1];
   185 		}
   186 	}
   187 
   188 	return NULL;
   189 }
   190 
   191 void GenerateErrorMessage(DWORD err, TCHAR *buffer, size_t maxchars)
   192 {
   193 	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
   194 		NULL,
   195 		err,
   196 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   197 		buffer,
   198 		(DWORD)maxchars,
   199 		NULL) == 0)
   200 	{
   201 		UTIL_Format(buffer, maxchars, _T("Unknown error"));
   202 	}
   203 }
   204 
   205 INT_PTR AskToExit(HWND hWnd)
   206 {
   207 	TCHAR verify_exit[100];
   208 
   209 	if (LoadString(g_hInstance,
   210 		IDS_VERIFY_EXIT,
   211 		verify_exit,
   212 		sizeof(verify_exit) / sizeof(TCHAR)
   213 		) == 0)
   214 	{
   215 		return (INT_PTR)FALSE;
   216 	}
   217 
   218 	int val = MessageBox(
   219 		hWnd, 
   220 		_T("Are you sure you want to exit?"), 
   221 		_T("SourceMod Installer"), 
   222 		MB_YESNO|MB_ICONQUESTION);
   223 
   224 	if (val == 0 || val == IDYES)
   225 	{
   226 		UpdateGlobalPosition(hWnd);
   227 		EndDialog(hWnd, NULL);
   228 		return (INT_PTR)TRUE;
   229 	}
   230 	
   231 	return (INT_PTR)FALSE;
   232 }
   233 
   234 size_t UTIL_GetFileSize(const TCHAR *file_path)
   235 {
   236 	HANDLE hFile;
   237 
   238 	if ((hFile = CreateFile(file_path, 
   239 		GENERIC_READ,
   240 		FILE_SHARE_READ,
   241 		NULL,
   242 		OPEN_EXISTING,
   243 		FILE_ATTRIBUTE_NORMAL,
   244 		NULL)) 
   245 		!= INVALID_HANDLE_VALUE)
   246 	{
   247 		LARGE_INTEGER size;
   248 
   249 		if (GetFileSizeEx(hFile, &size))
   250 		{
   251 			CloseHandle(hFile);
   252 			return (size_t)size.QuadPart;
   253 		}
   254 
   255 		CloseHandle(hFile);
   256 	}
   257 
   258 	return 0;
   259 }
   260 
   261 #if 0
   262 size_t UTIL_GetFolderSize(const TCHAR *basepath)
   263 {
   264 	HANDLE hFind;
   265 	WIN32_FIND_DATA fd;
   266 	TCHAR search_path[MAX_PATH];
   267 	size_t total = 0;
   268 
   269 	UTIL_PathFormat(search_path,
   270 		sizeof(search_path) / sizeof(TCHAR),
   271 		_T("%s\\*.*"),
   272 		basepath);
   273 
   274 	if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
   275 	{
   276 		return 0;
   277 	}
   278 
   279 	do
   280 	{
   281 		if (tstrcasecmp(fd.cFileName, _T(".")) == 0
   282 			|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
   283 		{
   284 			continue;
   285 		}
   286 
   287 		if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
   288 		{
   289 			UTIL_PathFormat(search_path,
   290 				sizeof(search_path) / sizeof(TCHAR),
   291 				_T("%s\\%s"),
   292 				basepath,
   293 				fd.cFileName);
   294 			total += UTIL_GetFolderSize(search_path);
   295 		}
   296 		else
   297 		{
   298 			UTIL_PathFormat(search_path,
   299 				sizeof(search_path) / sizeof(TCHAR),
   300 				_T("%s\\%s"),
   301 				basepath,
   302 				fd.cFileName);
   303 
   304 			total += UTIL_GetFileSize(search_path);
   305 		}
   306 	} while (FindNextFile(hFind, &fd));
   307 
   308 	FindClose(hFind);
   309 
   310 	return total;
   311 }
   312 #endif