mirror of
https://github.com/reactos/reactos.git
synced 2024-07-15 08:56:08 +00:00
Sync to Wine-20050111:
Vitaly Lipatov <lav@etersoft.ru> - Get real screen properties. - Add description for MsiGetMode, MSIRUNMODE constants. - Add ScreenX, ScreenY, ColorBits installer properties. Mike McCormack <mike@codeweavers.com> - Add a simple test case for MSI databases. - Remove unneeded whitespace, indent correctly. - Remove more fixed length buffers, rewrite functions to return malloc'ed memory. - Remove a lot of fixed length buffers. - Implement thread safety for records. - Fix selecting string columns and matching against a wildcard. - Implement MsiRecordSetStreamA/W and add tests for records containing streams. - Fix records according to test cases. - Fix transposition of 4 byte values when reading in table data from storage. - MsiCloseAllHandles only closes handles allocated in the calling thread. Francois Gouget <fgouget@free.fr> - Assorted spelling fixes. Aric Stewart <aric@codeweavers.com> - Make all custom type 1 actions happen in a seperate thread and close all handles for that thread when it exits. Honors the concept of temporary MSI handles for custom actions. - Properly deformat keys written to the registry. - Because directory mappings can change between the CostFinalize step and the InstallFiles step we need to do a final resolution of the target file name before installing. - When checking for an existing .lnk shortcut extension on the filename do not just search for '.' but actually verify it is '.lnk'. - CustomAction 35 should call SetTargetPath not just set the property. - TARGETDIR and SOURCEDIR may not be entries 0 in the directory tables. So when resolving the folder we need to seek them out. - When we handle SetTargetPath we need to be sure to recalculate the resulting paths as things with the now set Directory as the parent will change. - Change how we install files so that we extract files as we need them, cuts down on extraction time and unused files. - Improve progress bar tracking. - Be sure that set paths are terminated with a backslash. - Free allocated buffers. - Parse out the full features by using the ',' character and do comparisons based on the full feature names. - Continue when a duplicate component is found and loaded. - Rework how we handle Feature and Component States. I have confirmed from testing that, although documented nowhere, having ADDLOCAL on the install line overrides INSTALLLEVEL. - Track all files extracted from cabinents as tempfiles so they can be removed at the end of the install to not leave uninstalled but uncabbed files laying around. - Move Install Features selection and evaluation into CostFinalize. - Allow for end of install actions. - Create the shortcut directory if it does not exist. - Set the INSTALLLEVEL in CostFinalize if it is not set. - Eliminate some fixed length buffers. - Enable asynchronous dll custom action calls. - Make sure to include trailing backslash in path. - Move around and rename some functions. - Fix incorrect return code check. - Fix folder resolution. - Let negative number be parsed correctly. Needed for accessing actions with sequences such as -1. - Added MsiSetExternalUIW. - Include a System16Folder definition. - Free allocated buffers. - Blank the property buffers even if the property is not found. - Include the trailing backslash on the Windows volume. - Fix folder resolution. Eric Pouech <pouech-eric@wanadoo.fr> - Fixed some errors in function prototypes. Steven Edwards <steven@codeweavers.com> - Add and fix some stubs. Ulrich Czekalla <ulrich@codeweavers.com> - Set the out buffer count to zero on read error. Michael Stefaniuc <mstefani@redhat.de> - Add missing HeapFree's (found by smatch). Paul Vriens <Paul.Vriens@xs4all.nl> - Use Interlocked* functions in AddRef and Release. svn path=/trunk/; revision=12948
This commit is contained in:
parent
e620ebee7f
commit
7fb581fc0b
|
@ -59,7 +59,30 @@ typedef enum tagMSIMODIFY
|
||||||
#define MSIDBOPEN_TRANSACT (LPCTSTR)1
|
#define MSIDBOPEN_TRANSACT (LPCTSTR)1
|
||||||
#define MSIDBOPEN_DIRECT (LPCTSTR)2
|
#define MSIDBOPEN_DIRECT (LPCTSTR)2
|
||||||
#define MSIDBOPEN_CREATE (LPCTSTR)3
|
#define MSIDBOPEN_CREATE (LPCTSTR)3
|
||||||
|
#define MSIDBOPEN_CREATEDIRECT (LPCTSTR)4
|
||||||
|
|
||||||
|
typedef enum tagMSIRUNMODE
|
||||||
|
{
|
||||||
|
MSIRUNMODE_ADMIN = 0,
|
||||||
|
MSIRUNMODE_ADVERTISE = 1,
|
||||||
|
MSIRUNMODE_MAINTENANCE = 2,
|
||||||
|
MSIRUNMODE_ROLLBACKENABLED = 3,
|
||||||
|
MSIRUNMODE_LOGENABLED = 4,
|
||||||
|
MSIRUNMODE_OPERATIONS = 5,
|
||||||
|
MSIRUNMODE_REBOOTATEND = 6,
|
||||||
|
MSIRUNMODE_REBOOTNOW = 7,
|
||||||
|
MSIRUNMODE_CABINET = 8,
|
||||||
|
MSIRUNMODE_SOURCESHORTNAMES = 9,
|
||||||
|
MSIRUNMODE_TARGETSHORTNAMES = 10,
|
||||||
|
MSIRUNMODE_RESERVED11 = 11,
|
||||||
|
MSIRUNMODE_WINDOWS9X = 12,
|
||||||
|
MSIRUNMODE_ZAWENABLED = 13,
|
||||||
|
MSIRUNMODE_RESERVED14 = 14,
|
||||||
|
MSIRUNMODE_RESERVED15 = 15,
|
||||||
|
MSIRUNMODE_SCHEDULED = 16,
|
||||||
|
MSIRUNMODE_ROLLBACK = 17,
|
||||||
|
MSIRUNMODE_COMMIT = 18
|
||||||
|
} MSIRUNMODE;
|
||||||
|
|
||||||
/* view manipulation */
|
/* view manipulation */
|
||||||
UINT WINAPI MsiViewFetch(MSIHANDLE,MSIHANDLE*);
|
UINT WINAPI MsiViewFetch(MSIHANDLE,MSIHANDLE*);
|
||||||
|
@ -123,15 +146,12 @@ MSICONDITION WINAPI MsiEvaluateConditionW(MSIHANDLE,LPCWSTR);
|
||||||
#define MsiEvaluateCondition WINELIB_NAME_AW(MsiEvaluateCondition)
|
#define MsiEvaluateCondition WINELIB_NAME_AW(MsiEvaluateCondition)
|
||||||
|
|
||||||
/* property functions */
|
/* property functions */
|
||||||
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName,
|
UINT WINAPI MsiGetPropertyA(MSIHANDLE, LPCSTR, LPSTR, DWORD*);
|
||||||
LPSTR szValueBuf, DWORD* pchValueBuf);
|
UINT WINAPI MsiGetPropertyW(MSIHANDLE, LPCWSTR, LPWSTR, DWORD*);
|
||||||
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
|
|
||||||
LPWSTR szValueBuf, DWORD* pchValueBuf);
|
|
||||||
#define MsiGetProperty WINELIB_NAME_AW(MsiGetProperty)
|
#define MsiGetProperty WINELIB_NAME_AW(MsiGetProperty)
|
||||||
|
|
||||||
UINT WINAPI MsiSetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue);
|
UINT WINAPI MsiSetPropertyA(MSIHANDLE, LPCSTR, LPCSTR);
|
||||||
UINT WINAPI MsiSetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
|
UINT WINAPI MsiSetPropertyW(MSIHANDLE, LPCWSTR, LPCWSTR);
|
||||||
LPCWSTR szValue);
|
|
||||||
#define MsiSetProperty WINELIB_NAME_AW(MsiSetProperty)
|
#define MsiSetProperty WINELIB_NAME_AW(MsiSetProperty)
|
||||||
|
|
||||||
UINT WINAPI MsiGetTargetPathA(MSIHANDLE,LPCSTR,LPSTR,DWORD*);
|
UINT WINAPI MsiGetTargetPathA(MSIHANDLE,LPCSTR,LPSTR,DWORD*);
|
||||||
|
@ -155,4 +175,6 @@ UINT WINAPI MsiSetFeatureStateA( MSIHANDLE, LPCSTR, INSTALLSTATE);
|
||||||
UINT WINAPI MsiSetFeatureStateW(MSIHANDLE, LPCWSTR, INSTALLSTATE);
|
UINT WINAPI MsiSetFeatureStateW(MSIHANDLE, LPCWSTR, INSTALLSTATE);
|
||||||
#define MsiSetFeatureState WINELIB_NAME_AW(MsiSetFeatureState)
|
#define MsiSetFeatureState WINELIB_NAME_AW(MsiSetFeatureState)
|
||||||
|
|
||||||
|
BOOL WINAPI MsiGetMode(MSIHANDLE, MSIRUNMODE);
|
||||||
|
|
||||||
#endif /* __WINE_MSIQUERY_H */
|
#endif /* __WINE_MSIQUERY_H */
|
||||||
|
|
|
@ -3,7 +3,7 @@ TOPOBJDIR = ../..
|
||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = msi.dll
|
MODULE = msi.dll
|
||||||
IMPORTS = shell32 cabinet oleaut32 ole32 version user32 advapi32 kernel32
|
IMPORTS = shell32 cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32
|
||||||
EXTRALIBS = -luuid $(LIBUNICODE)
|
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
@ -31,6 +31,8 @@ RC_SRCS = version.rc
|
||||||
EXTRA_SRCS = sql.y cond.y
|
EXTRA_SRCS = sql.y cond.y
|
||||||
EXTRA_OBJS = sql.tab.o cond.tab.o
|
EXTRA_OBJS = sql.tab.o cond.tab.o
|
||||||
|
|
||||||
|
SUBDIRS = tests
|
||||||
|
|
||||||
@MAKE_DLL_RULES@
|
@MAKE_DLL_RULES@
|
||||||
|
|
||||||
sql.tab.c sql.tab.h: sql.y
|
sql.tab.c sql.tab.h: sql.y
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,7 +41,23 @@ static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
MSIOBJECTHDR *msihandletable[MSIMAXHANDLES];
|
static CRITICAL_SECTION MSI_object_cs;
|
||||||
|
static CRITICAL_SECTION_DEBUG MSI_object_cs_debug =
|
||||||
|
{
|
||||||
|
0, 0, &MSI_object_cs,
|
||||||
|
{ &MSI_object_cs_debug.ProcessLocksList,
|
||||||
|
&MSI_object_cs_debug.ProcessLocksList },
|
||||||
|
0, 0, { 0, (DWORD)(__FILE__ ": MSI_object_cs") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
typedef struct msi_handle_info_t
|
||||||
|
{
|
||||||
|
MSIOBJECTHDR *obj;
|
||||||
|
DWORD dwThreadId;
|
||||||
|
} msi_handle_info;
|
||||||
|
|
||||||
|
static msi_handle_info msihandletable[MSIMAXHANDLES];
|
||||||
|
|
||||||
MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
|
MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
|
||||||
{
|
{
|
||||||
|
@ -52,13 +68,14 @@ MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
|
||||||
|
|
||||||
/* find a slot */
|
/* find a slot */
|
||||||
for(i=0; i<MSIMAXHANDLES; i++)
|
for(i=0; i<MSIMAXHANDLES; i++)
|
||||||
if( !msihandletable[i] )
|
if( !msihandletable[i].obj )
|
||||||
break;
|
break;
|
||||||
if( (i>=MSIMAXHANDLES) || msihandletable[i] )
|
if( (i>=MSIMAXHANDLES) || msihandletable[i].obj )
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
msiobj_addref( obj );
|
msiobj_addref( obj );
|
||||||
msihandletable[i] = obj;
|
msihandletable[i].obj = obj;
|
||||||
|
msihandletable[i].dwThreadId = GetCurrentThreadId();
|
||||||
ret = (MSIHANDLE) (i+1);
|
ret = (MSIHANDLE) (i+1);
|
||||||
out:
|
out:
|
||||||
TRACE("%p -> %ld\n", obj, ret );
|
TRACE("%p -> %ld\n", obj, ret );
|
||||||
|
@ -77,13 +94,13 @@ void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
|
||||||
goto out;
|
goto out;
|
||||||
if( handle>=MSIMAXHANDLES )
|
if( handle>=MSIMAXHANDLES )
|
||||||
goto out;
|
goto out;
|
||||||
if( !msihandletable[handle] )
|
if( !msihandletable[handle].obj )
|
||||||
goto out;
|
goto out;
|
||||||
if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
|
if( msihandletable[handle].obj->magic != MSIHANDLE_MAGIC )
|
||||||
goto out;
|
goto out;
|
||||||
if( type && (msihandletable[handle]->type != type) )
|
if( type && (msihandletable[handle].obj->type != type) )
|
||||||
goto out;
|
goto out;
|
||||||
ret = msihandletable[handle];
|
ret = msihandletable[handle].obj;
|
||||||
msiobj_addref( ret );
|
msiobj_addref( ret );
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -101,7 +118,7 @@ MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
|
||||||
|
|
||||||
EnterCriticalSection( &MSI_handle_cs );
|
EnterCriticalSection( &MSI_handle_cs );
|
||||||
for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
|
for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
|
||||||
if( msihandletable[i] == hdr )
|
if( msihandletable[i].obj == hdr )
|
||||||
ret = i+1;
|
ret = i+1;
|
||||||
LeaveCriticalSection( &MSI_handle_cs );
|
LeaveCriticalSection( &MSI_handle_cs );
|
||||||
|
|
||||||
|
@ -143,6 +160,16 @@ void msiobj_addref( MSIOBJECTHDR *info )
|
||||||
info->refcount++;
|
info->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void msiobj_lock( MSIOBJECTHDR *info )
|
||||||
|
{
|
||||||
|
EnterCriticalSection( &MSI_object_cs );
|
||||||
|
}
|
||||||
|
|
||||||
|
void msiobj_unlock( MSIOBJECTHDR *info )
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &MSI_object_cs );
|
||||||
|
}
|
||||||
|
|
||||||
int msiobj_release( MSIOBJECTHDR *info )
|
int msiobj_release( MSIOBJECTHDR *info )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -170,6 +197,9 @@ int msiobj_release( MSIOBJECTHDR *info )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* MsiCloseHandle [MSI.@]
|
||||||
|
*/
|
||||||
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
|
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
|
||||||
{
|
{
|
||||||
MSIOBJECTHDR *info;
|
MSIOBJECTHDR *info;
|
||||||
|
@ -190,7 +220,7 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
msiobj_release( info );
|
msiobj_release( info );
|
||||||
msihandletable[handle-1] = NULL;
|
msihandletable[handle-1].obj = NULL;
|
||||||
ret = ERROR_SUCCESS;
|
ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
TRACE("handle %lx Destroyed\n", handle);
|
TRACE("handle %lx Destroyed\n", handle);
|
||||||
|
@ -202,14 +232,28 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* MsiCloseAllHandles [MSI.@]
|
||||||
|
*
|
||||||
|
* Closes all handles owned by the current thread
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* The number of handles closed
|
||||||
|
*/
|
||||||
UINT WINAPI MsiCloseAllHandles(void)
|
UINT WINAPI MsiCloseAllHandles(void)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i, n=0;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
for(i=0; i<MSIMAXHANDLES; i++)
|
for(i=0; i<MSIMAXHANDLES; i++)
|
||||||
|
{
|
||||||
|
if(msihandletable[i].dwThreadId == GetCurrentThreadId())
|
||||||
|
{
|
||||||
MsiCloseHandle( i+1 );
|
MsiCloseHandle( i+1 );
|
||||||
|
n++;
|
||||||
return 0;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ static const WCHAR szComponents[] = {
|
||||||
INSTALLUILEVEL gUILevel;
|
INSTALLUILEVEL gUILevel;
|
||||||
HWND gUIhwnd;
|
HWND gUIhwnd;
|
||||||
INSTALLUI_HANDLERA gUIHandler;
|
INSTALLUI_HANDLERA gUIHandler;
|
||||||
|
INSTALLUI_HANDLERW gUIHandlerW;
|
||||||
DWORD gUIFilter;
|
DWORD gUIFilter;
|
||||||
LPVOID gUIContext;
|
LPVOID gUIContext;
|
||||||
WCHAR gszLogFile[MAX_PATH];
|
WCHAR gszLogFile[MAX_PATH];
|
||||||
|
@ -849,6 +850,19 @@ INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
|
||||||
|
DWORD dwMessageFilter, LPVOID pvContext)
|
||||||
|
{
|
||||||
|
INSTALLUI_HANDLERW prev = gUIHandlerW;
|
||||||
|
|
||||||
|
TRACE("(%p %lx %p)\n",puiHandler,dwMessageFilter,pvContext);
|
||||||
|
gUIHandlerW = puiHandler;
|
||||||
|
gUIFilter = dwMessageFilter;
|
||||||
|
gUIContext = pvContext;
|
||||||
|
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
|
UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
|
||||||
{
|
{
|
||||||
/*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
|
/*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
|
||||||
|
@ -1505,13 +1519,13 @@ static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVO
|
||||||
|
|
||||||
static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface) {
|
static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface) {
|
||||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||||
return ++(This->ref);
|
return InterlockedIncrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) {
|
static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) {
|
||||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||||
/* static class, won't be freed */
|
/* static class, won't be freed */
|
||||||
return --(This->ref);
|
return InterlockedDecrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
|
static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
|
||||||
|
@ -1592,10 +1606,34 @@ BOOL WINAPI MSI_DllCanUnloadNow(void)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiEnumRelatedProductsA (LPCSTR lpUpgradeCode, DWORD dwReserved,
|
UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
|
||||||
DWORD iProductIndex, LPSTR lpProductBuf)
|
DWORD iProductIndex, LPWSTR lpProductBuf)
|
||||||
{
|
{
|
||||||
FIXME("STUB: (%s, %li %li %s)\n",lpUpgradeCode, dwReserved, iProductIndex,
|
FIXME("%s %lu %lu %p\n", debugstr_w(szUpgradeCode), dwReserved,
|
||||||
lpProductBuf);
|
iProductIndex, lpProductBuf);
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,
|
||||||
|
DWORD iProductIndex, LPSTR lpProductBuf)
|
||||||
|
{
|
||||||
|
FIXME("%s %lu %lu %p\n", debugstr_a(szUpgradeCode), dwReserved,
|
||||||
|
iProductIndex, lpProductBuf);
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
|
||||||
|
DWORD* pdwUseCount, WORD* pwDateUsed)
|
||||||
|
{
|
||||||
|
FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
|
||||||
|
pdwUseCount, pwDateUsed);
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
|
||||||
|
DWORD* pdwUseCount, WORD* pwDateUsed)
|
||||||
|
{
|
||||||
|
FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
|
||||||
|
pdwUseCount, pwDateUsed);
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
56 stub MsiGetFeatureInfoW
|
56 stub MsiGetFeatureInfoW
|
||||||
57 stdcall MsiGetFeatureStateA(long str ptr ptr)
|
57 stdcall MsiGetFeatureStateA(long str ptr ptr)
|
||||||
58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
|
58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
|
||||||
59 stub MsiGetFeatureUsageA
|
59 stdcall MsiGetFeatureUsageA(str str ptr ptr)
|
||||||
60 stub MsiGetFeatureUsageW
|
60 stdcall MsiGetFeatureUsageW(wstr wstr ptr ptr)
|
||||||
61 stub MsiGetFeatureValidStatesA
|
61 stub MsiGetFeatureValidStatesA
|
||||||
62 stub MsiGetFeatureValidStatesW
|
62 stub MsiGetFeatureValidStatesW
|
||||||
63 stub MsiGetLanguage
|
63 stub MsiGetLanguage
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
134 stub MsiSetComponentStateA
|
134 stub MsiSetComponentStateA
|
||||||
135 stub MsiSetComponentStateW
|
135 stub MsiSetComponentStateW
|
||||||
136 stdcall MsiSetExternalUIA(ptr long ptr)
|
136 stdcall MsiSetExternalUIA(ptr long ptr)
|
||||||
137 stub MsiSetExternalUIW
|
137 stdcall MsiSetExternalUIW(ptr long ptr)
|
||||||
138 stdcall MsiSetFeatureStateA(long str long)
|
138 stdcall MsiSetFeatureStateA(long str long)
|
||||||
139 stdcall MsiSetFeatureStateW(long wstr long)
|
139 stdcall MsiSetFeatureStateW(long wstr long)
|
||||||
140 stub MsiSetInstallLevel
|
140 stub MsiSetInstallLevel
|
||||||
|
@ -201,8 +201,8 @@
|
||||||
201 stub MsiDecomposeDescriptorW
|
201 stub MsiDecomposeDescriptorW
|
||||||
202 stub MsiProvideQualifiedComponentExA
|
202 stub MsiProvideQualifiedComponentExA
|
||||||
203 stub MsiProvideQualifiedComponentExW
|
203 stub MsiProvideQualifiedComponentExW
|
||||||
204 stdcall MsiEnumRelatedProductsA(str long long str)
|
204 stdcall MsiEnumRelatedProductsA(str long long ptr)
|
||||||
205 stub MsiEnumRelatedProductsW
|
205 stdcall MsiEnumRelatedProductsW(wstr long long ptr)
|
||||||
206 stub MsiSetFeatureAttributesA
|
206 stub MsiSetFeatureAttributesA
|
||||||
207 stub MsiSetFeatureAttributesW
|
207 stub MsiSetFeatureAttributesW
|
||||||
208 stub MsiSourceListClearAllA
|
208 stub MsiSourceListClearAllA
|
||||||
|
|
|
@ -194,6 +194,8 @@ typedef struct tagMSIPACKAGE
|
||||||
UINT loaded_components;
|
UINT loaded_components;
|
||||||
struct tagMSIFILE *files;
|
struct tagMSIFILE *files;
|
||||||
UINT loaded_files;
|
UINT loaded_files;
|
||||||
|
LPWSTR ActionFormat;
|
||||||
|
LPWSTR LastAction;
|
||||||
} MSIPACKAGE;
|
} MSIPACKAGE;
|
||||||
|
|
||||||
#define MSIHANDLETYPE_ANY 0
|
#define MSIHANDLETYPE_ANY 0
|
||||||
|
@ -228,6 +230,8 @@ extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
|
||||||
extern void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy );
|
extern void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy );
|
||||||
extern void msiobj_addref(MSIOBJECTHDR *);
|
extern void msiobj_addref(MSIOBJECTHDR *);
|
||||||
extern int msiobj_release(MSIOBJECTHDR *);
|
extern int msiobj_release(MSIOBJECTHDR *);
|
||||||
|
extern void msiobj_lock(MSIOBJECTHDR *);
|
||||||
|
extern void msiobj_unlock(MSIOBJECTHDR *);
|
||||||
extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
|
extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
|
||||||
|
|
||||||
/* add this table to the list of cached tables in the database */
|
/* add this table to the list of cached tables in the database */
|
||||||
|
@ -269,6 +273,7 @@ extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
|
||||||
USHORT **pdata, UINT *psz );
|
USHORT **pdata, UINT *psz );
|
||||||
extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
|
extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
|
||||||
extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
|
extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
|
||||||
|
extern void ACTION_free_package_structures( MSIPACKAGE* );
|
||||||
|
|
||||||
/* record internals */
|
/* record internals */
|
||||||
extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
|
extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "shlwapi.h"
|
#include "shlwapi.h"
|
||||||
|
#include "wingdi.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "msi.h"
|
#include "msi.h"
|
||||||
#include "msiquery.h"
|
#include "msiquery.h"
|
||||||
|
@ -53,18 +54,8 @@ void MSI_FreePackage( MSIOBJECTHDR *arg)
|
||||||
MSIPACKAGE *package= (MSIPACKAGE*) arg;
|
MSIPACKAGE *package= (MSIPACKAGE*) arg;
|
||||||
|
|
||||||
ACTION_remove_tracked_tempfiles(package);
|
ACTION_remove_tracked_tempfiles(package);
|
||||||
|
ACTION_free_package_structures(package);
|
||||||
|
|
||||||
if (package->features && package->loaded_features > 0)
|
|
||||||
HeapFree(GetProcessHeap(),0,package->features);
|
|
||||||
|
|
||||||
if (package->folders && package->loaded_folders > 0)
|
|
||||||
HeapFree(GetProcessHeap(),0,package->folders);
|
|
||||||
|
|
||||||
if (package->components && package->loaded_components > 0)
|
|
||||||
HeapFree(GetProcessHeap(),0,package->components);
|
|
||||||
|
|
||||||
if (package->files && package->loaded_files > 0)
|
|
||||||
HeapFree(GetProcessHeap(),0,package->files);
|
|
||||||
msiobj_release( &package->db->hdr );
|
msiobj_release( &package->db->hdr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +160,11 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/prope
|
||||||
static VOID set_installer_properties(MSIPACKAGE *package)
|
static VOID set_installer_properties(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
WCHAR pth[MAX_PATH];
|
WCHAR pth[MAX_PATH];
|
||||||
|
WCHAR *ptr;
|
||||||
OSVERSIONINFOA OSVersion;
|
OSVERSIONINFOA OSVersion;
|
||||||
DWORD verval;
|
DWORD verval;
|
||||||
WCHAR verstr[10], msiver[10];
|
WCHAR verstr[10], bufstr[20];
|
||||||
|
HDC dc;
|
||||||
|
|
||||||
static const WCHAR cszbs[]={'\\',0};
|
static const WCHAR cszbs[]={'\\',0};
|
||||||
static const WCHAR CFF[] =
|
static const WCHAR CFF[] =
|
||||||
|
@ -202,6 +195,8 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
||||||
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
||||||
static const WCHAR SF[] =
|
static const WCHAR SF[] =
|
||||||
{'S','y','s','t','e','m','F','o','l','d','e','r',0};
|
{'S','y','s','t','e','m','F','o','l','d','e','r',0};
|
||||||
|
static const WCHAR SF16[] =
|
||||||
|
{'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
|
||||||
static const WCHAR LADF[] =
|
static const WCHAR LADF[] =
|
||||||
{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
||||||
static const WCHAR MPF[] =
|
static const WCHAR MPF[] =
|
||||||
|
@ -210,6 +205,8 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
||||||
{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
|
{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
|
||||||
static const WCHAR WF[] =
|
static const WCHAR WF[] =
|
||||||
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
|
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
|
||||||
|
static const WCHAR WV[] =
|
||||||
|
{'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
|
||||||
static const WCHAR TF[]=
|
static const WCHAR TF[]=
|
||||||
{'T','e','m','p','F','o','l','d','e','r',0};
|
{'T','e','m','p','F','o','l','d','e','r',0};
|
||||||
static const WCHAR szAdminUser[] =
|
static const WCHAR szAdminUser[] =
|
||||||
|
@ -229,12 +226,15 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
||||||
|
|
||||||
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
|
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
|
||||||
static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
|
static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
|
||||||
|
/* Screen properties */
|
||||||
|
static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0};
|
||||||
|
static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
|
||||||
|
static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
|
||||||
|
static const WCHAR szScreenFormat[] = {'%','d',0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other things I notice set
|
* Other things I notice set
|
||||||
*
|
*
|
||||||
ScreenY
|
|
||||||
ScreenX
|
|
||||||
SystemLanguageID
|
SystemLanguageID
|
||||||
ComputerName
|
ComputerName
|
||||||
UserLanguageID
|
UserLanguageID
|
||||||
|
@ -251,7 +251,6 @@ CaptionHeight
|
||||||
BorderTop
|
BorderTop
|
||||||
BorderSide
|
BorderSide
|
||||||
TextHeight
|
TextHeight
|
||||||
ColorBits
|
|
||||||
RedirectedDllSupport
|
RedirectedDllSupport
|
||||||
Time
|
Time
|
||||||
Date
|
Date
|
||||||
|
@ -313,6 +312,7 @@ Privileged
|
||||||
SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
|
SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
|
||||||
strcatW(pth,cszbs);
|
strcatW(pth,cszbs);
|
||||||
MSI_SetPropertyW(package, SF, pth);
|
MSI_SetPropertyW(package, SF, pth);
|
||||||
|
MSI_SetPropertyW(package, SF16, pth);
|
||||||
|
|
||||||
SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
|
SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
|
||||||
strcatW(pth,cszbs);
|
strcatW(pth,cszbs);
|
||||||
|
@ -330,6 +330,12 @@ Privileged
|
||||||
strcatW(pth,cszbs);
|
strcatW(pth,cszbs);
|
||||||
MSI_SetPropertyW(package, WF, pth);
|
MSI_SetPropertyW(package, WF, pth);
|
||||||
|
|
||||||
|
SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
|
||||||
|
ptr = strchrW(pth,'\\');
|
||||||
|
if (ptr)
|
||||||
|
*(ptr+1) = 0;
|
||||||
|
MSI_SetPropertyW(package, WV, pth);
|
||||||
|
|
||||||
GetTempPathW(MAX_PATH,pth);
|
GetTempPathW(MAX_PATH,pth);
|
||||||
MSI_SetPropertyW(package, TF, pth);
|
MSI_SetPropertyW(package, TF, pth);
|
||||||
|
|
||||||
|
@ -357,8 +363,18 @@ Privileged
|
||||||
/* just fudge this */
|
/* just fudge this */
|
||||||
MSI_SetPropertyW(package,szSPL,szSix);
|
MSI_SetPropertyW(package,szSPL,szSix);
|
||||||
|
|
||||||
sprintfW( msiver, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
|
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
|
||||||
MSI_SetPropertyW( package, szVersionMsi, msiver );
|
MSI_SetPropertyW( package, szVersionMsi, bufstr );
|
||||||
|
|
||||||
|
/* Screen properties. */
|
||||||
|
dc = GetDC(0);
|
||||||
|
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, HORZRES ) );
|
||||||
|
MSI_SetPropertyW( package, szScreenX, bufstr );
|
||||||
|
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, VERTRES ));
|
||||||
|
MSI_SetPropertyW( package, szScreenY, bufstr );
|
||||||
|
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, BITSPIXEL ));
|
||||||
|
MSI_SetPropertyW( package, szColorBits, bufstr );
|
||||||
|
ReleaseDC(0, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
||||||
|
@ -406,6 +422,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
||||||
package->loaded_folders = 0;
|
package->loaded_folders = 0;
|
||||||
package->loaded_components= 0;
|
package->loaded_components= 0;
|
||||||
package->loaded_files = 0;
|
package->loaded_files = 0;
|
||||||
|
package->ActionFormat = NULL;
|
||||||
|
package->LastAction = NULL;
|
||||||
|
|
||||||
/* OK, here is where we do a slew of things to the database to
|
/* OK, here is where we do a slew of things to the database to
|
||||||
* prep for all that is to come as a package */
|
* prep for all that is to come as a package */
|
||||||
|
@ -747,6 +765,10 @@ UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName,
|
||||||
UINT rc;
|
UINT rc;
|
||||||
|
|
||||||
rc = MSI_GetPropertyRow(package, szName, &row);
|
rc = MSI_GetPropertyRow(package, szName, &row);
|
||||||
|
|
||||||
|
if (*pchValueBuf > 0)
|
||||||
|
szValueBuf[0] = 0;
|
||||||
|
|
||||||
if (rc == ERROR_SUCCESS)
|
if (rc == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
|
rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
|
||||||
|
@ -756,6 +778,9 @@ UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName,
|
||||||
if (rc == ERROR_SUCCESS)
|
if (rc == ERROR_SUCCESS)
|
||||||
TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
|
TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
|
||||||
debugstr_w(szName));
|
debugstr_w(szName));
|
||||||
|
else if (rc == ERROR_MORE_DATA)
|
||||||
|
TRACE("need %li sized buffer for %s\n", *pchValueBuf,
|
||||||
|
debugstr_w(szName));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*pchValueBuf = 0;
|
*pchValueBuf = 0;
|
||||||
|
@ -772,6 +797,9 @@ UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName,
|
||||||
UINT rc, len;
|
UINT rc, len;
|
||||||
LPWSTR szwName;
|
LPWSTR szwName;
|
||||||
|
|
||||||
|
if (*pchValueBuf > 0)
|
||||||
|
szValueBuf[0] = 0;
|
||||||
|
|
||||||
len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
|
len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
|
||||||
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||||
if (!szwName)
|
if (!szwName)
|
||||||
|
@ -788,6 +816,9 @@ UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName,
|
||||||
if (rc == ERROR_SUCCESS)
|
if (rc == ERROR_SUCCESS)
|
||||||
TRACE("returning %s for property %s\n", debugstr_a(szValueBuf),
|
TRACE("returning %s for property %s\n", debugstr_a(szValueBuf),
|
||||||
debugstr_a(szName));
|
debugstr_a(szName));
|
||||||
|
else if (rc == ERROR_MORE_DATA)
|
||||||
|
TRACE("need %ld sized buffer for %s\n", *pchValueBuf,
|
||||||
|
debugstr_a(szName));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*pchValueBuf = 0;
|
*pchValueBuf = 0;
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#define EXPR_STRCMP 7
|
#define EXPR_STRCMP 7
|
||||||
#define EXPR_UTF8 8
|
#define EXPR_UTF8 8
|
||||||
#define EXPR_WILDCARD 9
|
#define EXPR_WILDCARD 9
|
||||||
|
#define EXPR_COL_NUMBER_STRING 10
|
||||||
|
|
||||||
struct sql_str {
|
struct sql_str {
|
||||||
LPCWSTR data;
|
LPCWSTR data;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "msipriv.h"
|
#include "msipriv.h"
|
||||||
#include "objidl.h"
|
#include "objidl.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
|
@ -77,6 +78,9 @@ MSIRECORD *MSI_CreateRecord( unsigned int cParams )
|
||||||
|
|
||||||
TRACE("%d\n", cParams);
|
TRACE("%d\n", cParams);
|
||||||
|
|
||||||
|
if( cParams>65535 )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams;
|
len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams;
|
||||||
rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord );
|
rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord );
|
||||||
if( rec )
|
if( rec )
|
||||||
|
@ -111,12 +115,11 @@ unsigned int WINAPI MsiRecordGetFieldCount( MSIHANDLE handle )
|
||||||
|
|
||||||
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
if( !rec )
|
if( !rec )
|
||||||
{
|
return -1;
|
||||||
ERR("Record not found!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordGetFieldCount( rec );
|
ret = MSI_RecordGetFieldCount( rec );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -180,7 +183,9 @@ int WINAPI MsiRecordGetInteger( MSIHANDLE handle, unsigned int iField)
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return MSI_NULL_INTEGER;
|
return MSI_NULL_INTEGER;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordGetInteger( rec, iField );
|
ret = MSI_RecordGetInteger( rec, iField );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -197,12 +202,14 @@ UINT WINAPI MsiRecordClearData( MSIHANDLE handle )
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
for( i=0; i<=rec->count; i++)
|
for( i=0; i<=rec->count; i++)
|
||||||
{
|
{
|
||||||
MSI_FreeField( &rec->fields[i] );
|
MSI_FreeField( &rec->fields[i] );
|
||||||
rec->fields[i].type = MSIFIELD_NULL;
|
rec->fields[i].type = MSIFIELD_NULL;
|
||||||
rec->fields[i].u.iVal = 0;
|
rec->fields[i].u.iVal = 0;
|
||||||
}
|
}
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -211,12 +218,12 @@ UINT MSI_RecordSetInteger( MSIRECORD *rec, unsigned int iField, int iVal )
|
||||||
{
|
{
|
||||||
TRACE("%p %u %d\n", rec, iField, iVal);
|
TRACE("%p %u %d\n", rec, iField, iVal);
|
||||||
|
|
||||||
if( iField <= rec->count )
|
if( iField > rec->count )
|
||||||
{
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
MSI_FreeField( &rec->fields[iField] );
|
MSI_FreeField( &rec->fields[iField] );
|
||||||
rec->fields[iField].type = MSIFIELD_INT;
|
rec->fields[iField].type = MSIFIELD_INT;
|
||||||
rec->fields[iField].u.iVal = iVal;
|
rec->fields[iField].u.iVal = iVal;
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +239,9 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordSetInteger( rec, iField, iVal );
|
ret = MSI_RecordSetInteger( rec, iField, iVal );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -258,8 +267,10 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
|
||||||
|
|
||||||
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return 0;
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordIsNull( rec, iField );
|
ret = MSI_RecordIsNull( rec, iField );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -289,9 +300,12 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, unsigned int iField,
|
||||||
NULL, 0 , NULL, NULL);
|
NULL, 0 , NULL, NULL);
|
||||||
WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
|
WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
|
||||||
szValue, *pcchValue, NULL, NULL);
|
szValue, *pcchValue, NULL, NULL);
|
||||||
|
if( *pcchValue && len>*pcchValue )
|
||||||
|
szValue[*pcchValue-1] = 0;
|
||||||
|
if( len )
|
||||||
|
len--;
|
||||||
break;
|
break;
|
||||||
case MSIFIELD_NULL:
|
case MSIFIELD_NULL:
|
||||||
len = 1;
|
|
||||||
if( *pcchValue > 0 )
|
if( *pcchValue > 0 )
|
||||||
szValue[0] = 0;
|
szValue[0] = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -318,7 +332,9 @@ UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField,
|
||||||
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordGetStringA( rec, iField, szValue, pcchValue);
|
ret = MSI_RecordGetStringA( rec, iField, szValue, pcchValue);
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -385,15 +401,47 @@ UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, unsigned int iField,
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordGetStringW( rec, iField, szValue, pcchValue );
|
ret = MSI_RecordGetStringW( rec, iField, szValue, pcchValue );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiRecordDataSize(MSIHANDLE hRecord, unsigned int iField)
|
UINT MSI_RecordDataSize(MSIRECORD *rec, unsigned int iField)
|
||||||
{
|
{
|
||||||
FIXME("%ld %d\n", hRecord, iField);
|
TRACE("%p %d\n", rec, iField);
|
||||||
|
|
||||||
|
if( iField > rec->count )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
switch( rec->fields[iField].type )
|
||||||
|
{
|
||||||
|
case MSIFIELD_INT:
|
||||||
|
return sizeof (INT);
|
||||||
|
case MSIFIELD_WSTR:
|
||||||
|
return lstrlenW( rec->fields[iField].u.szwVal );
|
||||||
|
case MSIFIELD_NULL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiRecordDataSize(MSIHANDLE handle, unsigned int iField)
|
||||||
|
{
|
||||||
|
MSIRECORD *rec;
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
|
TRACE("%ld %d\n", handle, iField);
|
||||||
|
|
||||||
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
|
if( !rec )
|
||||||
|
return 0;
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
|
ret = MSI_RecordDataSize( rec, iField);
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
|
msiobj_release( &rec->hdr );
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
|
UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
|
||||||
|
@ -426,7 +474,9 @@ UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, unsigned int iField, LPCSTR s
|
||||||
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordSetStringA( rec, iField, szValue );
|
ret = MSI_RecordSetStringA( rec, iField, szValue );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -463,7 +513,9 @@ UINT WINAPI MsiRecordSetStringW( MSIHANDLE handle, unsigned int iField, LPCWSTR
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordSetStringW( rec, iField, szValue );
|
ret = MSI_RecordSetStringW( rec, iField, szValue );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -480,16 +532,133 @@ UINT WINAPI MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, LPWSTR szRes
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR szFilename)
|
/* read the data in a file into an IStream */
|
||||||
|
UINT RECORD_StreamFromFile(LPCWSTR szFile, IStream **pstm)
|
||||||
{
|
{
|
||||||
FIXME("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
|
DWORD sz, szHighWord = 0, read;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
HANDLE handle;
|
||||||
|
HGLOBAL hGlob = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
ULARGE_INTEGER ulSize;
|
||||||
|
|
||||||
|
TRACE("reading %s\n", debugstr_w(szFile));
|
||||||
|
|
||||||
|
/* read the file into memory */
|
||||||
|
handle = CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if( handle == INVALID_HANDLE_VALUE )
|
||||||
|
return GetLastError();
|
||||||
|
sz = GetFileSize(handle, &szHighWord);
|
||||||
|
if( sz != INVALID_FILE_SIZE && szHighWord == 0 )
|
||||||
|
{
|
||||||
|
hGlob = GlobalAlloc(GMEM_FIXED, sz);
|
||||||
|
if( hGlob )
|
||||||
|
{
|
||||||
|
BOOL r = ReadFile(handle, hGlob, sz, &read, NULL);
|
||||||
|
if( !r )
|
||||||
|
{
|
||||||
|
GlobalFree(hGlob);
|
||||||
|
hGlob = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(handle);
|
||||||
|
if( !hGlob )
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
/* make a stream out of it, and set the correct file size */
|
||||||
|
hr = CreateStreamOnHGlobal(hGlob, TRUE, pstm);
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
GlobalFree(hGlob);
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiRecordSetStreamW(MSIHANDLE hRecord, unsigned int iField, LPCWSTR szFilename)
|
/* set the correct size - CreateStreamOnHGlobal screws it up */
|
||||||
|
ulSize.QuadPart = sz;
|
||||||
|
IStream_SetSize(*pstm, ulSize);
|
||||||
|
|
||||||
|
TRACE("read %s, %ld bytes into IStream %p\n", debugstr_w(szFile), sz, *pstm);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSI_RecordSetStreamW(MSIRECORD *rec, unsigned int iField, LPCWSTR szFilename)
|
||||||
{
|
{
|
||||||
FIXME("%ld %d %s\n", hRecord, iField, debugstr_w(szFilename));
|
IStream *stm = NULL;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
HRESULT r;
|
||||||
|
|
||||||
|
if( (iField == 0) || (iField > rec->count) )
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* no filename means we should seek back to the start of the stream */
|
||||||
|
if( !szFilename )
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ofs;
|
||||||
|
ULARGE_INTEGER cur;
|
||||||
|
|
||||||
|
if( rec->fields[iField].type != MSIFIELD_STREAM )
|
||||||
|
return ERROR_INVALID_FIELD;
|
||||||
|
|
||||||
|
stm = rec->fields[iField].u.stream;
|
||||||
|
if( !stm )
|
||||||
|
return ERROR_INVALID_FIELD;
|
||||||
|
|
||||||
|
ofs.QuadPart = 0;
|
||||||
|
r = IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
|
||||||
|
if( FAILED( r ) )
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* read the file into a stream and save the stream in the record */
|
||||||
|
r = RECORD_StreamFromFile(szFilename, &stm);
|
||||||
|
if( r != ERROR_SUCCESS )
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* if all's good, store it in the record */
|
||||||
|
MSI_FreeField( &rec->fields[iField] );
|
||||||
|
rec->fields[iField].type = MSIFIELD_STREAM;
|
||||||
|
rec->fields[iField].u.stream = stm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR szFilename)
|
||||||
|
{
|
||||||
|
LPWSTR wstr = NULL;
|
||||||
|
UINT ret, len;
|
||||||
|
|
||||||
|
TRACE("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
|
||||||
|
|
||||||
|
if( szFilename )
|
||||||
|
{
|
||||||
|
len = MultiByteToWideChar(CP_ACP,0,szFilename,-1,NULL,0);
|
||||||
|
wstr = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
|
||||||
|
MultiByteToWideChar(CP_ACP,0,szFilename,-1,wstr,len);
|
||||||
|
}
|
||||||
|
ret = MsiRecordSetStreamW(hRecord, iField, wstr);
|
||||||
|
HeapFree(GetProcessHeap(),0,wstr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiRecordSetStreamW(MSIHANDLE handle, unsigned int iField, LPCWSTR szFilename)
|
||||||
|
{
|
||||||
|
MSIRECORD *rec;
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
|
TRACE("%ld %d %s\n", handle, iField, debugstr_w(szFilename));
|
||||||
|
|
||||||
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
|
if( !rec )
|
||||||
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
|
ret = MSI_RecordSetStreamW( rec, iField, szFilename );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
|
msiobj_release( &rec->hdr );
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD *sz)
|
UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD *sz)
|
||||||
|
@ -500,18 +669,18 @@ UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD
|
||||||
|
|
||||||
TRACE("%p %d %p %p\n", rec, iField, buf, sz);
|
TRACE("%p %d %p %p\n", rec, iField, buf, sz);
|
||||||
|
|
||||||
|
if( !sz )
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( iField > rec->count)
|
if( iField > rec->count)
|
||||||
return ERROR_INVALID_FIELD;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( rec->fields[iField].type != MSIFIELD_STREAM )
|
if( rec->fields[iField].type != MSIFIELD_STREAM )
|
||||||
{
|
return ERROR_INVALID_DATATYPE;
|
||||||
*sz = 0;
|
|
||||||
return ERROR_INVALID_FIELD;
|
|
||||||
}
|
|
||||||
|
|
||||||
stm = rec->fields[iField].u.stream;
|
stm = rec->fields[iField].u.stream;
|
||||||
if( !stm )
|
if( !stm )
|
||||||
return ERROR_INVALID_FIELD;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* if there's no buffer pointer, calculate the length to the end */
|
/* if there's no buffer pointer, calculate the length to the end */
|
||||||
if( !buf )
|
if( !buf )
|
||||||
|
@ -554,7 +723,9 @@ UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, unsigned int iField, char *buf
|
||||||
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
|
||||||
if( !rec )
|
if( !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
msiobj_lock( &rec->hdr );
|
||||||
ret = MSI_RecordReadStream( rec, iField, buf, sz );
|
ret = MSI_RecordReadStream( rec, iField, buf, sz );
|
||||||
|
msiobj_unlock( &rec->hdr );
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,329 @@
|
||||||
#ifndef BISON_SQL_TAB_H
|
/* A Bison parser, made by GNU Bison 1.875b. */
|
||||||
# define BISON_SQL_TAB_H
|
|
||||||
|
|
||||||
#ifndef YYSTYPE
|
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||||
typedef union
|
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
{
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* As a special exception, when this file is copied by Bison into a
|
||||||
|
Bison output file, you may use that output file without restriction.
|
||||||
|
This special exception was added by the Free Software Foundation
|
||||||
|
in version 1.24 of Bison. */
|
||||||
|
|
||||||
|
/* Tokens. */
|
||||||
|
#ifndef YYTOKENTYPE
|
||||||
|
# define YYTOKENTYPE
|
||||||
|
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||||
|
know about them. */
|
||||||
|
enum yytokentype {
|
||||||
|
TK_ABORT = 258,
|
||||||
|
TK_AFTER = 259,
|
||||||
|
TK_AGG_FUNCTION = 260,
|
||||||
|
TK_ALL = 261,
|
||||||
|
TK_AND = 262,
|
||||||
|
TK_AS = 263,
|
||||||
|
TK_ASC = 264,
|
||||||
|
TK_BEFORE = 265,
|
||||||
|
TK_BEGIN = 266,
|
||||||
|
TK_BETWEEN = 267,
|
||||||
|
TK_BITAND = 268,
|
||||||
|
TK_BITNOT = 269,
|
||||||
|
TK_BITOR = 270,
|
||||||
|
TK_BY = 271,
|
||||||
|
TK_CASCADE = 272,
|
||||||
|
TK_CASE = 273,
|
||||||
|
TK_CHAR = 274,
|
||||||
|
TK_CHECK = 275,
|
||||||
|
TK_CLUSTER = 276,
|
||||||
|
TK_COLLATE = 277,
|
||||||
|
TK_COLUMN = 278,
|
||||||
|
TK_COMMA = 279,
|
||||||
|
TK_COMMENT = 280,
|
||||||
|
TK_COMMIT = 281,
|
||||||
|
TK_CONCAT = 282,
|
||||||
|
TK_CONFLICT = 283,
|
||||||
|
TK_CONSTRAINT = 284,
|
||||||
|
TK_COPY = 285,
|
||||||
|
TK_CREATE = 286,
|
||||||
|
TK_DEFAULT = 287,
|
||||||
|
TK_DEFERRABLE = 288,
|
||||||
|
TK_DEFERRED = 289,
|
||||||
|
TK_DELETE = 290,
|
||||||
|
TK_DELIMITERS = 291,
|
||||||
|
TK_DESC = 292,
|
||||||
|
TK_DISTINCT = 293,
|
||||||
|
TK_DOT = 294,
|
||||||
|
TK_DROP = 295,
|
||||||
|
TK_EACH = 296,
|
||||||
|
TK_ELSE = 297,
|
||||||
|
TK_END = 298,
|
||||||
|
TK_END_OF_FILE = 299,
|
||||||
|
TK_EQ = 300,
|
||||||
|
TK_EXCEPT = 301,
|
||||||
|
TK_EXPLAIN = 302,
|
||||||
|
TK_FAIL = 303,
|
||||||
|
TK_FLOAT = 304,
|
||||||
|
TK_FOR = 305,
|
||||||
|
TK_FOREIGN = 306,
|
||||||
|
TK_FROM = 307,
|
||||||
|
TK_FUNCTION = 308,
|
||||||
|
TK_GE = 309,
|
||||||
|
TK_GLOB = 310,
|
||||||
|
TK_GROUP = 311,
|
||||||
|
TK_GT = 312,
|
||||||
|
TK_HAVING = 313,
|
||||||
|
TK_HOLD = 314,
|
||||||
|
TK_IGNORE = 315,
|
||||||
|
TK_ILLEGAL = 316,
|
||||||
|
TK_IMMEDIATE = 317,
|
||||||
|
TK_IN = 318,
|
||||||
|
TK_INDEX = 319,
|
||||||
|
TK_INITIALLY = 320,
|
||||||
|
TK_ID = 321,
|
||||||
|
TK_INSERT = 322,
|
||||||
|
TK_INSTEAD = 323,
|
||||||
|
TK_INT = 324,
|
||||||
|
TK_INTEGER = 325,
|
||||||
|
TK_INTERSECT = 326,
|
||||||
|
TK_INTO = 327,
|
||||||
|
TK_IS = 328,
|
||||||
|
TK_ISNULL = 329,
|
||||||
|
TK_JOIN = 330,
|
||||||
|
TK_JOIN_KW = 331,
|
||||||
|
TK_KEY = 332,
|
||||||
|
TK_LE = 333,
|
||||||
|
TK_LIKE = 334,
|
||||||
|
TK_LIMIT = 335,
|
||||||
|
TK_LONG = 336,
|
||||||
|
TK_LONGCHAR = 337,
|
||||||
|
TK_LP = 338,
|
||||||
|
TK_LSHIFT = 339,
|
||||||
|
TK_LT = 340,
|
||||||
|
TK_LOCALIZABLE = 341,
|
||||||
|
TK_MATCH = 342,
|
||||||
|
TK_MINUS = 343,
|
||||||
|
TK_NE = 344,
|
||||||
|
TK_NOT = 345,
|
||||||
|
TK_NOTNULL = 346,
|
||||||
|
TK_NULL = 347,
|
||||||
|
TK_OBJECT = 348,
|
||||||
|
TK_OF = 349,
|
||||||
|
TK_OFFSET = 350,
|
||||||
|
TK_ON = 351,
|
||||||
|
TK_OR = 352,
|
||||||
|
TK_ORACLE_OUTER_JOIN = 353,
|
||||||
|
TK_ORDER = 354,
|
||||||
|
TK_PLUS = 355,
|
||||||
|
TK_PRAGMA = 356,
|
||||||
|
TK_PRIMARY = 357,
|
||||||
|
TK_RAISE = 358,
|
||||||
|
TK_REFERENCES = 359,
|
||||||
|
TK_REM = 360,
|
||||||
|
TK_REPLACE = 361,
|
||||||
|
TK_RESTRICT = 362,
|
||||||
|
TK_ROLLBACK = 363,
|
||||||
|
TK_ROW = 364,
|
||||||
|
TK_RP = 365,
|
||||||
|
TK_RSHIFT = 366,
|
||||||
|
TK_SELECT = 367,
|
||||||
|
TK_SEMI = 368,
|
||||||
|
TK_SET = 369,
|
||||||
|
TK_SHORT = 370,
|
||||||
|
TK_SLASH = 371,
|
||||||
|
TK_SPACE = 372,
|
||||||
|
TK_STAR = 373,
|
||||||
|
TK_STATEMENT = 374,
|
||||||
|
TK_STRING = 375,
|
||||||
|
TK_TABLE = 376,
|
||||||
|
TK_TEMP = 377,
|
||||||
|
TK_THEN = 378,
|
||||||
|
TK_TRANSACTION = 379,
|
||||||
|
TK_TRIGGER = 380,
|
||||||
|
TK_UMINUS = 381,
|
||||||
|
TK_UNCLOSED_STRING = 382,
|
||||||
|
TK_UNION = 383,
|
||||||
|
TK_UNIQUE = 384,
|
||||||
|
TK_UPDATE = 385,
|
||||||
|
TK_UPLUS = 386,
|
||||||
|
TK_USING = 387,
|
||||||
|
TK_VACUUM = 388,
|
||||||
|
TK_VALUES = 389,
|
||||||
|
TK_VIEW = 390,
|
||||||
|
TK_WHEN = 391,
|
||||||
|
TK_WHERE = 392,
|
||||||
|
TK_WILDCARD = 393,
|
||||||
|
COLUMN = 395,
|
||||||
|
FUNCTION = 396,
|
||||||
|
COMMENT = 397,
|
||||||
|
UNCLOSED_STRING = 398,
|
||||||
|
SPACE = 399,
|
||||||
|
ILLEGAL = 400,
|
||||||
|
END_OF_FILE = 401
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#define TK_ABORT 258
|
||||||
|
#define TK_AFTER 259
|
||||||
|
#define TK_AGG_FUNCTION 260
|
||||||
|
#define TK_ALL 261
|
||||||
|
#define TK_AND 262
|
||||||
|
#define TK_AS 263
|
||||||
|
#define TK_ASC 264
|
||||||
|
#define TK_BEFORE 265
|
||||||
|
#define TK_BEGIN 266
|
||||||
|
#define TK_BETWEEN 267
|
||||||
|
#define TK_BITAND 268
|
||||||
|
#define TK_BITNOT 269
|
||||||
|
#define TK_BITOR 270
|
||||||
|
#define TK_BY 271
|
||||||
|
#define TK_CASCADE 272
|
||||||
|
#define TK_CASE 273
|
||||||
|
#define TK_CHAR 274
|
||||||
|
#define TK_CHECK 275
|
||||||
|
#define TK_CLUSTER 276
|
||||||
|
#define TK_COLLATE 277
|
||||||
|
#define TK_COLUMN 278
|
||||||
|
#define TK_COMMA 279
|
||||||
|
#define TK_COMMENT 280
|
||||||
|
#define TK_COMMIT 281
|
||||||
|
#define TK_CONCAT 282
|
||||||
|
#define TK_CONFLICT 283
|
||||||
|
#define TK_CONSTRAINT 284
|
||||||
|
#define TK_COPY 285
|
||||||
|
#define TK_CREATE 286
|
||||||
|
#define TK_DEFAULT 287
|
||||||
|
#define TK_DEFERRABLE 288
|
||||||
|
#define TK_DEFERRED 289
|
||||||
|
#define TK_DELETE 290
|
||||||
|
#define TK_DELIMITERS 291
|
||||||
|
#define TK_DESC 292
|
||||||
|
#define TK_DISTINCT 293
|
||||||
|
#define TK_DOT 294
|
||||||
|
#define TK_DROP 295
|
||||||
|
#define TK_EACH 296
|
||||||
|
#define TK_ELSE 297
|
||||||
|
#define TK_END 298
|
||||||
|
#define TK_END_OF_FILE 299
|
||||||
|
#define TK_EQ 300
|
||||||
|
#define TK_EXCEPT 301
|
||||||
|
#define TK_EXPLAIN 302
|
||||||
|
#define TK_FAIL 303
|
||||||
|
#define TK_FLOAT 304
|
||||||
|
#define TK_FOR 305
|
||||||
|
#define TK_FOREIGN 306
|
||||||
|
#define TK_FROM 307
|
||||||
|
#define TK_FUNCTION 308
|
||||||
|
#define TK_GE 309
|
||||||
|
#define TK_GLOB 310
|
||||||
|
#define TK_GROUP 311
|
||||||
|
#define TK_GT 312
|
||||||
|
#define TK_HAVING 313
|
||||||
|
#define TK_HOLD 314
|
||||||
|
#define TK_IGNORE 315
|
||||||
|
#define TK_ILLEGAL 316
|
||||||
|
#define TK_IMMEDIATE 317
|
||||||
|
#define TK_IN 318
|
||||||
|
#define TK_INDEX 319
|
||||||
|
#define TK_INITIALLY 320
|
||||||
|
#define TK_ID 321
|
||||||
|
#define TK_INSERT 322
|
||||||
|
#define TK_INSTEAD 323
|
||||||
|
#define TK_INT 324
|
||||||
|
#define TK_INTEGER 325
|
||||||
|
#define TK_INTERSECT 326
|
||||||
|
#define TK_INTO 327
|
||||||
|
#define TK_IS 328
|
||||||
|
#define TK_ISNULL 329
|
||||||
|
#define TK_JOIN 330
|
||||||
|
#define TK_JOIN_KW 331
|
||||||
|
#define TK_KEY 332
|
||||||
|
#define TK_LE 333
|
||||||
|
#define TK_LIKE 334
|
||||||
|
#define TK_LIMIT 335
|
||||||
|
#define TK_LONG 336
|
||||||
|
#define TK_LONGCHAR 337
|
||||||
|
#define TK_LP 338
|
||||||
|
#define TK_LSHIFT 339
|
||||||
|
#define TK_LT 340
|
||||||
|
#define TK_LOCALIZABLE 341
|
||||||
|
#define TK_MATCH 342
|
||||||
|
#define TK_MINUS 343
|
||||||
|
#define TK_NE 344
|
||||||
|
#define TK_NOT 345
|
||||||
|
#define TK_NOTNULL 346
|
||||||
|
#define TK_NULL 347
|
||||||
|
#define TK_OBJECT 348
|
||||||
|
#define TK_OF 349
|
||||||
|
#define TK_OFFSET 350
|
||||||
|
#define TK_ON 351
|
||||||
|
#define TK_OR 352
|
||||||
|
#define TK_ORACLE_OUTER_JOIN 353
|
||||||
|
#define TK_ORDER 354
|
||||||
|
#define TK_PLUS 355
|
||||||
|
#define TK_PRAGMA 356
|
||||||
|
#define TK_PRIMARY 357
|
||||||
|
#define TK_RAISE 358
|
||||||
|
#define TK_REFERENCES 359
|
||||||
|
#define TK_REM 360
|
||||||
|
#define TK_REPLACE 361
|
||||||
|
#define TK_RESTRICT 362
|
||||||
|
#define TK_ROLLBACK 363
|
||||||
|
#define TK_ROW 364
|
||||||
|
#define TK_RP 365
|
||||||
|
#define TK_RSHIFT 366
|
||||||
|
#define TK_SELECT 367
|
||||||
|
#define TK_SEMI 368
|
||||||
|
#define TK_SET 369
|
||||||
|
#define TK_SHORT 370
|
||||||
|
#define TK_SLASH 371
|
||||||
|
#define TK_SPACE 372
|
||||||
|
#define TK_STAR 373
|
||||||
|
#define TK_STATEMENT 374
|
||||||
|
#define TK_STRING 375
|
||||||
|
#define TK_TABLE 376
|
||||||
|
#define TK_TEMP 377
|
||||||
|
#define TK_THEN 378
|
||||||
|
#define TK_TRANSACTION 379
|
||||||
|
#define TK_TRIGGER 380
|
||||||
|
#define TK_UMINUS 381
|
||||||
|
#define TK_UNCLOSED_STRING 382
|
||||||
|
#define TK_UNION 383
|
||||||
|
#define TK_UNIQUE 384
|
||||||
|
#define TK_UPDATE 385
|
||||||
|
#define TK_UPLUS 386
|
||||||
|
#define TK_USING 387
|
||||||
|
#define TK_VACUUM 388
|
||||||
|
#define TK_VALUES 389
|
||||||
|
#define TK_VIEW 390
|
||||||
|
#define TK_WHEN 391
|
||||||
|
#define TK_WHERE 392
|
||||||
|
#define TK_WILDCARD 393
|
||||||
|
#define COLUMN 395
|
||||||
|
#define FUNCTION 396
|
||||||
|
#define COMMENT 397
|
||||||
|
#define UNCLOSED_STRING 398
|
||||||
|
#define SPACE 399
|
||||||
|
#define ILLEGAL 400
|
||||||
|
#define END_OF_FILE 401
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||||
|
#line 74 "./sql.y"
|
||||||
|
typedef union YYSTYPE {
|
||||||
struct sql_str str;
|
struct sql_str str;
|
||||||
LPWSTR string;
|
LPWSTR string;
|
||||||
string_list *column_list;
|
string_list *column_list;
|
||||||
|
@ -13,153 +333,15 @@ typedef union
|
||||||
USHORT column_type;
|
USHORT column_type;
|
||||||
create_col_info *column_info;
|
create_col_info *column_info;
|
||||||
column_assignment update_col_info;
|
column_assignment update_col_info;
|
||||||
} yystype;
|
} YYSTYPE;
|
||||||
# define YYSTYPE yystype
|
/* Line 1252 of yacc.c. */
|
||||||
|
#line 339 "sql.tab.h"
|
||||||
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
#endif
|
#endif
|
||||||
# define TK_ABORT 257
|
|
||||||
# define TK_AFTER 258
|
|
||||||
# define TK_AGG_FUNCTION 259
|
|
||||||
# define TK_ALL 260
|
|
||||||
# define TK_AND 261
|
|
||||||
# define TK_AS 262
|
|
||||||
# define TK_ASC 263
|
|
||||||
# define TK_BEFORE 264
|
|
||||||
# define TK_BEGIN 265
|
|
||||||
# define TK_BETWEEN 266
|
|
||||||
# define TK_BITAND 267
|
|
||||||
# define TK_BITNOT 268
|
|
||||||
# define TK_BITOR 269
|
|
||||||
# define TK_BY 270
|
|
||||||
# define TK_CASCADE 271
|
|
||||||
# define TK_CASE 272
|
|
||||||
# define TK_CHAR 273
|
|
||||||
# define TK_CHECK 274
|
|
||||||
# define TK_CLUSTER 275
|
|
||||||
# define TK_COLLATE 276
|
|
||||||
# define TK_COLUMN 277
|
|
||||||
# define TK_COMMA 278
|
|
||||||
# define TK_COMMENT 279
|
|
||||||
# define TK_COMMIT 280
|
|
||||||
# define TK_CONCAT 281
|
|
||||||
# define TK_CONFLICT 282
|
|
||||||
# define TK_CONSTRAINT 283
|
|
||||||
# define TK_COPY 284
|
|
||||||
# define TK_CREATE 285
|
|
||||||
# define TK_DEFAULT 286
|
|
||||||
# define TK_DEFERRABLE 287
|
|
||||||
# define TK_DEFERRED 288
|
|
||||||
# define TK_DELETE 289
|
|
||||||
# define TK_DELIMITERS 290
|
|
||||||
# define TK_DESC 291
|
|
||||||
# define TK_DISTINCT 292
|
|
||||||
# define TK_DOT 293
|
|
||||||
# define TK_DROP 294
|
|
||||||
# define TK_EACH 295
|
|
||||||
# define TK_ELSE 296
|
|
||||||
# define TK_END 297
|
|
||||||
# define TK_END_OF_FILE 298
|
|
||||||
# define TK_EQ 299
|
|
||||||
# define TK_EXCEPT 300
|
|
||||||
# define TK_EXPLAIN 301
|
|
||||||
# define TK_FAIL 302
|
|
||||||
# define TK_FLOAT 303
|
|
||||||
# define TK_FOR 304
|
|
||||||
# define TK_FOREIGN 305
|
|
||||||
# define TK_FROM 306
|
|
||||||
# define TK_FUNCTION 307
|
|
||||||
# define TK_GE 308
|
|
||||||
# define TK_GLOB 309
|
|
||||||
# define TK_GROUP 310
|
|
||||||
# define TK_GT 311
|
|
||||||
# define TK_HAVING 312
|
|
||||||
# define TK_HOLD 313
|
|
||||||
# define TK_IGNORE 314
|
|
||||||
# define TK_ILLEGAL 315
|
|
||||||
# define TK_IMMEDIATE 316
|
|
||||||
# define TK_IN 317
|
|
||||||
# define TK_INDEX 318
|
|
||||||
# define TK_INITIALLY 319
|
|
||||||
# define TK_ID 320
|
|
||||||
# define TK_INSERT 321
|
|
||||||
# define TK_INSTEAD 322
|
|
||||||
# define TK_INT 323
|
|
||||||
# define TK_INTEGER 324
|
|
||||||
# define TK_INTERSECT 325
|
|
||||||
# define TK_INTO 326
|
|
||||||
# define TK_IS 327
|
|
||||||
# define TK_ISNULL 328
|
|
||||||
# define TK_JOIN 329
|
|
||||||
# define TK_JOIN_KW 330
|
|
||||||
# define TK_KEY 331
|
|
||||||
# define TK_LE 332
|
|
||||||
# define TK_LIKE 333
|
|
||||||
# define TK_LIMIT 334
|
|
||||||
# define TK_LONG 335
|
|
||||||
# define TK_LONGCHAR 336
|
|
||||||
# define TK_LP 337
|
|
||||||
# define TK_LSHIFT 338
|
|
||||||
# define TK_LT 339
|
|
||||||
# define TK_LOCALIZABLE 340
|
|
||||||
# define TK_MATCH 341
|
|
||||||
# define TK_MINUS 342
|
|
||||||
# define TK_NE 343
|
|
||||||
# define TK_NOT 344
|
|
||||||
# define TK_NOTNULL 345
|
|
||||||
# define TK_NULL 346
|
|
||||||
# define TK_OBJECT 347
|
|
||||||
# define TK_OF 348
|
|
||||||
# define TK_OFFSET 349
|
|
||||||
# define TK_ON 350
|
|
||||||
# define TK_OR 351
|
|
||||||
# define TK_ORACLE_OUTER_JOIN 352
|
|
||||||
# define TK_ORDER 353
|
|
||||||
# define TK_PLUS 354
|
|
||||||
# define TK_PRAGMA 355
|
|
||||||
# define TK_PRIMARY 356
|
|
||||||
# define TK_RAISE 357
|
|
||||||
# define TK_REFERENCES 358
|
|
||||||
# define TK_REM 359
|
|
||||||
# define TK_REPLACE 360
|
|
||||||
# define TK_RESTRICT 361
|
|
||||||
# define TK_ROLLBACK 362
|
|
||||||
# define TK_ROW 363
|
|
||||||
# define TK_RP 364
|
|
||||||
# define TK_RSHIFT 365
|
|
||||||
# define TK_SELECT 366
|
|
||||||
# define TK_SEMI 367
|
|
||||||
# define TK_SET 368
|
|
||||||
# define TK_SHORT 369
|
|
||||||
# define TK_SLASH 370
|
|
||||||
# define TK_SPACE 371
|
|
||||||
# define TK_STAR 372
|
|
||||||
# define TK_STATEMENT 373
|
|
||||||
# define TK_STRING 374
|
|
||||||
# define TK_TABLE 375
|
|
||||||
# define TK_TEMP 376
|
|
||||||
# define TK_THEN 377
|
|
||||||
# define TK_TRANSACTION 378
|
|
||||||
# define TK_TRIGGER 379
|
|
||||||
# define TK_UMINUS 380
|
|
||||||
# define TK_UNCLOSED_STRING 381
|
|
||||||
# define TK_UNION 382
|
|
||||||
# define TK_UNIQUE 383
|
|
||||||
# define TK_UPDATE 384
|
|
||||||
# define TK_UPLUS 385
|
|
||||||
# define TK_USING 386
|
|
||||||
# define TK_VACUUM 387
|
|
||||||
# define TK_VALUES 388
|
|
||||||
# define TK_VIEW 389
|
|
||||||
# define TK_WHEN 390
|
|
||||||
# define TK_WHERE 391
|
|
||||||
# define TK_WILDCARD 392
|
|
||||||
# define END_OF_FILE 393
|
|
||||||
# define ILLEGAL 394
|
|
||||||
# define SPACE 395
|
|
||||||
# define UNCLOSED_STRING 396
|
|
||||||
# define COMMENT 397
|
|
||||||
# define FUNCTION 398
|
|
||||||
# define COLUMN 399
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* not BISON_SQL_TAB_H */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
|
||||||
|
|
||||||
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
|
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
|
||||||
static struct expr * EXPR_column( LPWSTR );
|
static struct expr * EXPR_column( LPWSTR );
|
||||||
static struct expr * EXPR_ival( struct sql_str *);
|
static struct expr * EXPR_ival( struct sql_str *, int sign);
|
||||||
static struct expr * EXPR_sval( struct sql_str *);
|
static struct expr * EXPR_sval( struct sql_str *);
|
||||||
static struct expr * EXPR_wildcard(void);
|
static struct expr * EXPR_wildcard(void);
|
||||||
|
|
||||||
|
@ -543,7 +543,11 @@ column_assignment:
|
||||||
const_val:
|
const_val:
|
||||||
TK_INTEGER
|
TK_INTEGER
|
||||||
{
|
{
|
||||||
$$ = EXPR_ival( &$1 );
|
$$ = EXPR_ival( &$1, 1 );
|
||||||
|
}
|
||||||
|
| TK_MINUS TK_INTEGER
|
||||||
|
{
|
||||||
|
$$ = EXPR_ival( &$2, -1 );
|
||||||
}
|
}
|
||||||
| TK_STRING
|
| TK_STRING
|
||||||
{
|
{
|
||||||
|
@ -717,13 +721,13 @@ static struct expr * EXPR_column( LPWSTR str )
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct expr * EXPR_ival( struct sql_str *str )
|
static struct expr * EXPR_ival( struct sql_str *str , int sign)
|
||||||
{
|
{
|
||||||
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
|
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
|
||||||
if( e )
|
if( e )
|
||||||
{
|
{
|
||||||
e->type = EXPR_IVAL;
|
e->type = EXPR_IVAL;
|
||||||
e->u.ival = atoiW( str->data );
|
e->u.ival = atoiW( str->data ) * sign;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1088,7 +1088,7 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Data [%d][%d] = %d \n", row, col, *val );
|
/* TRACE("Data [%d][%d] = %d \n", row, col, *val ); */
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ static const WCHAR *STRING_evaluate( string_table *st,
|
||||||
|
|
||||||
switch( expr->type )
|
switch( expr->type )
|
||||||
{
|
{
|
||||||
case EXPR_COL_NUMBER:
|
case EXPR_COL_NUMBER_STRING:
|
||||||
r = table->ops->fetch_int( table, row, expr->u.col_number, &val );
|
r = table->ops->fetch_int( table, row, expr->u.col_number, &val );
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -190,6 +190,7 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
|
||||||
|
|
||||||
switch( cond->type )
|
switch( cond->type )
|
||||||
{
|
{
|
||||||
|
case EXPR_COL_NUMBER_STRING:
|
||||||
case EXPR_COL_NUMBER:
|
case EXPR_COL_NUMBER:
|
||||||
return table->ops->fetch_int( table, row, cond->u.col_number, val );
|
return table->ops->fetch_int( table, row, cond->u.col_number, val );
|
||||||
|
|
||||||
|
@ -368,9 +369,19 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
|
||||||
r = VIEW_find_column( table, cond->u.column, &val );
|
r = VIEW_find_column( table, cond->u.column, &val );
|
||||||
if( r == ERROR_SUCCESS )
|
if( r == ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
*valid = 1;
|
UINT type = 0;
|
||||||
|
r = table->ops->get_column_info( table, val, NULL, &type );
|
||||||
|
if( r == ERROR_SUCCESS )
|
||||||
|
{
|
||||||
|
if (type&MSITYPE_STRING)
|
||||||
|
cond->type = EXPR_COL_NUMBER_STRING;
|
||||||
|
else
|
||||||
cond->type = EXPR_COL_NUMBER;
|
cond->type = EXPR_COL_NUMBER;
|
||||||
cond->u.col_number = val;
|
cond->u.col_number = val;
|
||||||
|
*valid = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*valid = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -390,7 +401,9 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
|
||||||
|
|
||||||
/* check the type of the comparison */
|
/* check the type of the comparison */
|
||||||
if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
|
if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
|
||||||
( cond->u.expr.right->type == EXPR_SVAL ) )
|
( cond->u.expr.left->type == EXPR_COL_NUMBER_STRING ) ||
|
||||||
|
( cond->u.expr.right->type == EXPR_SVAL ) ||
|
||||||
|
( cond->u.expr.right->type == EXPR_COL_NUMBER_STRING ) )
|
||||||
{
|
{
|
||||||
switch( cond->u.expr.op )
|
switch( cond->u.expr.op )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue