|
|
@@ -24,17 +24,21 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
+#include <unistd.h>
|
|
|
|
|
|
#include <errno.h>
|
|
|
#include <winpr/wtypes.h>
|
|
|
#include <winpr/crt.h>
|
|
|
|
|
|
#include <winpr/ini.h>
|
|
|
+#include "../log.h"
|
|
|
+#define TAG WINPR_TAG("ini")
|
|
|
|
|
|
struct _wIniFileKey
|
|
|
{
|
|
|
char* name;
|
|
|
char* value;
|
|
|
+ BOOL invalid; /*extend */
|
|
|
};
|
|
|
typedef struct _wIniFileKey wIniFileKey;
|
|
|
|
|
|
@@ -44,6 +48,7 @@ struct _wIniFileSection
|
|
|
size_t nKeys;
|
|
|
size_t cKeys;
|
|
|
wIniFileKey** keys;
|
|
|
+ BOOL invalid; /*extend */
|
|
|
};
|
|
|
typedef struct _wIniFileSection wIniFileSection;
|
|
|
|
|
|
@@ -65,6 +70,9 @@ struct _wIniFile
|
|
|
static BOOL IniFile_Load_NextLine(wIniFile* ini, char* str)
|
|
|
{
|
|
|
size_t length = 0;
|
|
|
+
|
|
|
+still: // fix \r\n gifur
|
|
|
+
|
|
|
ini->nextLine = strtok_s(str, "\n", &ini->tokctx);
|
|
|
|
|
|
if (ini->nextLine)
|
|
|
@@ -78,8 +86,13 @@ static BOOL IniFile_Load_NextLine(wIniFile* ini, char* str)
|
|
|
length--;
|
|
|
}
|
|
|
|
|
|
- if (length < 1)
|
|
|
- ini->nextLine = NULL;
|
|
|
+ if (length < 1) { // must be zero !!
|
|
|
+ if(strlen(ini->tokctx) > 0) {
|
|
|
+ goto still;
|
|
|
+ }else {
|
|
|
+ ini->nextLine = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return (ini->nextLine) ? TRUE : FALSE;
|
|
|
@@ -111,6 +124,7 @@ static BOOL IniFile_Load_String(wIniFile* ini, const char* iniString)
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
+/*fopen*/
|
|
|
static BOOL IniFile_Open_File(wIniFile* ini, const char* filename)
|
|
|
{
|
|
|
if (!ini || !filename)
|
|
|
@@ -127,6 +141,7 @@ static BOOL IniFile_Open_File(wIniFile* ini, const char* filename)
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
+/**/
|
|
|
static BOOL IniFile_Load_File(wIniFile* ini, const char* filename)
|
|
|
{
|
|
|
INT64 fileSize;
|
|
|
@@ -219,6 +234,7 @@ static wIniFileKey* IniFile_Key_New(const char* name, const char* value)
|
|
|
{
|
|
|
key->name = _strdup(name);
|
|
|
key->value = _strdup(value);
|
|
|
+ key->invalid = TRUE;
|
|
|
|
|
|
if (!key->name || !key->value)
|
|
|
{
|
|
|
@@ -255,6 +271,7 @@ static wIniFileSection* IniFile_Section_New(const char* name)
|
|
|
return NULL;
|
|
|
|
|
|
section->name = _strdup(name);
|
|
|
+ section->invalid = TRUE;
|
|
|
|
|
|
if (!section->name)
|
|
|
{
|
|
|
@@ -304,7 +321,8 @@ static wIniFileSection* IniFile_GetSection(wIniFile* ini, const char* name)
|
|
|
|
|
|
for (index = 0; index < ini->nSections; index++)
|
|
|
{
|
|
|
- if (_stricmp(name, ini->sections[index]->name) == 0)
|
|
|
+ if (_stricmp(name, ini->sections[index]->name) == 0
|
|
|
+ && !!ini->sections[index]->invalid)
|
|
|
{
|
|
|
section = ini->sections[index];
|
|
|
break;
|
|
|
@@ -330,8 +348,7 @@ static wIniFileSection* IniFile_AddSection(wIniFile* ini, const char* name)
|
|
|
size_t new_size;
|
|
|
wIniFileSection** new_sect;
|
|
|
new_size = ini->cSections * 2;
|
|
|
- new_sect =
|
|
|
- (wIniFileSection**)realloc(ini->sections, sizeof(wIniFileSection*) * new_size);
|
|
|
+ new_sect = (wIniFileSection**)realloc(ini->sections, sizeof(wIniFileSection*) * new_size);
|
|
|
|
|
|
if (!new_sect)
|
|
|
return NULL;
|
|
|
@@ -714,7 +731,7 @@ char* IniFile_WriteBuffer(wIniFile* ini)
|
|
|
|
|
|
if (!ini)
|
|
|
return NULL;
|
|
|
-
|
|
|
+ /*calculate the rquired buffer size for storing*/
|
|
|
for (i = 0; i < ini->nSections; i++)
|
|
|
{
|
|
|
section = ini->sections[i];
|
|
|
@@ -728,7 +745,7 @@ char* IniFile_WriteBuffer(wIniFile* ini)
|
|
|
|
|
|
size += 1;
|
|
|
}
|
|
|
-
|
|
|
+ /*allocate buffer*/
|
|
|
size += 1;
|
|
|
buffer = malloc(size + 1);
|
|
|
|
|
|
@@ -736,7 +753,7 @@ char* IniFile_WriteBuffer(wIniFile* ini)
|
|
|
return NULL;
|
|
|
|
|
|
offset = 0;
|
|
|
-
|
|
|
+ /*write to the buffer*/
|
|
|
for (i = 0; i < ini->nSections; i++)
|
|
|
{
|
|
|
section = ini->sections[i];
|
|
|
@@ -769,6 +786,7 @@ int IniFile_WriteFile(wIniFile* ini, const char* filename)
|
|
|
return -1;
|
|
|
|
|
|
length = strlen(buffer);
|
|
|
+ /*set write flag*/
|
|
|
ini->readOnly = FALSE;
|
|
|
|
|
|
if (!filename)
|
|
|
@@ -823,3 +841,250 @@ void IniFile_Free(wIniFile* ini)
|
|
|
free(ini->sections);
|
|
|
free(ini);
|
|
|
}
|
|
|
+
|
|
|
+DWORD GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault,
|
|
|
+ LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName)
|
|
|
+{
|
|
|
+ wIniFile* ini;
|
|
|
+ DWORD nRetSize = 0;
|
|
|
+ const char* value;
|
|
|
+ wIniFileSection* pSection = NULL;
|
|
|
+ int index;
|
|
|
+ wIniFileKey* key = NULL;
|
|
|
+ char *t;
|
|
|
+ size_t totalLen = 0;
|
|
|
+ ini = IniFile_New();
|
|
|
+ if(IniFile_ReadFile(ini, lpFileName) < 0) {
|
|
|
+ IniFile_Free(ini);
|
|
|
+ WLog_ERR(TAG, "failed to parse %s", lpFileName);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else { // key == null
|
|
|
+
|
|
|
+ pSection = IniFile_GetSection(ini, lpAppName);
|
|
|
+ if (pSection) {
|
|
|
+ totalLen = 0;
|
|
|
+ for (index = 0; index < pSection->nKeys; index++) {
|
|
|
+ key = pSection->keys[index];
|
|
|
+ if(strlen(key->name) > 0)
|
|
|
+ totalLen += strlen(key->name) + 1;
|
|
|
+ }
|
|
|
+ totalLen++;
|
|
|
+// if(totalLen > 0) {
|
|
|
+// totalLen--;
|
|
|
+// }
|
|
|
+ nRetSize = totalLen;
|
|
|
+ if(totalLen > 1 && nSize >= 2 && lpReturnedString) {
|
|
|
+
|
|
|
+ if(totalLen > nSize) {
|
|
|
+ // for compatible the upper invoke
|
|
|
+ nRetSize = nSize - 2;
|
|
|
+ } else {
|
|
|
+ char* temp = malloc(sizeof(char)*totalLen);
|
|
|
+ if(temp) {
|
|
|
+ memset(temp, 0, sizeof(char)*totalLen);
|
|
|
+ t = temp;
|
|
|
+ for (index = 0; index < pSection->nKeys; index++) {
|
|
|
+ key = pSection->keys[index];
|
|
|
+ if(strcmp(key->name, "InitiativeTransfer") == 0) {
|
|
|
+ ;
|
|
|
+ }
|
|
|
+ if(strlen(key->name) > 0) {
|
|
|
+ strcpy(t, key->name);
|
|
|
+ t += strlen(key->name);
|
|
|
+ *t = '\0';
|
|
|
+ t++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *t = '\0';
|
|
|
+ totalLen = nSize > totalLen ? totalLen : nSize;
|
|
|
+ memcpy(lpReturnedString, temp, sizeof(char)*totalLen);
|
|
|
+ free(temp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(nRetSize == 0 && nSize > 0 && lpReturnedString) {
|
|
|
+ lpReturnedString[0] = '\0';
|
|
|
+ if(lpDefault) {
|
|
|
+ nRetSize = nSize > strlen(lpDefault)+1 ? strlen(lpDefault)+1 : nSize;
|
|
|
+ strncpy(lpReturnedString, lpDefault, nRetSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IniFile_Free(ini);
|
|
|
+ return nRetSize;
|
|
|
+}
|
|
|
+
|
|
|
+DWORD GetPrivateProfileStringW(LPCWSTR lpAppName, LPCWSTR lpKeyName, LPCWSTR lpDefault,
|
|
|
+ LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName)
|
|
|
+{
|
|
|
+ WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+UINT GetPrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPCSTR lpFileName)
|
|
|
+{
|
|
|
+ UINT ret = nDefault;
|
|
|
+ wIniFile* ini;
|
|
|
+ ini = IniFile_New();
|
|
|
+ if(!ini) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ if(IniFile_ReadFile(ini, lpFileName) < 0) {
|
|
|
+ IniFile_Free(ini);
|
|
|
+ WLog_ERR(TAG, "failed to parse %s", lpFileName);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ ret = IniFile_GetKeyValueInt(ini, lpAppName, lpKeyName);
|
|
|
+ IniFile_Free(ini);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+UINT GetPrivateProfileIntW(LPCWSTR lpAppName, LPCWSTR lpKeyName, INT nDefault, LPCWSTR lpFileName)
|
|
|
+{
|
|
|
+ WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+DWORD GetPrivateProfileSectionNamesA(LPSTR lpszReturnBuffer, DWORD nSize, LPCSTR lpFileName)
|
|
|
+{
|
|
|
+ DWORD ret = 0;
|
|
|
+ wIniFile* ini;
|
|
|
+ int index;
|
|
|
+ int length;
|
|
|
+ int validCount = 0;
|
|
|
+ int nameLength;
|
|
|
+ char* sectionNames;
|
|
|
+ wIniFileSection* section = NULL;
|
|
|
+ char *p;
|
|
|
+ ini = IniFile_New();
|
|
|
+ if(!ini) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ if(IniFile_ReadFile(ini, lpFileName) < 0) {
|
|
|
+ IniFile_Free(ini);
|
|
|
+ WLog_ERR(TAG, "failed to parse %s", lpFileName);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ length = 0;
|
|
|
+ for (index = 0; index < ini->nSections; index++) {
|
|
|
+ section = ini->sections[index];
|
|
|
+ if(section->invalid) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ validCount++;
|
|
|
+ nameLength = (int) strlen(section->name);
|
|
|
+ length += (nameLength + 1);
|
|
|
+ }
|
|
|
+ length++;
|
|
|
+
|
|
|
+ sectionNames = (char*)malloc(length);
|
|
|
+ if (!sectionNames)
|
|
|
+ return ret;
|
|
|
+ p = sectionNames;
|
|
|
+ for (index = 0; index < ini->nSections; index++)
|
|
|
+ {
|
|
|
+ section = ini->sections[index];
|
|
|
+ if(section->invalid) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ nameLength = (int) strlen(section->name);
|
|
|
+ CopyMemory(p, section->name, nameLength + 1);
|
|
|
+ p += (nameLength + 1);
|
|
|
+ }
|
|
|
+ *p = '\0';
|
|
|
+
|
|
|
+ ret = length;
|
|
|
+ if(lpszReturnBuffer != NULL && nSize > 0) {
|
|
|
+ if(nSize < length) {
|
|
|
+ ret = nSize - 2;
|
|
|
+ } else {
|
|
|
+ CopyMemory(lpszReturnBuffer, sectionNames, length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(sectionNames != NULL) {
|
|
|
+ free(sectionNames);
|
|
|
+ }
|
|
|
+ IniFile_Free(ini);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+DWORD GetPrivateProfileSectionNamesW(LPWSTR lpszReturnBuffer, DWORD nSize, LPCWSTR lpFileName)
|
|
|
+{
|
|
|
+ WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+BOOL WritePrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpString, LPCSTR lpFileName)
|
|
|
+{
|
|
|
+ wIniFile* ini;
|
|
|
+ BOOL ret = TRUE;
|
|
|
+ ini = IniFile_New();
|
|
|
+ if(!ini) {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ if(IniFile_ReadFile(ini, lpFileName) < 0 && access(lpFileName, F_OK) == 0) {
|
|
|
+ ret = FALSE;
|
|
|
+ } else {
|
|
|
+ if(IniFile_SetKeyValueString(ini, lpAppName, lpKeyName, lpString) < 0) {
|
|
|
+ ret = FALSE;
|
|
|
+ } else {
|
|
|
+ if(IniFile_WriteFile(ini, lpFileName) < 0) {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IniFile_Free(ini);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+BOOL WritePrivateProfileStringW(LPCWSTR lpAppName, LPCWSTR lpKeyName, LPCWSTR lpString, LPCWSTR lpFileName)
|
|
|
+{
|
|
|
+ WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+BOOL WritePrivateProfileSectionA(LPCSTR lpAppName, LPCSTR lpString, LPCSTR lpFileName)
|
|
|
+{
|
|
|
+ wIniFile* ini;
|
|
|
+ BOOL ret = TRUE;
|
|
|
+ wIniFileSection* pSection = NULL;
|
|
|
+ ini = IniFile_New();
|
|
|
+ if(!ini) {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ 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(ret == TRUE && IniFile_WriteFile(ini, lpFileName) < 0) {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ IniFile_Free(ini);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+WINPR_API BOOL WritePrivateProfileSectionW(LPCWSTR lpAppName, LPCWSTR lpString,LPCWSTR lpFileName)
|
|
|
+{
|
|
|
+ WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
|
|
|
+ return FALSE;
|
|
|
+}
|