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

📄 format.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
        *size = sz * sizeof(WCHAR);
        return value;
     }
     else if (failcount < 0)
     {
         LPWSTR v2;

         v2 = msi_alloc((sz+2)*sizeof(WCHAR));
         v2[0] = '{';
         memcpy(&v2[1],value,sz*sizeof(WCHAR));
         v2[sz+1]='}';
         msi_free(value);

         *size = (sz+2)*sizeof(WCHAR);
         return v2;
     }
     else
     {
         msi_free(value);
         *size = 0;
         return NULL;
     }
}


/*
 * len is in WCHARs
 * return is also in WCHARs
 */
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 
                                     WCHAR** data, DWORD len, MSIRECORD* record,
                                     INT* failcount)
{
    LPCWSTR mark = NULL;
    LPCWSTR mark2 = NULL;
    DWORD size=0;
    DWORD chunk=0;
    LPWSTR key;
    LPWSTR value = NULL;
    DWORD sz;
    LPBYTE newdata = NULL;
    const WCHAR* progress = NULL;
    BOOL nested;

    if (ptr==NULL)
    {
        TRACE("Deformatting NULL string\n");
        *data = NULL;
        return 0;
    }

    TRACE("Starting with %s\n",debugstr_wn(ptr,len));

    /* scan for special characters... fast exit */
    if ((!scanW(ptr,'[',len) || (scanW(ptr,'[',len) && !scanW(ptr,']',len))) && 
        (scanW(ptr,'{',len) && !scanW(ptr,'}',len)))
    {
        /* not formatted */
        *data = msi_alloc((len*sizeof(WCHAR)));
        memcpy(*data,ptr,len*sizeof(WCHAR));
        TRACE("Returning %s\n",debugstr_wn(*data,len));
        return len;
    }
  
    progress = ptr;

    while (progress - ptr < len)
    {
        /* seek out first group if existing */
        if (find_next_group(progress, len - (progress - ptr), &key,
                                &mark, &mark2))
        {
            value = deformat_group(package, key, strlenW(key)+1, record, 
                            &chunk);
            msi_free( key );
            key = NULL;
            nested = FALSE;
        }
        /* formatted string located */
        else if (!find_next_outermost_key(progress, len - (progress - ptr), 
                                &key, &mark, &mark2, &nested))
        {
            LPBYTE nd2;

            TRACE("after value %s\n", debugstr_wn((LPWSTR)newdata,
                                    size/sizeof(WCHAR)));
            chunk = (len - (progress - ptr)) * sizeof(WCHAR);
            TRACE("after chunk is %i + %i\n",size,chunk);
            if (size)
                nd2 = msi_realloc(newdata,(size+chunk));
            else
                nd2 = msi_alloc(chunk);

            newdata = nd2;
            memcpy(&newdata[size],progress,chunk);
            size+=chunk;
            break;
        }

        if (mark != progress)
        {
            LPBYTE tgt;
            DWORD old_size = size;
            INT cnt = (mark - progress);
            TRACE("%i  (%i) characters before marker\n",cnt,(mark-progress));
            size += cnt * sizeof(WCHAR);
            if (!old_size)
                tgt = msi_alloc(size);
            else
                tgt = msi_realloc(newdata,size);
            newdata  = tgt;
            memcpy(&newdata[old_size],progress,(cnt * sizeof(WCHAR)));  
        }

        progress = mark;

        if (nested)
        {
            TRACE("Nested key... %s\n",debugstr_w(key));
            deformat_string_internal(package, key, &value, strlenW(key)+1,
                                     record, failcount);

            msi_free(key);
            key = value;
        }

        TRACE("Current %s .. %s\n",debugstr_wn((LPWSTR)newdata, 
                                size/sizeof(WCHAR)),debugstr_w(key));

        if (!package)
        {
            /* only deformat number indexs */
            if (key && is_key_number(key))
            {
                value = deformat_index(record,key,&chunk);  
                if (!chunk && failcount && *failcount >= 0)
                    (*failcount)++;
            }
            else
            {
                if (failcount)
                    *failcount = -1;
                if(key)
                {
                    DWORD keylen = strlenW(key);
                    chunk = (keylen + 2)*sizeof(WCHAR);
                    value = msi_alloc(chunk);
                    value[0] = '[';
                    memcpy(&value[1],key,keylen*sizeof(WCHAR));
                    value[1+keylen] = ']';
                }
            }
        }
        else
        {
            sz = 0;
            if (key) switch (key[0])
            {
                case '~':
                    value = deformat_NULL(&chunk);
                break;
                case '$':
                    value = deformat_component(package,&key[1],&chunk);
                break;
                case '#':
                    value = deformat_file(package,&key[1], &chunk, FALSE);
                break;
                case '!': /* should be short path */
                    value = deformat_file(package,&key[1], &chunk, TRUE);
                break;
                case '\\':
                    value = deformat_escape(&key[1],&chunk);
                break;
                case '%':
                    value = deformat_environment(package,&key[1],&chunk);
                break;
                default:
                    /* index keys cannot be nested */
                    if (is_key_number(key))
                        if (!nested)
                            value = deformat_index(record,key,&chunk);
                        else
                        {
                            static const WCHAR fmt[] = {'[','%','s',']',0};
                            value = msi_alloc(10);
                            sprintfW(value,fmt,key);
                            chunk = strlenW(value)*sizeof(WCHAR);
                        }
                    else
                        value = deformat_property(package,key,&chunk);
                break;      
            }
        }

        msi_free(key);

        if (value!=NULL)
        {
            LPBYTE nd2;
            TRACE("value %s, chunk %i size %i\n",debugstr_w((LPWSTR)value),
                    chunk, size);
            if (size)
                nd2= msi_realloc(newdata,(size + chunk));
            else
                nd2= msi_alloc(chunk);
            newdata = nd2;
            memcpy(&newdata[size],value,chunk);
            size+=chunk;   
            msi_free(value);
        }
        else if (failcount && *failcount >=0 )
            (*failcount)++;

        progress = mark2+1;
    }

    TRACE("after everything %s\n",debugstr_wn((LPWSTR)newdata, 
                            size/sizeof(WCHAR)));

    *data = (LPWSTR)newdata;
    return size / sizeof(WCHAR);
}


UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer,
                        DWORD *size )
{
    LPWSTR deformated;
    LPWSTR rec;
    DWORD len;
    UINT rc = ERROR_INVALID_PARAMETER;

    TRACE("%p %p %p %i\n", package, record ,buffer, *size);

    rec = msi_dup_record_field(record,0);
    if (!rec)
        rec = build_default_format(record);

    TRACE("(%s)\n",debugstr_w(rec));

    len = deformat_string_internal(package,rec,&deformated,strlenW(rec),
                                   record, NULL);

    if (buffer)
    {
        if (*size>len)
        {
            memcpy(buffer,deformated,len*sizeof(WCHAR));
            rc = ERROR_SUCCESS;
            buffer[len] = 0;
        }
        else
        {
            if (*size > 0)
            {
                memcpy(buffer,deformated,(*size)*sizeof(WCHAR));
                buffer[(*size)-1] = 0;
            }
            rc = ERROR_MORE_DATA;
        }
    }
    else
        rc = ERROR_SUCCESS;

    *size = len;

    msi_free(rec);
    msi_free(deformated);
    return rc;
}

UINT MSI_FormatRecordA( MSIPACKAGE* package, MSIRECORD* record, LPSTR buffer,
                        DWORD *size )
{
    LPWSTR deformated;
    LPWSTR rec;
    DWORD len,lenA;
    UINT rc = ERROR_INVALID_PARAMETER;

    TRACE("%p %p %p %i\n", package, record ,buffer, *size);

    rec = msi_dup_record_field(record,0);
    if (!rec)
        rec = build_default_format(record);

    TRACE("(%s)\n",debugstr_w(rec));

    len = deformat_string_internal(package,rec,&deformated,strlenW(rec),
                                   record, NULL);
    /* If len is zero then WideCharToMultiByte will return 0 indicating 
     * failure, but that will do just as well since we are ignoring
     * possible errors.
     */
    lenA = WideCharToMultiByte(CP_ACP,0,deformated,len,NULL,0,NULL,NULL);

    if (buffer)
    {
        /* Ditto above */
        WideCharToMultiByte(CP_ACP,0,deformated,len,buffer,*size,NULL, NULL);
        if (*size>lenA)
        {
            rc = ERROR_SUCCESS;
            buffer[lenA] = 0;
        }
        else
        {
            rc = ERROR_MORE_DATA;
            if (*size)
                buffer[(*size)-1] = 0;
        }
    }
    else
        rc = ERROR_SUCCESS;

    *size = lenA;

    msi_free(rec);
    msi_free(deformated);
    return rc;
}


UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, 
                              LPWSTR szResult, DWORD *sz )
{
    UINT r = ERROR_INVALID_HANDLE;
    MSIPACKAGE *package;
    MSIRECORD *record;

    TRACE("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);

    record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );

    if (!record)
        return ERROR_INVALID_HANDLE;
    if (!sz)
    {
        msiobj_release( &record->hdr );
        if (szResult)
            return ERROR_INVALID_PARAMETER;
        else
            return ERROR_SUCCESS;
    }

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );

    r = MSI_FormatRecordW( package, record, szResult, sz );
    msiobj_release( &record->hdr );
    if (package)
        msiobj_release( &package->hdr );
    return r;
}

UINT WINAPI MsiFormatRecordA( MSIHANDLE hInstall, MSIHANDLE hRecord,
                              LPSTR szResult, DWORD *sz )
{
    UINT r = ERROR_INVALID_HANDLE;
    MSIPACKAGE *package = NULL;
    MSIRECORD *record = NULL;

    TRACE("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);

    record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );

    if (!record)
        return ERROR_INVALID_HANDLE;
    if (!sz)
    {
        msiobj_release( &record->hdr );
        if (szResult)
            return ERROR_INVALID_PARAMETER;
        else
            return ERROR_SUCCESS;
    }

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );

    r = MSI_FormatRecordA( package, record, szResult, sz );
    msiobj_release( &record->hdr );
    if (package)
        msiobj_release( &package->hdr );
    return r;
}

⌨️ 快捷键说明

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