[ros-diffs] [cwittich] 41310: sync cabinet, jscript, msi and msxml3 with wine 1.1.23

cwittich at svn.reactos.org cwittich at svn.reactos.org
Sat Jun 6 17:59:48 CEST 2009


Author: cwittich
Date: Sat Jun  6 19:59:47 2009
New Revision: 41310

URL: http://svn.reactos.org/svn/reactos?rev=41310&view=rev
Log:
sync cabinet, jscript, msi and msxml3 with wine 1.1.23

Modified:
    trunk/reactos/dll/win32/cabinet/fdi.c
    trunk/reactos/dll/win32/jscript/date.c
    trunk/reactos/dll/win32/jscript/global.c
    trunk/reactos/dll/win32/jscript/jscript.h
    trunk/reactos/dll/win32/jscript/lex.c
    trunk/reactos/dll/win32/jscript/math.c
    trunk/reactos/dll/win32/jscript/regexp.c
    trunk/reactos/dll/win32/jscript/string.c
    trunk/reactos/dll/win32/msi/action.c
    trunk/reactos/dll/win32/msi/alter.c
    trunk/reactos/dll/win32/msi/create.c
    trunk/reactos/dll/win32/msi/database.c
    trunk/reactos/dll/win32/msi/drop.c
    trunk/reactos/dll/win32/msi/format.c
    trunk/reactos/dll/win32/msi/join.c
    trunk/reactos/dll/win32/msi/msipriv.h
    trunk/reactos/dll/win32/msi/query.h
    trunk/reactos/dll/win32/msi/record.c
    trunk/reactos/dll/win32/msi/registry.c
    trunk/reactos/dll/win32/msi/sql.tab.c
    trunk/reactos/dll/win32/msi/sql.tab.h
    trunk/reactos/dll/win32/msi/sql.y
    trunk/reactos/dll/win32/msi/storages.c
    trunk/reactos/dll/win32/msi/streams.c
    trunk/reactos/dll/win32/msi/table.c
    trunk/reactos/dll/win32/msi/update.c
    trunk/reactos/dll/win32/msxml3/node.c

Modified: trunk/reactos/dll/win32/cabinet/fdi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cabinet/fdi.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/cabinet/fdi.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/cabinet/fdi.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -2260,7 +2260,7 @@
   return DECR_OK;
 }
 
-static void free_decompression_temps(HFDI hfdi, struct fdi_folder *fol,
+static void free_decompression_temps(HFDI hfdi, const struct fdi_folder *fol,
   fdi_decomp_state *decomp_state)
 {
   switch (fol->comp_type & cffoldCOMPTYPE_MASK) {

Modified: trunk/reactos/dll/win32/jscript/date.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/date.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/date.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/date.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -25,11 +25,16 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+/* 1601 to 1970 is 369 years plus 89 leap days */
+#define TIME_EPOCH  ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000)
+
 typedef struct {
     DispatchEx dispex;
 
     /* ECMA-262 3rd Edition    15.9.1.1 */
     DOUBLE time;
+
+    LONG bias;
 } DateInstance;
 
 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
@@ -81,11 +86,8 @@
 /* ECMA-262 3rd Edition    15.9.1.14 */
 static inline DOUBLE time_clip(DOUBLE time)
 {
-    /* FIXME: Handle inf */
-
     if(8.64e15 < time || time < -8.64e15) {
-        FIXME("return NaN\n");
-        return 0.0;
+        return ret_nan();
     }
 
     return floor(time);
@@ -308,8 +310,33 @@
 static HRESULT Date_setTime(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+    DateInstance *date;
+
+    TRACE("\n");
+
+    if(!is_class(dispex, JSCLASS_DATE)) {
+        FIXME("throw TypeError\n");
+        return E_FAIL;
+    }
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    date = (DateInstance*)dispex;
+    date->time = time_clip(num_val(&v));
+
+    if(retv)
+        num_set_val(retv, date->time);
+
+    return S_OK;
 }
 
 static HRESULT Date_setMiliseconds(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
@@ -477,6 +504,9 @@
 {
     DateInstance *date;
     HRESULT hres;
+    TIME_ZONE_INFORMATION tzi;
+
+    GetTimeZoneInformation(&tzi);
 
     date = heap_alloc_zero(sizeof(DateInstance));
     if(!date)
@@ -492,6 +522,7 @@
     }
 
     date->time = time;
+    date->bias = tzi.Bias;
 
     *ret = &date->dispex;
     return S_OK;
@@ -511,12 +542,13 @@
         /* ECMA-262 3rd Edition    15.9.3.3 */
         case 0: {
             FILETIME time;
+            LONGLONG lltime;
 
             GetSystemTimeAsFileTime(&time);
-
-            hres = create_date(dispex->ctx, TRUE,
-                   floor((DOUBLE)(time.dwLowDateTime/1e6) + (DOUBLE)time.dwHighDateTime*((DOUBLE)UINT_MAX+1.0)/1.e6),
-                   &date);
+            lltime = ((LONGLONG)time.dwHighDateTime<<32)
+                + time.dwLowDateTime;
+
+            hres = create_date(dispex->ctx, TRUE, lltime/10000-TIME_EPOCH, &date);
             if(FAILED(hres))
                 return hres;
             break;

Modified: trunk/reactos/dll/win32/jscript/global.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/global.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/global.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/global.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -351,8 +351,8 @@
     HRESULT hres;
 
     if(!arg_cnt(dp)) {
-        FIXME("NAN\n");
-        return E_NOTIMPL;
+        if(retv) num_set_nan(retv);
+        return S_OK;
     }
 
     if(arg_cnt(dp) >= 2) {

Modified: trunk/reactos/dll/win32/jscript/jscript.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/jscript.h?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/jscript.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/jscript.h [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -255,6 +255,13 @@
 #endif
 }
 
+static inline DOUBLE ret_nan()
+{
+    VARIANT v;
+    num_set_nan(&v);
+    return V_R8(&v);
+}
+
 static inline void num_set_inf(VARIANT *v, BOOL positive)
 {
     V_VT(v) = VT_R8;

Modified: trunk/reactos/dll/win32/jscript/lex.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/lex.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/lex.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/lex.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -17,6 +17,7 @@
  */
 
 #include <math.h>
+#include <limits.h>
 
 #include "jscript.h"
 #include "activscp.h"
@@ -29,6 +30,8 @@
 #include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+
+#define LONGLONG_MAX (((LONGLONG)0x7fffffff<<32)|0xffffffff)
 
 static const WCHAR breakW[] = {'b','r','e','a','k',0};
 static const WCHAR caseW[] = {'c','a','s','e',0};
@@ -372,16 +375,42 @@
 
 static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **literal)
 {
-    double d, tmp = 1.0;
-
-    if(ctx->ptr == ctx->end || !isdigitW(*ctx->ptr)) {
-        ERR("No digit after point\n");
+    LONGLONG d, hlp;
+    int exp = 0;
+
+    if(ctx->ptr == ctx->end || (!isdigitW(*ctx->ptr) &&
+        *ctx->ptr!='.' && *ctx->ptr!='e' && *ctx->ptr!='E')) {
+        ERR("Illegal character\n");
         return 0;
     }
 
     d = int_part;
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        hlp = d*10 + *(ctx->ptr++) - '0';
+        if(d>LONGLONG_MAX/10 || hlp<0) {
+            exp++;
+            break;
+        }
+        else
+            d = hlp;
+    }
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        exp++;
+        ctx->ptr++;
+    }
+
+    if(*ctx->ptr == '.') ctx->ptr++;
+
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        hlp = d*10 + *(ctx->ptr++) - '0';
+        if(d>LONGLONG_MAX/10 || hlp<0)
+            break;
+
+        d = hlp;
+        exp--;
+    }
     while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-        d += (tmp /= 10.0)*(*ctx->ptr++ - '0');
+        ctx->ptr++;
 
     if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) {
         int sign = 1, e = 0;
@@ -404,16 +433,20 @@
             return lex_error(ctx, E_FAIL);
         }
 
-        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-            e = e*10 + *ctx->ptr++ - '0';
+        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+            if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
+                e = INT_MAX;
+        }
         e *= sign;
 
-        d *= pow(10, e);
+        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
+        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
+        else exp += e;
     }
 
     *literal = parser_alloc(ctx, sizeof(literal_t));
     (*literal)->vt = VT_R8;
-    (*literal)->u.dval = d;
+    (*literal)->u.dval = (double)d*pow(10, exp);
 
     return tNumericLiteral;
 }
@@ -458,13 +491,20 @@
     }
 
     while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
-        l = l*10 + *(ctx->ptr++)-'0';
+    {
+        d = l*10 + *(ctx->ptr)-'0';
+
+        /* Check for integer overflow */
+        if (l > INT_MAX/10 || d < 0)
+            return parse_double_literal(ctx, l, literal);
+
+        l = d;
+        ctx->ptr++;
+    }
 
     if(ctx->ptr < ctx->end) {
-        if(*ctx->ptr == '.') {
-            ctx->ptr++;
+        if(*ctx->ptr == '.' || *ctx->ptr == 'e' || *ctx->ptr == 'E')
             return parse_double_literal(ctx, l, literal);
-        }
 
         if(is_identifier_char(*ctx->ptr)) {
             WARN("unexpected identifier char\n");

Modified: trunk/reactos/dll/win32/jscript/math.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/math.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/math.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/math.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -105,8 +105,8 @@
 static HRESULT Math_LN10(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    TRACE("\n");
+    return math_constant(M_LN10, flags, retv);
 }
 
 /* ECMA-262 3rd Edition    15.8.1.6 */
@@ -120,15 +120,15 @@
 static HRESULT Math_SQRT2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    TRACE("\n");
+    return math_constant(M_SQRT2, flags, retv);
 }
 
 static HRESULT Math_SQRT1_2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    TRACE("\n");
+    return math_constant(M_SQRT1_2, flags, retv);
 }
 
 /* ECMA-262 3rd Edition    15.8.2.12 */
@@ -160,29 +160,89 @@
 static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, acos(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_asin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, asin(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_atan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, atan(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v1, v2;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(arg_cnt(dp)<2) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v1);
+    if(FAILED(hres))
+        return hres;
+
+    hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &v2);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, atan2(num_val(&v1), num_val(&v2)));
+    return S_OK;
 }
 
 /* ECMA-262 3rd Edition    15.8.2.6 */
