mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-19 23:59:36 +01:00
218 lines
5.0 KiB
C
218 lines
5.0 KiB
C
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include "debug.h"
|
|
#include "config.h"
|
|
#include "crc32.h"
|
|
#include "ini.h"
|
|
|
|
// Microsoft: The maximum profile section size is 32,767 characters.
|
|
#define BUF_SIZE (8192)
|
|
|
|
void ini_create(INIFILE* ini, char* filename)
|
|
{
|
|
if (!ini || !filename || !filename[0])
|
|
return;
|
|
|
|
ini->sections = calloc(sizeof(ini->sections[0]), 1);
|
|
if (ini->sections)
|
|
{
|
|
strncpy(ini->filename, filename, sizeof(ini->filename) - 1);
|
|
ini->filename[sizeof(ini->filename) - 1] = 0;
|
|
|
|
char* names = calloc(BUF_SIZE, 1);
|
|
if (names)
|
|
{
|
|
if (GetPrivateProfileSectionNamesA(names, BUF_SIZE, filename) > 0)
|
|
{
|
|
char* name = names;
|
|
|
|
for (int i = 0; *name; i++)
|
|
{
|
|
ini->sections = realloc(ini->sections, sizeof(ini->sections[0]) * (i + 2));
|
|
|
|
if (!ini->sections)
|
|
return;
|
|
|
|
memset(&ini->sections[i + 1], 0, sizeof(ini->sections[0]));
|
|
|
|
char* buf = malloc(BUF_SIZE);
|
|
if (buf)
|
|
{
|
|
DWORD size = GetPrivateProfileSectionA(name, buf, BUF_SIZE, filename);
|
|
if (size > 0)
|
|
{
|
|
ini->sections[i].data = malloc(size + 2);
|
|
if (ini->sections[i].data)
|
|
{
|
|
memcpy(ini->sections[i].data, buf, size + 2);
|
|
}
|
|
}
|
|
|
|
free(buf);
|
|
}
|
|
|
|
size_t len = strlen(name);
|
|
|
|
for (char* p = name; *p; ++p)
|
|
*p = tolower(*p);
|
|
|
|
ini->sections[i].hash = Crc32_ComputeBuf(0, name, len);
|
|
|
|
name += len + 1;
|
|
}
|
|
}
|
|
|
|
free(names);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL ini_section_exists(INIFILE* ini, LPCSTR section)
|
|
{
|
|
if (!ini || !ini->sections || !section || strlen(section) == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
char s[MAX_PATH];
|
|
strncpy(s, section, sizeof(s) - 1);
|
|
s[sizeof(s) - 1] = 0;
|
|
|
|
for (char* p = s; *p; ++p)
|
|
*p = tolower(*p);
|
|
|
|
unsigned long hash = Crc32_ComputeBuf(0, s, strlen(s));
|
|
|
|
for (int i = 0; ini->sections[i].hash; i++)
|
|
{
|
|
if (ini->sections[i].hash == hash)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD ini_get_string(INIFILE* ini, LPCSTR section, LPCSTR key, LPCSTR def, LPSTR buf, DWORD size)
|
|
{
|
|
if (!buf || size == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!ini || !ini->sections || !section || !key)
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
size_t key_len = strlen(key);
|
|
|
|
if (key_len == 0 || strlen(section) == 0)
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
char s[MAX_PATH];
|
|
strncpy(s, section, sizeof(s) - 1);
|
|
s[sizeof(s) - 1] = 0;
|
|
|
|
for (char* p = s; *p; ++p)
|
|
*p = tolower(*p);
|
|
|
|
unsigned long hash = Crc32_ComputeBuf(0, s, strlen(s));
|
|
|
|
for (int i = 0; ini->sections[i].hash; i++)
|
|
{
|
|
if (ini->sections[i].hash == hash)
|
|
{
|
|
if (!ini->sections[i].data)
|
|
break;
|
|
|
|
for (char* p = ini->sections[i].data; *p; p += strlen(p) + 1)
|
|
{
|
|
if (_strnicmp(key, p, key_len) == 0 && p[key_len] == '=')
|
|
{
|
|
strncpy(buf, &p[key_len + 1], size - 1);
|
|
buf[size - 1] = 0;
|
|
return strlen(buf);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
end:
|
|
if (def)
|
|
{
|
|
strncpy(buf, def, size - 1);
|
|
buf[size - 1] = 0;
|
|
return strlen(buf);
|
|
}
|
|
|
|
buf[0] = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL ini_get_bool(INIFILE* ini, LPCSTR section, LPCSTR key, BOOL def)
|
|
{
|
|
char value[8];
|
|
ini_get_string(ini, section, key, def ? "Yes" : "No", value, sizeof(value));
|
|
|
|
return (_stricmp(value, "yes") == 0 || _stricmp(value, "true") == 0 || _stricmp(value, "1") == 0);
|
|
}
|
|
|
|
int ini_get_int(INIFILE* ini, LPCSTR section, LPCSTR key, int def)
|
|
{
|
|
char def_str[32];
|
|
_snprintf(def_str, sizeof(def_str) - 1, "%d", def);
|
|
|
|
char value[32];
|
|
ini_get_string(ini, section, key, def_str, value, sizeof(value));
|
|
|
|
if (strstr(value, "0x"))
|
|
{
|
|
return strtol(value, NULL, 0);
|
|
}
|
|
else
|
|
{
|
|
return atoi(value);
|
|
}
|
|
}
|
|
|
|
float ini_get_float(INIFILE* ini, LPCSTR section, LPCSTR key, float def)
|
|
{
|
|
char def_str[32];
|
|
_snprintf(def_str, sizeof(def_str) - 1, "%f", def);
|
|
|
|
char value[32];
|
|
ini_get_string(ini, section, key, def_str, value, sizeof(value));
|
|
|
|
return (float)atof(value);
|
|
}
|
|
|
|
void ini_free(INIFILE* ini)
|
|
{
|
|
if (!ini)
|
|
return;
|
|
|
|
ini->filename[0] = 0;
|
|
|
|
if (ini->sections)
|
|
{
|
|
for (int i = 0; ini->sections[i].hash; i++)
|
|
{
|
|
if (ini->sections[i].data)
|
|
{
|
|
free(ini->sections[i].data);
|
|
ini->sections[i].data = NULL;
|
|
}
|
|
}
|
|
|
|
free(ini->sections);
|
|
ini->sections = NULL;
|
|
}
|
|
}
|