|
|
@@ -24,7 +24,9 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
+#ifndef _WIN32
|
|
|
#include <unistd.h>
|
|
|
+#endif
|
|
|
|
|
|
#include <errno.h>
|
|
|
#include <winpr/wtypes.h>
|
|
|
@@ -234,7 +236,7 @@ static wIniFileKey* IniFile_Key_New(const char* name, const char* value)
|
|
|
{
|
|
|
key->name = _strdup(name);
|
|
|
key->value = _strdup(value);
|
|
|
- key->invalid = TRUE;
|
|
|
+ key->invalid = FALSE;
|
|
|
|
|
|
if (!key->name || !key->value)
|
|
|
{
|
|
|
@@ -271,14 +273,12 @@ static wIniFileSection* IniFile_Section_New(const char* name)
|
|
|
return NULL;
|
|
|
|
|
|
section->name = _strdup(name);
|
|
|
- section->invalid = TRUE;
|
|
|
-
|
|
|
if (!section->name)
|
|
|
{
|
|
|
free(section);
|
|
|
return NULL;
|
|
|
}
|
|
|
-
|
|
|
+ section->invalid = FALSE;
|
|
|
section->nKeys = 0;
|
|
|
section->cKeys = 64;
|
|
|
section->keys = (wIniFileKey**)calloc(section->cKeys, sizeof(wIniFileKey*));
|
|
|
@@ -322,7 +322,7 @@ static wIniFileSection* IniFile_GetSection(wIniFile* ini, const char* name)
|
|
|
for (index = 0; index < ini->nSections; index++)
|
|
|
{
|
|
|
if (_stricmp(name, ini->sections[index]->name) == 0
|
|
|
- && !!ini->sections[index]->invalid)
|
|
|
+ && !ini->sections[index]->invalid)
|
|
|
{
|
|
|
section = ini->sections[index];
|
|
|
break;
|
|
|
@@ -365,6 +365,34 @@ static wIniFileSection* IniFile_AddSection(wIniFile* ini, const char* name)
|
|
|
return section;
|
|
|
}
|
|
|
|
|
|
+static BOOL IniFile_RemoveSection(wIniFile* ini, const char* name, BOOL* changed)
|
|
|
+{
|
|
|
+ size_t index;
|
|
|
+ wIniFileSection* section = NULL;
|
|
|
+
|
|
|
+ if (!ini || !name)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ for (index = 0; index < ini->nSections; index++) {
|
|
|
+ if (_stricmp(name, ini->sections[index]->name) == 0) {
|
|
|
+ section = ini->sections[index];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(section)
|
|
|
+ {
|
|
|
+ ini->nSections--;
|
|
|
+ ini->sections[index] = ini->sections[ini->nSections];
|
|
|
+ ini->sections[ini->nSections] = NULL;
|
|
|
+ IniFile_Section_Free(section);
|
|
|
+ if(changed)
|
|
|
+ {
|
|
|
+ *changed = TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
static wIniFileKey* IniFile_GetKey(wIniFile* ini, wIniFileSection* section, const char* name)
|
|
|
{
|
|
|
size_t index;
|
|
|
@@ -386,7 +414,7 @@ static wIniFileKey* IniFile_GetKey(wIniFile* ini, wIniFileSection* section, cons
|
|
|
}
|
|
|
|
|
|
static wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* name,
|
|
|
- const char* value)
|
|
|
+ const char* value, BOOL* changed)
|
|
|
{
|
|
|
wIniFileKey* key;
|
|
|
|
|
|
@@ -418,19 +446,52 @@ static wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, cons
|
|
|
|
|
|
section->keys[section->nKeys] = key;
|
|
|
section->nKeys++;
|
|
|
+ if (changed) { *changed = TRUE; }
|
|
|
}
|
|
|
- else
|
|
|
+ else if(_stricmp(key->value, value) != 0)
|
|
|
{
|
|
|
free(key->value);
|
|
|
key->value = _strdup(value);
|
|
|
|
|
|
if (!key->value)
|
|
|
return NULL;
|
|
|
+ if (changed) { *changed = TRUE; }
|
|
|
}
|
|
|
|
|
|
return key;
|
|
|
}
|
|
|
|
|
|
+static BOOL IniFile_RemoveKey(wIniFile* ini, const char* sectionName, const char* keyName, BOOL* changed)
|
|
|
+{
|
|
|
+ size_t index;
|
|
|
+ wIniFileKey* key = NULL;
|
|
|
+ wIniFileSection* section = NULL;
|
|
|
+ if (!sectionName || !keyName)
|
|
|
+ return FALSE;
|
|
|
+ section = IniFile_GetSection(ini, sectionName);
|
|
|
+ if(section)
|
|
|
+ {
|
|
|
+ for (index = 0; index < section->nKeys; index++) {
|
|
|
+ if (_stricmp(keyName, section->keys[index]->name) == 0) {
|
|
|
+ key = section->keys[index];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(key)
|
|
|
+ {
|
|
|
+ section->nKeys--;
|
|
|
+ section->keys[index] = section->keys[section->nKeys];
|
|
|
+ section->keys[section->nKeys] = NULL;
|
|
|
+ IniFile_Key_Free(key);
|
|
|
+ if(changed)
|
|
|
+ {
|
|
|
+ *changed = TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
static int IniFile_Load(wIniFile* ini)
|
|
|
{
|
|
|
char* line;
|
|
|
@@ -494,7 +555,7 @@ static int IniFile_Load(wIniFile* ini)
|
|
|
|
|
|
value = beg;
|
|
|
|
|
|
- if (!IniFile_AddKey(ini, section, name, value))
|
|
|
+ if (!IniFile_AddKey(ini, section, name, value, NULL))
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
@@ -649,7 +710,7 @@ const char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
-int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key)
|
|
|
+int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key, const int defValue)
|
|
|
{
|
|
|
int err;
|
|
|
long value = 0;
|
|
|
@@ -658,12 +719,12 @@ int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key)
|
|
|
pSection = IniFile_GetSection(ini, section);
|
|
|
|
|
|
if (!pSection)
|
|
|
- return 0;
|
|
|
+ return defValue;
|
|
|
|
|
|
pKey = IniFile_GetKey(ini, pSection, key);
|
|
|
|
|
|
if (!pKey)
|
|
|
- return 0;
|
|
|
+ return defValue;
|
|
|
|
|
|
err = errno;
|
|
|
errno = 0;
|
|
|
@@ -671,7 +732,7 @@ int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key)
|
|
|
if ((value < INT_MIN) || (value > INT_MAX) || (errno != 0))
|
|
|
{
|
|
|
errno = err;
|
|
|
- return 0;
|
|
|
+ return defValue;
|
|
|
}
|
|
|
return (int)value;
|
|
|
}
|
|
|
@@ -689,7 +750,7 @@ int IniFile_SetKeyValueString(wIniFile* ini, const char* section, const char* ke
|
|
|
if (!pSection)
|
|
|
return -1;
|
|
|
|
|
|
- pKey = IniFile_AddKey(ini, pSection, key, value);
|
|
|
+ pKey = IniFile_AddKey(ini, pSection, key, value, NULL);
|
|
|
|
|
|
if (!pKey)
|
|
|
return -1;
|
|
|
@@ -711,7 +772,7 @@ int IniFile_SetKeyValueInt(wIniFile* ini, const char* section, const char* key,
|
|
|
if (!pSection)
|
|
|
return -1;
|
|
|
|
|
|
- pKey = IniFile_AddKey(ini, pSection, key, strVal);
|
|
|
+ pKey = IniFile_AddKey(ini, pSection, key, strVal, NULL);
|
|
|
|
|
|
if (!pKey)
|
|
|
return -1;
|
|
|
@@ -842,17 +903,26 @@ void IniFile_Free(wIniFile* ini)
|
|
|
free(ini);
|
|
|
}
|
|
|
|
|
|
+#ifndef _WIN32
|
|
|
+
|
|
|
DWORD GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault,
|
|
|
LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName)
|
|
|
{
|
|
|
wIniFile* ini;
|
|
|
DWORD nRetSize = 0;
|
|
|
+ DWORD nRealSize = 0;
|
|
|
const char* value;
|
|
|
wIniFileSection* pSection = NULL;
|
|
|
int index;
|
|
|
wIniFileKey* key = NULL;
|
|
|
char *t;
|
|
|
size_t totalLen = 0;
|
|
|
+
|
|
|
+ if(lpAppName == NULL)
|
|
|
+ {
|
|
|
+ return GetPrivateProfileSectionNamesA(lpReturnedString, nSize, lpFileName);
|
|
|
+ }
|
|
|
+
|
|
|
ini = IniFile_New();
|
|
|
if(IniFile_ReadFile(ini, lpFileName) < 0) {
|
|
|
IniFile_Free(ini);
|
|
|
@@ -862,9 +932,17 @@ DWORD GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefa
|
|
|
if(lpKeyName != NULL) {
|
|
|
value = IniFile_GetKeyValueString(ini, lpAppName, lpKeyName);
|
|
|
if(value) {
|
|
|
- nRetSize = strlen(value);
|
|
|
- if(nSize > 0 && lpReturnedString) {
|
|
|
- strncpy(lpReturnedString, value, nSize > strlen(value)+1 ? strlen(value)+1 : nSize);
|
|
|
+ nRealSize = strlen(value);
|
|
|
+ if(nRealSize +1 > nSize)
|
|
|
+ {
|
|
|
+ nRetSize = nSize - 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (nSize > 0 && lpReturnedString) {
|
|
|
+ strncpy(lpReturnedString, value, strlen(value) + 1);
|
|
|
+ }
|
|
|
+ nRetSize = nRealSize;
|
|
|
}
|
|
|
}
|
|
|
} else { // key == null
|
|
|
@@ -881,7 +959,7 @@ DWORD GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefa
|
|
|
// if(totalLen > 0) {
|
|
|
// totalLen--;
|
|
|
// }
|
|
|
- nRetSize = totalLen;
|
|
|
+ nRealSize = nRetSize = totalLen;
|
|
|
if(totalLen > 1 && nSize >= 2 && lpReturnedString) {
|
|
|
|
|
|
if(totalLen > nSize) {
|
|
|
@@ -914,11 +992,12 @@ DWORD GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(nRetSize == 0 && nSize > 0 && lpReturnedString) {
|
|
|
+ if(nRealSize == 0 && nSize > 0 && lpReturnedString) {
|
|
|
lpReturnedString[0] = '\0';
|
|
|
if(lpDefault) {
|
|
|
- nRetSize = nSize > strlen(lpDefault)+1 ? strlen(lpDefault)+1 : nSize;
|
|
|
- strncpy(lpReturnedString, lpDefault, nRetSize);
|
|
|
+ nRealSize = nSize > strlen(lpDefault)+1 ? strlen(lpDefault)+1 : nSize;
|
|
|
+ strncpy(lpReturnedString, lpDefault, nRealSize);
|
|
|
+ nRetSize = strlen(lpReturnedString);
|
|
|
}
|
|
|
}
|
|
|
IniFile_Free(ini);
|
|
|
@@ -945,7 +1024,7 @@ UINT GetPrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPC
|
|
|
WLog_ERR(TAG, "failed to parse %s", lpFileName);
|
|
|
return ret;
|
|
|
}
|
|
|
- ret = IniFile_GetKeyValueInt(ini, lpAppName, lpKeyName);
|
|
|
+ ret = IniFile_GetKeyValueInt(ini, lpAppName, lpKeyName, nDefault);
|
|
|
IniFile_Free(ini);
|
|
|
return ret;
|
|
|
}
|
|
|
@@ -1029,21 +1108,49 @@ BOOL WritePrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpStr
|
|
|
{
|
|
|
wIniFile* ini;
|
|
|
BOOL ret = TRUE;
|
|
|
+ BOOL changed = FALSE;
|
|
|
ini = IniFile_New();
|
|
|
if(!ini) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
if(IniFile_ReadFile(ini, lpFileName) < 0 && access(lpFileName, F_OK) == 0) {
|
|
|
+ printf("open ini file failed.\n");
|
|
|
ret = FALSE;
|
|
|
} else {
|
|
|
- if(IniFile_SetKeyValueString(ini, lpAppName, lpKeyName, lpString) < 0) {
|
|
|
- ret = FALSE;
|
|
|
- } else {
|
|
|
- if(IniFile_WriteFile(ini, lpFileName) < 0) {
|
|
|
+ if(lpAppName == NULL)
|
|
|
+ {
|
|
|
+ //TODO:
|
|
|
+ }
|
|
|
+ if(lpKeyName == NULL)
|
|
|
+ {
|
|
|
+ //remove all entries inner section and the section also.
|
|
|
+ ret = IniFile_RemoveSection(ini, lpAppName, &changed);
|
|
|
+ }
|
|
|
+ else if(lpString == NULL)
|
|
|
+ {
|
|
|
+ //remote the specified entry inner section
|
|
|
+ ret = IniFile_RemoveKey(ini, lpAppName, lpKeyName, &changed);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (IniFile_SetKeyValueString(ini, lpAppName, lpKeyName, lpString) < 0) {
|
|
|
ret = FALSE;
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ changed = TRUE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+finished:
|
|
|
+
|
|
|
+ if(ret && changed)
|
|
|
+ {
|
|
|
+ if (IniFile_WriteFile(ini, lpFileName) < 0) {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
IniFile_Free(ini);
|
|
|
return ret;
|
|
|
}
|
|
|
@@ -1058,7 +1165,15 @@ BOOL WritePrivateProfileSectionA(LPCSTR lpAppName, LPCSTR lpString, LPCSTR lpFil
|
|
|
{
|
|
|
wIniFile* ini;
|
|
|
BOOL ret = TRUE;
|
|
|
+ BOOL changed = FALSE;
|
|
|
wIniFileSection* pSection = NULL;
|
|
|
+ wIniFileKey* pKey = NULL;
|
|
|
+ char* curToken = NULL;
|
|
|
+ char* nextToken = NULL;
|
|
|
+ char* newKey = NULL;
|
|
|
+ char* newValue = NULL;
|
|
|
+ char* newString = NULL;
|
|
|
+ char* keyValue = NULL;
|
|
|
ini = IniFile_New();
|
|
|
if(!ini) {
|
|
|
return FALSE;
|
|
|
@@ -1066,18 +1181,70 @@ BOOL WritePrivateProfileSectionA(LPCSTR lpAppName, LPCSTR lpString, LPCSTR lpFil
|
|
|
if(IniFile_ReadFile(ini, lpFileName) < 0) {
|
|
|
ret = FALSE;
|
|
|
} else {
|
|
|
- if(lpString == NULL) {
|
|
|
- //to delete the section...
|
|
|
- pSection = IniFile_GetSection(ini, lpAppName);
|
|
|
- if(!pSection) {
|
|
|
- ret = FALSE;
|
|
|
- } else {
|
|
|
- pSection->invalid = TRUE;
|
|
|
+ if(lpAppName != NULL)
|
|
|
+ {
|
|
|
+ if (lpString == NULL)
|
|
|
+ {
|
|
|
+ printf("to delete the section...\n");
|
|
|
+ ret = IniFile_RemoveSection(ini, lpAppName, &changed);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pSection = IniFile_GetSection(ini, lpAppName);
|
|
|
+ if(!pSection)
|
|
|
+ {
|
|
|
+ pSection = IniFile_AddSection(ini, lpAppName);
|
|
|
+ if(!pSection)
|
|
|
+ {
|
|
|
+ ret = FALSE;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ changed = TRUE;
|
|
|
+ }
|
|
|
+ curToken = (char*)&lpString[0];
|
|
|
+ while (curToken != NULL && curToken[0] != '\0')
|
|
|
+ {
|
|
|
+ keyValue = _strdup(curToken);
|
|
|
+ if (!keyValue) {
|
|
|
+ ret = FALSE;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ newKey = strtok_s(keyValue, "=", &newValue);
|
|
|
+ newValue = strtok_s(NULL, "=", &newValue);
|
|
|
+ pKey = IniFile_GetKey(ini, pSection, newKey);
|
|
|
+ if (pKey == NULL) {
|
|
|
+ pKey = IniFile_AddKey(ini, pSection, newKey, newValue, NULL);
|
|
|
+ changed = TRUE;
|
|
|
+ } else if(_stricmp(pKey->value, newValue) != 0)
|
|
|
+ {
|
|
|
+ free(pKey->value);
|
|
|
+ pKey->value = _strdup(newValue);
|
|
|
+ if (!pKey->value)
|
|
|
+ {
|
|
|
+ free(keyValue);
|
|
|
+ ret = FALSE;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ changed = TRUE;
|
|
|
+ }
|
|
|
+ free(keyValue);
|
|
|
+ //curToken = strtok_s(NULL, "\0", &nextToken);
|
|
|
+ curToken = curToken + strlen(curToken) + 1;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if(ret == TRUE && IniFile_WriteFile(ini, lpFileName) < 0) {
|
|
|
- ret = FALSE;
|
|
|
+ if(ret == TRUE && changed) {
|
|
|
+ if(IniFile_WriteFile(ini, lpFileName) < 0)
|
|
|
+ {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+end:
|
|
|
+ if(newString != NULL)
|
|
|
+ {
|
|
|
+ free(newString);
|
|
|
}
|
|
|
IniFile_Free(ini);
|
|
|
return ret;
|
|
|
@@ -1087,4 +1254,6 @@ WINPR_API BOOL WritePrivateProfileSectionW(LPCWSTR lpAppName, LPCWSTR lpString,L
|
|
|
{
|
|
|
WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
return FALSE;
|
|
|
-}
|
|
|
+}
|
|
|
+
|
|
|
+#endif //_WIN32
|