@@ -233,8 +293,22 @@
 static HRESULT Math_exp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, exp(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_floor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
@@ -263,8 +337,24 @@
 static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv)
+            num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv)
+        num_set_val(retv, log(num_val(&v)));
+    return S_OK;
 }
 
 /* ECMA-262 3rd Edition    15.8.2.11 */
@@ -351,8 +441,8 @@
     TRACE("\n");
 
     if(arg_cnt(dp) < 2) {
-        FIXME("unimplemented arg_cnt %d\n", arg_cnt(dp));
-        return E_NOTIMPL;
+        if(retv) num_set_nan(retv);
+        return S_OK;
     }
 
     hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &x);
@@ -411,22 +501,64 @@
 static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, sin(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_sqrt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, sqrt(num_val(&v)));
+    return S_OK;
 }
 
 static HRESULT Math_tan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) num_set_nan(retv);
+        return S_OK;
+    }
+
+    hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) num_set_val(retv, tan(num_val(&v)));
+    return S_OK;
 }
 
 static const builtin_prop_t Math_props[] = {

Modified: trunk/reactos/dll/win32/jscript/regexp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/regexp.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/regexp.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/regexp.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -3396,7 +3396,7 @@
         }
 
         if(FAILED(hres))
-            return hres;
+            break;
 
         if(ret_size == i) {
             if(ret)

Modified: trunk/reactos/dll/win32/jscript/string.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/string.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/jscript/string.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/string.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -254,8 +254,8 @@
             return hres;
 
         if(V_VT(&v) != VT_I4 || V_I4(&v) < 0 || V_I4(&v) >= length) {
-            FIXME("NAN\n");
-            return E_FAIL;
+            if(retv) num_set_nan(&v);
+            return S_OK;
         }
 
         idx = V_I4(&v);

Modified: trunk/reactos/dll/win32/msi/action.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/action.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/action.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/action.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -6076,7 +6076,7 @@
         /* FIXME: we should probably check the manifest file here */
 
         if (!MsiGetFileVersionW(assembly->file->TargetPath, version, &size, NULL, NULL) &&
-            strcmpW(version, assembly->file->Version) >= 0)
+            (!assembly->file->Version || strcmpW(version, assembly->file->Version) >= 0))
         {
             assembly->installed = TRUE;
         }

Modified: trunk/reactos/dll/win32/msi/alter.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/alter.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/alter.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/alter.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -257,8 +257,11 @@
         return ERROR_FUNCTION_FAILED;
 
     r = TABLE_CreateView( db, name, &av->table );
-    if (r != ERROR_SUCCESS || !av->table)
+    if (r != ERROR_SUCCESS)
+    {
+        msi_free( av );
         return r;
+    }
 
     if (colinfo)
         colinfo->table = name;

Modified: trunk/reactos/dll/win32/msi/create.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/create.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/create.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/create.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -42,7 +42,7 @@
 {
     MSIVIEW          view;
     MSIDATABASE     *db;
-    LPWSTR           name;
+    LPCWSTR          name;
     BOOL             bIsTemp;
     BOOL             hold;
     column_info     *col_info;
@@ -145,9 +145,9 @@
     NULL,
 };
 
-static UINT check_columns( column_info *col_info )
-{
-    column_info *c1, *c2;
+static UINT check_columns( const column_info *col_info )
+{
+    const column_info *c1, *c2;
 
     /* check for two columns with the same name */
     for( c1 = col_info; c1; c1 = c1->next )
@@ -158,7 +158,7 @@
     return ERROR_SUCCESS;
 }
 
-UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,
                         column_info *col_info, BOOL hold )
 {
     MSICREATEVIEW *cv = NULL;
@@ -180,7 +180,7 @@
     for( col = col_info; col; col = col->next )
     {
         if (!col->table)
-            col->table = strdupW(table);
+            col->table = table;
 
         if( !col->temporary )
             temp = FALSE;

Modified: trunk/reactos/dll/win32/msi/database.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/database.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/database.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/database.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -377,6 +377,7 @@
     static const WCHAR type_char[] = {'C','H','A','R',0};
     static const WCHAR type_int[] = {'I','N','T',0};
     static const WCHAR type_long[] = {'L','O','N','G',0};
+    static const WCHAR type_object[] = {'O','B','J','E','C','T',0};
     static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
     static const WCHAR localizable[] = {' ','L','O','C','A','L','I','Z','A','B','L','E',0};
 
@@ -421,6 +422,11 @@
                 else
                     type = type_long;
                 break;
+            case 'v':
+                lstrcpyW(extra, type_notnull);
+            case 'V':
+                type = type_object;
+                break;
             default:
                 ERR("Unknown type: %c\n", types[i][0]);
                 msi_free(columns);
@@ -522,8 +528,32 @@
     return r;
 }
 
+static LPWSTR msi_import_stream_filename(LPCWSTR path, LPCWSTR name)
+{
+    DWORD len;
+    LPWSTR fullname, ptr;
+
+    len = lstrlenW(path) + lstrlenW(name) + 1;
+    fullname = msi_alloc(len*sizeof(WCHAR));
+    if (!fullname)
+       return NULL;
+
+    lstrcpyW( fullname, path );
+
+    /* chop off extension from path */
+    ptr = strrchrW(fullname, '.');
+    if (!ptr)
+    {
+        msi_free (fullname);
+        return NULL;
+    }
+    *ptr++ = '\\';
+    lstrcpyW( ptr, name );
+    return fullname;
+}
+
 static UINT construct_record(DWORD num_columns, LPWSTR *types,
-                             LPWSTR *data, MSIRECORD **rec)
+                             LPWSTR *data, LPWSTR path, MSIRECORD **rec)
 {
     UINT i;
 
@@ -542,6 +572,20 @@
                 if (*data[i])
                     MSI_RecordSetInteger(*rec, i + 1, atoiW(data[i]));
                 break;
+            case 'V': case 'v':
+                if (*data[i])
+                {
+                    UINT r;
+                    LPWSTR file = msi_import_stream_filename(path, data[i]);
+                    if (!file)
+                        return ERROR_FUNCTION_FAILED;
+
+                    r = MSI_RecordSetStreamFromFileW(*rec, i + 1, file);
+                    msi_free (file);
+                    if (r != ERROR_SUCCESS)
+                        return ERROR_FUNCTION_FAILED;
+                }
+                break;
             default:
                 ERR("Unhandled column type: %c\n", types[i][0]);
                 msiobj_release(&(*rec)->hdr);
@@ -554,7 +598,8 @@
 
 static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
                                      LPWSTR *labels, LPWSTR **records,
-                                     int num_columns, int num_records)
+                                     int num_columns, int num_records,
+                                     LPWSTR path)
 {
     UINT r;
     int i;
@@ -579,7 +624,7 @@
 
     for (i = 0; i < num_records; i++)
     {
-        r = construct_record(num_columns, types, records[i], &rec);
+        r = construct_record(num_columns, types, records[i], path, &rec);
         if (r != ERROR_SUCCESS)
             goto done;
 
@@ -683,7 +728,7 @@
             }
         }
 
