ReactOS 0.4.15-dev-7934-g1dc8d80
format.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "msi.h"
#include "winnls.h"
#include "objbase.h"
#include "oleauto.h"
#include "msipriv.h"
#include "winemsi_s.h"
#include "wine/exception.h"
Include dependency graph for format.c:

Go to the source code of this file.

Classes

struct  _tagFORMAT
 
struct  _tagFORMSTR
 
struct  _tagSTACK
 

Macros

#define COBJMACROS
 
#define FORMAT_NULL   0x0001
 
#define FORMAT_LITERAL   0x0002
 
#define FORMAT_NUMBER   0x0004
 
#define FORMAT_LBRACK   0x0010
 
#define FORMAT_LBRACE   0x0020
 
#define FORMAT_RBRACK   0x0011
 
#define FORMAT_RBRACE   0x0021
 
#define FORMAT_ESCAPE   0x0040
 
#define FORMAT_PROPNULL   0x0080
 
#define FORMAT_ERROR   0x1000
 
#define FORMAT_FAIL   0x2000
 
#define left_type(x)   (x & 0xF0)
 

Typedefs

typedef struct _tagFORMAT FORMAT
 
typedef struct _tagFORMSTR FORMSTR
 
typedef struct _tagSTACK STACK
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
static STACKcreate_stack (void)
 
static void free_stack (STACK *stack)
 
static void stack_push (STACK *stack, FORMSTR *str)
 
static FORMSTRstack_pop (STACK *stack)
 
static FORMSTRstack_find (STACK *stack, int type)
 
static FORMSTRstack_peek (STACK *stack)
 
static LPCWSTR get_formstr_data (FORMAT *format, FORMSTR *str)
 
static WCHARdup_formstr (FORMAT *format, FORMSTR *str, int *ret_len)
 
static WCHARdeformat_index (FORMAT *format, FORMSTR *str, int *ret_len)
 
static WCHARdeformat_property (FORMAT *format, FORMSTR *str, int *ret_len)
 
static WCHARdeformat_component (FORMAT *format, FORMSTR *str, int *ret_len)
 
static WCHARdeformat_file (FORMAT *format, FORMSTR *str, BOOL shortname, int *ret_len)
 
static WCHARdeformat_environment (FORMAT *format, FORMSTR *str, int *ret_len)
 
static WCHARdeformat_literal (FORMAT *format, FORMSTR *str, BOOL *propfound, int *type, int *len)
 
static WCHARbuild_default_format (const MSIRECORD *record)
 
static BOOL format_is_number (WCHAR x)
 
static BOOL format_str_is_number (LPWSTR str)
 
static BOOL format_is_alpha (WCHAR x)
 
static BOOL format_is_literal (WCHAR x)
 
static int format_lex (FORMAT *format, FORMSTR **out)
 
static FORMSTRformat_replace (FORMAT *format, BOOL propfound, BOOL nonprop, int oldsize, int type, WCHAR *replace, int len)
 
static WCHARreplace_stack_group (FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
 
static WCHARreplace_stack_prop (FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
 
static UINT replace_stack (FORMAT *format, STACK *stack, STACK *values)
 
static BOOL verify_format (LPWSTR data)
 
static DWORD deformat_string_internal (MSIPACKAGE *package, LPCWSTR ptr, WCHAR **data, DWORD *len, MSIRECORD *record)
 
UINT MSI_FormatRecordW (MSIPACKAGE *package, MSIRECORD *record, LPWSTR buffer, LPDWORD size)
 
UINT WINAPI MsiFormatRecordW (MSIHANDLE hInstall, MSIHANDLE hRecord, WCHAR *szResult, DWORD *sz)
 
UINT WINAPI MsiFormatRecordA (MSIHANDLE hinst, MSIHANDLE hrec, char *buf, DWORD *sz)
 
DWORD deformat_string (MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 25 of file format.c.

◆ FORMAT_ERROR

#define FORMAT_ERROR   0x1000

Definition at line 52 of file format.c.

◆ FORMAT_ESCAPE

#define FORMAT_ESCAPE   0x0040

Definition at line 50 of file format.c.

◆ FORMAT_FAIL

#define FORMAT_FAIL   0x2000

Definition at line 53 of file format.c.

◆ FORMAT_LBRACE

#define FORMAT_LBRACE   0x0020

Definition at line 47 of file format.c.

◆ FORMAT_LBRACK

#define FORMAT_LBRACK   0x0010

Definition at line 46 of file format.c.

◆ FORMAT_LITERAL

#define FORMAT_LITERAL   0x0002

Definition at line 44 of file format.c.

◆ FORMAT_NULL

#define FORMAT_NULL   0x0001

Definition at line 43 of file format.c.

◆ FORMAT_NUMBER

#define FORMAT_NUMBER   0x0004

Definition at line 45 of file format.c.

◆ FORMAT_PROPNULL

#define FORMAT_PROPNULL   0x0080

Definition at line 51 of file format.c.

◆ FORMAT_RBRACE

#define FORMAT_RBRACE   0x0021

Definition at line 49 of file format.c.

◆ FORMAT_RBRACK

#define FORMAT_RBRACK   0x0011

Definition at line 48 of file format.c.

◆ left_type

#define left_type (   x)    (x & 0xF0)

Definition at line 55 of file format.c.

Typedef Documentation

◆ FORMAT

◆ FORMSTR

◆ STACK

Function Documentation

◆ build_default_format()

static WCHAR * build_default_format ( const MSIRECORD record)
static

Definition at line 342 of file format.c.

343{
345 WCHAR *ret, *tmp, buf[26];
346 DWORD size = 1;
347
348 if (!(ret = msi_alloc( sizeof(*ret) ))) return NULL;
349 ret[0] = 0;
350
351 for (i = 1; i <= count; i++)
352 {
353 size += swprintf( buf, ARRAY_SIZE(buf), L"%d: [%d] ", i, i );
354 if (!(tmp = msi_realloc( ret, size * sizeof(*ret) )))
355 {
356 msi_free( ret );
357 return NULL;
358 }
359 ret = tmp;
360 lstrcatW( ret, buf );
361 }
362 return ret;
363}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define NULL
Definition: types.h:112
#define swprintf
Definition: precomp.h:40
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
static void msi_free(void *mem)
Definition: msipriv.h:1159
UINT MSI_RecordGetFieldCount(const MSIRECORD *rec) DECLSPEC_HIDDEN
Definition: record.c:108
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
#define L(x)
Definition: ntvdm.h:50
int ret
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MSI_FormatRecordW().

◆ create_stack()

static STACK * create_stack ( void  )
static

Definition at line 84 of file format.c.

85{
86 STACK *stack = msi_alloc(sizeof(STACK));
87 list_init(&stack->items);
88 return stack;
89}
static void list_init(struct list_entry *head)
Definition: list.h:51
Definition: _stack.h:55

Referenced by deformat_string_internal().

◆ deformat_component()

static WCHAR * deformat_component ( FORMAT format,
FORMSTR str,
int ret_len 
)
static

Definition at line 206 of file format.c.

207{
208 WCHAR *key, *ret;
209 MSICOMPONENT *comp;
210
211 if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
213
214 if (!(comp = msi_get_loaded_component( format->package, key )))
215 {
216 msi_free( key );
217 return NULL;
218 }
219 if (comp->Action == INSTALLSTATE_SOURCE)
220 ret = msi_resolve_source_folder( format->package, comp->Directory, NULL );
221 else
222 ret = strdupW( msi_get_target_folder( format->package, comp->Directory ) );
223
224 if (ret) *ret_len = lstrlenW( ret );
225 else *ret_len = 0;
226 msi_free( key );
227 return ret;
228}
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:552
static LPCWSTR get_formstr_data(FORMAT *format, FORMSTR *str)
Definition: format.c:138
WCHAR * msi_resolve_source_folder(MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder)
Definition: install.c:364
const WCHAR * msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name)
Definition: install.c:232
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
@ INSTALLSTATE_SOURCE
Definition: msi.h:47
const WCHAR * str
Definition: copy.c:22
INSTALLSTATE Action
Definition: msipriv.h:533
LPWSTR Directory
Definition: msipriv.h:527

Referenced by deformat_literal().

◆ deformat_environment()

static WCHAR * deformat_environment ( FORMAT format,
FORMSTR str,
int ret_len 
)
static

Definition at line 260 of file format.c.

261{
262 WCHAR *key, *ret = NULL;
263 DWORD len;
264
265 if (!(key = msi_alloc((str->len + 1) * sizeof(WCHAR)))) return NULL;
267
268 if ((len = GetEnvironmentVariableW( key, NULL, 0 )))
269 {
270 len++;
271 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
273 }
274 msi_free( key );
275 return ret;
276}
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
GLenum GLsizei len
Definition: glext.h:6722

Referenced by deformat_literal().

◆ deformat_file()

static WCHAR * deformat_file ( FORMAT format,
FORMSTR str,
BOOL  shortname,
int ret_len 
)
static

Definition at line 230 of file format.c.

231{
232 WCHAR *key, *ret = NULL;
233 const MSIFILE *file;
234 DWORD len = 0;
235
236 if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
238
239 if (!(file = msi_get_loaded_file( format->package, key ))) goto done;
240 if (!shortname)
241 {
242 if ((ret = strdupW( file->TargetPath ))) len = lstrlenW( ret );
243 goto done;
244 }
245 if (!(len = GetShortPathNameW(file->TargetPath, NULL, 0)))
246 {
247 if ((ret = strdupW( file->TargetPath ))) len = lstrlenW( ret );
248 goto done;
249 }
250 len++;
251 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
252 len = GetShortPathNameW( file->TargetPath, ret, len );
253
254done:
255 msi_free( key );
256 *ret_len = len;
257 return ret;
258}
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:574
Definition: fci.c:127

Referenced by deformat_literal().

◆ deformat_index()

static WCHAR * deformat_index ( FORMAT format,
FORMSTR str,
int ret_len 
)
static

Definition at line 157 of file format.c.

158{
159 WCHAR *val, *ret;
160 DWORD len;
161 int field;
162
163 if (!(val = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
165 field = wcstol( val, NULL, 10 );
166 msi_free( val );
167
168 if (MSI_RecordIsNull( format->record, field ) ||
169 MSI_RecordGetStringW( format->record, field, NULL, &len )) return NULL;
170
171 len++;
172 if (!(ret = msi_alloc( len * sizeof(WCHAR) ))) return NULL;
173 ret[0] = 0;
174 if (MSI_RecordGetStringW( format->record, field, ret, &len ))
175 {
176 msi_free( ret );
177 return NULL;
178 }
179 *ret_len = len;
180 return ret;
181}
GLuint GLfloat * val
Definition: glext.h:7180
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
UINT MSI_RecordGetStringW(MSIRECORD *, UINT, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
BOOL MSI_RecordIsNull(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:321
Definition: parser.c:44

Referenced by replace_stack_prop().

◆ deformat_literal()

static WCHAR * deformat_literal ( FORMAT format,
FORMSTR str,
BOOL propfound,
int type,
int len 
)
static

Definition at line 278 of file format.c.

280{
282 WCHAR *replaced = NULL;
283 char ch = data[0];
284
285 if (ch == '\\')
286 {
287 str->n++;
288 if (str->len == 1)
289 {
290 str->len = 0;
291 replaced = NULL;
292 }
293 else
294 {
295 str->len = 1;
296 replaced = dup_formstr( format, str, len );
297 }
298 }
299 else if (ch == '~')
300 {
301 if (str->len != 1)
302 replaced = NULL;
303 else if ((replaced = msi_alloc( sizeof(WCHAR) )))
304 {
305 *replaced = 0;
306 *len = 0;
307 }
308 }
309 else if (ch == '%' || ch == '#' || ch == '!' || ch == '$')
310 {
311 str->n++;
312 str->len--;
313
314 switch (ch)
315 {
316 case '%':
317 replaced = deformat_environment( format, str, len ); break;
318 case '#':
319 replaced = deformat_file( format, str, FALSE, len ); break;
320 case '!':
321 replaced = deformat_file( format, str, TRUE, len ); break;
322 case '$':
323 replaced = deformat_component( format, str, len ); break;
324 }
325
327 }
328 else
329 {
330 replaced = deformat_property( format, str, len );
332
333 if (replaced)
334 *propfound = TRUE;
335 else
336 format->propfailed = TRUE;
337 }
338
339 return replaced;
340}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FORMAT_LITERAL
Definition: format.c:44
static WCHAR * deformat_property(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:183
static WCHAR * deformat_environment(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:260
static WCHAR * deformat_component(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:206
static WCHAR * dup_formstr(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:143
static WCHAR * deformat_file(FORMAT *format, FORMSTR *str, BOOL shortname, int *ret_len)
Definition: format.c:230
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by replace_stack_prop().

◆ deformat_property()

static WCHAR * deformat_property ( FORMAT format,
FORMSTR str,
int ret_len 
)
static

Definition at line 183 of file format.c.

184{
185 WCHAR *prop, *ret;
186 DWORD len = 0;
187 UINT r;
188
189 if (!(prop = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
190 lstrcpynW( prop, get_formstr_data(format, str), str->len + 1 );
191
192 r = msi_get_property( format->package->db, prop, NULL, &len );
193 if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
194 {
195 msi_free( prop );
196 return NULL;
197 }
198 len++;
199 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
200 msi_get_property( format->package->db, prop, ret, &len );
201 msi_free( prop );
202 *ret_len = len;
203 return ret;
204}
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_SUCCESS
Definition: deptool.c:10
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
Definition: package.c:2250
unsigned int UINT
Definition: ndis.h:50

Referenced by deformat_literal().

◆ deformat_string()

DWORD deformat_string ( MSIPACKAGE package,
const WCHAR fmt,
WCHAR **  data 
)

Definition at line 1016 of file format.c.

1017{
1018 DWORD len;
1019 MSIRECORD *rec;
1020
1021 *data = NULL;
1022 if (!fmt) return 0;
1023 if (!(rec = MSI_CreateRecord( 1 ))) return 0;
1024
1025 MSI_RecordSetStringW( rec, 0, fmt );
1026 MSI_FormatRecordW( package, rec, NULL, &len );
1027 if (!(*data = msi_alloc( ++len * sizeof(WCHAR) )))
1028 {
1029 msiobj_release( &rec->hdr );
1030 return 0;
1031 }
1032 MSI_FormatRecordW( package, rec, *data, &len );
1033 msiobj_release( &rec->hdr );
1034 return len;
1035}
UINT MSI_FormatRecordW(MSIPACKAGE *package, MSIRECORD *record, LPWSTR buffer, LPDWORD size)
Definition: format.c:838
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
Definition: dsound.c:943
MSIOBJECTHDR hdr
Definition: msipriv.h:151

Referenced by ACTION_CustomAction(), dialog_create_window(), dialog_handle_event(), expand_any_path(), HANDLE_CustomType18(), HANDLE_CustomType19(), HANDLE_CustomType2(), HANDLE_CustomType34(), HANDLE_CustomType50(), internal_ui_handler(), ITERATE_BindImage(), ITERATE_CreateShortcuts(), ITERATE_DeleteService(), ITERATE_InstallService(), ITERATE_LaunchConditions(), iterate_load_verb(), ITERATE_RemoveEnvironmentString(), ITERATE_RemoveExistingProducts(), ITERATE_RemoveIniValuesOnInstall(), ITERATE_RemoveIniValuesOnUninstall(), ITERATE_RemoveRegistryValuesOnInstall(), ITERATE_RemoveRegistryValuesOnUninstall(), ITERATE_StartService(), ITERATE_StopService(), ITERATE_WriteEnvironmentString(), ITERATE_WriteIniValues(), ITERATE_WriteRegistryValues(), load_appid(), load_class(), msi_dialog_send_event(), msi_dialog_set_property_event(), msi_get_deformatted_field(), msi_listview_add_item(), msi_publish_install_properties(), parse_value(), resolve_keypath(), and search_reg().

◆ deformat_string_internal()

static DWORD deformat_string_internal ( MSIPACKAGE package,
LPCWSTR  ptr,
WCHAR **  data,
DWORD len,
MSIRECORD record 
)
static

Definition at line 756 of file format.c.

759{
761 FORMSTR *str = NULL;
762 STACK *stack, *temp;
763 FORMSTR *node;
764 int type;
765
766 if (!ptr)
767 {
768 *data = NULL;
769 *len = 0;
770 return ERROR_SUCCESS;
771 }
772
773 *data = strdupW(ptr);
774 *len = lstrlenW(ptr);
775
776 ZeroMemory(&format, sizeof(FORMAT));
777 format.package = package;
778 format.record = record;
779 format.deformatted = *data;
780 format.len = *len;
781
782 if (!verify_format(*data))
783 return ERROR_SUCCESS;
784
786 temp = create_stack();
787
788 while ((type = format_lex(&format, &str)) != FORMAT_NULL)
789 {
790 if (type == FORMAT_LBRACK || type == FORMAT_LBRACE ||
793 {
794 if (type == FORMAT_LBRACE)
795 {
796 format.propfailed = FALSE;
797 format.groups++;
798 }
799 else if (type == FORMAT_ESCAPE &&
801 {
802 format.n -= str->len - 1;
803 str->len = 1;
804 }
805
807 }
808 else if (type == FORMAT_RBRACK || type == FORMAT_RBRACE)
809 {
810 if (type == FORMAT_RBRACE)
811 format.groups--;
812
814
816 {
817 do
818 {
821 } while (node->type != left_type(type));
822
824 }
825 }
826 }
827
828 *data = format.deformatted;
829 *len = format.len;
830
831 msi_free(str);
834
835 return ERROR_SUCCESS;
836}
#define FORMAT_NULL
Definition: format.c:43
static FORMSTR * stack_find(STACK *stack, int type)
Definition: format.c:120
static STACK * create_stack(void)
Definition: format.c:84
static BOOL verify_format(LPWSTR data)
Definition: format.c:736
#define FORMAT_PROPNULL
Definition: format.c:51
#define FORMAT_LBRACK
Definition: format.c:46
#define FORMAT_LBRACE
Definition: format.c:47
#define left_type(x)
Definition: format.c:55
static void free_stack(STACK *stack)
Definition: format.c:91
static FORMSTR * stack_pop(STACK *stack)
Definition: format.c:108
static void stack_push(STACK *stack, FORMSTR *str)
Definition: format.c:103
#define FORMAT_ESCAPE
Definition: format.c:50
#define FORMAT_NUMBER
Definition: format.c:45
#define FORMAT_RBRACE
Definition: format.c:49
static UINT replace_stack(FORMAT *format, STACK *stack, STACK *values)
Definition: format.c:679
#define FORMAT_RBRACK
Definition: format.c:48
static int format_lex(FORMAT *format, FORMSTR **out)
Definition: format.c:392
static PVOID ptr
Definition: dispmode.c:27
static calc_node_t temp
Definition: rpn_ieee.c:38
Definition: dlist.c:348
#define ZeroMemory
Definition: winbase.h:1712

Referenced by MSI_FormatRecordW().

◆ dup_formstr()

static WCHAR * dup_formstr ( FORMAT format,
FORMSTR str,
int ret_len 
)
static

Definition at line 143 of file format.c.

144{
145 WCHAR *val;
146
147 if (!str->len) return NULL;
148 if ((val = msi_alloc( (str->len + 1) * sizeof(WCHAR) )))
149 {
150 memcpy( val, get_formstr_data(format, str), str->len * sizeof(WCHAR) );
151 val[str->len] = 0;
152 *ret_len = str->len;
153 }
154 return val;
155}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by deformat_literal(), replace_stack_group(), and replace_stack_prop().

◆ format_is_alpha()

static BOOL format_is_alpha ( WCHAR  x)
static

Definition at line 381 of file format.c.

382{
383 return (!format_is_number(x) && x != '\0' &&
384 x != '[' && x != ']' && x != '{' && x != '}');
385}
static BOOL format_is_number(WCHAR x)
Definition: format.c:365
GLint GLint GLint GLint GLint x
Definition: gl.h:1548

Referenced by format_is_literal(), and format_lex().

◆ format_is_literal()

static BOOL format_is_literal ( WCHAR  x)
static

Definition at line 387 of file format.c.

388{
389 return (format_is_alpha(x) || format_is_number(x));
390}
static BOOL format_is_alpha(WCHAR x)
Definition: format.c:381

Referenced by format_lex().

◆ format_is_number()

static BOOL format_is_number ( WCHAR  x)
static

Definition at line 365 of file format.c.

366{
367 return ((x >= '0') && (x <= '9'));
368}

Referenced by format_is_alpha(), format_is_literal(), format_lex(), and format_str_is_number().

◆ format_lex()

static int format_lex ( FORMAT format,
FORMSTR **  out 
)
static

Definition at line 392 of file format.c.

393{
394 int type, len = 1;
395 FORMSTR *str;
397 WCHAR ch;
398
399 *out = NULL;
400
401 if (!format->deformatted)
402 return FORMAT_NULL;
403
404 *out = msi_alloc_zero(sizeof(FORMSTR));
405 if (!*out)
406 return FORMAT_FAIL;
407
408 str = *out;
409 str->n = format->n;
410 str->len = 1;
412
413 ch = data[0];
414 switch (ch)
415 {
416 case '{': type = FORMAT_LBRACE; break;
417 case '}': type = FORMAT_RBRACE; break;
418 case '[': type = FORMAT_LBRACK; break;
419 case ']': type = FORMAT_RBRACK; break;
420 case '~': type = FORMAT_PROPNULL; break;
421 case '\0': type = FORMAT_NULL; break;
422
423 default:
424 type = 0;
425 }
426
427 if (type)
428 {
429 str->type = type;
430 format->n++;
431 return type;
432 }
433
434 if (ch == '\\')
435 {
436 while (data[len] && data[len] != ']')
437 len++;
438
440 }
441 else if (format_is_alpha(ch))
442 {
443 while (format_is_literal(data[len]))
444 len++;
445
447 }
448 else if (format_is_number(ch))
449 {
450 while (format_is_number(data[len]))
451 len++;
452
454
455 if (data[len] != ']')
456 {
457 while (format_is_literal(data[len]))
458 len++;
459
461 }
462 }
463 else
464 {
465 ERR("Got unknown character %c(%x)\n", ch, ch);
466 return FORMAT_ERROR;
467 }
468
469 format->n += len;
470 str->len = len;
471 str->type = type;
472
473 return type;
474}
#define ERR(fmt,...)
Definition: debug.h:110
static BOOL format_is_literal(WCHAR x)
Definition: format.c:387
#define FORMAT_ERROR
Definition: format.c:52
#define FORMAT_FAIL
Definition: format.c:53
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
static FILE * out
Definition: regtests2xml.c:44

Referenced by deformat_string_internal().

◆ format_replace()

static FORMSTR * format_replace ( FORMAT format,
BOOL  propfound,
BOOL  nonprop,
int  oldsize,
int  type,
WCHAR replace,
int  len 
)
static

Definition at line 476 of file format.c.

478{
479 FORMSTR *ret;
480 LPWSTR str, ptr;
481 DWORD size = 0;
482 int n;
483
484 if (replace)
485 {
486 if (!len)
487 size = 1;
488 else
489 size = len;
490 }
491
492 size -= oldsize;
493 size = format->len + size + 1;
494
495 if (size <= 1)
496 {
497 msi_free(format->deformatted);
498 format->deformatted = NULL;
499 format->len = 0;
500 return NULL;
501 }
502
503 str = msi_alloc(size * sizeof(WCHAR));
504 if (!str)
505 return NULL;
506
507 str[0] = '\0';
508 memcpy(str, format->deformatted, format->n * sizeof(WCHAR));
509 n = format->n;
510
511 if (replace)
512 {
513 if (!len) str[n++] = 0;
514 else
515 {
516 memcpy( str + n, replace, len * sizeof(WCHAR) );
517 n += len;
518 str[n] = 0;
519 }
520 }
521
522 ptr = &format->deformatted[format->n + oldsize];
523 memcpy(&str[n], ptr, (lstrlenW(ptr) + 1) * sizeof(WCHAR));
524
525 msi_free(format->deformatted);
526 format->deformatted = str;
527 format->len = size - 1;
528
529 /* don't reformat the NULL */
530 if (replace && !len)
531 format->n++;
532
533 if (!replace)
534 return NULL;
535
536 ret = msi_alloc_zero(sizeof(FORMSTR));
537 if (!ret)
538 return NULL;
539
540 ret->len = len;
541 ret->type = type;
542 ret->n = format->n;
543 ret->propfound = propfound;
544 ret->nonprop = nonprop;
545
546 return ret;
547}
GLdouble n
Definition: glext.h:7729
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:47
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by replace_stack().

◆ format_str_is_number()

static BOOL format_str_is_number ( LPWSTR  str)
static

Definition at line 370 of file format.c.

371{
372 LPWSTR ptr;
373
374 for (ptr = str; *ptr; ptr++)
375 if (!format_is_number(*ptr))
376 return FALSE;
377
378 return TRUE;
379}

Referenced by replace_stack_prop().

◆ free_stack()

static void free_stack ( STACK stack)
static

Definition at line 91 of file format.c.

92{
93 while (!list_empty(&stack->items))
94 {
96 list_remove(&str->entry);
98 }
99
101}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
uint32_t entry
Definition: isohybrid.c:63
Definition: list.h:15
#define LIST_ENTRY(type)
Definition: queue.h:175

Referenced by deformat_string_internal().

◆ get_formstr_data()

static LPCWSTR get_formstr_data ( FORMAT format,
FORMSTR str 
)
static

Definition at line 138 of file format.c.

139{
140 return &format->deformatted[str->n];
141}

Referenced by deformat_component(), deformat_environment(), deformat_file(), deformat_index(), deformat_literal(), deformat_property(), dup_formstr(), and format_lex().

◆ MSI_FormatRecordW()

UINT MSI_FormatRecordW ( MSIPACKAGE package,
MSIRECORD record,
LPWSTR  buffer,
LPDWORD  size 
)

Definition at line 838 of file format.c.

840{
841 WCHAR *format, *deformated = NULL;
843 DWORD len;
844 MSIRECORD *record_deformated;
845 int field_count, i;
846
847 TRACE("%p %p %p %p\n", package, record, buffer, size);
849
850 if (!(format = msi_dup_record_field( record, 0 )))
852
853 field_count = MSI_RecordGetFieldCount(record);
854 record_deformated = MSI_CloneRecord(record);
855 if (!record_deformated)
856 {
858 goto end;
859 }
860 MSI_RecordSetStringW(record_deformated, 0, format);
861 for (i = 1; i <= field_count; i++)
862 {
864 {
865 deformat_string_internal(package, MSI_RecordGetString(record, i), &deformated, &len, NULL);
866 MSI_RecordSetStringW(record_deformated, i, deformated);
867 msi_free(deformated);
868 }
869 }
870
871 deformat_string_internal(package, format, &deformated, &len, record_deformated);
872 if (buffer)
873 {
874 if (*size>len)
875 {
876 memcpy(buffer,deformated,len*sizeof(WCHAR));
877 rc = ERROR_SUCCESS;
878 buffer[len] = 0;
879 }
880 else
881 {
882 if (*size > 0)
883 {
884 memcpy(buffer,deformated,(*size)*sizeof(WCHAR));
885 buffer[(*size)-1] = 0;
886 }
887 rc = ERROR_MORE_DATA;
888 }
889 }
890 else rc = ERROR_SUCCESS;
891
892 *size = len;
893 msiobj_release(&record_deformated->hdr);
894end:
895 msi_free( format );
896 msi_free( deformated );
897 return rc;
898}
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, WCHAR **data, DWORD *len, MSIRECORD *record)
Definition: format.c:756
static WCHAR * build_default_format(const MSIRECORD *record)
Definition: format.c:342
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1002
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
MSIRECORD * MSI_CloneRecord(MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:921
void dump_record(MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:1028
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by deformat_string(), MSI_ProcessMessageVerbatim(), MsiFormatRecordA(), and MsiFormatRecordW().

◆ MsiFormatRecordA()

UINT WINAPI MsiFormatRecordA ( MSIHANDLE  hinst,
MSIHANDLE  hrec,
char buf,
DWORD sz 
)

Definition at line 955 of file format.c.

956{
957 MSIPACKAGE *package;
958 MSIRECORD *rec;
960 DWORD len;
961 UINT r;
962
963 TRACE( "%lu, %lu, %p, %p\n", hinst, hrec, buf, sz );
964
966 if (!rec)
968
969 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
970 if (!package)
971 {
972 LPWSTR value = NULL;
973 MSIHANDLE remote;
974
975 if ((remote = msi_get_remote(hinst)))
976 {
977 __TRY
978 {
979 r = remote_FormatRecord(remote, (struct wire_record *)&rec->count, &value);
980 }
982 {
984 }
986
987 if (!r)
988 r = msi_strncpyWtoA(value, -1, buf, sz, TRUE);
989
991 msiobj_release(&rec->hdr);
992 return r;
993 }
994 }
995
996 r = MSI_FormatRecordW(package, rec, NULL, &len);
997 if (r != ERROR_SUCCESS)
998 return r;
999
1000 value = msi_alloc(++len * sizeof(WCHAR));
1001 if (!value)
1002 goto done;
1003
1004 r = MSI_FormatRecordW(package, rec, value, &len);
1005 if (!r)
1006 r = msi_strncpyWtoA(value, len, buf, sz, FALSE);
1007
1008 msi_free(value);
1009done:
1010 msiobj_release(&rec->hdr);
1011 if (package) msiobj_release(&package->hdr);
1012 return r;
1013}
#define __TRY
Definition: compat.h:80
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define __ENDTRY
Definition: compat.h:82
LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr)
Definition: custom.c:85
MSIHANDLE msi_get_remote(MSIHANDLE handle)
Definition: handle.c:183
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
Definition: handle.c:158
UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remote)
Definition: install.c:190
static HINSTANCE hinst
Definition: edit.c:551
#define MSIHANDLETYPE_RECORD
Definition: msipriv.h:725
#define __EXCEPT(func)
Definition: exception.h:84
#define midl_user_free
Definition: rpc.h:45
#define GetExceptionCode()
Definition: seh.h:27
MSIOBJECTHDR hdr
Definition: msipriv.h:393
UINT count
Definition: msipriv.h:152
Definition: pdh_main.c:94
unsigned long MSIHANDLE
Definition: winemsi.idl:27

Referenced by query_file_path(), test_format_record(), test_formatrecord(), test_formatrecord2(), test_formatrecord_package(), and test_formatrecord_tables().

◆ MsiFormatRecordW()

UINT WINAPI MsiFormatRecordW ( MSIHANDLE  hInstall,
MSIHANDLE  hRecord,
WCHAR szResult,
DWORD sz 
)

Definition at line 900 of file format.c.

901{
903 MSIPACKAGE *package;
905
906 TRACE( "%lu, %lu, %p, %p\n", hInstall, hRecord, szResult, sz );
907
909 if (!record)
911
912 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
913 if (!package)
914 {
915 LPWSTR value = NULL;
916 MSIHANDLE remote;
917
918 if ((remote = msi_get_remote(hInstall)))
919 {
920 __TRY
921 {
922 r = remote_FormatRecord(remote, (struct wire_record *)&record->count, &value);
923 }
925 {
927 }
929
930 if (!r)
931 r = msi_strncpyW(value, -1, szResult, sz);
932
934 msiobj_release(&record->hdr);
935 return r;
936 }
937 }
938
939 if (!sz)
940 {
941 msiobj_release( &record->hdr );
942 if (szResult)
944 else
945 return ERROR_SUCCESS;
946 }
947
948 r = MSI_FormatRecordW( package, record, szResult, sz );
949 msiobj_release( &record->hdr );
950 if (package)
951 msiobj_release( &package->hdr );
952 return r;
953}
UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz)
Definition: install.c:213

Referenced by s_remote_FormatRecord(), and test_format_record().

◆ replace_stack()

static UINT replace_stack ( FORMAT format,
STACK stack,
STACK values 
)
static

Definition at line 679 of file format.c.

680{
681 WCHAR *replaced = NULL;
682 FORMSTR *beg, *top, *node;
683 BOOL propfound = FALSE, nonprop = FALSE, group = FALSE;
684 int type, n, len = 0, oldsize = 0;
685
687 type = node->type;
688 n = node->n;
689
690 if (type == FORMAT_LBRACK)
691 replaced = replace_stack_prop( format, values, &propfound,
692 &nonprop, &oldsize, &type, &len );
693 else if (type == FORMAT_LBRACE)
694 {
695 replaced = replace_stack_group( format, values, &propfound,
696 &nonprop, &oldsize, &type, &len );
697 group = TRUE;
698 }
699
700 format->n = n;
701 beg = format_replace( format, propfound, nonprop, oldsize, type, replaced, len );
702 msi_free(replaced);
703 if (!beg)
704 return ERROR_SUCCESS;
705
706 format->n = beg->n + beg->len;
707
709 if (top)
710 {
711 type = top->type;
712
713 if ((type == FORMAT_LITERAL || type == FORMAT_NUMBER) &&
714 type == beg->type)
715 {
716 top->len += beg->len;
717
718 if (group)
719 top->nonprop = FALSE;
720
721 if (type == FORMAT_LITERAL)
722 top->nonprop = beg->nonprop;
723
724 if (beg->propfound)
725 top->propfound = TRUE;
726
727 msi_free(beg);
728 return ERROR_SUCCESS;
729 }
730 }
731
732 stack_push(stack, beg);
733 return ERROR_SUCCESS;
734}
static WCHAR * replace_stack_prop(FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
Definition: format.c:619
static FORMSTR * stack_peek(STACK *stack)
Definition: format.c:133
static FORMSTR * format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, int oldsize, int type, WCHAR *replace, int len)
Definition: format.c:476
static WCHAR * replace_stack_group(FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
Definition: format.c:549
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLboolean GLuint group
Definition: glext.h:11120
int n
Definition: format.c:72
BOOL nonprop
Definition: format.c:76
int type
Definition: format.c:74
BOOL propfound
Definition: format.c:75
int len
Definition: format.c:73

Referenced by deformat_string_internal().

◆ replace_stack_group()

static WCHAR * replace_stack_group ( FORMAT format,
STACK values,
BOOL propfound,
BOOL nonprop,
int oldsize,
int type,
int len 
)
static

Definition at line 549 of file format.c.

552{
553 WCHAR *replaced;
555 int n;
556
557 *nonprop = FALSE;
558 *propfound = FALSE;
559
561 n = node->n;
562 *oldsize = node->len;
563 msi_free(node);
564
565 while ((node = stack_pop(values)))
566 {
567 *oldsize += node->len;
568
569 if (node->nonprop)
570 *nonprop = TRUE;
571
572 if (node->propfound)
573 *propfound = TRUE;
574
575 msi_free(node);
576 }
577
578 content = msi_alloc_zero(sizeof(FORMSTR));
579 content->n = n;
580 content->len = *oldsize;
581 content->type = FORMAT_LITERAL;
582
583 if (!format->groupfailed && (*oldsize == 2 ||
584 (format->propfailed && !*nonprop)))
585 {
587 return NULL;
588 }
589 else if (format->deformatted[content->n + 1] == '{' &&
590 format->deformatted[content->n + content->len - 2] == '}')
591 {
592 format->groupfailed = FALSE;
593 content->len = 0;
594 }
595 else if (*propfound && !*nonprop &&
596 !format->groupfailed && format->groups == 0)
597 {
598 content->n++;
599 content->len -= 2;
600 }
601 else
602 {
603 if (format->groups != 0)
604 format->groupfailed = TRUE;
605
606 *nonprop = TRUE;
607 }
608
609 replaced = dup_formstr( format, content, len );
610 *type = content->type;
612
613 if (format->groups == 0)
614 format->propfailed = FALSE;
615
616 return replaced;
617}
content
Definition: atl_ax.c:994

Referenced by replace_stack().

◆ replace_stack_prop()

static WCHAR * replace_stack_prop ( FORMAT format,
STACK values,
BOOL propfound,
BOOL nonprop,
int oldsize,
int type,
int len 
)
static

Definition at line 619 of file format.c.

622{
623 WCHAR *replaced;
625 int n;
626
627 *propfound = FALSE;
628 *nonprop = FALSE;
629
631 n = node->n;
632 *oldsize = node->len;
634 msi_free(node);
635
636 while ((node = stack_pop(values)))
637 {
638 *oldsize += node->len;
639
640 if (*type != FORMAT_ESCAPE &&
641 stack_peek(values) && node->type != *type)
643
644 msi_free(node);
645 }
646
647 content = msi_alloc_zero(sizeof(FORMSTR));
648 content->n = n + 1;
649 content->len = *oldsize - 2;
650 content->type = *type;
651
652 if (*type == FORMAT_NUMBER && format->record)
653 {
654 replaced = deformat_index( format, content, len );
655 if (replaced)
656 *propfound = TRUE;
657 else
658 format->propfailed = TRUE;
659
660 if (replaced)
661 *type = format_str_is_number(replaced) ?
663 }
664 else if (format->package)
665 {
666 replaced = deformat_literal( format, content, propfound, type, len );
667 }
668 else
669 {
670 *nonprop = TRUE;
671 content->n--;
672 content->len += 2;
673 replaced = dup_formstr( format, content, len );
674 }
676 return replaced;
677}
static WCHAR * deformat_literal(FORMAT *format, FORMSTR *str, BOOL *propfound, int *type, int *len)
Definition: format.c:278
static BOOL format_str_is_number(LPWSTR str)
Definition: format.c:370
static WCHAR * deformat_index(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:157

Referenced by replace_stack().

◆ stack_find()

static FORMSTR * stack_find ( STACK stack,
int  type 
)
static

Definition at line 120 of file format.c.

121{
122 FORMSTR *str;
123
125 {
126 if (str->type == type)
127 return str;
128 }
129
130 return NULL;
131}
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198

Referenced by deformat_string_internal().

◆ stack_peek()

static FORMSTR * stack_peek ( STACK stack)
static

Definition at line 133 of file format.c.

134{
135 return LIST_ENTRY(list_head(&stack->items), FORMSTR, entry);
136}

Referenced by replace_stack(), and replace_stack_prop().

◆ stack_pop()

static FORMSTR * stack_pop ( STACK stack)
static

Definition at line 108 of file format.c.

109{
110 FORMSTR *ret;
111
112 if (list_empty(&stack->items))
113 return NULL;
114
116 list_remove(&ret->entry);
117 return ret;
118}

Referenced by deformat_string_internal(), replace_stack_group(), and replace_stack_prop().

◆ stack_push()

static void stack_push ( STACK stack,
FORMSTR str 
)
static

Definition at line 103 of file format.c.

104{
105 list_add_head(&stack->items, &str->entry);
106}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76

Referenced by deformat_string_internal(), and replace_stack().

◆ verify_format()

static BOOL verify_format ( LPWSTR  data)
static

Definition at line 736 of file format.c.

737{
738 int count = 0;
739
740 while (*data)
741 {
742 if (*data == '[' && *(data - 1) != '\\')
743 count++;
744 else if (*data == ']')
745 count--;
746
747 data++;
748 }
749
750 if (count > 0)
751 return FALSE;
752
753 return TRUE;
754}

Referenced by deformat_string_internal().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )