⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 profile.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
                if (buflen > 0) {
                    memcpy(buf, section->name, (buflen - 1) * sizeof(WCHAR));
                    buf += buflen - 1;
                    *buf++ = '\0';
                }
                *buf='\0';
                return len - 2;
            }
            memcpy(buf, section->name, tmplen * sizeof(WCHAR));
            buf += tmplen;
            buflen -= tmplen;
        }
        section = section->next;
    }
    *buf = '\0';
    return buf - buffer;
}


/***********************************************************************
 *           PROFILE_GetString
 *
 * Get a profile string.
 *
 * Tests with GetPrivateProfileString16, W95a,
 * with filled buffer ("****...") and section "set1" and key_name "1" valid:
 * section  key_name def_val     res   buffer
 * "set1"   "1"      "x"      43 [data]
 * "set1"   "1   "      "x"      43 [data]      (!)
 * "set1"   "  1  "' "x"      43 [data]      (!)
 * "set1"   ""    "x"      1  "x"
 * "set1"   ""    "x   "      1  "x"      (!)
 * "set1"   ""    "  x   " 3  "  x"    (!)
 * "set1"   NULL     "x"      6  "1\02\03\0\0"
 * "set1"   ""    "x"      1  "x"
 * NULL     "1"      "x"      0  ""    (!)
 * ""    "1"      "x"      1  "x"
 * NULL     NULL     ""    0  ""
 *
 *
 */
static INT PROFILE_GetString( LPCWSTR section, LPCWSTR key_name,
                              LPCWSTR def_val, LPWSTR buffer, UINT len, BOOL win32 )
{
    PROFILEKEY *key = NULL;
    static const WCHAR empty_strW[] = { 0 };

    if (!buffer) return 0;

    if (!def_val) def_val = empty_strW;
    if (key_name)
    {
        if (!key_name[0])
        {
            /* Win95 returns 0 on keyname "". Tested with Likse32 bon 000227 */
            return 0;
        }
        key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE, FALSE);
        PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
                           len, TRUE );
        DPRINT("(%S, %S, %S): returning %S\n",
               section, key_name,
               def_val, buffer);
        return wcslen(buffer);
    }

    /* no "else" here ! */
    if (section && section[0])
    {
        INT ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, FALSE, !win32);
        if (!buffer[0]) /* no luck -> def_val */
        {
            PROFILE_CopyEntry(buffer, def_val, len, TRUE);
            ret = wcslen(buffer);
        }
        return ret;
    }
    buffer[0] = '\0';
    return 0;
}


/***********************************************************************
 *           PROFILE_SetString
 *
 * Set a profile string.
 */
static BOOL PROFILE_SetString( LPCWSTR section_name, LPCWSTR key_name,
                               LPCWSTR value, BOOL create_always )
{
    if (!key_name)  /* Delete a whole section */
    {
        DPRINT("(%S)\n", section_name);
        CurProfile->changed |= PROFILE_DeleteSection( &CurProfile->section,
                                                      section_name );
        return TRUE;         /* Even if PROFILE_DeleteSection() has failed,
                                this is not an error on application's level.*/
    }
    else if (!value)  /* Delete a key */
    {
        DPRINT("(%S, %S)\n", section_name, key_name);
        CurProfile->changed |= PROFILE_DeleteKey( &CurProfile->section,
                                                  section_name, key_name );
        return TRUE;          /* same error handling as above */
    }
    else  /* Set the key value */
    {
        PROFILEKEY *key = PROFILE_Find(&CurProfile->section, section_name,
                                        key_name, TRUE, create_always );
        DPRINT("(%S, %S, %S):\n",
               section_name, key_name, value);
        if (!key) return FALSE;

        /* strip the leading spaces. We can safely strip \n\r and
         * friends too, they should not happen here anyway. */
        while (PROFILE_isspaceW(*value))  value++;

        if (key->value)
        {
            if (!wcscmp( key->value, value ))
            {
                DPRINT("  no change needed\n" );
                return TRUE;  /* No change needed */
            }
            DPRINT("  replacing %S\n", key->value);
            HeapFree( GetProcessHeap(), 0, key->value );
        }
        else
        {
            DPRINT("  creating key\n");
        }
        key->value = HeapAlloc( GetProcessHeap(), 0, (wcslen(value) + 1) * sizeof(WCHAR) );
        if(key->value == NULL)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
        wcscpy( key->value, value );
        CurProfile->changed = TRUE;
    }
    return TRUE;
}


/********************* API functions **********************************/


/***********************************************************************
 *           GetProfileIntA   (KERNEL32.@)
 */
UINT WINAPI GetProfileIntA( LPCSTR section, LPCSTR entry, INT def_val )
{
    return GetPrivateProfileIntA( section, entry, def_val, "win.ini" );
}

/***********************************************************************
 *           GetProfileIntW   (KERNEL32.@)
 */