-        r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records );
+        r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records, path );
     }
 
 done:
@@ -1011,6 +1056,12 @@
     struct list rows;
     LPWSTR name;
     DWORD numconflicts;
+    LPWSTR *columns;
+    DWORD numcolumns;
+    LPWSTR *types;
+    DWORD numtypes;
+    LPWSTR *labels;
+    DWORD numlabels;
 } MERGETABLE;
 
 typedef struct _tagMERGEROW
@@ -1129,8 +1180,8 @@
 static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
 {
     MSIRECORD *colnames;
-    LPWSTR str;
-    UINT r, i = 0;
+    LPWSTR str, val;
+    UINT r, i = 0, sz = 0;
     int cmp;
 
     r = MSI_ViewGetColumnInfo(view, MSICOLINFO_NAMES, &colnames);
@@ -1145,7 +1196,43 @@
     } while (cmp);
 
     msiobj_release(&colnames->hdr);
-    return msi_dup_record_field(rec, i);
+
+    r = MSI_RecordGetStringW(rec, i, NULL, &sz);
+    if (r != ERROR_SUCCESS)
+        return NULL;
+    sz++;
+
+    if (MSI_RecordGetString(rec, i))  /* check record field is a string */
+    {
+        /* quote string record fields */
+        const WCHAR szQuote[] = {'\'', 0};
+        sz += 2;
+        val = msi_alloc(sz*sizeof(WCHAR));
+        if (!val)
+            return NULL;
+
+        lstrcpyW(val, szQuote);
+        r = MSI_RecordGetStringW(rec, i, val+1, &sz);
+        lstrcpyW(val+1+sz, szQuote);
+    }
+    else
+    {
+        /* do not quote integer record fields */
+        val = msi_alloc(sz*sizeof(WCHAR));
+        if (!val)
+            return NULL;
+
+        r = MSI_RecordGetStringW(rec, i, val, &sz);
+    }
+
+    if (r != ERROR_SUCCESS)
+    {
+        ERR("failed to get string!\n");
+        msi_free(val);
+        return NULL;
+    }
+
+    return val;
 }
 
 static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view,
@@ -1219,31 +1306,34 @@
     MERGEDATA *data = param;
     MERGETABLE *table = data->curtable;
     MERGEROW *mergerow;
-    MSIQUERY *dbview;
+    MSIQUERY *dbview = NULL;
     MSIRECORD *row = NULL;
-    LPWSTR query;
-    UINT r;
-
-    query = create_diff_row_query(data->merge, data->curview, table->name, rec);
-    if (!query)
-        return ERROR_OUTOFMEMORY;
-
-    r = MSI_DatabaseOpenViewW(data->db, query, &dbview);
-    if (r != ERROR_SUCCESS)
-        goto done;
-
-    r = MSI_ViewExecute(dbview, NULL);
-    if (r != ERROR_SUCCESS)
-        goto done;
-
-    r = MSI_ViewFetch(dbview, &row);
-    if (r == ERROR_SUCCESS && !MSI_RecordsAreEqual(rec, row))
-    {
-        table->numconflicts++;
-        goto done;
-    }
-    else if (r != ERROR_NO_MORE_ITEMS)
-        goto done;
+    LPWSTR query = NULL;
+    UINT r = ERROR_SUCCESS;
+
+    if (TABLE_Exists(data->db, table->name))
+    {
+        query = create_diff_row_query(data->merge, data->curview, table->name, rec);
+        if (!query)
+            return ERROR_OUTOFMEMORY;
+
+        r = MSI_DatabaseOpenViewW(data->db, query, &dbview);
+        if (r != ERROR_SUCCESS)
+            goto done;
+
+        r = MSI_ViewExecute(dbview, NULL);
+        if (r != ERROR_SUCCESS)
+            goto done;
+
+        r = MSI_ViewFetch(dbview, &row);
+        if (r == ERROR_SUCCESS && !MSI_RecordsAreEqual(rec, row))
+        {
+            table->numconflicts++;
+            goto done;
+        }
+        else if (r != ERROR_NO_MORE_ITEMS)
+            goto done;
+    }
 
     mergerow = msi_alloc(sizeof(MERGEROW));
     if (!mergerow)
@@ -1269,11 +1359,188 @@
     return r;
 }
 
+static UINT msi_get_table_labels(MSIDATABASE *db, LPCWSTR table, LPWSTR **labels, DWORD *numlabels)
+{
+    UINT r, i, count;
+    MSIRECORD *prec = NULL;
+
+    r = MSI_DatabaseGetPrimaryKeys(db, table, &prec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    count = MSI_RecordGetFieldCount(prec);
+    *numlabels = count + 1;
+    *labels = msi_alloc((*numlabels)*sizeof(LPWSTR));
+    if (!*labels)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto end;
+    }
+
+    (*labels)[0] = strdupW(table);
+    for (i=1; i<=count; i++ )
+    {
+        (*labels)[i] = strdupW(MSI_RecordGetString(prec, i));
+    }
+
+end:
+    msiobj_release( &prec->hdr );
+    return r;
+}
+
+static UINT msi_get_query_columns(MSIQUERY *query, LPWSTR **columns, DWORD *numcolumns)
+{
+    UINT r, i, count;
+    MSIRECORD *prec = NULL;
+
+    r = MSI_ViewGetColumnInfo(query, MSICOLINFO_NAMES, &prec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    count = MSI_RecordGetFieldCount(prec);
+    *columns = msi_alloc(count*sizeof(LPWSTR));
+    if (!*columns)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto end;
+    }
+
+    for (i=1; i<=count; i++ )
+    {
+        (*columns)[i-1] = strdupW(MSI_RecordGetString(prec, i));
+    }
+
+    *numcolumns = count;
+
+end:
+    msiobj_release( &prec->hdr );
+    return r;
+}
+
+static UINT msi_get_query_types(MSIQUERY *query, LPWSTR **types, DWORD *numtypes)
+{
+    UINT r, i, count;
+    MSIRECORD *prec = NULL;
+
+    r = MSI_ViewGetColumnInfo(query, MSICOLINFO_TYPES, &prec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    count = MSI_RecordGetFieldCount(prec);
+    *types = msi_alloc(count*sizeof(LPWSTR));
+    if (!*types)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto end;
+    }
+
+    for (i=1; i<=count; i++ )
+    {
+        (*types)[i-1] = strdupW(MSI_RecordGetString(prec, i));
+    }
+
+end:
+    msiobj_release( &prec->hdr );
+    return r;
+}
+
+static void merge_free_rows(MERGETABLE *table)
+{
+    struct list *item, *cursor;
+
+    LIST_FOR_EACH_SAFE(item, cursor, &table->rows)
+    {
+        MERGEROW *row = LIST_ENTRY(item, MERGEROW, entry);
+
+        list_remove(&row->entry);
+        msiobj_release(&row->data->hdr);
+        msi_free(row);
+    }
+}
+
+static void free_merge_table(MERGETABLE *table)
+{
+        UINT i;
+
+        if (table->labels != NULL)
+        {
+            for (i = 0; i < table->numlabels; i++)
+                msi_free(table->labels[i]);
+            msi_free(table->labels);
+        }
+
+        if (table->columns != NULL)
+        {
+            for (i = 0; i < table->numcolumns; i++)
+                msi_free(table->columns[i]);
+            msi_free(table->columns);
+        }
+
+        if (table->types != NULL)
+        {
+            for (i = 0; i < table->numtypes; i++)
+                msi_free(table->types[i]);
+            msi_free(table->types);
+        }
+        msi_free(table->name);
+        merge_free_rows(table);
+
+        msi_free(table);
+}
+
+static UINT msi_get_merge_table (MSIDATABASE *db, LPCWSTR name, MERGETABLE **ptable)
+{
+    UINT r;
+    MERGETABLE *table;
+    MSIQUERY *mergeview = NULL;
+
+    static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','`','%','s','`',0};
+
+    table = msi_alloc_zero(sizeof(MERGETABLE));
+    if (!table)
+    {
+       *ptable = NULL;
+       return ERROR_OUTOFMEMORY;
+    }
+
+    r = msi_get_table_labels(db, name, &table->labels, &table->numlabels);
+    if (r != ERROR_SUCCESS)
+        goto err;
+
+    r = MSI_OpenQuery(db, &mergeview, query, name);
+    if (r != ERROR_SUCCESS)
+        goto err;
+
+    r = msi_get_query_columns(mergeview, &table->columns, &table->numcolumns);
+    if (r != ERROR_SUCCESS)
+        goto err;
+
+    r = msi_get_query_types(mergeview, &table->types, &table->numtypes);
+    if (r != ERROR_SUCCESS)
+        goto err;
+
+    list_init(&table->rows);
+
+    table->name = strdupW(name);
+    table->numconflicts = 0;
+
+    msiobj_release(&mergeview->hdr);
+    *ptable = table;
+    return ERROR_SUCCESS;
+
+err:
+    msiobj_release(&mergeview->hdr);
+    free_merge_table(table);
+    *ptable = NULL;
+    return r;
+}
+
 static UINT merge_diff_tables(MSIRECORD *rec, LPVOID param)
 {
     MERGEDATA *data = param;
     MERGETABLE *table;
-    MSIQUERY *dbview;
+    MSIQUERY *dbview = NULL;
     MSIQUERY *mergeview = NULL;
     LPCWSTR name;
     UINT r;
@@ -1283,40 +1550,35 @@
 
     name = MSI_RecordGetString(rec, 1);
 
-    r = MSI_OpenQuery(data->db, &dbview, query, name);
-    if (r != ERROR_SUCCESS)
-        return r;
-
     r = MSI_OpenQuery(data->merge, &mergeview, query, name);
     if (r != ERROR_SUCCESS)
         goto done;
 
-    r = merge_verify_colnames(dbview, mergeview);
+    if (TABLE_Exists(data->db, name))
+    {
+        r = MSI_OpenQuery(data->db, &dbview, query, name);
+        if (r != ERROR_SUCCESS)
+            goto done;
+
+        r = merge_verify_colnames(dbview, mergeview);
+        if (r != ERROR_SUCCESS)
+            goto done;
+
+        r = merge_verify_primary_keys(data->db, data->merge, name);
+        if (r != ERROR_SUCCESS)
+            goto done;
+    }
+
+    r = msi_get_merge_table(data->merge, name, &table);
     if (r != ERROR_SUCCESS)
         goto done;
 
-    r = merge_verify_primary_keys(data->db, data->merge, name);
-    if (r != ERROR_SUCCESS)
-        goto done;
-
-    table = msi_alloc(sizeof(MERGETABLE));
-    if (!table)
-    {
-        r = ERROR_OUTOFMEMORY;
-        goto done;
-    }
-
-    list_init(&table->rows);
-    table->name = strdupW(name);
-    table->numconflicts = 0;
     data->curtable = table;
     data->curview = mergeview;
-
     r = MSI_IterateRecords(mergeview, NULL, merge_diff_row, data);
     if (r != ERROR_SUCCESS)
     {
-        msi_free(table->name);
-        msi_free(table);
+        free_merge_table(table);
         goto done;
     }
 
@@ -1356,6 +1618,14 @@
     UINT r;
     MERGEROW *row;
     MSIVIEW *tv;
+
+    if (!TABLE_Exists(db, table->name))
+    {
+        r = msi_add_table_to_db(db, table->columns, table->types,
+               table->labels, table->numlabels, table->numcolumns);
+        if (r != ERROR_SUCCESS)
+           return ERROR_FUNCTION_FAILED;
+    }
 
     LIST_FOR_EACH_ENTRY(row, &table->rows, MERGEROW, entry)
     {
@@ -1415,21 +1685,6 @@
     return r;
 }
 
-static void merge_free_rows(MERGETABLE *table)
-{
-    struct list *item, *cursor;
-
-    LIST_FOR_EACH_SAFE(item, cursor, &table->rows)
-    {
-        MERGEROW *row = LIST_ENTRY(item, MERGEROW, entry);
-
-        list_remove(&row->entry);
-        merge_free_rows(table);
-        msiobj_release(&row->data->hdr);
-        msi_free(row);
-    }
-}
-
 UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge,
                               LPCWSTR szTableName)
 {
@@ -1483,9 +1738,7 @@
         MERGETABLE *table = LIST_ENTRY(item, MERGETABLE, entry);
 
         list_remove(&table->entry);
-        merge_free_rows(table);
-        msi_free(table->name);
-        msi_free(table);
+        free_merge_table(table);
     }
 
     if (conflicts)

Modified: trunk/reactos/dll/win32/msi/drop.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/drop.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/drop.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/drop.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -113,8 +113,11 @@
         return ERROR_FUNCTION_FAILED;
 
     r = TABLE_CreateView(db, name, &dv->table);
-    if (r != ERROR_SUCCESS || !dv->table)
+    if (r != ERROR_SUCCESS)
+    {
+        msi_free( dv );
         return r;
+    }
 
     dv->view.ops = &drop_ops;
     dv->db = db;

Modified: trunk/reactos/dll/win32/msi/format.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/format.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/format.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/format.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -869,7 +869,7 @@
     DWORD len;
     UINT rc = ERROR_INVALID_PARAMETER;
 
-    TRACE("%p %p %p %i\n", package, record ,buffer, *size);
+    TRACE("%p %p %p %p\n", package, record, buffer, size);
 
     rec = msi_dup_record_field(record,0);
     if (!rec)

Modified: trunk/reactos/dll/win32/msi/join.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/join.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/join.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/join.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -338,7 +338,10 @@
 
         table = msi_alloc(sizeof(JOINTABLE));
         if (!table)
-            return ERROR_OUTOFMEMORY;
+        {
+            r = ERROR_OUTOFMEMORY;
+            goto end;
+        }
 
         r = TABLE_CreateView( db, tables, &table->view );
         if( r != ERROR_SUCCESS )

Modified: trunk/reactos/dll/win32/msi/msipriv.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msipriv.h?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -701,8 +701,10 @@
 extern UINT MSI_RecordGetStringA( MSIRECORD *, UINT, LPSTR, LPDWORD);
 extern int MSI_RecordGetInteger( MSIRECORD *, UINT );
 extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD);
+extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *);
 extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec );
 extern UINT MSI_RecordStreamToFile( MSIRECORD *, UINT, LPCWSTR );
+extern UINT MSI_RecordSetStreamFromFileW( MSIRECORD *, UINT, LPCWSTR );
 extern UINT MSI_RecordCopyField( MSIRECORD *, UINT, MSIRECORD *, UINT );
 extern MSIRECORD *MSI_CloneRecord( MSIRECORD * );
 extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * );

Modified: trunk/reactos/dll/win32/msi/query.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/query.h?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/query.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/query.h [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -98,7 +98,7 @@
 UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
                        struct expr *cond );
 
-UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,
                         column_info *col_info, BOOL hold );
 
 UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,

Modified: trunk/reactos/dll/win32/msi/record.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/record.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/record.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/record.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -661,7 +661,7 @@
     return ERROR_SUCCESS;
 }
 
-static UINT MSI_RecordSetStream(MSIRECORD *rec, UINT iField, IStream *stream)
+UINT MSI_RecordSetStream(MSIRECORD *rec, UINT iField, IStream *stream)
 {
     if ( (iField == 0) || (iField > rec->count) )
         return ERROR_INVALID_PARAMETER;
@@ -673,7 +673,7 @@
     return ERROR_SUCCESS;
 }
 
-static UINT MSI_RecordSetStreamFromFileW(MSIRECORD *rec, UINT iField, LPCWSTR szFilename)
+UINT MSI_RecordSetStreamFromFileW(MSIRECORD *rec, UINT iField, LPCWSTR szFilename)
 {
     IStream *stm = NULL;
     HRESULT r;
@@ -930,6 +930,7 @@
                 msiobj_release(&clone->hdr);
                 return NULL;
             }
+            clone->fields[i].type = MSIFIELD_STREAM;
         }
         else
         {

Modified: trunk/reactos/dll/win32/msi/registry.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/registry.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -1822,7 +1822,7 @@
         LPWSTR patch, LPWSTR targetprod, MSIINSTALLCONTEXT *targetctx,
         LPWSTR targetsid, DWORD *sidsize, LPWSTR *transforms)
 {
-    MSIPATCHSTATE state;
+    MSIPATCHSTATE state = MSIPATCHSTATE_INVALID;
     LPWSTR ptr, patches = NULL;
     HKEY prod, patchkey = 0;
     HKEY localprod = 0, localpatch = 0;

Modified: trunk/reactos/dll/win32/msi/sql.tab.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/sql.tab.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/sql.tab.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/sql.tab.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -111,6 +111,7 @@
 #include "query.h"
 #include "wine/list.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #define YYLEX_PARAM info
 #define YYPARSE_PARAM info
@@ -133,7 +134,7 @@
 static INT SQL_getint( void *info );
 static int sql_lex( void *SQL_lval, SQL_input *info );
 
-static LPWSTR parser_add_table( LPWSTR list, LPWSTR table );
+static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table );
 static void *parser_alloc( void *info, unsigned int sz );
 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
 
@@ -149,7 +150,7 @@
 
 
 /* Line 189 of yacc.c  */
-#line 153 "sql.tab.c"
+#line 154 "sql.tab.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -247,7 +248,7 @@
 {
 
 /* Line 214 of yacc.c  */
-#line 75 "sql.y"
+#line 76 "sql.y"
 
     struct sql_str str;
     LPWSTR string;
@@ -260,7 +261,7 @@
 
 
 /* Line 214 of yacc.c  */
-#line 264 "sql.tab.c"
+#line 265 "sql.tab.c"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -272,7 +273,7 @@
 
 
 /* Line 264 of yacc.c  */
-#line 276 "sql.tab.c"
+#line 277 "sql.tab.c"
 
 #ifdef short
 # undef short
@@ -594,12 +595,12 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   125,   125,   133,   134,   135,   136,   137,   138,   139,
-     143,   153,   166,   182,   197,   207,   220,   233,   243,   253,
-     266,   270,   277,   290,   300,   310,   317,   326,   330,   334,
-     341,   345,   352,   356,   360,   364,   368,   372,   376,   383,
-     392,   405,   409,   413,   429,   450,   451,   455,   462,   463,
-     479,   489,   502,   507,   516,   522,   528,   534,   540,   546,
+       0,   126,   126,   134,   135,   136,   137,   138,   139,   140,
+     144,   154,   167,   183,   198,   208,   221,   234,   244,   254,
+     267,   271,   278,   291,   301,   311,   318,   327,   331,   335,
+     342,   346,   353,   357,   361,   365,   369,   373,   377,   384,
+     393,   406,   410,   414,   430,   451,   452,   456,   463,   464,
+     480,   490,   502,   507,   516,   522,   528,   534,   540,   546,
      552,   558,   564,   570,   576,   585,   586,   590,   597,   608,
      609,   617,   625,   631,   637,   643,   652,   661,   667,   676,
      683,   691
@@ -1611,7 +1612,7 @@
         case 2:
 
 /* Line 1455 of yacc.c  */
-#line 126 "sql.y"
+#line 127 "sql.y"
     {
         SQL_input* sql = (SQL_input*) info;
         *sql->view = (yyvsp[(1) - (1)].query);
@@ -1621,7 +1622,7 @@
   case 10:
 
 /* Line 1455 of yacc.c  */
-#line 144 "sql.y"
+#line 145 "sql.y"
     {
             SQL_input *sql = (SQL_input*) info;
             MSIVIEW *insert = NULL;
@@ -1636,7 +1637,7 @@
   case 11:
 
 /* Line 1455 of yacc.c  */
-#line 154 "sql.y"
+#line 155 "sql.y"
     {
             SQL_input *sql = (SQL_input*) info;
             MSIVIEW *insert = NULL;
@@ -1651,7 +1652,7 @@
   case 12:
 
 /* Line 1455 of yacc.c  */
-#line 167 "sql.y"
+#line 168 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL;
@@ -1672,7 +1673,7 @@
   case 13:
 
 /* Line 1455 of yacc.c  */
-#line 183 "sql.y"
+#line 184 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL;
@@ -1689,7 +1690,7 @@
   case 14:
 
 /* Line 1455 of yacc.c  */
-#line 198 "sql.y"
+#line 199 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *update = NULL;
@@ -1704,7 +1705,7 @@
   case 15:
 
 /* Line 1455 of yacc.c  */
-#line 208 "sql.y"
+#line 209 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *update = NULL;
@@ -1719,7 +1720,7 @@
   case 16:
 
 /* Line 1455 of yacc.c  */
-#line 221 "sql.y"
+#line 222 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *delete = NULL;
@@ -1734,7 +1735,7 @@
   case 17:
 
 /* Line 1455 of yacc.c  */
-#line 234 "sql.y"
+#line 235 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *alter = NULL;
@@ -1749,7 +1750,7 @@
   case 18:
 
 /* Line 1455 of yacc.c  */
-#line 244 "sql.y"
+#line 245 "sql.y"
     {
             SQL_input *sql = (SQL_input *)info;
             MSIVIEW *alter = NULL;
@@ -1764,7 +1765,7 @@
   case 19:
 
 /* Line 1455 of yacc.c  */
-#line 254 "sql.y"
+#line 255 "sql.y"
     {
             SQL_input *sql = (SQL_input *)info;
             MSIVIEW *alter = NULL;
@@ -1779,7 +1780,7 @@
   case 20:
 
 /* Line 1455 of yacc.c  */
-#line 267 "sql.y"
+#line 268 "sql.y"
     {
             (yyval.integer) = 1;
         ;}
@@ -1788,7 +1789,7 @@
   case 21:
 
 /* Line 1455 of yacc.c  */
-#line 271 "sql.y"
+#line 272 "sql.y"
     {
             (yyval.integer) = -1;
         ;}
@@ -1797,7 +1798,7 @@
   case 22:
 
 /* Line 1455 of yacc.c  */
-#line 278 "sql.y"
+#line 279 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1812,7 +1813,7 @@
   case 23:
 
 /* Line 1455 of yacc.c  */
-#line 291 "sql.y"
+#line 292 "sql.y"
     {
             if( SQL_MarkPrimaryKeys( &(yyvsp[(1) - (4)].column_list), (yyvsp[(4) - (4)].column_list) ) )
                 (yyval.column_list) = (yyvsp[(1) - (4)].column_list);
@@ -1824,7 +1825,7 @@
   case 24:
 
 /* Line 1455 of yacc.c  */
-#line 301 "sql.y"
+#line 302 "sql.y"
     {
             column_info *ci;
 
@@ -1839,7 +1840,7 @@
   case 25:
 
 /* Line 1455 of yacc.c  */
-#line 311 "sql.y"
+#line 312 "sql.y"
     {
             (yyval.column_list) = (yyvsp[(1) - (1)].column_list);
         ;}
@@ -1848,7 +1849,7 @@
   case 26:
 
 /* Line 1455 of yacc.c  */
-#line 318 "sql.y"
+#line 319 "sql.y"
     {
             (yyval.column_list) = (yyvsp[(1) - (2)].column_list);
             (yyval.column_list)->type = ((yyvsp[(2) - (2)].column_type) | MSITYPE_VALID);
@@ -1859,7 +1860,7 @@
   case 27:
 
 /* Line 1455 of yacc.c  */
-#line 327 "sql.y"
+#line 328 "sql.y"
     {
             (yyval.column_type) = (yyvsp[(1) - (1)].column_type);
         ;}
@@ -1868,7 +1869,7 @@
   case 28:
 
 /* Line 1455 of yacc.c  */
-#line 331 "sql.y"
+#line 332 "sql.y"
     {
             (yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_LOCALIZABLE;
         ;}
@@ -1877,7 +1878,7 @@
   case 29:
 
 /* Line 1455 of yacc.c  */
-#line 335 "sql.y"
+#line 336 "sql.y"
     {
             (yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_TEMPORARY;
         ;}
@@ -1886,7 +1887,7 @@
   case 30:
 
 /* Line 1455 of yacc.c  */
-#line 342 "sql.y"
+#line 343 "sql.y"
     {
             (yyval.column_type) |= MSITYPE_NULLABLE;
         ;}
@@ -1895,7 +1896,7 @@
   case 31:
 
 /* Line 1455 of yacc.c  */
-#line 346 "sql.y"
+#line 347 "sql.y"
     {
             (yyval.column_type) = (yyvsp[(1) - (3)].column_type);
         ;}
@@ -1904,7 +1905,7 @@
   case 32:
 
 /* Line 1455 of yacc.c  */
-#line 353 "sql.y"
+#line 354 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | 1;
         ;}
@@ -1913,7 +1914,7 @@
   case 33:
 
 /* Line 1455 of yacc.c  */
-#line 357 "sql.y"
+#line 358 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[(3) - (4)].column_type);
         ;}
@@ -1922,7 +1923,7 @@
   case 34:
 
 /* Line 1455 of yacc.c  */
-#line 361 "sql.y"
+#line 362 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | 0x400;
         ;}
@@ -1931,7 +1932,7 @@
   case 35:
 
 /* Line 1455 of yacc.c  */
-#line 365 "sql.y"
+#line 366 "sql.y"
     {
             (yyval.column_type) = 2 | 0x400;
         ;}
@@ -1940,7 +1941,7 @@
   case 36:
 
 /* Line 1455 of yacc.c  */
-#line 369 "sql.y"
+#line 370 "sql.y"
     {
             (yyval.column_type) = 2 | 0x400;
         ;}
@@ -1949,7 +1950,7 @@
   case 37:
 
 /* Line 1455 of yacc.c  */
-#line 373 "sql.y"
+#line 374 "sql.y"
     {
             (yyval.column_type) = 4;
         ;}
@@ -1958,7 +1959,7 @@
   case 38:
 
 /* Line 1455 of yacc.c  */
-#line 377 "sql.y"
+#line 378 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID;
         ;}
@@ -1967,7 +1968,7 @@
   case 39:
 
 /* Line 1455 of yacc.c  */
-#line 384 "sql.y"
+#line 385 "sql.y"
     {
             if( ( (yyvsp[(1) - (1)].integer) > 255 ) || ( (yyvsp[(1) - (1)].integer) < 0 ) )
                 YYABORT;
@@ -1978,7 +1979,7 @@
   case 40:
 
 /* Line 1455 of yacc.c  */
-#line 393 "sql.y"
+#line 394 "sql.y"
     {
             UINT r;
 
@@ -1996,7 +1997,7 @@
   case 42:
 
 /* Line 1455 of yacc.c  */
-#line 410 "sql.y"
+#line 411 "sql.y"
     {
             (yyval.query) = (yyvsp[(2) - (2)].query);
         ;}
@@ -2005,7 +2006,7 @@
   case 43:
 
 /* Line 1455 of yacc.c  */
-#line 414 "sql.y"
+#line 415 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -2023,7 +2024,7 @@
   case 44:
 
 /* Line 1455 of yacc.c  */
-#line 430 "sql.y"
+#line 431 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -2046,7 +2047,7 @@
   case 46:
 
 /* Line 1455 of yacc.c  */
-#line 452 "sql.y"
+#line 453 "sql.y"
     {
             (yyvsp[(1) - (3)].column_list)->next = (yyvsp[(3) - (3)].column_list);
         ;}
@@ -2055,7 +2056,7 @@
   case 47:
 
 /* Line 1455 of yacc.c  */
-#line 456 "sql.y"
+#line 457 "sql.y"
     {
             (yyval.column_list) = NULL;
         ;}
@@ -2064,7 +2065,7 @@
   case 49:
 
 /* Line 1455 of yacc.c  */
-#line 464 "sql.y"
+#line 465 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -2082,7 +2083,7 @@
   case 50:
 
 /* Line 1455 of yacc.c  */
-#line 480 "sql.y"
+#line 481 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -2097,13 +2098,12 @@
   case 51:
 
 /* Line 1455 of yacc.c  */
-#line 490 "sql.y"
+#line 491 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
 
             r = JOIN_CreateView( sql->db, &(yyval.query), (yyvsp[(2) - (2)].string) );
-            msi_free( (yyvsp[(2) - (2)].string) );
             if( r != ERROR_SUCCESS )
                 YYABORT;
         ;}
@@ -2114,7 +2114,7 @@
 /* Line 1455 of yacc.c  */
 #line 503 "sql.y"
     {
-            (yyval.string) = strdupW((yyvsp[(1) - (1)].string));
+            (yyval.string) = (yyvsp[(1) - (1)].string);
         ;}
     break;
 
@@ -2123,7 +2123,7 @@
 /* Line 1455 of yacc.c  */
 #line 508 "sql.y"
     {
-            (yyval.string) = parser_add_table((yyvsp[(3) - (3)].string), (yyvsp[(1) - (3)].string));
+            (yyval.string) = parser_add_table( info, (yyvsp[(3) - (3)].string), (yyvsp[(1) - (3)].string) );
             if (!(yyval.string))
                 YYABORT;
         ;}
@@ -2618,17 +2618,20 @@
 #line 697 "sql.y"
 
 
-static LPWSTR parser_add_table(LPWSTR list, LPWSTR table)
-{
-    DWORD size = lstrlenW(list) + lstrlenW(table) + 2;
+static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
+{
     static const WCHAR space[] = {' ',0};
-
-    list = msi_realloc(list, size * sizeof(WCHAR));
-    if (!list) return NULL;
-
-    lstrcatW(list, space);
-    lstrcatW(list, table);
-    return list;
+    DWORD len = strlenW( list ) + strlenW( table ) + 2;
+    LPWSTR ret;
+
+    ret = parser_alloc( info, len * sizeof(WCHAR) );
+    if( ret )
+    {
+        strcpyW( ret, list );
+        strcatW( ret, space );
+        strcatW( ret, table );
+    }
+    return ret;
 }
 
 static void *parser_alloc( void *info, unsigned int sz )

Modified: trunk/reactos/dll/win32/msi/sql.tab.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/sql.tab.h?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/sql.tab.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/sql.tab.h [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -110,7 +110,7 @@
 {
 
 /* Line 1676 of yacc.c  */
-#line 75 "sql.y"
+#line 76 "sql.y"
 
     struct sql_str str;
     LPWSTR string;

Modified: trunk/reactos/dll/win32/msi/sql.y
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/sql.y?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/sql.y [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/sql.y [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -32,6 +32,7 @@
 #include "query.h"
 #include "wine/list.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #define YYLEX_PARAM info
 #define YYPARSE_PARAM info
@@ -54,7 +55,7 @@
 static INT SQL_getint( void *info );
 static int sql_lex( void *SQL_lval, SQL_input *info );
 
-static LPWSTR parser_add_table( LPWSTR list, LPWSTR table );
+static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table );
 static void *parser_alloc( void *info, unsigned int sz );
 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
 
@@ -492,7 +493,6 @@
             UINT r;
 
             r = JOIN_CreateView( sql->db, &$$, $2 );
-            msi_free( $2 );
             if( r != ERROR_SUCCESS )
                 YYABORT;
         }
@@ -501,12 +501,12 @@
 tablelist:
     table
         {
-            $$ = strdupW($1);
+            $$ = $1;
         }
   |
     table TK_COMMA tablelist
         {
-            $$ = parser_add_table($3, $1);
+            $$ = parser_add_table( info, $3, $1 );
             if (!$$)
                 YYABORT;
         }
@@ -696,17 +696,20 @@
 
 %%
 
-static LPWSTR parser_add_table(LPWSTR list, LPWSTR table)
-{
-    DWORD size = lstrlenW(list) + lstrlenW(table) + 2;
+static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
+{
     static const WCHAR space[] = {' ',0};
-
-    list = msi_realloc(list, size * sizeof(WCHAR));
-    if (!list) return NULL;
-
-    lstrcatW(list, space);
-    lstrcatW(list, table);
-    return list;
+    DWORD len = strlenW( list ) + strlenW( table ) + 2;
+    LPWSTR ret;
+
+    ret = parser_alloc( info, len * sizeof(WCHAR) );
+    if( ret )
+    {
+        strcpyW( ret, list );
+        strcatW( ret, space );
+        strcatW( ret, table );
+    }
+    return ret;
 }
 
 static void *parser_alloc( void *info, unsigned int sz )

Modified: trunk/reactos/dll/win32/msi/storages.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/storages.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -559,8 +559,10 @@
 
     rows = add_storages_to_table(sv);
     if (rows < 0)
+    {
+        msi_free( sv );
         return ERROR_FUNCTION_FAILED;
-
+    }
     sv->num_rows = rows;
 
     *view = (MSIVIEW *)sv;

Modified: trunk/reactos/dll/win32/msi/streams.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/streams.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -523,7 +523,10 @@
     sv->db = db;
     rows = add_streams_to_table(sv);
     if (rows < 0)
+    {
+        msi_free( sv );
         return ERROR_FUNCTION_FAILED;
+    }
     sv->num_rows = rows;
 
     *view = (MSIVIEW *)sv;

Modified: trunk/reactos/dll/win32/msi/table.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/table.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/table.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/table.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -1158,6 +1158,93 @@
     return ERROR_SUCCESS;
 }
 
+static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname )
+{
+    LPWSTR p, stname = NULL;
+    UINT i, r, type, ival;
+    DWORD len;
+    LPCWSTR sval;
+    MSIVIEW *view = (MSIVIEW *) tv;
+
+    TRACE("%p %d\n", tv, row);
+
+    len = lstrlenW( tv->name ) + 1;
+    stname = msi_alloc( len*sizeof(WCHAR) );
+    if ( !stname )
+    {
+       r = ERROR_OUTOFMEMORY;
+       goto err;
+    }
+
+    lstrcpyW( stname, tv->name );
+
+    for ( i = 0; i < tv->num_cols; i++ )
+    {
+        type = tv->columns[i].type;
+        if ( type & MSITYPE_KEY )
+        {
+            static const WCHAR szDot[] = { '.', 0 };
+
+            r = TABLE_fetch_int( view, row, i+1, &ival );
+            if ( r != ERROR_SUCCESS )
+                goto err;
+
+            if ( tv->columns[i].type & MSITYPE_STRING )
+            {
+                sval = msi_string_lookup_id( tv->db->strings, ival );
+                if ( !sval )
+                {
+                    r = ERROR_INVALID_PARAMETER;
+                    goto err;
+                }
+            }
+            else
+            {
+                static const WCHAR fmt[] = { '%','d',0 };
+                WCHAR number[0x20];
+                UINT n = bytes_per_column( tv->db, &tv->columns[i] );
+
+                switch( n )
+                {
+                case 2:
+                    sprintfW( number, fmt, ival^0x8000 );
+                    break;
+                case 4:
+                    sprintfW( number, fmt, ival^0x80000000 );
+                    break;
+                default:
+                    ERR( "oops - unknown column width %d\n", n );
+                    r = ERROR_FUNCTION_FAILED;
+                    goto err;
+                }
+                sval = number;
+            }
+
+            len += lstrlenW( szDot ) + lstrlenW( sval );
+            p = msi_realloc ( stname, len*sizeof(WCHAR) );
+            if ( !p )
+            {
+                r = ERROR_OUTOFMEMORY;
+                goto err;
+            }
+            stname = p;
+
+            lstrcatW( stname, szDot );
+            lstrcatW( stname, sval );
+        }
+        else
+           continue;
+    }
+
+    *pstname = stname;
+    return ERROR_SUCCESS;
+
+err:
+    msi_free( stname );
+    *pstname = NULL;
+    return r;
+}
+
 /*
  * We need a special case for streams, as we need to reference column with
  * the name of the stream in the same table, and the table name
@@ -1166,57 +1253,18 @@
 static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
 {
     MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
-    UINT ival = 0, refcol = 0, r;
-    LPCWSTR sval;
-    LPWSTR full_name;
-    DWORD len;
-    static const WCHAR szDot[] = { '.', 0 };
-    WCHAR number[0x20];
+    UINT r;
+    LPWSTR full_name = NULL;
 
     if( !view->ops->fetch_int )
         return ERROR_INVALID_PARAMETER;
 
-    /*
-     * The column marked with the type stream data seems to have a single number
-     * which references the column containing the name of the stream data
-     *
-     * Fetch the column to reference first.
-     */
-    r = view->ops->fetch_int( view, row, col, &ival );
-    if( r != ERROR_SUCCESS )
+    r = msi_stream_name( tv, row, &full_name );
+    if ( r != ERROR_SUCCESS )
+    {
+        ERR("fetching stream, error = %d\n", r);
         return r;
-
-    /* check the column value is in range */
-    if (ival > tv->num_cols || ival == col)
-    {
-        ERR("bad column ref (%u) for stream\n", ival);
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    if ( tv->columns[ival - 1].type & MSITYPE_STRING )
-    {
-        /* now get the column with the name of the stream */
-        r = view->ops->fetch_int( view, row, ival, &refcol );
-        if ( r != ERROR_SUCCESS )
-            return r;
-
-        /* lookup the string value from the string table */
-        sval = msi_string_lookup_id( tv->db->strings, refcol );
-        if ( !sval )
-            return ERROR_INVALID_PARAMETER;
-    }
-    else
-    {
-        static const WCHAR fmt[] = { '%','d',0 };
-        sprintfW( number, fmt, ival );
-        sval = number;
-    }
-
-    len = lstrlenW( tv->name ) + 2 + lstrlenW( sval );
-    full_name = msi_alloc( len*sizeof(WCHAR) );
-    lstrcpyW( full_name, tv->name );
-    lstrcatW( full_name, szDot );
-    lstrcatW( full_name, sval );
+    }
 
     r = db_get_raw_stream( tv->db, full_name, stm );
     if( r )
@@ -1285,6 +1333,46 @@
     return msi_view_get_row(tv->db, view, row, rec);
 }
 
+static UINT msi_addstreamW( MSIDATABASE *db, LPCWSTR name, IStream *data )
+{
+    UINT r;
+    MSIQUERY *query = NULL;
+    MSIRECORD *rec = NULL;
+
+    static const WCHAR insert[] = {
+       'I','N','S','E','R','T',' ','I','N','T','O',' ',
+          '`','_','S','t','r','e','a','m','s','`',' ',
+         '(','`','N','a','m','e','`',',',
+             '`','D','a','t','a','`',')',' ',
+         'V','A','L','U','E','S',' ','(','?',',','?',')',0};
+
+    TRACE("%p %s %p\n", db, debugstr_w(name), data);
+
+    rec = MSI_CreateRecord( 2 );
+    if ( !rec )
+        return ERROR_OUTOFMEMORY;
+
+    r = MSI_RecordSetStringW( rec, 1, name );
+    if ( r != ERROR_SUCCESS )
+       goto err;
+
+    r = MSI_RecordSetIStream( rec, 2, data );
+    if ( r != ERROR_SUCCESS )
+       goto err;
+
+    r = MSI_DatabaseOpenViewW( db, insert, &query );
+    if ( r != ERROR_SUCCESS )
+       goto err;
+
+    r = MSI_ViewExecute( query, rec );
+
+err:
+    msiobj_release( &query->hdr );
+    msiobj_release( &rec->hdr );
+
+    return r;
+}
+
 static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
 {
     MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
@@ -1315,6 +1403,27 @@
         {
             if ( MSITYPE_IS_BINARY(tv->columns[ i ].type) )
             {
+                IStream *stm;
+                LPWSTR stname;
+
+                r = MSI_RecordGetIStream( rec, i + 1, &stm );
+                if ( r != ERROR_SUCCESS )
+                    return r;
+
+                r = msi_stream_name( tv, row, &stname );
+                if ( r != ERROR_SUCCESS )
+                {
+                    IStream_Release( stm );
+                    return r;
+                }
+
+                r = msi_addstreamW( tv->db, stname, stm );
+                IStream_Release( stm );
+                msi_free ( stname );
+
+                if ( r != ERROR_SUCCESS )
+                    return r;
+
                 val = 1; /* refers to the first key column */
             }
             else if ( tv->columns[i].type & MSITYPE_STRING )
@@ -2264,7 +2373,67 @@
     return ret;
 }
 
+static UINT msi_record_encoded_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWSTR *pstname )
+{
+    static const WCHAR szDot[] = { '.', 0 };
+    LPWSTR stname = NULL, sval, p;
+    DWORD len;
+    UINT i, r;
+
+    TRACE("%p %p\n", tv, rec);
+
+    len = lstrlenW( tv->name ) + 1;
+    stname = msi_alloc( len*sizeof(WCHAR) );
+    if ( !stname )
+    {
+       r = ERROR_OUTOFMEMORY;
+       goto err;
+    }
+
+    lstrcpyW( stname, tv->name );
+
+    for ( i = 0; i < tv->num_cols; i++ )
+    {
+        if ( tv->columns[i].type & MSITYPE_KEY )
+        {
+            sval = msi_dup_record_field( rec, i + 1 );
+            if ( !sval )
+            {
+                r = ERROR_OUTOFMEMORY;
+                goto err;
+            }
+
+            len += lstrlenW( szDot ) + lstrlenW ( sval );
+            p = msi_realloc ( stname, len*sizeof(WCHAR) );
+            if ( !p )
+            {
+                r = ERROR_OUTOFMEMORY;
+                goto err;
+            }
+            stname = p;
+
+            lstrcatW( stname, szDot );
+            lstrcatW( stname, sval );
+
+            msi_free( sval );
+        }
+        else
+            continue;
+    }
+
+    *pstname = encode_streamname( FALSE, stname );
+    msi_free( stname );
+
+    return ERROR_SUCCESS;
+
+err:
+    msi_free ( stname );
+    *pstname = NULL;
+    return r;
+}
+
 static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string_table *st,
+                                            IStorage *stg,
                                             const BYTE *rawdata, UINT bytes_per_strref )
 {
     UINT i, val, ofs = 0;
@@ -2288,8 +2457,28 @@
         if ( (~mask&1) && (~columns[i].type & MSITYPE_KEY) && ((1<<i) & ~mask) )
             continue;
 
-        if( (columns[i].type & MSITYPE_STRING) &&
-            ! MSITYPE_IS_BINARY(tv->columns[i].type) )
+        if( MSITYPE_IS_BINARY(tv->columns[i].type) )
+        {
+            LPWSTR encname;
+            IStream *stm = NULL;
+            UINT r;
+
+            ofs += bytes_per_column( tv->db, &columns[i] );
+
+            r = msi_record_encoded_stream_name( tv, rec, &encname );
+            if ( r != ERROR_SUCCESS )
+                return NULL;
+
+            r = IStorage_OpenStream( stg, encname, NULL,
+                     STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm );
+            msi_free( encname );
+            if ( r != ERROR_SUCCESS )
+                return NULL;
+
+            MSI_RecordSetStream( rec, i+1, stm );
+            TRACE(" field %d [%s]\n", i+1, debugstr_w(encname));
+        }
+        else if( columns[i].type & MSITYPE_STRING )
         {
             LPCWSTR sval;
 
@@ -2550,7 +2739,7 @@
             break;
         }
 
-        rec = msi_get_transform_record( tv, st, &rawdata[n], bytes_per_strref );
+        rec = msi_get_transform_record( tv, st, stg, &rawdata[n], bytes_per_strref );
         if (rec)
         {
             if ( mask & 1 )

Modified: trunk/reactos/dll/win32/msi/update.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/update.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msi/update.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/update.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -261,7 +261,10 @@
 
     uv = msi_alloc_zero( sizeof *uv );
     if( !uv )
-        return ERROR_FUNCTION_FAILED;
+    {
+        wv->ops->delete( wv );
+        return ERROR_FUNCTION_FAILED;
+    }
 
     /* fill the structure */
     uv->view.ops = &update_ops;

Modified: trunk/reactos/dll/win32/msxml3/node.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msxml3/node.c?rev=41310&r1=41309&r2=41310&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msxml3/node.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msxml3/node.c [iso-8859-1] Sat Jun  6 19:59:47 2009
@@ -369,8 +369,8 @@
 
     TRACE("%p %p\n", This, type);
 
-    assert( NODE_ELEMENT == XML_ELEMENT_NODE );
-    assert( NODE_NOTATION == XML_NOTATION_NODE );
+    assert( (int)NODE_ELEMENT  == (int)XML_ELEMENT_NODE );
+    assert( (int)NODE_NOTATION == (int)XML_NOTATION_NODE );
 
     *type = This->node->type;
 



More information about the Ros-diffs mailing list