mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
Winesync to Wine-0.9.55.
svn path=/trunk/; revision=32261
This commit is contained in:
parent
9791a75ef7
commit
235ef9487e
7 changed files with 874 additions and 520 deletions
|
@ -2240,6 +2240,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
|
||||||
DWORD *size)
|
DWORD *size)
|
||||||
{
|
{
|
||||||
LPSTR data = NULL;
|
LPSTR data = NULL;
|
||||||
|
|
||||||
if (value[0]=='#' && value[1]!='#' && value[1]!='%')
|
if (value[0]=='#' && value[1]!='#' && value[1]!='%')
|
||||||
{
|
{
|
||||||
if (value[1]=='x')
|
if (value[1]=='x')
|
||||||
|
@ -2321,6 +2322,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
|
||||||
{
|
{
|
||||||
static const WCHAR szMulti[] = {'[','~',']',0};
|
static const WCHAR szMulti[] = {'[','~',']',0};
|
||||||
LPCWSTR ptr;
|
LPCWSTR ptr;
|
||||||
|
LPWSTR newdata;
|
||||||
*type=REG_SZ;
|
*type=REG_SZ;
|
||||||
|
|
||||||
if (value[0]=='#')
|
if (value[0]=='#')
|
||||||
|
@ -2339,7 +2341,29 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
|
||||||
if (strstrW(value,szMulti))
|
if (strstrW(value,szMulti))
|
||||||
*type = REG_MULTI_SZ;
|
*type = REG_MULTI_SZ;
|
||||||
|
|
||||||
|
/* remove initial delimiter */
|
||||||
|
if (!strncmpW(value, szMulti, 3))
|
||||||
|
ptr = value + 3;
|
||||||
|
|
||||||
*size = deformat_string(package, ptr,(LPWSTR*)&data);
|
*size = deformat_string(package, ptr,(LPWSTR*)&data);
|
||||||
|
|
||||||
|
/* add double NULL terminator */
|
||||||
|
if (*type == REG_MULTI_SZ)
|
||||||
|
{
|
||||||
|
*size += sizeof(WCHAR);
|
||||||
|
newdata = msi_alloc(*size);
|
||||||
|
if (!newdata)
|
||||||
|
{
|
||||||
|
msi_free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(newdata, data, *size - 1);
|
||||||
|
newdata[*size] = '\0';
|
||||||
|
|
||||||
|
msi_free(data);
|
||||||
|
data = (LPSTR)newdata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,6 +408,10 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
|
||||||
else
|
else
|
||||||
type = type_long;
|
type = type_long;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ERR("Unknown type: %c\n", types[i][0]);
|
||||||
|
msi_free(columns);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintfW(expanded, column_fmt, columns_data[i], type, size, extra, comma);
|
sprintfW(expanded, column_fmt, columns_data[i], type, size, extra, comma);
|
||||||
|
|
|
@ -901,13 +901,11 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = build_directory_name(2, dest_path, dest_name);
|
dest = build_directory_name(2, dest_path, dest_name);
|
||||||
create_full_pathW(dest);
|
create_full_pathW(dest_path);
|
||||||
|
|
||||||
TRACE("Duplicating file %s to %s\n",debugstr_w(file->TargetPath),
|
TRACE("Duplicating file %s to %s\n",debugstr_w(file->TargetPath),
|
||||||
debugstr_w(dest));
|
debugstr_w(dest));
|
||||||
|
|
||||||
CreateDirectoryW(dest_path, NULL);
|
|
||||||
|
|
||||||
if (strcmpW(file->TargetPath,dest))
|
if (strcmpW(file->TargetPath,dest))
|
||||||
rc = !CopyFileW(file->TargetPath,dest,TRUE);
|
rc = !CopyFileW(file->TargetPath,dest,TRUE);
|
||||||
else
|
else
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1519,6 +1519,10 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
|
||||||
LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
|
LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
|
||||||
UINT ret = ERROR_OUTOFMEMORY;
|
UINT ret = ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if ((lpVersionBuf && !pcchVersionBuf) ||
|
||||||
|
(lpLangBuf && !pcchLangBuf))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( szFilePath )
|
if( szFilePath )
|
||||||
{
|
{
|
||||||
szwFilePath = strdupAtoW( szFilePath );
|
szwFilePath = strdupAtoW( szFilePath );
|
||||||
|
@ -1543,12 +1547,12 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
|
||||||
ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
|
ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
|
||||||
lpwLangBuff, pcchLangBuf);
|
lpwLangBuff, pcchLangBuf);
|
||||||
|
|
||||||
if( lpwVersionBuff )
|
if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
|
||||||
WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
|
WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
|
||||||
lpVersionBuf, *pcchVersionBuf, NULL, NULL);
|
lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
|
||||||
if( lpwLangBuff )
|
if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
|
||||||
WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
|
WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
|
||||||
lpLangBuf, *pcchLangBuf, NULL, NULL);
|
lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
msi_free(szwFilePath);
|
msi_free(szwFilePath);
|
||||||
|
@ -1569,7 +1573,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
|
||||||
'%','d','.','%','d','.','%','d','.','%','d',0};
|
'%','d','.','%','d','.','%','d','.','%','d',0};
|
||||||
static const WCHAR szLangFormat[] = {'%','d',0};
|
static const WCHAR szLangFormat[] = {'%','d',0};
|
||||||
UINT ret = 0;
|
UINT ret = 0;
|
||||||
DWORD dwVerLen;
|
DWORD dwVerLen, gle;
|
||||||
LPVOID lpVer = NULL;
|
LPVOID lpVer = NULL;
|
||||||
VS_FIXEDFILEINFO *ffi;
|
VS_FIXEDFILEINFO *ffi;
|
||||||
UINT puLen;
|
UINT puLen;
|
||||||
|
@ -1579,9 +1583,21 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
|
||||||
lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
|
lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
|
||||||
lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
|
lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
|
||||||
|
|
||||||
|
if ((lpVersionBuf && !pcchVersionBuf) ||
|
||||||
|
(lpLangBuf && !pcchLangBuf))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
|
dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
|
||||||
if( !dwVerLen )
|
if( !dwVerLen )
|
||||||
return GetLastError();
|
{
|
||||||
|
gle = GetLastError();
|
||||||
|
if (gle == ERROR_BAD_PATHNAME)
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
|
||||||
|
return ERROR_FILE_INVALID;
|
||||||
|
|
||||||
|
return gle;
|
||||||
|
}
|
||||||
|
|
||||||
lpVer = msi_alloc(dwVerLen);
|
lpVer = msi_alloc(dwVerLen);
|
||||||
if( !lpVer )
|
if( !lpVer )
|
||||||
|
@ -1595,7 +1611,8 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
|
||||||
ret = GetLastError();
|
ret = GetLastError();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
|
|
||||||
|
if (pcchVersionBuf)
|
||||||
{
|
{
|
||||||
if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
|
if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
|
||||||
(puLen > 0) )
|
(puLen > 0) )
|
||||||
|
@ -1603,24 +1620,32 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
|
||||||
wsprintfW(tmp, szVersionFormat,
|
wsprintfW(tmp, szVersionFormat,
|
||||||
HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
|
HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
|
||||||
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
|
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
|
||||||
lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
|
if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
|
||||||
*pcchVersionBuf = lstrlenW(lpVersionBuf);
|
|
||||||
|
if (lstrlenW(tmp) >= *pcchVersionBuf)
|
||||||
|
ret = ERROR_MORE_DATA;
|
||||||
|
|
||||||
|
*pcchVersionBuf = lstrlenW(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*lpVersionBuf = 0;
|
if (lpVersionBuf) *lpVersionBuf = 0;
|
||||||
*pcchVersionBuf = 0;
|
*pcchVersionBuf = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
|
if (pcchLangBuf)
|
||||||
{
|
{
|
||||||
DWORD lang = GetUserDefaultLangID();
|
DWORD lang = GetUserDefaultLangID();
|
||||||
|
|
||||||
FIXME("Retrieve language from file\n");
|
FIXME("Retrieve language from file\n");
|
||||||
wsprintfW(tmp, szLangFormat, lang);
|
wsprintfW(tmp, szLangFormat, lang);
|
||||||
lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
|
if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
|
||||||
*pcchLangBuf = lstrlenW(lpLangBuf);
|
|
||||||
|
if (lstrlenW(tmp) >= *pcchLangBuf)
|
||||||
|
ret = ERROR_MORE_DATA;
|
||||||
|
|
||||||
|
*pcchLangBuf = lstrlenW(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
|
@ -478,21 +478,17 @@ static UINT get_user_sid(LPWSTR *usersid)
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
size = sizeof(buf);
|
size = sizeof(buf);
|
||||||
if (!GetTokenInformation(token, TokenUser, (void *)buf, size, &size))
|
if (!GetTokenInformation(token, TokenUser, (void *)buf, size, &size)) {
|
||||||
{
|
|
||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
user = (PTOKEN_USER)buf;
|
user = (PTOKEN_USER)buf;
|
||||||
if (!ConvertSidToStringSidW(user->User.Sid, usersid))
|
if (!ConvertSidToStringSidW(user->User.Sid, usersid)) {
|
||||||
{
|
|
||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +662,7 @@ UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
|
||||||
else
|
else
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,7 +739,7 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create
|
||||||
else
|
else
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,7 +764,7 @@ UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent)
|
||||||
|
|
||||||
sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
|
sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
|
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +794,7 @@ UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
|
||||||
else
|
else
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,7 +824,7 @@ UINT MSIREG_OpenInstallPropertiesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
|
||||||
else
|
else
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,7 +849,7 @@ UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
|
||||||
|
|
||||||
sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
|
sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
|
||||||
|
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
|
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,7 +1039,7 @@ UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL cr
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintfW(keypath, szInstaller_LocalManagedProd_fmt, usersid, squished_pc);
|
sprintfW(keypath, szInstaller_LocalManagedProd_fmt, usersid, squished_pc);
|
||||||
msi_free(usersid);
|
LocalFree(usersid);
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
|
@ -54,9 +54,9 @@ typedef struct tagMSISTREAMSVIEW
|
||||||
UINT row_size;
|
UINT row_size;
|
||||||
} MSISTREAMSVIEW;
|
} MSISTREAMSVIEW;
|
||||||
|
|
||||||
static BOOL add_stream_to_table(MSISTREAMSVIEW *sv, STREAM *stream, int index)
|
static BOOL streams_set_table_size(MSISTREAMSVIEW *sv, int size)
|
||||||
{
|
{
|
||||||
if (index >= sv->max_streams)
|
if (size >= sv->max_streams)
|
||||||
{
|
{
|
||||||
sv->max_streams *= 2;
|
sv->max_streams *= 2;
|
||||||
sv->streams = msi_realloc(sv->streams, sv->max_streams * sizeof(STREAM *));
|
sv->streams = msi_realloc(sv->streams, sv->max_streams * sizeof(STREAM *));
|
||||||
|
@ -64,7 +64,6 @@ static BOOL add_stream_to_table(MSISTREAMSVIEW *sv, STREAM *stream, int index)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sv->streams[index] = stream;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +138,6 @@ static UINT STREAMS_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
|
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
|
||||||
{
|
|
||||||
FIXME("(%p, %d, %p, %d): stub!\n", view, row, rec, mask);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temporary)
|
|
||||||
{
|
{
|
||||||
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||||
STREAM *stream;
|
STREAM *stream;
|
||||||
|
@ -156,7 +149,10 @@ static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, BOOL tem
|
||||||
ULONG count;
|
ULONG count;
|
||||||
UINT r = ERROR_FUNCTION_FAILED;
|
UINT r = ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
TRACE("(%p, %p, %d)\n", view, rec, temporary);
|
TRACE("(%p, %p)\n", view, rec);
|
||||||
|
|
||||||
|
if (row > sv->num_rows)
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
r = MSI_RecordGetIStream(rec, 2, &stm);
|
r = MSI_RecordGetIStream(rec, 2, &stm);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
|
@ -201,8 +197,7 @@ static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, BOOL tem
|
||||||
IStorage_OpenStream(sv->db->storage, name, 0,
|
IStorage_OpenStream(sv->db->storage, name, 0,
|
||||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
|
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
|
||||||
|
|
||||||
if (!add_stream_to_table(sv, stream, sv->num_rows++))
|
sv->streams[row] = stream;
|
||||||
goto done;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
msi_free(name);
|
msi_free(name);
|
||||||
|
@ -213,6 +208,16 @@ done:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temporary)
|
||||||
|
{
|
||||||
|
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||||
|
|
||||||
|
if (!streams_set_table_size(sv, ++sv->num_rows))
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
return STREAMS_set_row(view, sv->num_rows - 1, rec, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row)
|
static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row)
|
||||||
{
|
{
|
||||||
FIXME("(%p %d): stub!\n", view, row);
|
FIXME("(%p %d): stub!\n", view, row);
|
||||||
|
@ -278,6 +283,52 @@ static UINT STREAMS_get_column_info(struct tagMSIVIEW *view,
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT streams_find_row(MSISTREAMSVIEW *sv, MSIRECORD *rec, UINT *row)
|
||||||
|
{
|
||||||
|
LPCWSTR str;
|
||||||
|
UINT i, id, data;
|
||||||
|
|
||||||
|
str = MSI_RecordGetString(rec, 1);
|
||||||
|
msi_string2idW(sv->db->strings, str, &id);
|
||||||
|
|
||||||
|
for (i = 0; i < sv->num_rows; i++)
|
||||||
|
{
|
||||||
|
STREAMS_fetch_int(&sv->view, i, 1, &data);
|
||||||
|
|
||||||
|
if (data == id)
|
||||||
|
{
|
||||||
|
*row = i;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT streams_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
|
||||||
|
{
|
||||||
|
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||||
|
UINT r, row;
|
||||||
|
|
||||||
|
r = streams_find_row(sv, rec, &row);
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
return STREAMS_set_row(view, row, rec, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT streams_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
|
||||||
|
{
|
||||||
|
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||||
|
UINT r, row;
|
||||||
|
|
||||||
|
r = streams_find_row(sv, rec, &row);
|
||||||
|
if (r == ERROR_SUCCESS)
|
||||||
|
return streams_modify_update(view, rec);
|
||||||
|
|
||||||
|
return STREAMS_insert_row(view, rec, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
|
static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
|
||||||
{
|
{
|
||||||
UINT r;
|
UINT r;
|
||||||
|
@ -286,15 +337,21 @@ static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRE
|
||||||
|
|
||||||
switch (eModifyMode)
|
switch (eModifyMode)
|
||||||
{
|
{
|
||||||
|
case MSIMODIFY_ASSIGN:
|
||||||
|
r = streams_modify_assign(view, rec);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSIMODIFY_INSERT:
|
case MSIMODIFY_INSERT:
|
||||||
r = STREAMS_insert_row(view, rec, FALSE);
|
r = STREAMS_insert_row(view, rec, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSIMODIFY_UPDATE:
|
||||||
|
r = streams_modify_update(view, rec);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSIMODIFY_VALIDATE_NEW:
|
case MSIMODIFY_VALIDATE_NEW:
|
||||||
case MSIMODIFY_INSERT_TEMPORARY:
|
case MSIMODIFY_INSERT_TEMPORARY:
|
||||||
case MSIMODIFY_UPDATE:
|
|
||||||
case MSIMODIFY_REFRESH:
|
case MSIMODIFY_REFRESH:
|
||||||
case MSIMODIFY_ASSIGN:
|
|
||||||
case MSIMODIFY_REPLACE:
|
case MSIMODIFY_REPLACE:
|
||||||
case MSIMODIFY_MERGE:
|
case MSIMODIFY_MERGE:
|
||||||
case MSIMODIFY_DELETE:
|
case MSIMODIFY_DELETE:
|
||||||
|
@ -425,11 +482,13 @@ static UINT add_streams_to_table(MSISTREAMSVIEW *sv)
|
||||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
|
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
|
||||||
CoTaskMemFree(stat.pwcsName);
|
CoTaskMemFree(stat.pwcsName);
|
||||||
|
|
||||||
if (!add_stream_to_table(sv, stream, count++))
|
if (!streams_set_table_size(sv, ++count))
|
||||||
{
|
{
|
||||||
count = -1;
|
count = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sv->streams[count - 1] = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumSTATSTG_Release(stgenum);
|
IEnumSTATSTG_Release(stgenum);
|
||||||
|
|
Loading…
Reference in a new issue