Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/format.c | 59 ++++++++++++++++++++++++++----------------------- dlls/msi/install.c | 23 +++++++++++++++++++ dlls/msi/msipriv.h | 1 + dlls/msi/tests/custom.c | 8 +++---- 4 files changed, 59 insertions(+), 32 deletions(-)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c index 0533cc0..d34fb2b 100644 --- a/dlls/msi/format.c +++ b/dlls/msi/format.c @@ -952,52 +952,55 @@ UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, return r; }
-UINT WINAPI MsiFormatRecordA( MSIHANDLE hInstall, MSIHANDLE hRecord, - LPSTR szResult, LPDWORD sz ) +UINT WINAPI MsiFormatRecordA(MSIHANDLE hinst, MSIHANDLE hrec, char *buf, DWORD *sz) { - UINT r; - DWORD len, save; + MSIPACKAGE *package; + MSIRECORD *rec; LPWSTR value; + DWORD len; + UINT r;
- TRACE("%d %d %p %p\n", hInstall, hRecord, szResult, sz); + TRACE("%d %d %p %p\n", hinst, hrec, buf, sz);
- if (!hRecord) + rec = msihandle2msiinfo(hrec, MSIHANDLETYPE_RECORD); + if (!rec) return ERROR_INVALID_HANDLE;
- if (!sz) + package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE); + if (!package) { - if (szResult) - return ERROR_INVALID_PARAMETER; - else - return ERROR_SUCCESS; + LPWSTR value = NULL; + MSIHANDLE remote; + + if ((remote = msi_get_remote(hinst))) + { + r = remote_FormatRecord(remote, (struct wire_record *)&rec->count, &value); + + if (!r) + r = msi_strncpyWtoA(value, -1, buf, sz, TRUE); + + midl_user_free(value); + msiobj_release(&rec->hdr); + return r; + } }
- r = MsiFormatRecordW( hInstall, hRecord, NULL, &len ); + r = MSI_FormatRecordW(package, rec, NULL, &len); if (r != ERROR_SUCCESS) return r;
value = msi_alloc(++len * sizeof(WCHAR)); if (!value) - return ERROR_OUTOFMEMORY; - - r = MsiFormatRecordW( hInstall, hRecord, value, &len ); - if (r != ERROR_SUCCESS) goto done;
- save = len + 1; - len = WideCharToMultiByte(CP_ACP, 0, value, len + 1, NULL, 0, NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, value, len, szResult, *sz, NULL, NULL); + r = MSI_FormatRecordW(package, rec, value, &len); + if (!r) + r = msi_strncpyWtoA(value, len, buf, sz, FALSE);
- if (szResult && len > *sz) - { - if (*sz) szResult[*sz - 1] = '\0'; - r = ERROR_MORE_DATA; - } - - *sz = save - 1; - -done: msi_free(value); +done: + msiobj_release(&rec->hdr); + if (package) msiobj_release(&package->hdr); return r; }
diff --git a/dlls/msi/install.c b/dlls/msi/install.c index 45c5537..ca277d3 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -168,6 +168,29 @@ UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD * return r; }
+UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remote) +{ + UINT r = ERROR_SUCCESS; + DWORD lenA; + + if (!sz) + return buf ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS; + + if (lenW < 0) lenW = strlenW(str); + lenA = WideCharToMultiByte(CP_ACP, 0, str, lenW + 1, NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, str, lenW + 1, buf, *sz, NULL, NULL); + lenA--; + if (buf && lenA >= *sz) + { + if (*sz) buf[*sz - 1] = 0; + r = ERROR_MORE_DATA; + } + if (remote && lenA >= *sz) + lenA *= 2; + *sz = lenA; + return r; +} + const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name ) { MSIFOLDER *folder = msi_get_loaded_folder( package, name ); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 46cbb43..5c6cd40 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1045,6 +1045,7 @@ extern WCHAR *msi_font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN; extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_get_error_message(MSIDATABASE *, int) DECLSPEC_HIDDEN; +extern UINT msi_strncpyWtoA(const WCHAR *str, int len, char *buf, DWORD *sz, BOOL remote) DECLSPEC_HIDDEN;
/* media */
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 04946d9..320aa6f 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -785,28 +785,28 @@ static void test_format_record(MSIHANDLE hinst) sz = 0; r = MsiFormatRecordA(hinst, rec, NULL, &sz); ok(hinst, !r, "got %u\n", r); - todo_wine_ok(hinst, sz == 14, "got size %u\n", sz); + ok(hinst, sz == 14, "got size %u\n", sz);
sz = 0; strcpy(buffer,"q"); r = MsiFormatRecordA(hinst, rec, buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !strcmp(buffer, "q"), "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 14, "got size %u\n", sz); + ok(hinst, sz == 14, "got size %u\n", sz);
sz = 1; strcpy(buffer,"x"); r = MsiFormatRecordA(hinst, rec, buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !buffer[0], "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 14, "got size %u\n", sz); + ok(hinst, sz == 14, "got size %u\n", sz);
sz = 7; strcpy(buffer,"x"); r = MsiFormatRecordA(hinst, rec, buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !strcmp(buffer, "foo 12"), "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 14, "got size %u\n", sz); + ok(hinst, sz == 14, "got size %u\n", sz);
sz = 8; strcpy(buffer,"x");
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/format.c | 12 +++--------- dlls/msi/install.c | 19 +++++++++++++++++++ dlls/msi/msipriv.h | 1 + dlls/msi/tests/custom.c | 11 +++++++++++ 4 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c index d34fb2b..9356c9e 100644 --- a/dlls/msi/format.c +++ b/dlls/msi/format.c @@ -916,22 +916,16 @@ UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, { LPWSTR value = NULL; MSIHANDLE remote; - awstring wstr;
if ((remote = msi_get_remote(hInstall))) { r = remote_FormatRecord(remote, (struct wire_record *)&record->count, &value); - if (r) - { - midl_user_free(value); - return r; - }
- wstr.unicode = TRUE; - wstr.str.w = szResult; - r = msi_strcpy_to_awstring(value, -1, &wstr, sz); + if (!r) + r = msi_strncpyW(value, -1, szResult, sz);
midl_user_free(value); + msiobj_release(&record->hdr); return r; } } diff --git a/dlls/msi/install.c b/dlls/msi/install.c index ca277d3..b54daff 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -191,6 +191,25 @@ UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remo return r; }
+UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz) +{ + UINT r = ERROR_SUCCESS; + + if (!sz) + return buf ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS; + + if (len < 0) len = strlenW(str); + if (buf) + memcpy(buf, str, min(len + 1, *sz) * sizeof(WCHAR)); + if (buf && len >= *sz) + { + if (*sz) buf[*sz - 1] = 0; + r = ERROR_MORE_DATA; + } + *sz = len; + return r; +} + const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name ) { MSIFOLDER *folder = msi_get_loaded_folder( package, name ); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 5c6cd40..707144f 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1046,6 +1046,7 @@ extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN; extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_get_error_message(MSIDATABASE *, int) DECLSPEC_HIDDEN; extern UINT msi_strncpyWtoA(const WCHAR *str, int len, char *buf, DWORD *sz, BOOL remote) DECLSPEC_HIDDEN; +extern UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz) DECLSPEC_HIDDEN;
/* media */
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 320aa6f..723b2b5 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -815,6 +815,17 @@ static void test_format_record(MSIHANDLE hinst) ok(hinst, !strcmp(buffer, "foo 123"), "got "%s"\n", buffer); ok(hinst, sz == 7, "got size %u\n", sz);
+ r = MsiFormatRecordW(hinst, rec, NULL, NULL); + ok(hinst, !r, "got %u\n", r); + + r = MsiFormatRecordW(hinst, rec, bufferW, NULL); + ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); + + sz = 0; + r = MsiFormatRecordW(hinst, rec, NULL, &sz); + ok(hinst, !r, "got %u\n", r); + ok(hinst, sz == 7, "got size %u\n", sz); + sz = 0; bufferW[0] = 'q'; r = MsiFormatRecordW(hinst, rec, bufferW, &sz);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=38426
Your paranoid android.
=== w7pro64 (64 bit custom) === The previous 1 run(s) terminated abnormally
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/package.c | 54 ++++++++++++++++++++++++++++++++++++++++--------- dlls/msi/tests/custom.c | 6 +++--- 2 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/dlls/msi/package.c b/dlls/msi/package.c index a290904..133bfd8 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2410,22 +2410,58 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, return r; }
-UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName, - LPSTR szValueBuf, LPDWORD pchValueBuf ) +UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz) { + MSIPACKAGE *package; awstring val; - LPWSTR name; + WCHAR *nameW; UINT r;
- val.unicode = FALSE; - val.str.a = szValueBuf; + if (!name) + return ERROR_INVALID_PARAMETER;
- name = strdupAtoW( szName ); - if (szName && !name) + if (!(nameW = strdupAtoW(name))) return ERROR_OUTOFMEMORY;
- r = MSI_GetProperty( hInstall, name, &val, pchValueBuf ); - msi_free( name ); + package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE); + if (!package) + { + WCHAR *value = NULL, *tmp; + MSIHANDLE remote; + DWORD len; + + if (!(remote = msi_get_remote(hinst))) + return ERROR_INVALID_HANDLE; + + r = remote_GetProperty(remote, nameW, &value, &len); + if (!r) + { + /* String might contain embedded nulls. + * Native returns the correct size but truncates the string. */ + tmp = heap_alloc_zero((len + 1) * sizeof(WCHAR)); + if (!tmp) + { + midl_user_free(value); + return ERROR_OUTOFMEMORY; + } + strcpyW(tmp, value); + + r = msi_strncpyWtoA(tmp, len, buf, sz, TRUE); + + heap_free(tmp); + } + midl_user_free(value); + heap_free(nameW); + return r; + } + + val.unicode = FALSE; + val.str.a = buf; + + r = MSI_GetProperty(hinst, nameW, &val, sz); + + heap_free(nameW); + msiobj_release(&package->hdr); return r; }
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 723b2b5..96344eb 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -168,21 +168,21 @@ static void test_props(MSIHANDLE hinst) r = MsiGetPropertyA(hinst, "boo", buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !strcmp(buffer, "q"), "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 6, "got size %u\n", sz); + ok(hinst, sz == 6, "got size %u\n", sz);
sz = 1; strcpy(buffer,"x"); r = MsiGetPropertyA(hinst, "boo", buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !buffer[0], "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 6, "got size %u\n", sz); + ok(hinst, sz == 6, "got size %u\n", sz);
sz = 3; strcpy(buffer,"x"); r = MsiGetPropertyA(hinst, "boo", buffer, &sz); ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); ok(hinst, !strcmp(buffer, "xy"), "got "%s"\n", buffer); - todo_wine_ok(hinst, sz == 6, "got size %u\n", sz); + ok(hinst, sz == 6, "got size %u\n", sz);
sz = 4; strcpy(buffer,"x");
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=38427
Your paranoid android.
=== w7pro64 (64 bit custom) === The previous 1 run(s) terminated abnormally
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/package.c | 131 +++++++++++++++++++++--------------------------- dlls/msi/tests/custom.c | 6 +++ 2 files changed, 62 insertions(+), 75 deletions(-)
diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 133bfd8..ab6c3dd 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2345,76 +2345,13 @@ int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def ) return val; }
-static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, - awstring *szValueBuf, LPDWORD pchValueBuf ) -{ - MSIPACKAGE *package; - MSIRECORD *row = NULL; - UINT r = ERROR_FUNCTION_FAILED; - LPCWSTR val = NULL; - DWORD len = 0; - - TRACE("%u %s %p %p\n", handle, debugstr_w(name), - szValueBuf->str.w, pchValueBuf ); - - if (!name) - return ERROR_INVALID_PARAMETER; - - package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ); - if (!package) - { - LPWSTR value = NULL, buffer; - MSIHANDLE remote; - - if (!(remote = msi_get_remote(handle))) - return ERROR_INVALID_HANDLE; - - r = remote_GetProperty(remote, name, &value, &len); - if (r != ERROR_SUCCESS) - return r; - - /* String might contain embedded nulls. - * Native returns the correct size but truncates the string. */ - buffer = heap_alloc_zero((len + 1) * sizeof(WCHAR)); - if (!buffer) - { - midl_user_free(value); - return ERROR_OUTOFMEMORY; - } - strcpyW(buffer, value); - - r = msi_strcpy_to_awstring(buffer, len, szValueBuf, pchValueBuf); - - /* Bug required by Adobe installers */ - if (pchValueBuf && !szValueBuf->unicode && !szValueBuf->str.a) - *pchValueBuf *= sizeof(WCHAR); - - heap_free(buffer); - midl_user_free(value); - return r; - } - - row = msi_get_property_row( package->db, name ); - if (row) - val = msi_record_get_string( row, 1, (int *)&len ); - - if (!val) - val = szEmpty; - - r = msi_strcpy_to_awstring( val, len, szValueBuf, pchValueBuf ); - - if (row) - msiobj_release( &row->hdr ); - msiobj_release( &package->hdr ); - - return r; -} - UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz) { + const WCHAR *value = szEmpty; MSIPACKAGE *package; - awstring val; + MSIRECORD *row; WCHAR *nameW; + int len = 0; UINT r;
if (!name) @@ -2455,25 +2392,69 @@ UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD return r; }
- val.unicode = FALSE; - val.str.a = buf; + row = msi_get_property_row(package->db, nameW); + if (row) + value = msi_record_get_string(row, 1, &len);
- r = MSI_GetProperty(hinst, nameW, &val, sz); + r = msi_strncpyWtoA(value, len, buf, sz, FALSE);
heap_free(nameW); + if (row) msiobj_release(&row->hdr); msiobj_release(&package->hdr); return r; }
-UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, - LPWSTR szValueBuf, LPDWORD pchValueBuf ) +UINT WINAPI MsiGetPropertyW(MSIHANDLE hinst, const WCHAR *name, WCHAR *buf, DWORD *sz) { - awstring val; + const WCHAR *value = szEmpty; + MSIPACKAGE *package; + MSIRECORD *row; + int len = 0; + UINT r;
- val.unicode = TRUE; - val.str.w = szValueBuf; + if (!name) + return ERROR_INVALID_PARAMETER;
- return MSI_GetProperty( hInstall, szName, &val, pchValueBuf ); + package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE); + if (!package) + { + WCHAR *value = NULL, *tmp; + MSIHANDLE remote; + DWORD len; + + if (!(remote = msi_get_remote(hinst))) + return ERROR_INVALID_HANDLE; + + r = remote_GetProperty(remote, name, &value, &len); + if (!r) + { + /* String might contain embedded nulls. + * Native returns the correct size but truncates the string. */ + tmp = heap_alloc_zero((len + 1) * sizeof(WCHAR)); + if (!tmp) + { + midl_user_free(value); + return ERROR_OUTOFMEMORY; + } + strcpyW(tmp, value); + + r = msi_strncpyW(tmp, len, buf, sz); + + heap_free(tmp); + } + midl_user_free(value); + return r; + } + + row = msi_get_property_row(package->db, name); + if (row) + value = msi_record_get_string(row, 1, &len); + + r = msi_strncpyW(value, len, buf, sz); + + if (row) msiobj_release(&row->hdr); + msiobj_release(&package->hdr); + return r; }
MSIHANDLE __cdecl s_remote_GetActiveDatabase(MSIHANDLE hinst) diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 96344eb..d240964 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -191,6 +191,12 @@ static void test_props(MSIHANDLE hinst) ok(hinst, !strcmp(buffer, "xyz"), "got "%s"\n", buffer); ok(hinst, sz == 3, "got size %u\n", sz);
+ r = MsiGetPropertyW(hinst, booW, NULL, NULL); + ok(hinst, !r, "got %u\n", r); + + r = MsiGetPropertyW(hinst, booW, bufferW, NULL ); + ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); + sz = 0; r = MsiGetPropertyW(hinst, booW, NULL, &sz); ok(hinst, !r, "got %u\n", r);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=38428
Your paranoid android.
=== w7pro64 (64 bit custom) === The previous 1 run(s) terminated abnormally
Signed-off-by: Hans Leidekker hans@codeweavers.com
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=38425
Your paranoid android.
=== w7pro64 (64 bit custom) === The previous 1 run(s) terminated abnormally