UINT WINAPI GetProfileIntW( LPCWSTR section, LPCWSTR entry, INT def_val )
{
    return GetPrivateProfileIntW( section, entry, def_val, L"win.ini" );
}

/*
 * if win32, copy:
 *   - Section names if 'section' is NULL
 *   - Keys in a Section if 'entry' is NULL
 * (see MSDN doc for GetPrivateProfileString)
 */
static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
                   LPCWSTR def_val, LPWSTR buffer,
                   UINT len, LPCWSTR filename,
		   BOOL win32 )
{
    int     ret;
    LPCWSTR pDefVal = NULL;

    if (!filename)
        filename = L"win.ini";

    DPRINT("%S, %S, %S, %p, %u, %S\n",
           section, entry,
           def_val, buffer, len, filename);

    /* strip any trailing ' ' of def_val. */
    if (def_val)
    {
        LPCWSTR p = &def_val[wcslen(def_val)]; /* even "" works ! */

        while (p > def_val)
        {
            p--;
            if ((*p) != ' ')
                break;
        }

        if (*p == ' ') /* ouch, contained trailing ' ' */
        {
           int len = (int)(p - def_val);
           LPWSTR p;

           p = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
           if(p == NULL)
           {
               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
               return FALSE;
           }
           memcpy(p, def_val, len * sizeof(WCHAR));
           p[len] = '\0';
           pDefVal = p;
        }
    }

    if (!pDefVal)
        pDefVal = (LPCWSTR)def_val;

    RtlEnterCriticalSection( &PROFILE_CritSect );

    if (PROFILE_Open( filename )) {
        if (win32 && (section == NULL))
            ret = PROFILE_GetSectionNames(buffer, len);
        else
            /* PROFILE_GetString can handle the 'entry == NULL' case */
            ret = PROFILE_GetString( section, entry, pDefVal, buffer, len, win32 );
    } else {
       lstrcpynW( buffer, pDefVal, len );
       ret = wcslen( buffer );
    }

    RtlLeaveCriticalSection( &PROFILE_CritSect );

    if (pDefVal != def_val) /* allocated */
        HeapFree(GetProcessHeap(), 0, (void*)pDefVal);

    DPRINT("returning %S, %d\n", buffer, ret);

    return ret;
}


/***********************************************************************
 *           GetPrivateProfileStringA   (KERNEL32.@)
 */
DWORD WINAPI GetPrivateProfileStringA( LPCSTR section, LPCSTR entry,
                 LPCSTR def_val, LPSTR buffer,
                 DWORD len, LPCSTR filename )
{
    UNICODE_STRING sectionW, entryW, def_valW, filenameW;
    LPWSTR bufferW;
    INT retW, ret = 0;

    bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
    if (section) RtlCreateUnicodeStringFromAsciiz(&sectionW, section);
    else sectionW.Buffer = NULL;
    if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
    else entryW.Buffer = NULL;
    if (def_val) RtlCreateUnicodeStringFromAsciiz(&def_valW, def_val);
    else def_valW.Buffer = NULL;
    if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
    else filenameW.Buffer = NULL;

    retW = GetPrivateProfileStringW( sectionW.Buffer, entryW.Buffer,
                                     def_valW.Buffer, bufferW, len,
                                     filenameW.Buffer);
    if (len)
    {
        ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 1, buffer, len, NULL, NULL);
        if (!ret)
        {
            ret = len - 1;
            buffer[ret] = 0;
        }
        else
            ret--; /* strip terminating 0 */
    }

    RtlFreeUnicodeString(&sectionW);
    RtlFreeUnicodeString(&entryW);
    RtlFreeUnicodeString(&def_valW);
    RtlFreeUnicodeString(&filenameW);
    HeapFree(GetProcessHeap(), 0, bufferW);
    return ret;
}


/***********************************************************************
 *           GetPrivateProfileStringW   (KERNEL32.@)
 */
DWORD WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
                 LPCWSTR def_val, LPWSTR buffer,
                 DWORD len, LPCWSTR filename )
{
    DPRINT("(%S, %S, %S, %p, %d, %S)\n",
           section, entry, def_val, buffer, len, filename);

    return PROFILE_GetPrivateProfileString( section, entry, def_val,
                                            buffer, len, filename, TRUE );
}


/***********************************************************************
 *           GetProfileStringA   (KERNEL32.@)
 */
DWORD WINAPI GetProfileStringA( LPCSTR section, LPCSTR entry, LPCSTR def_val,
               LPSTR buffer, DWORD len )
{
    return GetPrivateProfileStringA( section, entry, def_val,
                                     buffer, len, "win.ini" );
}


/***********************************************************************
 *           GetProfileStringW   (KERNEL32.@)
 */
DWORD WINAPI GetProfileStringW( LPCWSTR section, LPCWSTR entry,
               LPCWSTR def_val, LPWSTR buffer, DWORD len )
{
    return GetPrivateProfileStringW( section, entry, def_val,
                                     buffer, len, L"win.ini" );
}

/***********************************************************************
 *           WriteProfileStringA   (KERNEL32.@)
 */
BOOL WINAPI WriteProfileStringA( LPCSTR section, LPCSTR entry,
             LPCSTR string )
{
    return WritePrivateProfileStringA( section, entry, string, "win.ini" );
}

/***********************************************************************
 *           WriteProfileStringW   (KERNEL32.@)
 */
BOOL WINAPI WriteProfileStringW( LPCWSTR section, LPCWSTR entry,
                                     LPCWSTR string )
{
    return WritePrivateProfileStringW( section, entry, string, L"win.ini" );
}


/***********************************************************************
 *           GetPrivateProfileIntW   (KERNEL32.@)
 */
UINT WINAPI GetPrivateProfileIntW( LPCWSTR section, LPCWSTR entry,
                                   INT def_val, LPCWSTR filename )
{
    WCHAR buffer[30];
    UNICODE_STRING bufferW;
    INT len;
    ULONG result;

    if (!(len = GetPrivateProfileStringW( section, entry, emptystringW,
                                          buffer, sizeof(buffer)/sizeof(WCHAR),
                                          filename )))
        return def_val;

    if (len+1 == sizeof(buffer)/sizeof(WCHAR))
        DPRINT1("result may be wrong!\n");

    /* FIXME: if entry can be found but it's empty, then Win16 is
     * supposed to return 0 instead of def_val ! Difficult/problematic
     * to implement (every other failure also returns zero buffer),
     * thus wait until testing framework avail for making sure nothing
     * else gets broken that way. */
    if (!buffer[0])
        return (UINT)def_val;

    RtlInitUnicodeString( &bufferW, buffer );
    RtlUnicodeStringToInteger( &bufferW, 10, &result);
    return result;
}

/***********************************************************************
 *           GetPrivateProfileIntA   (KERNEL32.@)
 *
 * FIXME: rewrite using unicode
 */
UINT WINAPI GetPrivateProfileIntA( LPCSTR section, LPCSTR entry,
               INT def_val, LPCSTR filename )
{
    UNICODE_STRING entryW, filenameW, sectionW;
    UINT res;
    if(entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
    else entryW.Buffer = NULL;
    if(filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
    else filenameW.Buffer = NULL;
    if(section) RtlCreateUnicodeStringFromAsciiz(&sectionW, section);
    else sectionW.Buffer = NULL;
    res = GetPrivateProfileIntW(sectionW.Buffer, entryW.Buffer, def_val,
                                filenameW.Buffer);
    RtlFreeUnicodeString(&sectionW);
    RtlFreeUnicodeString(&filenameW);
    RtlFreeUnicodeString(&entryW);
    return res;
}


/***********************************************************************
 *           GetPrivateProfileSectionW   (KERNEL32.@)
 */
DWORD WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
                  DWORD len, LPCWSTR filename )
{
    int     ret = 0;

    DPRINT("(%S, %p, %ld, %S)\n",
           section, buffer, len, filename);

    RtlEnterCriticalSection( &PROFILE_CritSect );

    if (PROFILE_Open( filename ))
        ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, TRUE, FALSE);

    RtlLeaveCriticalSection( &PROFILE_CritSect );

    return ret;
}


/***********************************************************************
 *           GetPrivateProfileSectionA   (KERNEL32.@)
 */
DWORD WINAPI GetPrivateProfileSectionA( LPCSTR section, LPSTR buffer,
                                      DWORD len, LPCSTR filename )
{
    UNICODE_STRING sectionW, filenameW;
    LPWSTR bufferW;
    INT retW, ret = 0;

    bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
    if (section) RtlCreateUnicodeStringFromAsciiz(&sectionW, section);
    else sectionW.Buffer = NULL;
    if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
    else filenameW.Buffer = NULL;

    retW = GetPrivateProfileSectionW(sectionW.Buffer, bufferW, len, filenameW.Buffer);
    if (len > 2)
    {
        ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 2, buffer, len, NULL, NULL);
        if (ret > 2)
            ret -= 2;
        else
        {
            ret = 0;
            buffer[len-2] = 0;
            buffer[len-1] = 0;
        }
    }
    else
    {
        buffer[0] = 0;
        buffer[1] = 0;
    }

    RtlFreeUnicodeString(&sectionW);
    RtlFreeUnicodeString(&filenameW);
    HeapFree(GetProcessHeap(), 0, bufferW);
    return ret;
}

/***********************************************************************
 *           GetProfileSectionA   (KERNEL32.@)
 */
DWORD WINAPI GetProfileSectionA( LPCSTR section, LPSTR buffer, DWORD len )
{
    return GetPrivateProfileSectionA( section, buffer, len, "win.ini" );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -