static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq, BOOL UI);
-/*
- * action handlers
- */
-typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
-
-static UINT ACTION_LaunchConditions(MSIPACKAGE *package);
-static UINT ACTION_CostInitialize(MSIPACKAGE *package);
-static UINT ACTION_CreateFolders(MSIPACKAGE *package);
-static UINT ACTION_CostFinalize(MSIPACKAGE *package);
-static UINT ACTION_FileCost(MSIPACKAGE *package);
-static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package);
-static UINT ACTION_InstallInitialize(MSIPACKAGE *package);
-static UINT ACTION_InstallValidate(MSIPACKAGE *package);
-static UINT ACTION_ProcessComponents(MSIPACKAGE *package);
-static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package);
-static UINT ACTION_RegisterUser(MSIPACKAGE *package);
-static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);
-static UINT ACTION_PublishProduct(MSIPACKAGE *package);
-static UINT ACTION_WriteIniValues(MSIPACKAGE *package);
-static UINT ACTION_SelfRegModules(MSIPACKAGE *package);
-static UINT ACTION_PublishFeatures(MSIPACKAGE *package);
-static UINT ACTION_RegisterProduct(MSIPACKAGE *package);
-static UINT ACTION_InstallExecute(MSIPACKAGE *package);
-static UINT ACTION_InstallFinalize(MSIPACKAGE *package);
-static UINT ACTION_ForceReboot(MSIPACKAGE *package);
-static UINT ACTION_ResolveSource(MSIPACKAGE *package);
-static UINT ACTION_ExecuteAction(MSIPACKAGE *package);
-static UINT ACTION_RegisterFonts(MSIPACKAGE *package);
-static UINT ACTION_PublishComponents(MSIPACKAGE *package);
-
/*
* consts and values used
*/
{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t',
'S','t','r','i','n','g','s',0};
+/* action handlers */
+typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
+
struct _actions {
LPCWSTR action;
STANDARDACTIONHANDLER handler;
};
-static struct _actions StandardActions[] = {
- { szAllocateRegistrySpace, NULL},
- { szAppSearch, ACTION_AppSearch },
- { szBindImage, NULL},
- { szCCPSearch, NULL},
- { szCostFinalize, ACTION_CostFinalize },
- { szCostInitialize, ACTION_CostInitialize },
- { szCreateFolders, ACTION_CreateFolders },
- { szCreateShortcuts, ACTION_CreateShortcuts },
- { szDeleteServices, NULL},
- { szDisableRollback, NULL},
- { szDuplicateFiles, ACTION_DuplicateFiles },
- { szExecuteAction, ACTION_ExecuteAction },
- { szFileCost, ACTION_FileCost },
- { szFindRelatedProducts, ACTION_FindRelatedProducts },
- { szForceReboot, ACTION_ForceReboot },
- { szInstallAdminPackage, NULL},
- { szInstallExecute, ACTION_InstallExecute },
- { szInstallExecuteAgain, ACTION_InstallExecute },
- { szInstallFiles, ACTION_InstallFiles},
- { szInstallFinalize, ACTION_InstallFinalize },
- { szInstallInitialize, ACTION_InstallInitialize },
- { szInstallSFPCatalogFile, NULL},
- { szInstallValidate, ACTION_InstallValidate },
- { szIsolateComponents, NULL},
- { szLaunchConditions, ACTION_LaunchConditions },
- { szMigrateFeatureStates, NULL},
- { szMoveFiles, NULL},
- { szMsiPublishAssemblies, NULL},
- { szMsiUnpublishAssemblies, NULL},
- { szInstallODBC, NULL},
- { szInstallServices, NULL},
- { szPatchFiles, NULL},
- { szProcessComponents, ACTION_ProcessComponents },
- { szPublishComponents, ACTION_PublishComponents },
- { szPublishFeatures, ACTION_PublishFeatures },
- { szPublishProduct, ACTION_PublishProduct },
- { szRegisterClassInfo, ACTION_RegisterClassInfo },
- { szRegisterComPlus, NULL},
- { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo },
- { szRegisterFonts, ACTION_RegisterFonts },
- { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo },
- { szRegisterProduct, ACTION_RegisterProduct },
- { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo },
- { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries },
- { szRegisterUser, ACTION_RegisterUser},
- { szRemoveDuplicateFiles, NULL},
- { szRemoveEnvironmentStrings, NULL},
- { szRemoveExistingProducts, NULL},
- { szRemoveFiles, NULL},
- { szRemoveFolders, NULL},
- { szRemoveIniValues, NULL},
- { szRemoveODBC, NULL},
- { szRemoveRegistryValues, NULL},
- { szRemoveShortcuts, NULL},
- { szResolveSource, ACTION_ResolveSource},
- { szRMCCPSearch, NULL},
- { szScheduleReboot, NULL},
- { szSelfRegModules, ACTION_SelfRegModules },
- { szSelfUnregModules, NULL},
- { szSetODBCFolders, NULL},
- { szStartServices, NULL},
- { szStopServices, NULL},
- { szUnpublishComponents, NULL},
- { szUnpublishFeatures, NULL},
- { szUnregisterClassInfo, NULL},
- { szUnregisterComPlus, NULL},
- { szUnregisterExtensionInfo, NULL},
- { szUnregisterFonts, NULL},
- { szUnregisterMIMEInfo, NULL},
- { szUnregisterProgIdInfo, NULL},
- { szUnregisterTypeLibraries, NULL},
- { szValidateProductID, NULL},
- { szWriteEnvironmentStrings, NULL},
- { szWriteIniValues, ACTION_WriteIniValues },
- { szWriteRegistryValues, ACTION_WriteRegistryValues},
- { NULL, NULL},
-};
+static struct _actions StandardActions[];
/********************************************************
MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row);
msiobj_release(&row->hdr);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
msiobj_release(&row->hdr);
}
+static int msi_get_property_int( MSIPACKAGE *package, LPCWSTR prop, int def )
+{
+ LPWSTR str = msi_dup_property( package, prop );
+ int val = str ? atoiW( str ) : def;
+ msi_free( str );
+ return val;
+}
+
+static UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine )
+{
+ LPCWSTR ptr,ptr2;
+ BOOL quote;
+ DWORD len;
+ LPWSTR prop = NULL, val = NULL;
+
+ if (!szCommandLine)
+ return ERROR_SUCCESS;
+
+ ptr = szCommandLine;
+
+ while (*ptr)
+ {
+ if (*ptr==' ')
+ {
+ ptr++;
+ continue;
+ }
+
+ TRACE("Looking at %s\n",debugstr_w(ptr));
+
+ ptr2 = strchrW(ptr,'=');
+ if (!ptr2)
+ {
+ ERR("command line contains unknown string : %s\n", debugstr_w(ptr));
+ break;
+ }
+
+ quote = FALSE;
+
+ len = ptr2-ptr;
+ prop = msi_alloc((len+1)*sizeof(WCHAR));
+ memcpy(prop,ptr,len*sizeof(WCHAR));
+ prop[len]=0;
+ ptr2++;
+
+ len = 0;
+ ptr = ptr2;
+ while (*ptr && (quote || (!quote && *ptr!=' ')))
+ {
+ if (*ptr == '"')
+ quote = !quote;
+ ptr++;
+ len++;
+ }
+
+ if (*ptr2=='"')
+ {
+ ptr2++;
+ len -= 2;
+ }
+ val = msi_alloc((len+1)*sizeof(WCHAR));
+ memcpy(val,ptr2,len*sizeof(WCHAR));
+ val[len] = 0;
+
+ if (lstrlenW(prop) > 0)
+ {
+ TRACE("Found commandline property (%s) = (%s)\n",
+ debugstr_w(prop), debugstr_w(val));
+ MSI_SetPropertyW(package,prop,val);
+ }
+ msi_free(val);
+ msi_free(prop);
+ }
+
+ return ERROR_SUCCESS;
+}
+
/****************************************************
* TOP level entry points
*****************************************************/
-UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
- LPCWSTR szCommandLine, LPCWSTR msiFilePath)
+UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
+ LPCWSTR szCommandLine )
{
- DWORD sz;
- WCHAR buffer[10];
UINT rc;
BOOL ui = FALSE;
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
MSI_SetPropertyW(package, szAction, szInstall);
- package->script = HeapAlloc(GetProcessHeap(),0,sizeof(MSISCRIPT));
+ package->script = msi_alloc(sizeof(MSISCRIPT));
memset(package->script,0,sizeof(MSISCRIPT));
package->script->InWhatSequence = SEQUENCE_INSTALL;
- package->msiFilePath= strdupW(msiFilePath);
-
if (szPackagePath)
{
LPWSTR p, check, path;
}
else
{
- HeapFree(GetProcessHeap(),0,path);
- path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
+ msi_free(path);
+ path = msi_alloc(MAX_PATH*sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH,path);
strcatW(path,cszbs);
}
- check = load_dynamic_property(package, cszSourceDir,NULL);
+ check = msi_dup_property( package, cszSourceDir );
if (!check)
MSI_SetPropertyW(package, cszSourceDir, path);
- else
- HeapFree(GetProcessHeap(), 0, check);
-
- HeapFree(GetProcessHeap(), 0, path);
+ msi_free(check);
+ msi_free(path);
}
- if (szCommandLine)
- {
- LPWSTR ptr,ptr2;
- ptr = (LPWSTR)szCommandLine;
-
- while (*ptr)
- {
- WCHAR *prop = NULL;
- WCHAR *val = NULL;
-
- TRACE("Looking at %s\n",debugstr_w(ptr));
-
- ptr2 = strchrW(ptr,'=');
- if (ptr2)
- {
- BOOL quote=FALSE;
- DWORD len = 0;
-
- while (*ptr == ' ') ptr++;
- len = ptr2-ptr;
- prop = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
- memcpy(prop,ptr,len*sizeof(WCHAR));
- prop[len]=0;
- ptr2++;
-
- len = 0;
- ptr = ptr2;
- while (*ptr && (quote || (!quote && *ptr!=' ')))
- {
- if (*ptr == '"')
- quote = !quote;
- ptr++;
- len++;
- }
-
- if (*ptr2=='"')
- {
- ptr2++;
- len -= 2;
- }
- val = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
- memcpy(val,ptr2,len*sizeof(WCHAR));
- val[len] = 0;
+ msi_parse_command_line( package, szCommandLine );
- if (strlenW(prop) > 0)
- {
- TRACE("Found commandline property (%s) = (%s)\n",
- debugstr_w(prop), debugstr_w(val));
- MSI_SetPropertyW(package,prop,val);
- }
- HeapFree(GetProcessHeap(),0,val);
- HeapFree(GetProcessHeap(),0,prop);
- }
- ptr++;
- }
- }
-
- sz = 10;
- if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS)
+ if ( msi_get_property_int(package, szUILevel, 0) >= INSTALLUILEVEL_REDUCED )
{
- if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)
+ package->script->InWhatSequence |= SEQUENCE_UI;
+ rc = ACTION_ProcessUISequence(package);
+ ui = TRUE;
+ if (rc == ERROR_SUCCESS)
{
- package->script->InWhatSequence |= SEQUENCE_UI;
- rc = ACTION_ProcessUISequence(package);
- ui = TRUE;
- if (rc == ERROR_SUCCESS)
- {
- package->script->InWhatSequence |= SEQUENCE_EXEC;
- rc = ACTION_ProcessExecSequence(package,TRUE);
- }
+ package->script->InWhatSequence |= SEQUENCE_EXEC;
+ rc = ACTION_ProcessExecSequence(package,TRUE);
}
- else
- rc = ACTION_ProcessExecSequence(package,FALSE);
}
else
rc = ACTION_ProcessExecSequence(package,FALSE);
return rc;
}
+UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode )
+{
+ MSIQUERY * view;
+ UINT r;
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','%','s','`',
+ ' ','W','H','E','R','E',' ',
+ '`','S','e','q','u','e','n','c','e','`',' ',
+ '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
+ '`','S','e','q','u','e','n','c','e','`',0};
+ iterate_action_param iap;
+
+ /*
+ * FIXME: probably should be checking UILevel in the
+ * ACTION_PerformUIAction/ACTION_PerformAction
+ * rather than saving the UI level here. Those
+ * two functions can be merged too.
+ */
+ iap.package = package;
+ iap.UI = TRUE;
+
+ TRACE("%p %s %i\n", package, debugstr_w(szTable), iSequenceMode );
+
+ r = MSI_OpenQuery( package->db, &view, query, szTable );
+ if (r == ERROR_SUCCESS)
+ {
+ r = MSI_IterateRecords( view, NULL, ITERATE_Actions, &iap );
+ msiobj_release(&view->hdr);
+ }
+
+ return r;
+}
+
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)
{
MSIQUERY * view;
}
else
{
- FIXME("UNHANDLED Standard Action %s\n",debugstr_w(action));
+ FIXME("unhandled standard action %s\n",debugstr_w(action));
*rc = ERROR_SUCCESS;
}
}
if (!handled)
{
- FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+ FIXME("unhandled msi action %s\n",debugstr_w(action));
rc = ERROR_FUNCTION_NOT_CALLED;
}
if (!handled)
{
- FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+ FIXME("unhandled msi action %s\n",debugstr_w(action));
rc = ERROR_FUNCTION_NOT_CALLED;
}
folder->State = 3;
- HeapFree(GetProcessHeap(),0,full_path);
+ msi_free(full_path);
return ERROR_SUCCESS;
}
static MSICOMPONENT* load_component( MSIRECORD * row )
{
MSICOMPONENT *comp;
- DWORD sz;
- comp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSICOMPONENT) );
+ comp = msi_alloc_zero( sizeof(MSICOMPONENT) );
if (!comp)
return comp;
/* fill in the data */
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row,1,comp->Component,&sz);
-
- TRACE("Loading Component %s\n",
- debugstr_w(comp->Component));
+ comp->Component = load_dynamic_stringW( row, 1 );
- sz = 0x100;
- if (!MSI_RecordIsNull(row,2))
- MSI_RecordGetStringW(row,2,comp->ComponentId,&sz);
-
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row,3,comp->Directory,&sz);
+ TRACE("Loading Component %s\n", debugstr_w(comp->Component));
+ comp->ComponentId = load_dynamic_stringW( row, 2 );
+ comp->Directory = load_dynamic_stringW( row, 3 );
comp->Attributes = MSI_RecordGetInteger(row,4);
-
- sz = 0x100;
- MSI_RecordGetStringW(row,5,comp->Condition,&sz);
-
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row,6,comp->KeyPath,&sz);
+ comp->Condition = load_dynamic_stringW( row, 5 );
+ comp->KeyPath = load_dynamic_stringW( row, 6 );
comp->Installed = INSTALLSTATE_ABSENT;
comp->Action = INSTALLSTATE_UNKNOWN;
{
ComponentList *cl;
- cl = HeapAlloc( GetProcessHeap(), 0, sizeof (*cl) );
+ cl = msi_alloc( sizeof (*cl) );
if ( !cl )
return ERROR_NOT_ENOUGH_MEMORY;
cl->component = comp;
{
MSIPACKAGE* package = (MSIPACKAGE*)param;
MSIFEATURE* feature;
- DWORD sz;
static const WCHAR Query1[] =
{'S','E','L','E','C','T',' ',
'`','C','o','m','p','o','n','e','n','t','_','`',
/* fill in the data */
- feature = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFEATURE) );
+ feature = msi_alloc_zero( sizeof (MSIFEATURE) );
if (!feature)
return ERROR_NOT_ENOUGH_MEMORY;
list_init( &feature->Components );
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row,1,feature->Feature,&sz);
+ feature->Feature = load_dynamic_stringW( row, 1 );
TRACE("Loading feature %s\n",debugstr_w(feature->Feature));
- sz = IDENTIFIER_SIZE;
- if (!MSI_RecordIsNull(row,2))
- MSI_RecordGetStringW(row,2,feature->Feature_Parent,&sz);
-
- sz = 0x100;
- if (!MSI_RecordIsNull(row,3))
- MSI_RecordGetStringW(row,3,feature->Title,&sz);
-
- sz = 0x100;
- if (!MSI_RecordIsNull(row,4))
- MSI_RecordGetStringW(row,4,feature->Description,&sz);
+ feature->Feature_Parent = load_dynamic_stringW( row, 2 );
+ feature->Title = load_dynamic_stringW( row, 3 );
+ feature->Description = load_dynamic_stringW( row, 4 );
if (!MSI_RecordIsNull(row,5))
feature->Display = MSI_RecordGetInteger(row,5);
feature->Level= MSI_RecordGetInteger(row,6);
-
- sz = IDENTIFIER_SIZE;
- if (!MSI_RecordIsNull(row,7))
- MSI_RecordGetStringW(row,7,feature->Directory,&sz);
-
+ feature->Directory = load_dynamic_stringW( row, 7 );
feature->Attributes = MSI_RecordGetInteger(row,8);
feature->Installed = INSTALLSTATE_ABSENT;
/* fill in the data */
- file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFILE) );
+ file = msi_alloc_zero( sizeof (MSIFILE) );
if (!file)
return ERROR_NOT_ENOUGH_MEMORY;
file->Attributes = MSI_RecordGetInteger( row, 7 );
file->Sequence = MSI_RecordGetInteger( row, 8 );
- file->Temporary = FALSE;
file->State = 0;
TRACE("File Loaded (%s)\n",debugstr_w(file->File));
ui_actionstart(package, action);
TRACE("Executing Action (%s)\n",debugstr_w(action));
rc = ACTION_PerformAction(package, action, TRUE);
- HeapFree(GetProcessHeap(),0,package->script->Actions[script][i]);
+ msi_free(package->script->Actions[script][i]);
if (rc != ERROR_SUCCESS)
break;
}
- HeapFree(GetProcessHeap(),0,package->script->Actions[script]);
+ msi_free(package->script->Actions[script]);
package->script->ActionCount[script] = 0;
package->script->Actions[script] = NULL;
TRACE("Working to load %s\n",debugstr_w(dir));
- folder = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFOLDER) );
+ folder = msi_alloc_zero( sizeof (MSIFOLDER) );
if (!folder)
return NULL;
if (targetdir)
{
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
- HeapFree(GetProcessHeap(),0, folder->TargetDefault);
+ msi_free( folder->TargetDefault);
folder->TargetDefault = strdupW(targetdir);
}
folder->SourceDefault = strdupW(shortname);
else if (targetdir)
folder->SourceDefault = strdupW(targetdir);
- HeapFree(GetProcessHeap(), 0, ptargetdir);
+ msi_free(ptargetdir);
TRACE(" SourceDefault = %s\n", debugstr_w( folder->SourceDefault ));
parent = MSI_RecordGetString(row,2);
ERR("failed to load parent folder %s\n", debugstr_w(parent));
}
- folder->Property = load_dynamic_property( package, dir, NULL );
+ folder->Property = msi_dup_property( package, dir );
msiobj_release(&row->hdr);
INSTALLSTATE state)
{
static const WCHAR all[]={'A','L','L',0};
- LPWSTR override = NULL;
- BOOL rc = FALSE;
+ LPWSTR override;
MSIFEATURE *feature;
- override = load_dynamic_property(package, property, NULL);
- if (override)
+ override = msi_dup_property( package, property );
+ if (!override)
+ return FALSE;
+
+ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
- rc = TRUE;
- LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
+ if (strcmpiW(override,all)==0)
{
- if (strcmpiW(override,all)==0)
- {
- feature->ActionRequest= state;
- feature->Action = state;
- }
- else
- {
- LPWSTR ptr = override;
- LPWSTR ptr2 = strchrW(override,',');
+ feature->ActionRequest= state;
+ feature->Action = state;
+ }
+ else
+ {
+ LPWSTR ptr = override;
+ LPWSTR ptr2 = strchrW(override,',');
- while (ptr)
+ while (ptr)
+ {
+ if ((ptr2 && strncmpW(ptr,feature->Feature, ptr2-ptr)==0)
+ || (!ptr2 && strcmpW(ptr,feature->Feature)==0))
{
- if ((ptr2 &&
- strncmpW(ptr,feature->Feature, ptr2-ptr)==0)
- || (!ptr2 && strcmpW(ptr,feature->Feature)==0))
- {
- feature->ActionRequest= state;
- feature->Action = state;
- break;
- }
- if (ptr2)
- {
- ptr=ptr2+1;
- ptr2 = strchrW(ptr,',');
- }
- else
- break;
+ feature->ActionRequest= state;
+ feature->Action = state;
+ break;
}
+ if (ptr2)
+ {
+ ptr=ptr2+1;
+ ptr2 = strchrW(ptr,',');
+ }
+ else
+ break;
}
}
- HeapFree(GetProcessHeap(),0,override);
}
+ msi_free(override);
- return rc;
+ return TRUE;
}
static UINT SetFeatureStates(MSIPACKAGE *package)
{
- LPWSTR level;
- INT install_level;
+ int install_level;
static const WCHAR szlevel[] =
{'I','N','S','T','A','L','L','L','E','V','E','L',0};
static const WCHAR szAddLocal[] =
TRACE("Checking Install Level\n");
- level = load_dynamic_property(package,szlevel,NULL);
- if (level)
- {
- install_level = atoiW(level);
- HeapFree(GetProcessHeap(), 0, level);
- }
- else
- install_level = 1;
+ install_level = msi_get_property_int( package, szlevel, 1 );
/* ok hereis the _real_ rub
* all these activation/deactivation things happen in order and things
load_folder(package,name);
path = resolve_folder(package,name,FALSE,TRUE,NULL);
TRACE("resolves to %s\n",debugstr_w(path));
- HeapFree( GetProcessHeap(), 0, path);
+ msi_free(path);
return ERROR_SUCCESS;
}
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
- MSICOMPONENT* comp = NULL;
-
- comp = file->Component;
+ MSICOMPONENT* comp = file->Component;
+ LPWSTR p;
- if (file->Temporary == TRUE)
+ if (!comp)
continue;
- if (comp)
- {
- LPWSTR p;
+ /* calculate target */
+ p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
- /* calculate target */
- p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
+ msi_free(file->TargetPath);
- HeapFree(GetProcessHeap(),0,file->TargetPath);
+ TRACE("file %s is named %s\n",
+ debugstr_w(file->File),debugstr_w(file->FileName));
- TRACE("file %s is named %s\n",
- debugstr_w(file->File),debugstr_w(file->FileName));
+ file->TargetPath = build_directory_name(2, p, file->FileName);
- file->TargetPath = build_directory_name(2, p, file->FileName);
+ msi_free(p);
- HeapFree(GetProcessHeap(),0,p);
+ TRACE("file %s resolves to %s\n",
+ debugstr_w(file->File),debugstr_w(file->TargetPath));
- TRACE("file %s resolves to %s\n",
- debugstr_w(file->File),debugstr_w(file->TargetPath));
+ if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
+ {
+ file->State = 1;
+ comp->Cost += file->FileSize;
+ continue;
+ }
- if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
+ if (file->Version)
+ {
+ DWORD handle;
+ DWORD versize;
+ UINT sz;
+ LPVOID version;
+ static const WCHAR name[] =
+ {'\\',0};
+ static const WCHAR name_fmt[] =
+ {'%','u','.','%','u','.','%','u','.','%','u',0};
+ WCHAR filever[0x100];
+ VS_FIXEDFILEINFO *lpVer;
+
+ TRACE("Version comparison.. \n");
+ versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);
+ version = msi_alloc(versize);
+ GetFileVersionInfoW(file->TargetPath, 0, versize, version);
+
+ VerQueryValueW(version, (LPWSTR)name, (LPVOID*)&lpVer, &sz);
+
+ sprintfW(filever,name_fmt,
+ HIWORD(lpVer->dwFileVersionMS),
+ LOWORD(lpVer->dwFileVersionMS),
+ HIWORD(lpVer->dwFileVersionLS),
+ LOWORD(lpVer->dwFileVersionLS));
+
+ TRACE("new %s old %s\n", debugstr_w(file->Version),
+ debugstr_w(filever));
+ if (strcmpiW(filever,file->Version)<0)
{
- file->State = 1;
+ file->State = 2;
+ FIXME("cost should be diff in size\n");
comp->Cost += file->FileSize;
}
else
- {
- if (file->Version)
- {
- DWORD handle;
- DWORD versize;
- UINT sz;
- LPVOID version;
- static const WCHAR name[] =
- {'\\',0};
- static const WCHAR name_fmt[] =
- {'%','u','.','%','u','.','%','u','.','%','u',0};
- WCHAR filever[0x100];
- VS_FIXEDFILEINFO *lpVer;
-
- TRACE("Version comparison.. \n");
- versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);
- version = HeapAlloc(GetProcessHeap(),0,versize);
- GetFileVersionInfoW(file->TargetPath, 0, versize, version);
-
- VerQueryValueW(version, (LPWSTR)name, (LPVOID*)&lpVer, &sz);
-
- sprintfW(filever,name_fmt,
- HIWORD(lpVer->dwFileVersionMS),
- LOWORD(lpVer->dwFileVersionMS),
- HIWORD(lpVer->dwFileVersionLS),
- LOWORD(lpVer->dwFileVersionLS));
-
- TRACE("new %s old %s\n", debugstr_w(file->Version),
- debugstr_w(filever));
- if (strcmpiW(filever,file->Version)<0)
- {
- file->State = 2;
- FIXME("cost should be diff in size\n");
- comp->Cost += file->FileSize;
- }
- else
- file->State = 3;
- HeapFree(GetProcessHeap(),0,version);
- }
- else
- file->State = 3;
- }
- }
+ file->State = 3;
+ msi_free(version);
+ }
+ else
+ file->State = 3;
}
TRACE("Evaluating Condition Table\n");
TRACE("Enabling or Disabling Components\n");
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
- if (comp->Condition[0])
+ if (comp->Condition)
{
if (MSI_EvaluateConditionW(package,
comp->Condition) == MSICONDITION_FALSE)
MSI_SetPropertyW(package,szCosting,szOne);
/* set default run level if not set */
- level = load_dynamic_property(package,szlevel,NULL);
+ level = msi_dup_property( package, szlevel );
if (!level)
MSI_SetPropertyW(package,szlevel, szOne);
- else
- HeapFree(GetProcessHeap(),0,level);
+ msi_free(level);
ACTION_UpdateInstallStates(package);
else
*size = strlenW(ptr)/2;
- data = HeapAlloc(GetProcessHeap(),0,*size);
+ data = msi_alloc(*size);
byte[0] = '0';
byte[1] = 'x';
data[count] = (BYTE)strtol(byte,NULL,0);
count ++;
}
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
TRACE("Data %li bytes(%i)\n",*size,count);
}
*type=REG_DWORD;
*size = sizeof(DWORD);
- data = HeapAlloc(GetProcessHeap(),0,*size);
+ data = msi_alloc(*size);
p = deformated;
if (*p == '-')
p++;
*(LPDWORD)data = d;
TRACE("DWORD %li\n",*(LPDWORD)data);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
}
else
case -1:
{
static const WCHAR szALLUSER[] = {'A','L','L','U','S','E','R','S',0};
- LPWSTR all_users = load_dynamic_property(package, szALLUSER, NULL);
+ LPWSTR all_users = msi_dup_property( package, szALLUSER );
if (all_users && all_users[0] == '1')
{
root_key = HKEY_LOCAL_MACHINE;
root_key = HKEY_CURRENT_USER;
szRoot = szHCU;
}
- HeapFree(GetProcessHeap(),0,all_users);
+ msi_free(all_users);
}
break;
case 0: root_key = HKEY_CLASSES_ROOT;
deformat_string(package, key , &deformated);
size = strlenW(deformated) + strlenW(szRoot) + 1;
- uikey = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
+ uikey = msi_alloc(size*sizeof(WCHAR));
strcpyW(uikey,szRoot);
strcatW(uikey,deformated);
if (RegCreateKeyW( root_key, deformated, &hkey))
{
ERR("Could not create key %s\n",debugstr_w(deformated));
- HeapFree(GetProcessHeap(),0,deformated);
- HeapFree(GetProcessHeap(),0,uikey);
+ msi_free(deformated);
+ msi_free(uikey);
return ERROR_SUCCESS;
}
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
value = MSI_RecordGetString(row,5);
if (value)
ui_actiondata(package,szWriteRegistryValues,uirow);
msiobj_release( &uirow->hdr );
- HeapFree(GetProcessHeap(),0,value_data);
- HeapFree(GetProcessHeap(),0,deformated);
- HeapFree(GetProcessHeap(),0,uikey);
+ msi_free(value_data);
+ msi_free(deformated);
+ msi_free(uikey);
return ERROR_SUCCESS;
}
'`','R','e','g','i','s','t','r','y','`',0};
UINT rc;
MSIQUERY * view;
- MSIRECORD * row = 0;
MSIFEATURE *feature;
MSIFILE *file;
- TRACE(" InstallValidate \n");
+ TRACE("InstallValidate\n");
rc = MSI_DatabaseOpenViewW(package->db, q1, &view);
- if (rc != ERROR_SUCCESS)
- return ERROR_SUCCESS;
-
- rc = MSI_ViewExecute(view, 0);
- if (rc != ERROR_SUCCESS)
+ if (rc == ERROR_SUCCESS)
{
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- return rc;
+ MSI_IterateRecords( view, &progress, NULL, package );
+ msiobj_release( &view->hdr );
+ total += progress * REG_PROGRESS_VALUE;
}
- while (1)
- {
- rc = MSI_ViewFetch(view,&row);
- if (rc != ERROR_SUCCESS)
- {
- rc = ERROR_SUCCESS;
- break;
- }
- progress +=1;
- msiobj_release(&row->hdr);
- }
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
-
- total = total + progress * REG_PROGRESS_VALUE;
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
- {
total += COMPONENT_PROGRESS_VALUE;
- }
+
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
- {
total += file->FileSize;
- }
+
ui_progress(package,0,total,0,0);
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
message = MSI_RecordGetString(row,2);
deformat_string(package,message,&deformated);
MessageBoxW(NULL,deformated,title,MB_OK);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
return ERROR_FUNCTION_FAILED;
}
static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp )
{
- if (cmp->KeyPath[0]==0)
- {
- LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
- return p;
- }
+ if (!cmp->KeyPath)
+ return resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
+
if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath)
{
MSIRECORD * row = 0;
if (deformated_name)
len+=strlenW(deformated_name);
- buffer = HeapAlloc(GetProcessHeap(),0, len *sizeof(WCHAR));
+ buffer = msi_alloc( len *sizeof(WCHAR));
if (deformated_name)
sprintfW(buffer,fmt2,root,deformated,deformated_name);
else
sprintfW(buffer,fmt,root,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
- HeapFree(GetProcessHeap(),0,deformated_name);
+ msi_free(deformated);
+ msi_free(deformated_name);
msiobj_release(&row->hdr);
return buffer;
hkey = openSharedDLLsKey();
if (count > 0)
- RegSetValueExW(hkey,path,0,REG_DWORD,
- (LPBYTE)&count,sizeof(count));
+ msi_reg_set_val_dword( hkey, path, count );
else
RegDeleteValueW(hkey,path);
RegCloseKey(hkey);
BOOL write = FALSE;
/* only refcount DLLs */
- if (comp->KeyPath[0]==0 ||
+ if (comp->KeyPath == NULL ||
comp->Attributes & msidbComponentAttributesRegistryKeyPath ||
comp->Attributes & msidbComponentAttributesODBCDataSource)
write = FALSE;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
- if (file->Temporary)
- continue;
if (file->Component == comp)
ACTION_WriteSharedDLLsCount( file->TargetPath, count );
}
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
ui_progress(package,2,0,0,0);
- if (comp->ComponentId[0]!=0)
+ if (comp->ComponentId)
{
- WCHAR *keypath = NULL;
MSIRECORD * uirow;
squash_guid(comp->ComponentId,squished_cc);
- keypath = resolve_keypath( package, comp );
- comp->FullKeypath = keypath;
+ msi_free(comp->FullKeypath);
+ comp->FullKeypath = resolve_keypath( package, comp );
/* do the refcounting */
ACTION_RefCountComponent( package, comp );
if (rc != ERROR_SUCCESS)
continue;
- if (keypath)
+ if (comp->FullKeypath)
{
- RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPBYTE)keypath,
- (strlenW(keypath)+1)*sizeof(WCHAR));
+ msi_reg_set_val_str( hkey2, squished_pc, comp->FullKeypath );
if (comp->Attributes & msidbComponentAttributesPermanent)
{
static const WCHAR szPermKey[] =
{ '0','0','0','0','0','0','0','0','0','0','0','0',
- '0','0','0','0','0','0','0', '0','0','0','0','0',
+ '0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',0};
- RegSetValueExW(hkey2,szPermKey,0,REG_SZ,
- (LPBYTE)keypath,
- (strlenW(keypath)+1)*sizeof(WCHAR));
+ msi_reg_set_val_str( hkey2, szPermKey, comp->FullKeypath );
}
RegCloseKey(hkey2);
uirow = MSI_CreateRecord(3);
MSI_RecordSetStringW(uirow,1,package->ProductCode);
MSI_RecordSetStringW(uirow,2,comp->ComponentId);
- MSI_RecordSetStringW(uirow,3,keypath);
+ MSI_RecordSetStringW(uirow,3,comp->FullKeypath);
ui_actiondata(package,szProcessComponents,uirow);
msiobj_release( &uirow->hdr );
}
tl_struct->path = strdupW(tl_struct->source);
else
{
- tl_struct->path = HeapAlloc(GetProcessHeap(),0,sz);
+ tl_struct->path = msi_alloc(sz);
sprintfW(tl_struct->path,fmt,tl_struct->source, lpszName);
}
res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
if (!SUCCEEDED(res))
{
- HeapFree(GetProcessHeap(),0,tl_struct->path);
+ msi_free(tl_struct->path);
tl_struct->path = NULL;
return TRUE;
return FALSE;
}
- HeapFree(GetProcessHeap(),0,tl_struct->path);
+ msi_free(tl_struct->path);
tl_struct->path = NULL;
ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
LPWSTR guid;
guid = load_dynamic_stringW(row,1);
CLSIDFromString(guid, &tl_struct.clsid);
- HeapFree(GetProcessHeap(),0,guid);
+ msi_free(guid);
tl_struct.source = strdupW( file->TargetPath );
tl_struct.path = NULL;
if (helpid)
help = resolve_folder(package,helpid,FALSE,FALSE,NULL);
res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help);
- HeapFree(GetProcessHeap(),0,help);
+ msi_free(help);
if (!SUCCEEDED(res))
ERR("Failed to register type library %s\n",
}
ITypeLib_Release(tl_struct.ptLib);
- HeapFree(GetProcessHeap(),0,tl_struct.path);
+ msi_free(tl_struct.path);
}
else
ERR("Failed to load type library %s\n",
debugstr_w(tl_struct.source));
FreeLibrary(module);
- HeapFree(GetProcessHeap(),0,tl_struct.source);
+ msi_free(tl_struct.source);
}
else
ERR("Could not load file! %s\n", debugstr_w(file->TargetPath));
if (!strchrW(filename,'.') || strcmpiW(strchrW(filename,'.'),szlnk))
strcatW(filename,szlnk);
target_file = build_directory_name(2, target_folder, filename);
- HeapFree(GetProcessHeap(),0,target_folder);
+ msi_free(target_folder);
buffer = MSI_RecordGetString(row,5);
if (strchrW(buffer,'['))
LPWSTR deformated;
deformat_string(package,buffer,&deformated);
IShellLinkW_SetPath(sl,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
else
{
- LPWSTR keypath;
FIXME("poorly handled shortcut format, advertised shortcut\n");
- keypath = strdupW( comp->FullKeypath );
- IShellLinkW_SetPath(sl,keypath);
- HeapFree(GetProcessHeap(),0,keypath);
+ IShellLinkW_SetPath(sl,comp->FullKeypath);
}
if (!MSI_RecordIsNull(row,6))
buffer = MSI_RecordGetString(row,6);
deformat_string(package,buffer,&deformated);
IShellLinkW_SetArguments(sl,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
if (!MSI_RecordIsNull(row,7))
if (!MSI_RecordIsNull(row,9))
{
- WCHAR *Path = NULL;
+ LPWSTR Path;
INT index;
buffer = MSI_RecordGetString(row,9);
- build_icon_path(package,buffer,&Path);
+ Path = build_icon_path(package,buffer);
index = MSI_RecordGetInteger(row,10);
IShellLinkW_SetIconLocation(sl,Path,index);
- HeapFree(GetProcessHeap(),0,Path);
+ msi_free(Path);
}
if (!MSI_RecordIsNull(row,11))
buffer = MSI_RecordGetString(row,12);
Path = resolve_folder(package, buffer, FALSE, FALSE, NULL);
IShellLinkW_SetWorkingDirectory(sl,Path);
- HeapFree(GetProcessHeap(), 0, Path);
+ msi_free(Path);
}
TRACE("Writing shortcut to %s\n",debugstr_w(target_file));
IPersistFile_Save(pf,target_file,FALSE);
- HeapFree(GetProcessHeap(),0,target_file);
+ msi_free(target_file);
IPersistFile_Release( pf );
IShellLinkW_Release( sl );
{
MSIPACKAGE* package = (MSIPACKAGE*)param;
HANDLE the_file;
- LPWSTR FilePath=NULL;
- LPCWSTR FileName=NULL;
+ LPWSTR FilePath;
+ LPCWSTR FileName;
CHAR buffer[1024];
DWORD sz;
UINT rc;
return ERROR_SUCCESS;
}
- build_icon_path(package,FileName,&FilePath);
+ FilePath = build_icon_path(package,FileName);
TRACE("Creating icon file at %s\n",debugstr_w(FilePath));
if (the_file == INVALID_HANDLE_VALUE)
{
ERR("Unable to create file %s\n",debugstr_w(FilePath));
- HeapFree(GetProcessHeap(),0,FilePath);
+ msi_free(FilePath);
return ERROR_SUCCESS;
}
WriteFile(the_file,buffer,sz,&write,NULL);
} while (sz == 1024);
- HeapFree(GetProcessHeap(),0,FilePath);
+ msi_free(FilePath);
CloseHandle(the_file);
return ERROR_SUCCESS;
goto end;
- buffer = load_dynamic_property(package,INSTALLPROPERTY_PRODUCTNAMEW,NULL);
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hukey,INSTALLPROPERTY_PRODUCTNAMEW,0,REG_SZ,
- (LPBYTE)buffer,size);
- HeapFree(GetProcessHeap(),0,buffer);
+ buffer = msi_dup_property( package, INSTALLPROPERTY_PRODUCTNAMEW );
+ msi_reg_set_val_str( hukey, INSTALLPROPERTY_PRODUCTNAMEW, buffer );
+ msi_free(buffer);
- buffer = load_dynamic_property(package,szProductLanguage,NULL);
- size = sizeof(DWORD);
- langid = atoiW(buffer);
- RegSetValueExW(hukey,INSTALLPROPERTY_LANGUAGEW,0,REG_DWORD,
- (LPBYTE)&langid,size);
- HeapFree(GetProcessHeap(),0,buffer);
+ langid = msi_get_property_int( package, szProductLanguage, 0 );
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_LANGUAGEW, langid );
- buffer = load_dynamic_property(package,szARPProductIcon,NULL);
+ buffer = msi_dup_property( package, szARPProductIcon );
if (buffer)
{
- LPWSTR path;
- build_icon_path(package,buffer,&path);
- size = strlenW(path) * sizeof(WCHAR);
- RegSetValueExW(hukey,INSTALLPROPERTY_PRODUCTICONW,0,REG_SZ,
- (LPBYTE)path,size);
+ LPWSTR path = build_icon_path(package,buffer);
+ msi_reg_set_val_str( hukey, INSTALLPROPERTY_PRODUCTICONW, path );
+ msi_free( path );
}
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
- buffer = load_dynamic_property(package,szProductVersion,NULL);
+ buffer = msi_dup_property( package, szProductVersion );
if (buffer)
{
DWORD verdword = build_version_dword(buffer);
- size = sizeof(DWORD);
- RegSetValueExW(hukey,INSTALLPROPERTY_VERSIONW,0,REG_DWORD, (LPBYTE
- )&verdword,size);
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONW, verdword );
}
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
FIXME("Need to write more keys to the user registry\n");
LPWSTR ptr = strchrW(guidbuffer,';');
if (ptr) *ptr = 0;
squash_guid(guidbuffer,squashed);
- size = strlenW(squashed)*sizeof(WCHAR);
- RegSetValueExW(hukey,INSTALLPROPERTY_PACKAGECODEW,0,REG_SZ,
- (LPBYTE)squashed, size);
+ msi_reg_set_val_str( hukey, INSTALLPROPERTY_PACKAGECODEW, squashed );
}
else
{
{
folder = resolve_folder(package, dirproperty, FALSE, FALSE, NULL);
if (!folder)
- folder = load_dynamic_property(package,dirproperty,NULL);
+ folder = msi_dup_property( package, dirproperty );
}
else
- folder = load_dynamic_property(package, szWindowsFolder, NULL);
+ folder = msi_dup_property( package, szWindowsFolder );
if (!folder)
{
ui_actiondata(package,szWriteIniValues,uirow);
msiobj_release( &uirow->hdr );
cleanup:
- HeapFree(GetProcessHeap(),0,fullname);
- HeapFree(GetProcessHeap(),0,folder);
- HeapFree(GetProcessHeap(),0,deformated_key);
- HeapFree(GetProcessHeap(),0,deformated_value);
- HeapFree(GetProcessHeap(),0,deformated_section);
+ msi_free(fullname);
+ msi_free(folder);
+ msi_free(deformated_key);
+ msi_free(deformated_value);
+ msi_free(deformated_section);
return ERROR_SUCCESS;
}
len = strlenW(ExeStr) + strlenW( file->TargetPath ) + 2;
- FullName = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+ FullName = msi_alloc(len*sizeof(WCHAR));
strcpyW(FullName,ExeStr);
strcatW( FullName, file->TargetPath );
strcatW(FullName,close);
if (brc)
msi_dialog_check_messages(info.hProcess);
- HeapFree(GetProcessHeap(),0,FullName);
+ msi_free(FullName);
return ERROR_SUCCESS;
}
{
size += 21;
}
- if (feature->Feature_Parent[0])
+ if (feature->Feature_Parent)
size += strlenW( feature->Feature_Parent )+2;
- data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+ data = msi_alloc(size * sizeof(WCHAR));
data[0] = 0;
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
WCHAR buf[21];
memset(buf,0,sizeof(buf));
- if ( component->ComponentId[0] )
+ if (component->ComponentId)
{
TRACE("From %s\n",debugstr_w(component->ComponentId));
CLSIDFromString(component->ComponentId, &clsid);
strcatW(data,buf);
}
}
- if (feature->Feature_Parent[0])
+ if (feature->Feature_Parent)
{
static const WCHAR sep[] = {'\2',0};
strcatW(data,sep);
strcatW(data,feature->Feature_Parent);
}
- size = (strlenW(data)+1)*sizeof(WCHAR);
- RegSetValueExW( hkey, feature->Feature, 0, REG_SZ, (LPBYTE)data,size );
- HeapFree(GetProcessHeap(),0,data);
+ msi_reg_set_val_str( hkey, feature->Feature, data );
+ msi_free(data);
+ size = 0;
+ if (feature->Feature_Parent)
+ size = strlenW(feature->Feature_Parent)*sizeof(WCHAR);
if (!absent)
{
- size = strlenW(feature->Feature_Parent)*sizeof(WCHAR);
RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
(LPBYTE)feature->Feature_Parent,size);
}
else
{
- size = (strlenW(feature->Feature_Parent)+2)* sizeof(WCHAR);
- data = HeapAlloc(GetProcessHeap(),0,size);
+ size += 2*sizeof(WCHAR);
+ data = msi_alloc(size);
data[0] = 0x6;
- strcpyW( &data[1], feature->Feature_Parent );
+ data[1] = 0;
+ if (feature->Feature_Parent)
+ strcpyW( &data[1], feature->Feature_Parent );
RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
(LPBYTE)data,size);
- HeapFree(GetProcessHeap(),0,data);
+ msi_free(data);
}
}
return rc;
}
+static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
+{
+ static const WCHAR installerPathFmt[] = {
+ '%','s','\\','I','n','s','t','a','l','l','e','r','\\',0};
+ static const WCHAR fmt[] = {
+ '%','s','\\',
+ 'I','n','s','t','a','l','l','e','r','\\',
+ '%','x','.','m','s','i',0};
+ static const WCHAR szOriginalDatabase[] =
+ {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
+ WCHAR windir[MAX_PATH], path[MAX_PATH], packagefile[MAX_PATH];
+ INT num, start;
+ LPWSTR msiFilePath;
+ BOOL r;
+
+ /* copy the package locally */
+ num = GetTickCount() & 0xffff;
+ if (!num)
+ num = 1;
+ start = num;
+ GetWindowsDirectoryW( windir, MAX_PATH );
+ snprintfW( packagefile, MAX_PATH, fmt, windir, num );
+ do
+ {
+ HANDLE handle = CreateFileW(packagefile,GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+ if (handle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(handle);
+ break;
+ }
+ if (GetLastError() != ERROR_FILE_EXISTS &&
+ GetLastError() != ERROR_SHARING_VIOLATION)
+ break;
+ if (!(++num & 0xffff)) num = 1;
+ sprintfW(packagefile,fmt,num);
+ } while (num != start);
+
+ snprintfW( path, MAX_PATH, installerPathFmt, windir );
+ create_full_pathW(path);
+
+ TRACE("Copying to local package %s\n",debugstr_w(packagefile));
+
+ msiFilePath = msi_dup_property( package, szOriginalDatabase );
+ r = CopyFileW( msiFilePath, packagefile, FALSE);
+ msi_free( msiFilePath );
+
+ if (!r)
+ {
+ ERR("Unable to copy package (%s -> %s) (error %ld)\n",
+ debugstr_w(msiFilePath), debugstr_w(packagefile), GetLastError());
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ /* FIXME: maybe set this key in ACTION_RegisterProduct instead */
+ msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile );
+ return ERROR_SUCCESS;
+}
+
static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
{
HKEY hkey=0;
LPWSTR buffer = NULL;
UINT rc,i;
- DWORD size;
- static WCHAR szNONE[] = {0};
- static const WCHAR szWindowsInstaler[] =
+ DWORD size, langid;
+ static const WCHAR szWindowsInstaller[] =
{'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
static const WCHAR szPropKeys[][80] =
{
{'U','R','L','U','p','d','a','t','e','I','n','f','o',0},
{0},
};
-
- static const WCHAR installerPathFmt[] = {
- '%','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\',0};
- static const WCHAR fmt[] = {
- '%','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\',
- '%','x','.','m','s','i',0};
static const WCHAR szUpgradeCode[] =
{'U','p','g','r','a','d','e','C','o','d','e',0};
static const WCHAR modpath_fmt[] =
SYSTEMTIME systime;
static const WCHAR date_fmt[] = {'%','i','%','i','%','i',0};
LPWSTR upgrade_code;
- WCHAR windir[MAX_PATH], path[MAX_PATH], packagefile[MAX_PATH];
- INT num,start;
if (!package)
return ERROR_INVALID_HANDLE;
/* dump all the info i can grab */
FIXME("Flesh out more information \n");
- i = 0;
- while (szPropKeys[i][0]!=0)
+ for( i=0; szPropKeys[i][0]; i++ )
{
- buffer = load_dynamic_property(package,szPropKeys[i],&rc);
- if (rc != ERROR_SUCCESS)
- buffer = szNONE;
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPBYTE)buffer,size);
- HeapFree(GetProcessHeap(),0,buffer);
- i++;
+ buffer = msi_dup_property( package, szPropKeys[i] );
+ msi_reg_set_val_str( hkey, szRegKeys[i], buffer );
+ msi_free(buffer);
}
- rc = 0x1;
- size = sizeof(rc);
- RegSetValueExW(hkey,szWindowsInstaler,0,REG_DWORD,(LPBYTE)&rc,size);
+ msi_reg_set_val_dword( hkey, szWindowsInstaller, 1 );
- /* copy the package locally */
- num = GetTickCount() & 0xffff;
- if (!num)
- num = 1;
- start = num;
- GetWindowsDirectoryW(windir, sizeof(windir) / sizeof(windir[0]));
- snprintfW(packagefile,sizeof(packagefile)/sizeof(packagefile[0]),fmt,
- windir,num);
- do
- {
- HANDLE handle = CreateFileW(packagefile,GENERIC_WRITE, 0, NULL,
- CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
- if (handle != INVALID_HANDLE_VALUE)
- {
- CloseHandle(handle);
- break;
- }
- if (GetLastError() != ERROR_FILE_EXISTS &&
- GetLastError() != ERROR_SHARING_VIOLATION)
- break;
- if (!(++num & 0xffff)) num = 1;
- sprintfW(packagefile,fmt,num);
- } while (num != start);
-
- snprintfW(path,sizeof(path)/sizeof(path[0]),installerPathFmt,windir);
- create_full_pathW(path);
- TRACE("Copying to local package %s\n",debugstr_w(packagefile));
- if (!CopyFileW(package->msiFilePath,packagefile,FALSE))
- ERR("Unable to copy package (%s -> %s) (error %ld)\n",
- debugstr_w(package->msiFilePath), debugstr_w(packagefile),
- GetLastError());
- size = strlenW(packagefile)*sizeof(WCHAR);
- RegSetValueExW(hkey,INSTALLPROPERTY_LOCALPACKAGEW,0,REG_SZ,
- (LPBYTE)packagefile,size);
+ msi_make_package_local( package, hkey );
/* do ModifyPath and UninstallString */
size = deformat_string(package,modpath_fmt,&buffer);
RegSetValueExW(hkey,szModifyPath,0,REG_EXPAND_SZ,(LPBYTE)buffer,size);
RegSetValueExW(hkey,szUninstallString,0,REG_EXPAND_SZ,(LPBYTE)buffer,size);
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
FIXME("Write real Estimated Size when we have it\n");
- size = 0;
- RegSetValueExW(hkey,szEstimatedSize,0,REG_DWORD,(LPBYTE)&size,sizeof(DWORD));
+ msi_reg_set_val_dword( hkey, szEstimatedSize, 0 );
GetLocalTime(&systime);
size = 9*sizeof(WCHAR);
- buffer= HeapAlloc(GetProcessHeap(),0,size);
+ buffer= msi_alloc(size);
sprintfW(buffer,date_fmt,systime.wYear,systime.wMonth,systime.wDay);
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,INSTALLPROPERTY_INSTALLDATEW,0,REG_SZ,
- (LPBYTE)buffer,size);
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_reg_set_val_str( hkey, INSTALLPROPERTY_INSTALLDATEW, buffer );
+ msi_free(buffer);
- buffer = load_dynamic_property(package,szProductLanguage,NULL);
- size = atoiW(buffer);
- RegSetValueExW(hkey,INSTALLPROPERTY_LANGUAGEW,0,REG_DWORD,
- (LPBYTE)&size,sizeof(DWORD));
- HeapFree(GetProcessHeap(),1,buffer);
+ langid = msi_get_property_int( package, szProductLanguage, 0 );
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_LANGUAGEW, langid );
- buffer = load_dynamic_property(package,szProductVersion,NULL);
+ buffer = msi_dup_property( package, szProductVersion );
if (buffer)
{
DWORD verdword = build_version_dword(buffer);
- DWORD vermajor = verdword>>24;
- DWORD verminor = (verdword>>16)&0x00FF;
- size = sizeof(DWORD);
- RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONW,0,REG_DWORD,
- (LPBYTE)&verdword,size);
- RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONMAJORW,0,REG_DWORD,
- (LPBYTE)&vermajor,size);
- RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONMINORW,0,REG_DWORD,
- (LPBYTE)&verminor,size);
- }
- HeapFree(GetProcessHeap(),0,buffer);
+
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONW, verdword );
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONMAJORW, verdword>>24 );
+ msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONMINORW, (verdword>>16)&0x00FF );
+ }
+ msi_free(buffer);
/* Handle Upgrade Codes */
- upgrade_code = load_dynamic_property(package,szUpgradeCode, NULL);
+ upgrade_code = msi_dup_property( package, szUpgradeCode );
if (upgrade_code)
{
HKEY hkey2;
WCHAR squashed[33];
MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey2, TRUE);
squash_guid(package->ProductCode,squashed);
- RegSetValueExW(hkey2, squashed, 0,REG_SZ,NULL,0);
+ msi_reg_set_val_str( hkey2, squashed, NULL );
RegCloseKey(hkey2);
MSIREG_OpenUserUpgradeCodesKey(upgrade_code, &hkey2, TRUE);
squash_guid(package->ProductCode,squashed);
- RegSetValueExW(hkey2, squashed, 0,REG_SZ,NULL,0);
+ msi_reg_set_val_str( hkey2, squashed, NULL );
RegCloseKey(hkey2);
- HeapFree(GetProcessHeap(),0,upgrade_code);
+ msi_free(upgrade_code);
}
end:
'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};
WCHAR buffer[256], sysdir[MAX_PATH];
HKEY hkey;
- WCHAR squished_pc[100];
- DWORD size;
+ WCHAR squished_pc[100];
if (!package)
return ERROR_INVALID_HANDLE;
snprintfW(buffer,sizeof(buffer)/sizeof(buffer[0]),msiexec_fmt,sysdir,
squished_pc);
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPBYTE)buffer,size);
+ msi_reg_set_val_str( hkey, squished_pc, buffer );
RegCloseKey(hkey);
TRACE("Reboot command %s\n",debugstr_w(buffer));
RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);
sprintfW(buffer,install_fmt,package->ProductCode,squished_pc);
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPBYTE)buffer,size);
+ msi_reg_set_val_str( hkey, squished_pc, buffer );
RegCloseKey(hkey);
return ERROR_INSTALL_SUSPEND;
INSTALLPROPERTY_DISKPROMPTW,NULL,&size);
if (rc == ERROR_MORE_DATA)
{
- prompt = HeapAlloc(GetProcessHeap(),0,size * sizeof(WCHAR));
+ prompt = msi_alloc(size * sizeof(WCHAR));
MsiSourceListGetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
INSTALLPROPERTY_DISKPROMPTW,prompt,&size);
}
attrib = GetFileAttributesW(package->PackagePath);
}
- HeapFree(GetProcessHeap(),0,prompt);
+ msi_free(prompt);
rc = ERROR_SUCCESS;
}
else
LPWSTR buffer;
LPWSTR productid;
UINT rc,i;
- DWORD size;
static const WCHAR szPropKeys[][80] =
{
if (!package)
return ERROR_INVALID_HANDLE;
- productid = load_dynamic_property(package,INSTALLPROPERTY_PRODUCTIDW,
- &rc);
+ productid = msi_dup_property( package, INSTALLPROPERTY_PRODUCTIDW );
if (!productid)
return ERROR_SUCCESS;
if (rc != ERROR_SUCCESS)
goto end;
- i = 0;
- while (szPropKeys[i][0]!=0)
+ for( i = 0; szPropKeys[i][0]; i++ )
{
- buffer = load_dynamic_property(package,szPropKeys[i],&rc);
- if (rc == ERROR_SUCCESS)
- {
- size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPBYTE)buffer,size);
- }
- else
- RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,NULL,0);
- i++;
+ buffer = msi_dup_property( package, szPropKeys[i] );
+ msi_reg_set_val_str( hkey, szRegKeys[i], buffer );
+ msi_free( buffer );
}
end:
- HeapFree(GetProcessHeap(),0,productid);
+ msi_free(productid);
RegCloseKey(hkey);
return ERROR_SUCCESS;
static const WCHAR szTwo[] = {'2',0};
UINT rc;
LPWSTR level;
- level = load_dynamic_property(package,szUILevel,NULL);
+ level = msi_dup_property( package, szUILevel );
MSI_SetPropertyW(package,szUILevel,szTwo);
package->script->InWhatSequence |= SEQUENCE_EXEC;
rc = ACTION_ProcessExecSequence(package,FALSE);
MSI_SetPropertyW(package,szUILevel,level);
- HeapFree(GetProcessHeap(),0,level);
+ msi_free(level);
return rc;
}
ttRecord.uStringOffset +
ttNTHeader.uStorageOffset,
NULL, FILE_BEGIN);
- buf = HeapAlloc(GetProcessHeap(), 0,
- ttRecord.uStringLength + 1 + strlen(tt));
+ buf = msi_alloc( ttRecord.uStringLength + 1 + strlen(tt) );
memset(buf, 0, ttRecord.uStringLength + 1 + strlen(tt));
ReadFile(handle, buf, ttRecord.uStringLength, NULL, NULL);
if (strlen(buf) > 0)
{
strcat(buf,tt);
ret = strdupAtoW(buf);
- HeapFree(GetProcessHeap(),0,buf);
+ msi_free(buf);
break;
}
- HeapFree(GetProcessHeap(),0,buf);
+ msi_free(buf);
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
}
}
LPWSTR name;
LPCWSTR filename;
MSIFILE *file;
- DWORD size;
static const WCHAR regfont1[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
if (name)
{
- size = strlenW( file->FileName ) * sizeof(WCHAR);
- RegSetValueExW( hkey1, name, 0, REG_SZ, (LPBYTE)file->FileName, size );
- RegSetValueExW( hkey2, name, 0, REG_SZ, (LPBYTE)file->FileName, size );
+ msi_reg_set_val_str( hkey1, name, file->FileName );
+ msi_reg_set_val_str( hkey2, name, file->FileName );
}
- HeapFree(GetProcessHeap(),0,name);
+ msi_free(name);
RegCloseKey(hkey1);
RegCloseKey(hkey2);
return ERROR_SUCCESS;
sz+=3;
sz *= sizeof(WCHAR);
- output = HeapAlloc(GetProcessHeap(),0,sz);
+ output = msi_alloc(sz);
memset(output,0,sz);
strcpyW(output,advertise);
+ msi_free(advertise);
if (text)
strcatW(output,text);
- sz = (lstrlenW(output)+2) * sizeof(WCHAR);
- RegSetValueExW(hkey, qualifier,0,REG_MULTI_SZ, (LPBYTE)output, sz);
+ msi_reg_set_val_multi_str( hkey, qualifier, output );
end:
RegCloseKey(hkey);
- HeapFree(GetProcessHeap(),0,output);
+ msi_free(output);
return rc;
}
return rc;
}
+
+static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
+ LPCSTR action, LPCWSTR table )
+{
+ static const WCHAR query[] = {
+ 'S','E','L','E','C','T',' ','*',' ',
+ 'F','R','O','M',' ','`','%','s','`',0 };
+ MSIQUERY *view = NULL;
+ DWORD count = 0;
+ UINT r;
+
+ r = MSI_OpenQuery( package->db, &view, query, table );
+ if (r == ERROR_SUCCESS)
+ {
+ r = MSI_IterateRecords(view, &count, NULL, package);
+ msiobj_release(&view->hdr);
+ }
+
+ if (count)
+ FIXME("%s -> %lu ignored %s table values\n",
+ action, count, debugstr_w(table));
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
+{
+ static const WCHAR table[] =
+ {'R','e','m','o','v','e','I','n','i','F','i','l','e',0 };
+ return msi_unimplemented_action_stub( package, "RemoveIniValues", table );
+}
+
+static UINT ACTION_MoveFiles( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'M','o','v','e','F','i','l','e',0 };
+ return msi_unimplemented_action_stub( package, "MoveFiles", table );
+}
+
+static UINT ACTION_PatchFiles( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'P','a','t','c','h',0 };
+ return msi_unimplemented_action_stub( package, "PatchFiles", table );
+}
+
+static UINT ACTION_BindImage( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'B','i','n','d','I','m','a','g','e',0 };
+ return msi_unimplemented_action_stub( package, "BindImage", table );
+}
+
+static UINT ACTION_IsolateComponents( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t',0 };
+ return msi_unimplemented_action_stub( package, "IsolateComponents", table );
+}
+
+static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 };
+ return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
+}
+
+static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'S','e','l','f','R','e','g',0 };
+ return msi_unimplemented_action_stub( package, "SelfUnregModules", table );
+}
+
+static UINT ACTION_InstallServices( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'S','e','r','v','i','c','e','I','n','s','t','a','l','l',0 };
+ return msi_unimplemented_action_stub( package, "InstallServices", table );
+}
+
+static UINT ACTION_StartServices( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };
+ return msi_unimplemented_action_stub( package, "StartServices", table );
+}
+
+static UINT ACTION_StopServices( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };
+ return msi_unimplemented_action_stub( package, "StopServices", table );
+}
+
+static UINT ACTION_DeleteServices( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };
+ return msi_unimplemented_action_stub( package, "DeleteServices", table );
+}
+
+static UINT ACTION_WriteEnvironmentStrings( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'E','n','v','i','r','o','n','m','e','n','t',0 };
+ return msi_unimplemented_action_stub( package, "WriteEnvironmentStrings", table );
+}
+
+static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'E','n','v','i','r','o','n','m','e','n','t',0 };
+ return msi_unimplemented_action_stub( package, "RemoveEnvironmentStrings", table );
+}
+
+static UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'M','s','i','A','s','s','e','m','b','l','y',0 };
+ return msi_unimplemented_action_stub( package, "MsiPublishAssemblies", table );
+}
+
+static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = {
+ 'M','s','i','A','s','s','e','m','b','l','y',0 };
+ return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table );
+}
+
+static UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
+{
+ static const WCHAR table[] = { 'F','o','n','t',0 };
+ return msi_unimplemented_action_stub( package, "UnregisterFonts", table );
+}
+
+static struct _actions StandardActions[] = {
+ { szAllocateRegistrySpace, NULL},
+ { szAppSearch, ACTION_AppSearch },
+ { szBindImage, ACTION_BindImage },
+ { szCCPSearch, NULL},
+ { szCostFinalize, ACTION_CostFinalize },
+ { szCostInitialize, ACTION_CostInitialize },
+ { szCreateFolders, ACTION_CreateFolders },
+ { szCreateShortcuts, ACTION_CreateShortcuts },
+ { szDeleteServices, ACTION_DeleteServices },
+ { szDisableRollback, NULL},
+ { szDuplicateFiles, ACTION_DuplicateFiles },
+ { szExecuteAction, ACTION_ExecuteAction },
+ { szFileCost, ACTION_FileCost },
+ { szFindRelatedProducts, ACTION_FindRelatedProducts },
+ { szForceReboot, ACTION_ForceReboot },
+ { szInstallAdminPackage, NULL},
+ { szInstallExecute, ACTION_InstallExecute },
+ { szInstallExecuteAgain, ACTION_InstallExecute },
+ { szInstallFiles, ACTION_InstallFiles},
+ { szInstallFinalize, ACTION_InstallFinalize },
+ { szInstallInitialize, ACTION_InstallInitialize },
+ { szInstallSFPCatalogFile, NULL},
+ { szInstallValidate, ACTION_InstallValidate },
+ { szIsolateComponents, ACTION_IsolateComponents },
+ { szLaunchConditions, ACTION_LaunchConditions },
+ { szMigrateFeatureStates, ACTION_MigrateFeatureStates },
+ { szMoveFiles, ACTION_MoveFiles },
+ { szMsiPublishAssemblies, ACTION_MsiPublishAssemblies },
+ { szMsiUnpublishAssemblies, ACTION_MsiUnpublishAssemblies },
+ { szInstallODBC, NULL},
+ { szInstallServices, ACTION_InstallServices },
+ { szPatchFiles, ACTION_PatchFiles },
+ { szProcessComponents, ACTION_ProcessComponents },
+ { szPublishComponents, ACTION_PublishComponents },
+ { szPublishFeatures, ACTION_PublishFeatures },
+ { szPublishProduct, ACTION_PublishProduct },
+ { szRegisterClassInfo, ACTION_RegisterClassInfo },
+ { szRegisterComPlus, NULL},
+ { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo },
+ { szRegisterFonts, ACTION_RegisterFonts },
+ { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo },
+ { szRegisterProduct, ACTION_RegisterProduct },
+ { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo },
+ { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries },
+ { szRegisterUser, ACTION_RegisterUser},
+ { szRemoveDuplicateFiles, NULL},
+ { szRemoveEnvironmentStrings, ACTION_RemoveEnvironmentStrings },
+ { szRemoveExistingProducts, NULL},
+ { szRemoveFiles, NULL},
+ { szRemoveFolders, NULL},
+ { szRemoveIniValues, ACTION_RemoveIniValues },
+ { szRemoveODBC, NULL},
+ { szRemoveRegistryValues, NULL},
+ { szRemoveShortcuts, NULL},
+ { szResolveSource, ACTION_ResolveSource},
+ { szRMCCPSearch, NULL},
+ { szScheduleReboot, NULL},
+ { szSelfRegModules, ACTION_SelfRegModules },
+ { szSelfUnregModules, ACTION_SelfUnregModules },
+ { szSetODBCFolders, NULL},
+ { szStartServices, ACTION_StartServices },
+ { szStopServices, ACTION_StopServices },
+ { szUnpublishComponents, NULL},
+ { szUnpublishFeatures, NULL},
+ { szUnregisterClassInfo, NULL},
+ { szUnregisterComPlus, NULL},
+ { szUnregisterExtensionInfo, NULL},
+ { szUnregisterFonts, ACTION_UnregisterFonts },
+ { szUnregisterMIMEInfo, NULL},
+ { szUnregisterProgIdInfo, NULL},
+ { szUnregisterTypeLibraries, NULL},
+ { szValidateProductID, NULL},
+ { szWriteEnvironmentStrings, ACTION_WriteEnvironmentStrings },
+ { szWriteIniValues, ACTION_WriteIniValues },
+ { szWriteRegistryValues, ACTION_WriteRegistryValues},
+ { NULL, NULL},
+};
#include "wine/list.h"
-#define IDENTIFIER_SIZE 96
-
typedef struct tagMSIFEATURE
{
struct list entry;
- WCHAR Feature[IDENTIFIER_SIZE];
- WCHAR Feature_Parent[IDENTIFIER_SIZE];
- WCHAR Title[0x100];
- WCHAR Description[0x100];
+ LPWSTR Feature;
+ LPWSTR Feature_Parent;
+ LPWSTR Title;
+ LPWSTR Description;
INT Display;
INT Level;
- WCHAR Directory[IDENTIFIER_SIZE];
+ LPWSTR Directory;
INT Attributes;
INSTALLSTATE Installed;
{
struct list entry;
DWORD magic;
- WCHAR Component[IDENTIFIER_SIZE];
- WCHAR ComponentId[IDENTIFIER_SIZE];
- WCHAR Directory[IDENTIFIER_SIZE];
+ LPWSTR Component;
+ LPWSTR ComponentId;
+ LPWSTR Directory;
INT Attributes;
- WCHAR Condition[0x100];
- WCHAR KeyPath[IDENTIFIER_SIZE];
+ LPWSTR Condition;
+ LPWSTR KeyPath;
INSTALLSTATE Installed;
INSTALLSTATE ActionRequest;
/* 2 = present but replace */
/* 3 = present do not replace */
/* 4 = Installed */
+ /* 5 = Skipped */
LPWSTR SourcePath;
LPWSTR TargetPath;
- BOOL Temporary;
} MSIFILE;
+typedef struct tagMSITEMPFILE
+{
+ struct list entry;
+ LPWSTR File;
+ LPWSTR Path;
+} MSITEMPFILE;
+
typedef struct tagMSIAPPID
{
struct list entry;
- WCHAR AppID[IDENTIFIER_SIZE]; /* Primary key */
+ LPWSTR AppID; /* Primary key */
LPWSTR RemoteServerName;
LPWSTR LocalServer;
LPWSTR ServiceParameters;
BOOL RunAsInteractiveUser;
} MSIAPPID;
+typedef struct tagMSIPROGID MSIPROGID;
+
typedef struct tagMSICLASS
{
struct list entry;
- WCHAR CLSID[IDENTIFIER_SIZE]; /* Primary Key */
- WCHAR Context[IDENTIFIER_SIZE]; /* Primary Key */
+ LPWSTR clsid; /* Primary Key */
+ LPWSTR Context; /* Primary Key */
MSICOMPONENT *Component;
- INT ProgIDIndex;
+ MSIPROGID *ProgID;
LPWSTR ProgIDText;
LPWSTR Description;
MSIAPPID *AppID;
typedef struct tagMSIEXTENSION
{
struct list entry;
- WCHAR Extension[256]; /* Primary Key */
+ LPWSTR Extension; /* Primary Key */
MSICOMPONENT *Component;
- INT ProgIDIndex;
+ MSIPROGID *ProgID;
LPWSTR ProgIDText;
MSIMIME *Mime;
MSIFEATURE *Feature;
/* not in the table, set during installation */
BOOL Installed;
- INT VerbCount;
- INT Verbs[100]; /* yes hard coded limit, but realistically 100 verbs??? */
+ struct list verbs;
} MSIEXTENSION;
-typedef struct tagMSIPROGID
+struct tagMSIPROGID
{
+ struct list entry;
LPWSTR ProgID; /* Primary Key */
- INT ParentIndex;
+ MSIPROGID *Parent;
MSICLASS *Class;
LPWSTR Description;
LPWSTR IconPath;
/* not in the table, set during installation */
BOOL InstallMe;
- INT CurVerIndex;
- INT VersionIndIndex;
-} MSIPROGID;
+ MSIPROGID *CurVer;
+ MSIPROGID *VersionInd;
+};
typedef struct tagMSIVERB
{
- MSIEXTENSION *Extension;
+ struct list entry;
LPWSTR Verb;
INT Sequence;
LPWSTR Command;
struct list entry;
LPWSTR ContentType; /* Primary Key */
MSIEXTENSION *Extension;
- WCHAR CLSID[IDENTIFIER_SIZE];
+ LPWSTR clsid;
MSICLASS *Class;
/* not in the table, set during installation */
BOOL InstallMe;
/* Helpers */
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
extern WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index);
-extern LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc);
+extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop);
extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
BOOL set_prop, MSIFOLDER **folder);
extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
extern MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir );
extern int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
extern UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
-extern UINT build_icon_path(MSIPACKAGE *, LPCWSTR, LPWSTR *);
+extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR);
extern DWORD build_version_dword(LPCWSTR);
extern LPWSTR build_directory_name(DWORD , ...);
extern BOOL create_full_pathW(const WCHAR *path);
{
ACTION_VerStrToInteger(minVersion, &sig->MinVersionMS,
&sig->MinVersionLS);
- HeapFree(GetProcessHeap(), 0, minVersion);
+ msi_free( minVersion);
}
maxVersion = load_dynamic_stringW(row,4);
if (maxVersion)
{
ACTION_VerStrToInteger(maxVersion, &sig->MaxVersionMS,
&sig->MaxVersionLS);
- HeapFree(GetProcessHeap(), 0, maxVersion);
+ msi_free( maxVersion);
}
sig->MinSize = MSI_RecordGetInteger(row,5);
if (sig->MinSize == MSI_NULL_INTEGER)
/* FIXME: sanity-check sz before allocating (is there an upper-limit
* on the value of a property?)
*/
- value = HeapAlloc(GetProcessHeap(), 0, sz);
+ value = msi_alloc( sz);
rc = RegQueryValueExW(key, valueName, NULL, ®Type, value, &sz);
if (rc)
{
if (*(LPWSTR)value == '#')
{
/* escape leading pound with another */
- propertyValue = HeapAlloc(GetProcessHeap(), 0,
- sz + sizeof(WCHAR));
+ propertyValue = msi_alloc( sz + sizeof(WCHAR));
propertyValue[0] = '#';
strcpyW(propertyValue + 1, (LPWSTR)value);
}
else
{
- propertyValue = HeapAlloc(GetProcessHeap(), 0, sz);
+ propertyValue = msi_alloc( sz);
strcpyW(propertyValue, (LPWSTR)value);
}
break;
/* 7 chars for digits, 1 for NULL, 1 for #, and 1 for sign
* char if needed
*/
- propertyValue = HeapAlloc(GetProcessHeap(), 0,
- 10 * sizeof(WCHAR));
+ propertyValue = msi_alloc( 10 * sizeof(WCHAR));
sprintfW(propertyValue, dwordFmt, *(DWORD *)value);
break;
case REG_EXPAND_SZ:
/* space for extra #% characters in front */
- propertyValue = HeapAlloc(GetProcessHeap(), 0,
- sz + 2 * sizeof(WCHAR));
+ propertyValue = msi_alloc( sz + 2 * sizeof(WCHAR));
sprintfW(propertyValue, expandSzFmt, (LPWSTR)value);
break;
case REG_BINARY:
/* 3 == length of "#x<nibble>" */
- propertyValue = HeapAlloc(GetProcessHeap(), 0,
- (sz * 3 + 1) * sizeof(WCHAR));
+ propertyValue = msi_alloc( (sz * 3 + 1) * sizeof(WCHAR));
for (i = 0; i < sz; i++)
sprintfW(propertyValue + i * 3, binFmt, value[i]);
break;
*appFound = TRUE;
end:
- HeapFree(GetProcessHeap(), 0, propertyValue);
- HeapFree(GetProcessHeap(), 0, value);
+ msi_free( propertyValue);
+ msi_free( value);
RegCloseKey(key);
- HeapFree(GetProcessHeap(), 0, keyPath);
- HeapFree(GetProcessHeap(), 0, valueName);
+ msi_free( keyPath);
+ msi_free( valueName);
msiobj_release(&row->hdr);
MSI_ViewClose(view);
fileName = load_dynamic_stringW(row,2);
FIXME("AppSearch unimplemented for IniLocator (ini file name %s)\n",
debugstr_w(fileName));
- HeapFree(GetProcessHeap(), 0, fileName);
+ msi_free( fileName);
end:
msiobj_release(&row->hdr);
if (size)
{
- LPVOID buf = HeapAlloc(GetProcessHeap(), 0, size);
+ LPVOID buf = msi_alloc( size);
if (buf)
{
else
*matches = TRUE;
}
- HeapFree(GetProcessHeap(), 0, buf);
+ msi_free( buf);
}
else
rc = ERROR_OUTOFMEMORY;
* here. Add two because we might need to add a backslash if the dir name
* isn't backslash-terminated.
*/
- buf = HeapAlloc(GetProcessHeap(), 0,
- (dirLen + max(fileLen, lstrlenW(starDotStarW)) + 2) * sizeof(WCHAR));
+ buf = msi_alloc( (dirLen + max(fileLen, lstrlenW(starDotStarW)) + 2) * sizeof(WCHAR));
if (buf)
{
/* a depth of 0 implies we should search dir, so go ahead and search */
FindClose(hFind);
}
}
- HeapFree(GetProcessHeap(), 0, buf);
+ msi_free(buf);
}
else
rc = ERROR_OUTOFMEMORY;
}
}
}
- HeapFree(GetProcessHeap(), 0, sig.File);
- HeapFree(GetProcessHeap(), 0, sig.Languages);
+ msi_free( sig.File);
+ msi_free( sig.Languages);
msiobj_release(&row->hdr);
}
static MSIAPPID *load_appid( MSIPACKAGE* package, MSIRECORD *row )
{
- DWORD sz;
LPCWSTR buffer;
MSIAPPID *appid;
/* fill in the data */
- appid = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSIAPPID) );
+ appid = msi_alloc_zero( sizeof(MSIAPPID) );
if (!appid)
return NULL;
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row, 1, appid->AppID, &sz);
+ appid->AppID = load_dynamic_stringW( row, 1 );
TRACE("loading appid %s\n", debugstr_w( appid->AppID ));
buffer = MSI_RecordGetString(row,2);
return appid;
}
-static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
+static MSIPROGID *load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
static MSICLASS *load_given_class( MSIPACKAGE *package, LPCWSTR classid );
-static INT load_progid(MSIPACKAGE* package, MSIRECORD *row)
+static MSIPROGID *load_progid( MSIPACKAGE* package, MSIRECORD *row )
{
- DWORD index = package->loaded_progids;
+ MSIPROGID *progid;
LPCWSTR buffer;
/* fill in the data */
- package->loaded_progids++;
- if (package->loaded_progids == 1)
- package->progids = HeapAlloc(GetProcessHeap(),0,sizeof(MSIPROGID));
- else
- package->progids = HeapReAlloc(GetProcessHeap(),0,
- package->progids , package->loaded_progids * sizeof(MSIPROGID));
+ progid = msi_alloc_zero( sizeof(MSIPROGID) );
+ if (!progid)
+ return NULL;
- memset(&package->progids[index],0,sizeof(MSIPROGID));
+ list_add_tail( &package->progids, &progid->entry );
- package->progids[index].ProgID = load_dynamic_stringW(row,1);
- TRACE("loading progid %s\n",debugstr_w(package->progids[index].ProgID));
+ progid->ProgID = load_dynamic_stringW(row,1);
+ TRACE("loading progid %s\n",debugstr_w(progid->ProgID));
buffer = MSI_RecordGetString(row,2);
- package->progids[index].ParentIndex = load_given_progid(package,buffer);
- if (package->progids[index].ParentIndex < 0 && buffer)
+ progid->Parent = load_given_progid(package,buffer);
+ if (progid->Parent == NULL && buffer)
FIXME("Unknown parent ProgID %s\n",debugstr_w(buffer));
buffer = MSI_RecordGetString(row,3);
- package->progids[index].Class = load_given_class(package,buffer);
- if (package->progids[index].Class == NULL && buffer)
+ progid->Class = load_given_class(package,buffer);
+ if (progid->Class == NULL && buffer)
FIXME("Unknown class %s\n",debugstr_w(buffer));
- package->progids[index].Description = load_dynamic_stringW(row,4);
+ progid->Description = load_dynamic_stringW(row,4);
if (!MSI_RecordIsNull(row,6))
{
LPWSTR FilePath;
static const WCHAR fmt[] = {'%','s',',','%','i',0};
- build_icon_path(package,FileName,&FilePath);
+ FilePath = build_icon_path(package,FileName);
- package->progids[index].IconPath =
- HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+10)*
- sizeof(WCHAR));
+ progid->IconPath = msi_alloc( (strlenW(FilePath)+10)* sizeof(WCHAR) );
- sprintfW(package->progids[index].IconPath,fmt,FilePath,icon_index);
+ sprintfW(progid->IconPath,fmt,FilePath,icon_index);
- HeapFree(GetProcessHeap(),0,FilePath);
- HeapFree(GetProcessHeap(),0,FileName);
+ msi_free(FilePath);
+ msi_free(FileName);
}
else
{
buffer = MSI_RecordGetString(row,5);
if (buffer)
- build_icon_path(package,buffer,&(package->progids[index].IconPath));
+ progid->IconPath = build_icon_path(package,buffer);
}
- package->progids[index].CurVerIndex = -1;
- package->progids[index].VersionIndIndex = -1;
+ progid->CurVer = NULL;
+ progid->VersionInd = NULL;
/* if we have a parent then we may be that parents CurVer */
- if (package->progids[index].ParentIndex >= 0 &&
- package->progids[index].ParentIndex != index)
+ if (progid->Parent && progid->Parent != progid)
{
- int pindex = package->progids[index].ParentIndex;
- while (package->progids[pindex].ParentIndex>= 0 &&
- package->progids[pindex].ParentIndex != pindex)
- pindex = package->progids[pindex].ParentIndex;
+ MSIPROGID *parent = progid->Parent;
+
+ while (parent->Parent && parent->Parent != parent)
+ parent = parent->Parent;
- FIXME("BAD BAD need to determing if we are really the CurVer\n");
+ FIXME("need to determing if we are really the CurVer\n");
- package->progids[index].CurVerIndex = pindex;
- package->progids[pindex].VersionIndIndex = index;
+ progid->CurVer = parent;
+ parent->VersionInd = progid;
}
- return index;
+ return progid;
}
-static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid)
+static MSIPROGID *load_given_progid(MSIPACKAGE *package, LPCWSTR name)
{
- INT rc;
+ MSIPROGID *progid;
MSIRECORD *row;
- INT i;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','P','r','o','g','I','d','`',' ','W','H','E','R','E',' ',
'`','P','r','o','g','I','d','`',' ','=',' ','\'','%','s','\'',0};
- if (!progid)
- return -1;
+ if (!name)
+ return NULL;
/* check for progids already loaded */
- for (i = 0; i < package->loaded_progids; i++)
- if (strcmpiW(package->progids[i].ProgID,progid)==0)
+ LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry )
+ {
+ if (strcmpiW( progid->ProgID,name )==0)
{
- TRACE("found progid %s at index %i\n",debugstr_w(progid), i);
- return i;
+ TRACE("found progid %s (%p)\n",debugstr_w(name), progid );
+ return progid;
}
+ }
- row = MSI_QueryGetRecord(package->db, ExecSeqQuery, progid);
- if(!row)
- return -1;
+ row = MSI_QueryGetRecord( package->db, ExecSeqQuery, name );
+ if (!row)
+ return NULL;
- rc = load_progid(package, row);
+ progid = load_progid(package, row);
msiobj_release(&row->hdr);
- return rc;
+ return progid;
}
static MSICLASS *load_class( MSIPACKAGE* package, MSIRECORD *row )
{
MSICLASS *cls;
- DWORD sz,i;
+ DWORD i;
LPCWSTR buffer;
/* fill in the data */
- cls = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSICLASS) );
+ cls = msi_alloc_zero( sizeof(MSICLASS) );
if (!cls)
return NULL;
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row, 1, cls->CLSID, &sz);
- TRACE("loading class %s\n",debugstr_w(cls->CLSID));
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW(row, 2, cls->Context, &sz);
+ list_add_tail( &package->classes, &cls->entry );
+
+ cls->clsid = load_dynamic_stringW( row, 1 );
+ TRACE("loading class %s\n",debugstr_w(cls->clsid));
+ cls->Context = load_dynamic_stringW( row, 2 );
buffer = MSI_RecordGetString(row,3);
cls->Component = get_loaded_component(package, buffer);
cls->ProgIDText = load_dynamic_stringW(row,4);
- cls->ProgIDIndex =
- load_given_progid(package, cls->ProgIDText);
+ cls->ProgID = load_given_progid(package, cls->ProgIDText);
cls->Description = load_dynamic_stringW(row,5);
LPWSTR FilePath;
static const WCHAR fmt[] = {'%','s',',','%','i',0};
- build_icon_path(package,FileName,&FilePath);
+ FilePath = build_icon_path(package,FileName);
- cls->IconPath =
- HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*
- sizeof(WCHAR));
+ cls->IconPath = msi_alloc( (strlenW(FilePath)+5)* sizeof(WCHAR) );
sprintfW(cls->IconPath,fmt,FilePath,icon_index);
- HeapFree(GetProcessHeap(),0,FilePath);
- HeapFree(GetProcessHeap(),0,FileName);
+ msi_free(FilePath);
+ msi_free(FileName);
}
else
{
buffer = MSI_RecordGetString(row,8);
if (buffer)
- build_icon_path(package,buffer,&(cls->IconPath));
+ cls->IconPath = build_icon_path(package,buffer);
}
if (!MSI_RecordIsNull(row,10))
}
else
{
- cls->DefInprocHandler32 = load_dynamic_stringW(
- row, 10);
+ cls->DefInprocHandler32 = load_dynamic_stringW( row, 10);
reduce_to_longfilename(cls->DefInprocHandler32);
}
}
/* check for classes already loaded */
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
{
- if (lstrcmpiW( cls->CLSID, classid )==0)
+ if (lstrcmpiW( cls->clsid, classid )==0)
{
TRACE("found class %s (%p)\n",debugstr_w(classid), cls);
return cls;
static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row )
{
- DWORD sz;
LPCWSTR buffer;
MSIMIME *mt;
/* fill in the data */
- mt = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSIMIME) );
+ mt = msi_alloc_zero( sizeof(MSIMIME) );
if (!mt)
return mt;
buffer = MSI_RecordGetString( row, 2 );
mt->Extension = load_given_extension( package, buffer );
- sz = IDENTIFIER_SIZE;
- MSI_RecordGetStringW( row, 3, mt->CLSID, &sz );
- mt->Class = load_given_class( package, mt->CLSID );
+ mt->clsid = load_dynamic_stringW( row, 3 );
+ mt->Class = load_given_class( package, mt->clsid );
list_add_tail( &package->mimes, &mt->entry );
static MSIEXTENSION *load_extension( MSIPACKAGE* package, MSIRECORD *row )
{
MSIEXTENSION *ext;
- DWORD sz;
LPCWSTR buffer;
/* fill in the data */
- ext = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSIEXTENSION) );
+ ext = msi_alloc_zero( sizeof(MSIEXTENSION) );
+ if (!ext)
+ return NULL;
+
+ list_init( &ext->verbs );
+
+ list_add_tail( &package->extensions, &ext->entry );
- sz = 256;
- MSI_RecordGetStringW( row, 1, ext->Extension, &sz );
+ ext->Extension = load_dynamic_stringW( row, 1 );
TRACE("loading extension %s\n", debugstr_w(ext->Extension));
buffer = MSI_RecordGetString( row, 2 );
ext->Component = get_loaded_component( package,buffer );
ext->ProgIDText = load_dynamic_stringW( row, 3 );
- ext->ProgIDIndex = load_given_progid( package, ext->ProgIDText );
+ ext->ProgID = load_given_progid( package, ext->ProgIDText );
buffer = MSI_RecordGetString( row, 4 );
ext->Mime = load_given_mime( package, buffer );
buffer = MSI_RecordGetString(row,5);
ext->Feature = get_loaded_feature( package, buffer );
- list_add_tail( &package->extensions, &ext->entry );
-
return ext;
}
static UINT iterate_load_verb(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE* package = (MSIPACKAGE*)param;
- DWORD index = package->loaded_verbs;
+ MSIVERB *verb;
LPCWSTR buffer;
-
- /* fill in the data */
-
- package->loaded_verbs++;
- if (package->loaded_verbs == 1)
- package->verbs = HeapAlloc(GetProcessHeap(),0,sizeof(MSIVERB));
- else
- package->verbs = HeapReAlloc(GetProcessHeap(),0,
- package->verbs , package->loaded_verbs * sizeof(MSIVERB));
-
- memset(&package->verbs[index],0,sizeof(MSIVERB));
+ MSIEXTENSION *extension;
buffer = MSI_RecordGetString(row,1);
- package->verbs[index].Extension = load_given_extension(package,buffer);
- if (package->verbs[index].Extension == NULL && buffer)
+ extension = load_given_extension( package, buffer );
+ if (!extension)
+ {
ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer));
+ return ERROR_SUCCESS;
+ }
- package->verbs[index].Verb = load_dynamic_stringW(row,2);
- TRACE("loading verb %s\n",debugstr_w(package->verbs[index].Verb));
- package->verbs[index].Sequence = MSI_RecordGetInteger(row,3);
+ /* fill in the data */
+
+ verb = msi_alloc_zero( sizeof(MSIVERB) );
+ if (!verb)
+ return ERROR_OUTOFMEMORY;
+
+ verb->Verb = load_dynamic_stringW(row,2);
+ TRACE("loading verb %s\n",debugstr_w(verb->Verb));
+ verb->Sequence = MSI_RecordGetInteger(row,3);
buffer = MSI_RecordGetString(row,4);
- deformat_string(package,buffer,&package->verbs[index].Command);
+ deformat_string(package,buffer,&verb->Command);
buffer = MSI_RecordGetString(row,5);
- deformat_string(package,buffer,&package->verbs[index].Argument);
+ deformat_string(package,buffer,&verb->Argument);
/* assosiate the verb with the correct extension */
- if (package->verbs[index].Extension)
- {
- MSIEXTENSION* extension = package->verbs[index].Extension;
- int count = extension->VerbCount;
-
- if (count >= 99)
- FIXME("Exceeding max verb count! Increase that limit!!!\n");
- else
- {
- extension->VerbCount++;
- extension->Verbs[count] = index;
- }
- }
+ list_add_tail( &extension->verbs, &verb->entry );
return ERROR_SUCCESS;
}
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
{
- if (strcmpiW( clsid, cls->CLSID ))
+ if (strcmpiW( clsid, cls->clsid ))
continue;
if (strcmpW( context, cls->Context ))
continue;
if (!list_empty( &package->classes ) ||
!list_empty( &package->mimes ) ||
!list_empty( &package->extensions ) ||
- package->progids || package->verbs )
+ !list_empty( &package->progids ) )
return;
load_all_classes(package);
load_all_mimes(package);
}
-static void mark_progid_for_install(MSIPACKAGE* package, INT index)
+static void mark_progid_for_install( MSIPACKAGE* package, MSIPROGID *progid )
{
- MSIPROGID* progid;
- int i;
+ MSIPROGID *child;
- if (index < 0 || index >= package->loaded_progids)
+ if (!progid)
return;
- progid = &package->progids[index];
-
if (progid->InstallMe == TRUE)
return;
progid->InstallMe = TRUE;
/* all children if this is a parent also install */
- for (i = 0; i < package->loaded_progids; i++)
- if (package->progids[i].ParentIndex == index)
- mark_progid_for_install(package,i);
+ LIST_FOR_EACH_ENTRY( child, &package->progids, MSIPROGID, entry )
+ {
+ if (child->Parent == progid)
+ mark_progid_for_install( package, child );
+ }
}
static void mark_mime_for_install( MSIMIME *mime )
mime->InstallMe = TRUE;
}
+LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value )
+{
+ DWORD len = value ? (lstrlenW(value) + 1) * sizeof (WCHAR) : 0;
+ return RegSetValueExW( hkey, name, 0, REG_SZ, (LPBYTE)value, len );
+}
+
+LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value )
+{
+ LPCWSTR p = value;
+ while (*p) p += lstrlenW(p) + 1;
+ return RegSetValueExW( hkey, name, 0, REG_MULTI_SZ,
+ (LPBYTE)value, (p + 1 - value) * sizeof(WCHAR) );
+}
+
+LONG msi_reg_set_val_dword( HKEY hkey, LPCWSTR name, DWORD val )
+{
+ return RegSetValueExW( hkey, name, 0, REG_DWORD, (LPBYTE)&val, sizeof (DWORD) );
+}
+
+LONG msi_reg_set_subkey_val( HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val )
+{
+ HKEY hsubkey = 0;
+ LONG r;
+
+ r = RegCreateKeyW( hkey, path, &hsubkey );
+ if (r != ERROR_SUCCESS)
+ return r;
+ r = msi_reg_set_val_str( hsubkey, name, val );
+ RegCloseKey( hsubkey );
+ return r;
+}
+
static UINT register_appid(MSIAPPID *appid, LPCWSTR app )
{
static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
+ static const WCHAR szRemoteServerName[] =
+ {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
+ static const WCHAR szLocalService[] =
+ {'L','o','c','a','l','S','e','r','v','i','c','e',0};
+ static const WCHAR szService[] =
+ {'S','e','r','v','i','c','e','P','a','r','a','m','e','t','e','r','s',0};
+ static const WCHAR szDLL[] =
+ {'D','l','l','S','u','r','r','o','g','a','t','e',0};
+ static const WCHAR szActivate[] =
+ {'A','c','t','i','v','a','t','e','A','s','S','t','o','r','a','g','e',0};
+ static const WCHAR szY[] = {'Y',0};
+ static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
+ static const WCHAR szUser[] =
+ {'I','n','t','e','r','a','c','t','i','v','e',' ','U','s','e','r',0};
+
HKEY hkey2,hkey3;
- UINT size;
RegCreateKeyW(HKEY_CLASSES_ROOT,szAppID,&hkey2);
RegCreateKeyW( hkey2, appid->AppID, &hkey3 );
- RegSetValueExW( hkey3, NULL, 0, REG_SZ,
- (LPBYTE)app, (strlenW(app)+1)*sizeof(WCHAR) );
+ RegCloseKey(hkey2);
+ msi_reg_set_val_str( hkey3, NULL, app );
if (appid->RemoteServerName)
- {
- static const WCHAR szRemoteServerName[] =
- {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
-
- size = (lstrlenW(appid->RemoteServerName)+1) * sizeof(WCHAR);
-
- RegSetValueExW( hkey3, szRemoteServerName, 0, REG_SZ,
- (LPBYTE)appid->RemoteServerName, size);
- }
+ msi_reg_set_val_str( hkey3, szRemoteServerName, appid->RemoteServerName );
if (appid->LocalServer)
- {
- static const WCHAR szLocalService[] =
- {'L','o','c','a','l','S','e','r','v','i','c','e',0};
-
- size = (lstrlenW(appid->LocalServer)+1) * sizeof(WCHAR);
-
- RegSetValueExW( hkey3, szLocalService, 0, REG_SZ,
- (LPBYTE)appid->LocalServer, size );
- }
+ msi_reg_set_val_str( hkey3, szLocalService, appid->LocalServer );
if (appid->ServiceParameters)
- {
- static const WCHAR szService[] =
- {'S','e','r','v','i','c','e',
- 'P','a','r','a','m','e','t','e','r','s',0};
-
- size = (lstrlenW(appid->ServiceParameters)+1) * sizeof(WCHAR);
- RegSetValueExW( hkey3, szService, 0, REG_SZ,
- (LPBYTE)appid->ServiceParameters, size );
- }
+ msi_reg_set_val_str( hkey3, szService, appid->ServiceParameters );
if (appid->DllSurrogate)
- {
- static const WCHAR szDLL[] =
- {'D','l','l','S','u','r','r','o','g','a','t','e',0};
-
- size = (lstrlenW(appid->DllSurrogate)+1) * sizeof(WCHAR);
- RegSetValueExW( hkey3, szDLL, 0, REG_SZ,
- (LPBYTE)appid->DllSurrogate, size );
- }
+ msi_reg_set_val_str( hkey3, szDLL, appid->DllSurrogate );
if (appid->ActivateAtStorage)
- {
- static const WCHAR szActivate[] =
- {'A','c','t','i','v','a','t','e','A','s',
- 'S','t','o','r','a','g','e',0};
- static const WCHAR szY[] = {'Y',0};
-
- RegSetValueExW( hkey3, szActivate, 0, REG_SZ,
- (LPBYTE)szY, sizeof szY );
- }
+ msi_reg_set_val_str( hkey3, szActivate, szY );
if (appid->RunAsInteractiveUser)
- {
- static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
- static const WCHAR szUser[] =
- {'I','n','t','e','r','a','c','t','i','v','e',' ',
- 'U','s','e','r',0};
-
- RegSetValueExW( hkey3, szRunAs, 0, REG_SZ,
- (LPBYTE)szUser, sizeof szUser );
- }
+ msi_reg_set_val_str( hkey3, szRunAs, szUser );
RegCloseKey(hkey3);
- RegCloseKey(hkey2);
return ERROR_SUCCESS;
}
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
{
TRACE("Skipping class %s reg due to disabled feature %s\n",
- debugstr_w(cls->CLSID),
+ debugstr_w(cls->clsid),
debugstr_w(feature->Feature));
continue;
}
- TRACE("Registering class %s (%p)\n", debugstr_w(cls->CLSID), cls);
+ TRACE("Registering class %s (%p)\n", debugstr_w(cls->clsid), cls);
cls->Installed = TRUE;
- if (cls->ProgIDIndex >= 0)
- mark_progid_for_install( package, cls->ProgIDIndex );
+ mark_progid_for_install( package, cls->ProgID );
- RegCreateKeyW( hkey, cls->CLSID, &hkey2 );
+ RegCreateKeyW( hkey, cls->clsid, &hkey2 );
if (cls->Description)
- RegSetValueExW( hkey2, NULL, 0, REG_SZ, (LPBYTE)cls->Description,
- (strlenW(cls->Description)+1)*sizeof(WCHAR));
+ msi_reg_set_val_str( hkey2, NULL, cls->Description );
RegCreateKeyW( hkey2, cls->Context, &hkey3 );
file = get_loaded_file( package, comp->KeyPath );
*/
if (strcmpiW( cls->Context, szInprocServer32 )!=0)
{
- sz = 0;
sz = GetShortPathNameW( file->TargetPath, NULL, 0 );
if (sz == 0)
{
size += sizeof(WCHAR);
}
- argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
+ argument = msi_alloc( size + sizeof(WCHAR));
GetShortPathNameW( file->TargetPath, argument, sz );
if (cls->Argument)
size += sizeof(WCHAR);
}
- argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
+ argument = msi_alloc( size + sizeof(WCHAR));
strcpyW( argument, file->TargetPath );
if (cls->Argument)
if (argument)
{
- RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPBYTE)argument, size);
- HeapFree(GetProcessHeap(),0,argument);
+ msi_reg_set_val_str( hkey3, NULL, argument );
+ msi_free(argument);
}
RegCloseKey(hkey3);
- if (cls->ProgIDIndex >= 0 || cls->ProgIDText)
+ if (cls->ProgID || cls->ProgIDText)
{
LPCWSTR progid;
- if (cls->ProgIDIndex >= 0)
- progid = package->progids[cls->ProgIDIndex].ProgID;
+ if (cls->ProgID)
+ progid = cls->ProgID->ProgID;
else
progid = cls->ProgIDText;
- RegCreateKeyW(hkey2,szProgID,&hkey3);
- RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)progid,
- (strlenW(progid)+1) *sizeof(WCHAR));
- RegCloseKey(hkey3);
+ msi_reg_set_subkey_val( hkey2, szProgID, NULL, progid );
- if (cls->ProgIDIndex >= 0 &&
- package->progids[cls->ProgIDIndex].VersionIndIndex >= 0)
+ if (cls->ProgID && cls->ProgID->VersionInd)
{
- LPWSTR viprogid = strdupW(package->progids[package->progids[
- cls->ProgIDIndex].VersionIndIndex].ProgID);
- RegCreateKeyW(hkey2,szVIProgID,&hkey3);
- RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)viprogid,
- (strlenW(viprogid)+1) *sizeof(WCHAR));
- RegCloseKey(hkey3);
- HeapFree(GetProcessHeap(), 0, viprogid);
+ msi_reg_set_subkey_val( hkey2, szVIProgID, NULL,
+ cls->ProgID->VersionInd->ProgID );
}
}
{
MSIAPPID *appid = cls->AppID;
- RegSetValueExW( hkey2, szAppID, 0, REG_SZ, (LPBYTE)appid->AppID,
- (lstrlenW(appid->AppID)+1)*sizeof(WCHAR) );
+ msi_reg_set_val_str( hkey2, szAppID, appid->AppID );
register_appid( appid, cls->Description );
}
static const WCHAR szDefaultIcon[] =
{'D','e','f','a','u','l','t','I','c','o','n',0};
- RegCreateKeyW(hkey2,szDefaultIcon,&hkey3);
-
- RegSetValueExW( hkey3, NULL, 0, REG_SZ, (LPVOID)cls->IconPath,
- (strlenW(cls->IconPath)+1) * sizeof(WCHAR));
-
- RegCloseKey(hkey3);
+ msi_reg_set_subkey_val( hkey2, szDefaultIcon, NULL, cls->IconPath );
}
if (cls->DefInprocHandler)
static const WCHAR szInproc[] =
{'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
- size = (strlenW(cls->DefInprocHandler) + 1) * sizeof(WCHAR);
- RegCreateKeyW(hkey2,szInproc,&hkey3);
- RegSetValueExW(hkey3,NULL,0,REG_SZ,
- (LPBYTE)cls->DefInprocHandler, size);
- RegCloseKey(hkey3);
+ msi_reg_set_subkey_val( hkey2, szInproc, NULL, cls->DefInprocHandler );
}
if (cls->DefInprocHandler32)
{
static const WCHAR szInproc32[] =
- {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',
- 0};
- size = (strlenW(cls->DefInprocHandler32) + 1) * sizeof(WCHAR);
-
- RegCreateKeyW(hkey2,szInproc32,&hkey3);
- RegSetValueExW(hkey3,NULL,0,REG_SZ,
- (LPBYTE)cls->DefInprocHandler32,size);
- RegCloseKey(hkey3);
+ {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
+
+ msi_reg_set_subkey_val( hkey2, szInproc32, NULL, cls->DefInprocHandler32 );
}
RegCloseKey(hkey2);
ptr2 = strchrW(ptr,';');
if (ptr2)
*ptr2 = 0;
- keyname = HeapAlloc(GetProcessHeap(),0,(strlenW(szFileType_fmt)+
- strlenW(cls->CLSID) + 4) * sizeof(WCHAR));
- sprintfW( keyname, szFileType_fmt, cls->CLSID, index );
+ keyname = msi_alloc( (strlenW(szFileType_fmt) + strlenW(cls->clsid) + 4) * sizeof(WCHAR));
+ sprintfW( keyname, szFileType_fmt, cls->clsid, index );
- RegCreateKeyW(HKEY_CLASSES_ROOT,keyname,&hkey2);
- RegSetValueExW(hkey2,NULL,0,REG_SZ, (LPVOID)ptr,
- strlenW(ptr)*sizeof(WCHAR));
- RegCloseKey(hkey2);
- HeapFree(GetProcessHeap(), 0, keyname);
+ msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, keyname, NULL, ptr );
+ msi_free(keyname);
if (ptr2)
ptr = ptr2+1;
uirow = MSI_CreateRecord(1);
- MSI_RecordSetStringW( uirow, 1, cls->CLSID );
+ MSI_RecordSetStringW( uirow, 1, cls->clsid );
ui_actiondata(package,szRegisterClassInfo,uirow);
msiobj_release(&uirow->hdr);
}
static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
static const WCHAR szDefaultIcon[] =
{'D','e','f','a','u','l','t','I','c','o','n',0};
- HKEY hkey,hkey2;
+ HKEY hkey;
RegCreateKeyW(HKEY_CLASSES_ROOT,progid->ProgID,&hkey);
if (progid->Description)
- {
- RegSetValueExW(hkey,NULL,0,REG_SZ,
- (LPVOID)progid->Description,
- (strlenW(progid->Description)+1) *
- sizeof(WCHAR));
- }
+ msi_reg_set_val_str( hkey, NULL, progid->Description );
if (progid->Class)
{
- RegCreateKeyW(hkey,szCLSID,&hkey2);
- RegSetValueExW( hkey2, NULL, 0, REG_SZ, (LPBYTE)progid->Class->CLSID,
- (strlenW(progid->Class->CLSID)+1) * sizeof(WCHAR) );
-
+ msi_reg_set_subkey_val( hkey, szCLSID, NULL, progid->Class->clsid );
if (clsid)
- strcpyW( clsid, progid->Class->CLSID );
-
- RegCloseKey(hkey2);
+ strcpyW( clsid, progid->Class->clsid );
}
else
{
- FIXME("UNHANDLED case, Parent progid but classid is NULL\n");
+ FIXME("progid (%s) with null classid\n", debugstr_w(progid->ProgID));
}
if (progid->IconPath)
- {
- RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
+ msi_reg_set_subkey_val( hkey, szDefaultIcon, NULL, progid->IconPath );
- RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)progid->IconPath,
- (strlenW(progid->IconPath)+1) * sizeof(WCHAR));
- RegCloseKey(hkey2);
- }
return ERROR_SUCCESS;
}
{
UINT rc = ERROR_SUCCESS;
- if (progid->ParentIndex < 0)
+ if (progid->Parent == NULL)
rc = register_progid_base(package, progid, clsid);
else
{
DWORD disp;
- HKEY hkey,hkey2;
+ HKEY hkey;
static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
static const WCHAR szDefaultIcon[] =
{'D','e','f','a','u','l','t','I','c','o','n',0};
return rc;
}
- TRACE("Registering Parent %s index %i\n",
- debugstr_w(package->progids[progid->ParentIndex].ProgID),
- progid->ParentIndex);
- rc = register_progid(package,&package->progids[progid->ParentIndex],
- clsid);
+ TRACE("Registering Parent %s\n", debugstr_w(progid->Parent->ProgID) );
+ rc = register_progid( package, progid->Parent, clsid );
/* clsid is same as parent */
- RegCreateKeyW(hkey,szCLSID,&hkey2);
- RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)clsid, (strlenW(clsid)+1) *
- sizeof(WCHAR));
-
- RegCloseKey(hkey2);
-
+ msi_reg_set_subkey_val( hkey, szCLSID, NULL, clsid );
if (progid->Description)
- {
- RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)progid->Description,
- (strlenW(progid->Description)+1) * sizeof(WCHAR));
- }
+ msi_reg_set_val_str( hkey, NULL, progid->Description );
if (progid->IconPath)
- {
- RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
- RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)progid->IconPath,
- (strlenW(progid->IconPath)+1) * sizeof(WCHAR));
- RegCloseKey(hkey2);
- }
+ msi_reg_set_subkey_val( hkey, szDefaultIcon, NULL, progid->IconPath );
/* write out the current version */
- if (progid->CurVerIndex >= 0)
- {
- RegCreateKeyW(hkey,szCurVer,&hkey2);
- RegSetValueExW(hkey2,NULL,0,REG_SZ,
- (LPVOID)package->progids[progid->CurVerIndex].ProgID,
- (strlenW(package->progids[progid->CurVerIndex].ProgID)+1) *
- sizeof(WCHAR));
- RegCloseKey(hkey2);
- }
+ if (progid->CurVer)
+ msi_reg_set_subkey_val( hkey, szCurVer, NULL, progid->CurVer->ProgID );
RegCloseKey(hkey);
}
UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
{
- INT i;
+ MSIPROGID *progid;
MSIRECORD *uirow;
if (!package)
load_classes_and_such(package);
- for (i = 0; i < package->loaded_progids; i++)
+ LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry )
{
WCHAR clsid[0x1000];
/* check if this progid is to be installed */
- package->progids[i].InstallMe = ((package->progids[i].InstallMe) ||
- (package->progids[i].Class &&
- package->progids[i].Class->Installed));
+ if (progid->Class && progid->Class->Installed)
+ progid->InstallMe = TRUE;
- if (!package->progids[i].InstallMe)
+ if (!progid->InstallMe)
{
TRACE("progid %s not scheduled to be installed\n",
- debugstr_w(package->progids[i].ProgID));
+ debugstr_w(progid->ProgID));
continue;
}
- TRACE("Registering progid %s index %i\n",
- debugstr_w(package->progids[i].ProgID), i);
+ TRACE("Registering progid %s\n", debugstr_w(progid->ProgID));
- register_progid(package,&package->progids[i],clsid);
+ register_progid( package, progid, clsid );
uirow = MSI_CreateRecord(1);
- MSI_RecordSetStringW(uirow,1,package->progids[i].ProgID);
- ui_actiondata(package,szRegisterProgIdInfo,uirow);
- msiobj_release(&uirow->hdr);
+ MSI_RecordSetStringW( uirow, 1, progid->ProgID );
+ ui_actiondata( package, szRegisterProgIdInfo, uirow );
+ msiobj_release( &uirow->hdr );
}
return ERROR_SUCCESS;
size += strlenW(verb->Argument);
size += 4;
- command = HeapAlloc(GetProcessHeap(),0, size * sizeof (WCHAR));
+ command = msi_alloc(size * sizeof (WCHAR));
if (verb->Argument)
sprintfW(command, fmt, component->FullKeypath, verb->Argument);
else
sprintfW(command, fmt2, component->FullKeypath);
- RegSetValueExW(key,NULL,0,REG_SZ, (LPVOID)command, (strlenW(command)+1)*
- sizeof(WCHAR));
- HeapFree(GetProcessHeap(),0,command);
+ msi_reg_set_val_str( key, NULL, command );
+ msi_free(command);
advertise = create_component_advertise_string(package, component,
extension->Feature->Feature);
size += strlenW(verb->Argument);
size += 4;
- command = HeapAlloc(GetProcessHeap(),0, size * sizeof (WCHAR));
+ command = msi_alloc(size * sizeof (WCHAR));
memset(command,0,size*sizeof(WCHAR));
strcpyW(command,advertise);
strcatW(command,verb->Argument);
}
- RegSetValueExW(key, szCommand, 0, REG_MULTI_SZ, (LPBYTE)command,
- (strlenW(command)+2)*sizeof(WCHAR));
+ msi_reg_set_val_multi_str( key, szCommand, command );
RegCloseKey(key);
- HeapFree(GetProcessHeap(),0,keyname);
- HeapFree(GetProcessHeap(),0,advertise);
- HeapFree(GetProcessHeap(),0,command);
+ msi_free(keyname);
+ msi_free(advertise);
+ msi_free(command);
if (verb->Command)
{
keyname = build_directory_name(3, progid, szShell, verb->Verb);
- RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key);
- RegSetValueExW(key,NULL,0,REG_SZ, (LPVOID)verb->Command,
- (strlenW(verb->Command)+1) *sizeof(WCHAR));
- RegCloseKey(key);
- HeapFree(GetProcessHeap(),0,keyname);
+ msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, keyname, NULL, verb->Command );
+ msi_free(keyname);
}
if (verb->Sequence != MSI_NULL_INTEGER)
{
*Sequence = verb->Sequence;
keyname = build_directory_name(2, progid, szShell);
- RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key);
- RegSetValueExW(key,NULL,0,REG_SZ, (LPVOID)verb->Verb,
- (strlenW(verb->Verb)+1) *sizeof(WCHAR));
- RegCloseKey(key);
- HeapFree(GetProcessHeap(),0,keyname);
+ msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, keyname, NULL, verb->Verb );
+ msi_free(keyname);
}
}
return ERROR_SUCCESS;
LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
{
- WCHAR extension[257];
+ LPWSTR extension;
MSIFEATURE *feature;
if (!ext->Component)
/* this is only registered if the extension has at least 1 verb
* according to MSDN
*/
- if (ext->ProgIDIndex >= 0 && ext->VerbCount > 0)
- mark_progid_for_install(package, ext->ProgIDIndex);
+ if (ext->ProgID && !list_empty( &ext->verbs ) )
+ mark_progid_for_install( package, ext->ProgID );
mark_mime_for_install(ext->Mime);
+ extension = msi_alloc( (lstrlenW( ext->Extension ) + 2)*sizeof(WCHAR) );
extension[0] = '.';
- extension[1] = 0;
- strcatW(extension,ext->Extension);
+ lstrcpyW(extension+1,ext->Extension);
RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey);
+ msi_free( extension );
if (ext->Mime)
- {
- RegSetValueExW(hkey,szContentType,0,REG_SZ,
- (LPBYTE)ext->Mime->ContentType,
- (strlenW(ext->Mime->ContentType)+1)*sizeof(WCHAR));
- }
+ msi_reg_set_val_str( hkey, szContentType, ext->Mime->ContentType );
- if (ext->ProgIDIndex >= 0 || ext->ProgIDText)
+ if (ext->ProgID || ext->ProgIDText)
{
static const WCHAR szSN[] =
{'\\','S','h','e','l','l','N','e','w',0};
HKEY hkey2;
LPWSTR newkey;
LPCWSTR progid;
- INT v;
+ MSIVERB *verb;
INT Sequence = MSI_NULL_INTEGER;
- if (ext->ProgIDIndex >= 0)
- progid = package->progids[ext->ProgIDIndex].ProgID;
+ if (ext->ProgID)
+ progid = ext->ProgID->ProgID;
else
progid = ext->ProgIDText;
- RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)progid,
- (strlenW(progid)+1)*sizeof(WCHAR));
+ msi_reg_set_val_str( hkey, NULL, progid );
- newkey = HeapAlloc(GetProcessHeap(),0,
- (strlenW(progid)+strlenW(szSN)+1) * sizeof(WCHAR));
+ newkey = msi_alloc( (strlenW(progid)+strlenW(szSN)+1) * sizeof(WCHAR));
strcpyW(newkey,progid);
strcatW(newkey,szSN);
RegCreateKeyW(hkey,newkey,&hkey2);
RegCloseKey(hkey2);
- HeapFree(GetProcessHeap(),0,newkey);
+ msi_free(newkey);
/* do all the verbs */
- for (v = 0; v < ext->VerbCount; v++)
+ LIST_FOR_EACH_ENTRY( verb, &ext->verbs, MSIVERB, entry )
+ {
register_verb( package, progid, ext->Component,
- ext, &package->verbs[ext->Verbs[v]], &Sequence);
+ ext, verb, &Sequence);
+ }
}
RegCloseKey(hkey);
{
static const WCHAR szExten[] =
{'E','x','t','e','n','s','i','o','n',0 };
- HKEY hkey;
MSIRECORD *uirow;
MSIMIME *mt;
LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry )
{
- WCHAR extension[257];
+ LPWSTR extension;
LPCWSTR exten;
LPCWSTR mime;
static const WCHAR fmt[] =
mime = mt->ContentType;
exten = mt->Extension->Extension;
+
+ extension = msi_alloc( (lstrlenW( exten ) + 2)*sizeof(WCHAR) );
extension[0] = '.';
- extension[1] = 0;
- strcatW(extension,exten);
+ lstrcpyW(extension+1,exten);
- key = HeapAlloc(GetProcessHeap(),0,(strlenW(mime)+strlenW(fmt)+1) *
- sizeof(WCHAR));
+ key = msi_alloc( (strlenW(mime)+strlenW(fmt)+1) * sizeof(WCHAR) );
sprintfW(key,fmt,mime);
- RegCreateKeyW(HKEY_CLASSES_ROOT,key,&hkey);
- RegSetValueExW(hkey,szExten,0,REG_SZ,(LPVOID)extension,
- (strlenW(extension)+1)*sizeof(WCHAR));
+ msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExten, extension );
- HeapFree(GetProcessHeap(),0,key);
+ msi_free(extension);
+ msi_free(key);
- if (mt->CLSID[0])
- {
+ if (mt->clsid)
FIXME("Handle non null for field 3\n");
- }
-
- RegCloseKey(hkey);
uirow = MSI_CreateRecord(2);
MSI_RecordSetStringW(uirow,1,mt->ContentType);
-/* A Bison parser, made from ./cond.y
- by GNU bison 1.35. */
+/* A Bison parser, made by GNU Bison 1.875c. */
-#define YYBISON 1 /* Identify Bison output. */
+/* Skeleton parser for Yacc-like parsing with Bison,
+ 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. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
#define yyparse COND_parse
-#define yylex COND_lex
+#define yylex COND_lex
#define yyerror COND_error
-#define yylval COND_lval
-#define yychar COND_char
+#define yylval COND_lval
+#define yychar COND_char
#define yydebug COND_debug
#define yynerrs COND_nerrs
-# define COND_SPACE 257
-# define COND_EOF 258
-# define COND_OR 259
-# define COND_AND 260
-# define COND_NOT 261
-# define COND_LT 262
-# define COND_GT 263
-# define COND_EQ 264
-# define COND_LPAR 265
-# define COND_RPAR 266
-# define COND_TILDA 267
-# define COND_PERCENT 268
-# define COND_DOLLARS 269
-# define COND_QUESTION 270
-# define COND_AMPER 271
-# define COND_EXCLAM 272
-# define COND_IDENT 273
-# define COND_NUMBER 274
-# define COND_LITER 275
-# define COND_ERROR 276
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ COND_SPACE = 258,
+ COND_EOF = 259,
+ COND_OR = 260,
+ COND_AND = 261,
+ COND_NOT = 262,
+ COND_LT = 263,
+ COND_GT = 264,
+ COND_EQ = 265,
+ COND_LPAR = 266,
+ COND_RPAR = 267,
+ COND_TILDA = 268,
+ COND_PERCENT = 269,
+ COND_DOLLARS = 270,
+ COND_QUESTION = 271,
+ COND_AMPER = 272,
+ COND_EXCLAM = 273,
+ COND_IDENT = 274,
+ COND_NUMBER = 275,
+ COND_LITER = 276,
+ COND_ERROR = 277
+ };
+#endif
+#define COND_SPACE 258
+#define COND_EOF 259
+#define COND_OR 260
+#define COND_AND 261
+#define COND_NOT 262
+#define COND_LT 263
+#define COND_GT 264
+#define COND_EQ 265
+#define COND_LPAR 266
+#define COND_RPAR 267
+#define COND_TILDA 268
+#define COND_PERCENT 269
+#define COND_DOLLARS 270
+#define COND_QUESTION 271
+#define COND_AMPER 272
+#define COND_EXCLAM 273
+#define COND_IDENT 274
+#define COND_NUMBER 275
+#define COND_LITER 276
+#define COND_ERROR 277
+
+
+
+
+/* Copy the first part of user declarations. */
#line 1 "./cond.y"
static INT comp_ge_m2(INT a, LPWSTR b);
-#line 105 "./cond.y"
-#ifndef YYSTYPE
-typedef union
-{
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 106 "./cond.y"
+typedef union YYSTYPE {
struct cond_str str;
LPWSTR string;
INT value;
comp_str fn_comp_str;
comp_m1 fn_comp_m1;
comp_m2 fn_comp_m2;
-} yystype;
-# define YYSTYPE yystype
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+#line 241 "cond.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#define YYFINAL 74
-#define YYFLAG -32768
-#define YYNTBASE 23
+/* Copy the second part of user declarations. */
-/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
-#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 39)
-/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
-static const char yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22
-};
-
-#if YYDEBUG
-static const short yyprhs[] =
-{
- 0, 0, 2, 4, 8, 10, 14, 16, 19, 21,
- 23, 27, 31, 36, 40, 44, 48, 50, 53, 55,
- 57, 60, 63, 66, 69, 72, 74, 77, 79, 81,
- 84, 87, 90, 93, 96, 98, 101, 103, 105, 108,
- 111, 114, 117, 120, 122, 125, 127, 129, 132, 135,
- 138, 141, 144, 146, 148, 150, 152, 154, 157, 160,
- 163, 166, 168, 171, 173
-};
-static const short yyrhs[] =
-{
- 24, 0, 25, 0, 25, 5, 24, 0, 26, 0,
- 25, 6, 26, 0, 27, 0, 7, 27, 0, 32,
- 0, 33, 0, 32, 28, 32, 0, 33, 29, 33,
- 0, 33, 13, 29, 33, 0, 33, 30, 32, 0,
- 32, 31, 33, 0, 11, 24, 12, 0, 10, 0,
- 8, 9, 0, 8, 0, 9, 0, 8, 10, 0,
- 9, 10, 0, 9, 8, 0, 8, 8, 0, 9,
- 9, 0, 10, 0, 8, 9, 0, 8, 0, 9,
- 0, 8, 10, 0, 9, 10, 0, 9, 8, 0,
- 8, 8, 0, 9, 9, 0, 10, 0, 8, 9,
- 0, 8, 0, 9, 0, 8, 10, 0, 9, 10,
- 0, 9, 8, 0, 8, 8, 0, 9, 9, 0,
- 10, 0, 8, 9, 0, 8, 0, 9, 0, 8,
- 10, 0, 9, 10, 0, 9, 8, 0, 8, 8,
- 0, 9, 9, 0, 35, 0, 38, 0, 36, 0,
- 34, 0, 21, 0, 15, 37, 0, 16, 37, 0,
- 17, 37, 0, 18, 37, 0, 37, 0, 14, 37,
- 0, 19, 0, 20, 0
-};
-
-#endif
-
-#if YYDEBUG
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const short yyrline[] =
-{
- 0, 135, 143, 148, 154, 159, 165, 170, 177, 182,
- 186, 190, 194, 198, 202, 206, 212, 218, 222, 226,
- 230, 234, 239, 243, 247, 253, 259, 263, 267, 271,
- 275, 280, 284, 288, 294, 300, 304, 308, 312, 316,
- 321, 325, 329, 335, 341, 345, 349, 353, 357, 362,
- 366, 370, 376, 381, 387, 392, 398, 407, 417, 426,
- 435, 446, 470, 483, 492
-};
-#endif
-
-
-#if (YYDEBUG) || defined YYERROR_VERBOSE
-
-/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
-static const char *const yytname[] =
-{
- "$", "error", "$undefined.", "COND_SPACE", "COND_EOF", "COND_OR",
- "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR",
- "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS",
- "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
- "COND_NUMBER", "COND_LITER", "COND_ERROR", "condition", "expression",
- "boolean_term", "boolean_factor", "term", "comp_op_i", "comp_op_s",
- "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", "symbol_i",
- "symbol_s", "identifier", "integer", 0
-};
-#endif
+/* Line 214 of yacc.c. */
+#line 253 "cond.tab.c"
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const short yyr1[] =
-{
- 0, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 27, 27, 27, 27, 27, 27, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 32, 32, 33, 33, 34, 35, 35, 35,
- 35, 36, 36, 37, 38
-};
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const short yyr2[] =
-{
- 0, 1, 1, 3, 1, 3, 1, 2, 1, 1,
- 3, 3, 4, 3, 3, 3, 1, 2, 1, 1,
- 2, 2, 2, 2, 2, 1, 2, 1, 1, 2,
- 2, 2, 2, 2, 1, 2, 1, 1, 2, 2,
- 2, 2, 2, 1, 2, 1, 1, 2, 2, 2,
- 2, 2, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 1, 2, 1, 1
-};
-
-/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
- doesn't specify something else to do. Zero means the default is an
- error. */
-static const short yydefact[] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 64,
- 56, 1, 2, 4, 6, 8, 9, 55, 52, 54,
- 61, 53, 7, 0, 62, 57, 58, 59, 60, 0,
- 0, 18, 19, 16, 0, 0, 36, 37, 34, 0,
- 0, 0, 15, 3, 5, 23, 17, 20, 22, 24,
- 21, 10, 14, 41, 35, 38, 40, 42, 39, 27,
- 28, 25, 0, 11, 13, 32, 26, 29, 31, 33,
- 30, 12, 0, 0, 0
-};
-
-static const short yydefgoto[] =
-{
- 72, 11, 12, 13, 14, 34, 40, 41, 35, 15,
- 16, 17, 18, 19, 20, 21
-};
-
-static const short yypact[] =
-{
- -5, 50, -5, -12, -12, -12, -12, -12,-32768,-32768,
- -32768,-32768, -2,-32768,-32768, 48, 123,-32768,-32768,-32768,
- -32768,-32768,-32768, -4,-32768,-32768,-32768,-32768,-32768, -5,
- -5, 10, 24, 33, 110, 58, 27, 41, 59, 135,
- 58, 110,-32768,-32768,-32768, 62, 68, 71, 72, 80,
- 81,-32768,-32768, 84, 90, 93, 94, 102, 103, 138,
- 141,-32768, 58,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
- -32768,-32768, 17, 21,-32768
-};
-
-static const short yypgoto[] =
-{
- -32768, -1,-32768, -8, 25,-32768, -14,-32768,-32768, -11,
- -35,-32768,-32768,-32768, 134,-32768
-};
-
-
-#define YYLAST 151
-
-
-static const short yytable[] =
-{
- 52, 23, 1, 29, 30, 63, 2, 8, 42, 3,
- 4, 5, 6, 7, 8, 9, 10, 73, 45, 46,
- 47, 74, 44, 51, -45, 62, 22, 71, 43, -45,
- 64, -45, 48, 49, 50, 53, 54, 55, -46, 0,
- 0, -27, 0, -46, 0, -46, -27, -43, -27, 56,
- 57, 58, -43, 0, -43, -28, 31, 32, 33, 0,
- -28, 2, -28, 0, 3, 4, 5, 6, 7, 8,
- 9, 10, 3, -25, 0, 0, -50, 8, -25, 10,
- -25, -50, -44, -50, 0, -47, -49, -44, 0, -44,
- -47, -49, -47, -49, -51, -48, 0, 0, -32, -51,
- -48, -51, -48, -32, -26, -32, 0, -29, -31, -26,
- 0, -26, -29, -31, -29, -31, -33, -30, 0, 0,
- 0, -33, -30, -33, -30, 4, 5, 6, 7, 0,
- 9, 36, 37, 38, 0, 0, 39, 24, 25, 26,
- 27, 28, 0, 59, 60, 61, 65, 66, 67, 68,
- 69, 70
-};
-
-static const short yycheck[] =
-{
- 35, 2, 7, 5, 6, 40, 11, 19, 12, 14,
- 15, 16, 17, 18, 19, 20, 21, 0, 8, 9,
- 10, 0, 30, 34, 14, 39, 1, 62, 29, 19,
- 41, 21, 8, 9, 10, 8, 9, 10, 14, -1,
- -1, 14, -1, 19, -1, 21, 19, 14, 21, 8,
- 9, 10, 19, -1, 21, 14, 8, 9, 10, -1,
- 19, 11, 21, -1, 14, 15, 16, 17, 18, 19,
- 20, 21, 14, 14, -1, -1, 14, 19, 19, 21,
- 21, 19, 14, 21, -1, 14, 14, 19, -1, 21,
- 19, 19, 21, 21, 14, 14, -1, -1, 14, 19,
- 19, 21, 21, 19, 14, 21, -1, 14, 14, 19,
- -1, 21, 19, 19, 21, 21, 14, 14, -1, -1,
- -1, 19, 19, 21, 21, 15, 16, 17, 18, -1,
- 20, 8, 9, 10, -1, -1, 13, 3, 4, 5,
- 6, 7, -1, 8, 9, 10, 8, 9, 10, 8,
- 9, 10
-};
-#define YYPURE 1
-
-/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/bison/bison.simple"
-
-/* Skeleton output parser for bison,
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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. */
-
-/* This is the parser code that is written into each bison parser when
- the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
/* The parser invokes alloca or malloc; define the necessary symbols. */
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
# else
-# ifndef YYSTACK_USE_ALLOCA
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
# endif
# endif
# endif
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
-# define YYSTACK_ALLOC malloc
-# define YYSTACK_FREE free
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
# endif
-#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
#if (! defined (yyoverflow) \
&& (! defined (__cplusplus) \
- || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
short yyss;
YYSTYPE yyvs;
-# if YYLSP_NEEDED
- YYLTYPE yyls;
-# endif
-};
+ };
/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
-# if YYLSP_NEEDED
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAX)
-# else
-# define YYSTACK_BYTES(N) \
+# define YYSTACK_BYTES(N) \
((N) * (sizeof (short) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAX)
-# endif
+ + YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if 1 < __GNUC__
+# if defined (__GNUC__) && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (0)
#endif
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 30
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 146
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 23
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 17
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 65
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 74
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 277
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 11, 13, 17, 19, 22,
+ 24, 26, 30, 34, 39, 43, 47, 51, 53, 56,
+ 58, 60, 63, 66, 69, 72, 75, 77, 80, 82,
+ 84, 87, 90, 93, 96, 99, 101, 104, 106, 108,
+ 111, 114, 117, 120, 123, 125, 128, 130, 132, 135,
+ 138, 141, 144, 147, 149, 151, 153, 155, 157, 160,
+ 163, 166, 169, 171, 174, 176
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 24, 0, -1, 25, -1, 26, -1, 26, 5, 25,
+ -1, 27, -1, 26, 6, 27, -1, 28, -1, 7,
+ 28, -1, 33, -1, 34, -1, 33, 29, 33, -1,
+ 34, 30, 34, -1, 34, 13, 30, 34, -1, 34,
+ 31, 33, -1, 33, 32, 34, -1, 11, 25, 12,
+ -1, 10, -1, 8, 9, -1, 8, -1, 9, -1,
+ 8, 10, -1, 9, 10, -1, 9, 8, -1, 8,
+ 8, -1, 9, 9, -1, 10, -1, 8, 9, -1,
+ 8, -1, 9, -1, 8, 10, -1, 9, 10, -1,
+ 9, 8, -1, 8, 8, -1, 9, 9, -1, 10,
+ -1, 8, 9, -1, 8, -1, 9, -1, 8, 10,
+ -1, 9, 10, -1, 9, 8, -1, 8, 8, -1,
+ 9, 9, -1, 10, -1, 8, 9, -1, 8, -1,
+ 9, -1, 8, 10, -1, 9, 10, -1, 9, 8,
+ -1, 8, 8, -1, 9, 9, -1, 36, -1, 39,
+ -1, 37, -1, 35, -1, 21, -1, 15, 38, -1,
+ 16, 38, -1, 17, 38, -1, 18, 38, -1, 38,
+ -1, 14, 38, -1, 19, -1, 20, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 136, 136, 144, 148, 155, 159, 166, 170, 178,
+ 182, 187, 191, 197, 203, 208, 213, 221, 225, 229,
+ 233, 237, 241, 246, 250, 254, 262, 266, 270, 274,
+ 278, 282, 287, 291, 295, 303, 307, 311, 315, 319,
+ 323, 328, 332, 336, 344, 348, 352, 356, 360, 364,
+ 369, 373, 377, 384, 388, 395, 399, 406, 415, 424,
+ 433, 442, 454, 477, 491, 500
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR",
+ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR",
+ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS",
+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition",
+ "expression", "boolean_term", "boolean_factor", "term", "comp_op_i",
+ "comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal",
+ "symbol_i", "symbol_s", "identifier", "integer", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 23, 24, 25, 25, 26, 26, 27, 27, 28,
+ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 35, 36, 36,
+ 36, 36, 37, 37, 38, 39
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 1, 3, 1, 3, 1, 2, 1,
+ 1, 3, 3, 4, 3, 3, 3, 1, 2, 1,
+ 1, 2, 2, 2, 2, 2, 1, 2, 1, 1,
+ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2,
+ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 1, 2, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 64, 65,
+ 57, 0, 2, 3, 5, 7, 9, 10, 56, 53,
+ 55, 62, 54, 8, 0, 63, 58, 59, 60, 61,
+ 1, 0, 0, 19, 20, 17, 0, 0, 37, 38,
+ 35, 0, 0, 0, 16, 4, 6, 24, 18, 21,
+ 23, 25, 22, 11, 15, 42, 36, 39, 41, 43,
+ 40, 28, 29, 26, 0, 12, 14, 33, 27, 30,
+ 32, 34, 31, 13
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 11, 12, 13, 14, 15, 36, 42, 43, 37,
+ 16, 17, 18, 19, 20, 21, 22
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -37
+static const short yypact[] =
+{
+ -4, 51, -4, -11, -11, -11, -11, -11, -37, -37,
+ -37, 18, -37, -1, -37, -37, 49, 14, -37, -37,
+ -37, -37, -37, -37, 19, -37, -37, -37, -37, -37,
+ -37, -4, -4, 11, 25, 34, 111, 59, 28, 42,
+ 60, 130, 59, 111, -37, -37, -37, 63, 69, 72,
+ 73, 81, 82, -37, -37, 85, 91, 94, 95, 103,
+ 104, 133, 136, -37, 59, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short yypgoto[] =
+{
+ -37, -37, -2, -37, -6, 39, -37, 0, -37, -37,
+ -34, -36, -37, -37, -37, 129, -37
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -53
+static const yysigned_char yytable[] =
+{
+ 24, 54, 53, 1, 31, 32, 65, 2, 8, 66,
+ 3, 4, 5, 6, 7, 8, 9, 10, 30, 47,
+ 48, 49, 38, 39, 40, -46, 46, 41, 73, 45,
+ -46, 44, -46, 50, 51, 52, 55, 56, 57, -47,
+ 23, 64, -28, 0, -47, 0, -47, -28, -44, -28,
+ 58, 59, 60, -44, 0, -44, -29, 33, 34, 35,
+ 0, -29, 2, -29, 0, 3, 4, 5, 6, 7,
+ 8, 9, 10, 3, -26, 0, 0, -51, 8, -26,
+ 10, -26, -51, -45, -51, 0, -48, -50, -45, 0,
+ -45, -48, -50, -48, -50, -52, -49, 0, 0, -33,
+ -52, -49, -52, -49, -33, -27, -33, 0, -30, -32,
+ -27, 0, -27, -30, -32, -30, -32, -34, -31, 0,
+ 0, 0, -34, -31, -34, -31, 4, 5, 6, 7,
+ 0, 9, 25, 26, 27, 28, 29, 0, 61, 62,
+ 63, 67, 68, 69, 70, 71, 72
+};
+
+static const yysigned_char yycheck[] =
+{
+ 2, 37, 36, 7, 5, 6, 42, 11, 19, 43,
+ 14, 15, 16, 17, 18, 19, 20, 21, 0, 8,
+ 9, 10, 8, 9, 10, 14, 32, 13, 64, 31,
+ 19, 12, 21, 8, 9, 10, 8, 9, 10, 14,
+ 1, 41, 14, -1, 19, -1, 21, 19, 14, 21,
+ 8, 9, 10, 19, -1, 21, 14, 8, 9, 10,
+ -1, 19, 11, 21, -1, 14, 15, 16, 17, 18,
+ 19, 20, 21, 14, 14, -1, -1, 14, 19, 19,
+ 21, 21, 19, 14, 21, -1, 14, 14, 19, -1,
+ 21, 19, 19, 21, 21, 14, 14, -1, -1, 14,
+ 19, 19, 21, 21, 19, 14, 21, -1, 14, 14,
+ 19, -1, 21, 19, 19, 21, 21, 14, 14, -1,
+ -1, -1, 19, 19, 21, 21, 15, 16, 17, 18,
+ -1, 20, 3, 4, 5, 6, 7, -1, 8, 9,
+ 10, 8, 9, 10, 8, 9, 10
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 7, 11, 14, 15, 16, 17, 18, 19, 20,
+ 21, 24, 25, 26, 27, 28, 33, 34, 35, 36,
+ 37, 38, 39, 28, 25, 38, 38, 38, 38, 38,
+ 0, 5, 6, 8, 9, 10, 29, 32, 8, 9,
+ 10, 13, 30, 31, 12, 25, 27, 8, 9, 10,
+ 8, 9, 10, 33, 34, 8, 9, 10, 8, 9,
+ 10, 8, 9, 10, 30, 34, 33, 8, 9, 10,
+ 8, 9, 10, 34
+};
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
# define YYSIZE_T __SIZE_TYPE__
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY -2
+#define YYEMPTY (-2)
#define YYEOF 0
+
#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
+
#define YYFAIL goto yyerrlab
+
#define YYRECOVERING() (!!yyerrstatus)
+
#define YYBACKUP(Token, Value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ \
yychar = (Token); \
yylval = (Value); \
- yychar1 = YYTRANSLATE (yychar); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ \
- yyerror ("syntax error: cannot back up"); \
+ yyerror ("syntax error: cannot back up");\
YYERROR; \
} \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
-
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run).
-
- When YYLLOC_DEFAULT is run, CURRENT is set the location of the
- first token. By default, to implement support for ranges, extend
- its range to the last symbol. */
+ are run). */
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
#endif
-
/* YYLEX -- calling `yylex' with the right arguments. */
-#if YYPURE
-# if YYLSP_NEEDED
-# ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-# else
-# define YYLEX yylex (&yylval, &yylloc)
-# endif
-# else /* !YYLSP_NEEDED */
-# ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-# else
-# define YYLEX yylex (&yylval)
-# endif
-# endif /* !YYLSP_NEEDED */
-#else /* !YYPURE */
-# define YYLEX yylex ()
-#endif /* !YYPURE */
-
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
/* Enable debugging if requested. */
#if YYDEBUG
if (yydebug) \
YYFPRINTF Args; \
} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
+
/* YYINITDEPTH -- initial size of the parser's stacks. */
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if YYMAXDEPTH == 0
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
# undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
+
\f
-#ifdef YYERROR_VERBOSE
+
+#if YYERROR_VERBOSE
# ifndef yystrlen
# if defined (__GLIBC__) && defined (_STRING_H)
}
# endif
# endif
-#endif
+
+#endif /* !YYERROR_VERBOSE */
+
\f
-#line 315 "/usr/share/bison/bison.simple"
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
- into yyparse. The argument should have type void *.
- It should actually point to an object.
- Grammar actions can access the variable by casting it
- to the proper pointer type. */
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
# if defined (__STDC__) || defined (__cplusplus)
-# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-# define YYPARSE_PARAM_DECL
+int yyparse (void *YYPARSE_PARAM);
# else
-# define YYPARSE_PARAM_ARG YYPARSE_PARAM
-# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+int yyparse ();
# endif
-#else /* !YYPARSE_PARAM */
-# define YYPARSE_PARAM_ARG
-# define YYPARSE_PARAM_DECL
-#endif /* !YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-# ifdef YYPARSE_PARAM
-int yyparse (void *);
-# else
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
int yyparse (void);
-# endif
+#else
+int yyparse ();
#endif
+#endif /* ! YYPARSE_PARAM */
-/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
- variables are global, or local to YYPARSE. */
-
-#define YY_DECL_NON_LSP_VARIABLES \
-/* The lookahead symbol. */ \
-int yychar; \
- \
-/* The semantic value of the lookahead symbol. */ \
-YYSTYPE yylval; \
- \
-/* Number of parse errors so far. */ \
-int yynerrs;
-#if YYLSP_NEEDED
-# define YY_DECL_VARIABLES \
-YY_DECL_NON_LSP_VARIABLES \
- \
-/* Location data for the lookahead symbol. */ \
-YYLTYPE yylloc;
-#else
-# define YY_DECL_VARIABLES \
-YY_DECL_NON_LSP_VARIABLES
-#endif
-/* If nonreentrant, generate the variables here. */
-#if !YYPURE
-YY_DECL_VARIABLES
-#endif /* !YYPURE */
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
int
-yyparse (YYPARSE_PARAM_ARG)
- YYPARSE_PARAM_DECL
+yyparse ()
+
+#endif
+#endif
{
- /* If reentrant, generate the variables here. */
-#if YYPURE
- YY_DECL_VARIABLES
-#endif /* !YYPURE */
+ /* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
register int yystate;
register int yyn;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Lookahead token as an internal (translated) token number. */
- int yychar1 = 0;
+ int yytoken = 0;
/* Three stacks and their tools:
`yyss': related to states,
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
- /* The state stack. */
+ /* The state stack. */
short yyssa[YYINITDEPTH];
short *yyss = yyssa;
register short *yyssp;
YYSTYPE *yyvs = yyvsa;
register YYSTYPE *yyvsp;
-#if YYLSP_NEEDED
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
-#endif
-#if YYLSP_NEEDED
-# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
-#else
-# define YYPOPSTACK (yyvsp--, yyssp--)
-#endif
- YYSIZE_T yystacksize = YYINITDEPTH;
+#define YYPOPSTACK (yyvsp--, yyssp--)
+ YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
-#if YYLSP_NEEDED
- YYLTYPE yyloc;
-#endif
+
/* When reducing, the number of symbols on the RHS of the reduced
- rule. */
+ rule. */
int yylen;
YYDPRINTF ((stderr, "Starting parse\n"));
yyssp = yyss;
yyvsp = yyvs;
-#if YYLSP_NEEDED
- yylsp = yyls;
-#endif
+
goto yysetstate;
/*------------------------------------------------------------.
yysetstate:
*yyssp = yystate;
- if (yyssp >= yyss + yystacksize - 1)
+ if (yyss + yystacksize - 1 <= yyssp)
{
/* Get the current used size of the three stacks, in elements. */
YYSIZE_T yysize = yyssp - yyss + 1;
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. */
-# if YYLSP_NEEDED
- YYLTYPE *yyls1 = yyls;
- /* This used to be a conditional around just the two extra args,
- but that might be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
- &yystacksize);
- yyls = yyls1;
-# else
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
yyoverflow ("parser stack overflow",
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
-# endif
+
yyss = yyss1;
yyvs = yyvs1;
}
goto yyoverflowlab;
# else
/* Extend the stack our own way. */
- if (yystacksize >= YYMAXDEPTH)
+ if (YYMAXDEPTH <= yystacksize)
goto yyoverflowlab;
yystacksize *= 2;
- if (yystacksize > YYMAXDEPTH)
+ if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
goto yyoverflowlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
-# if YYLSP_NEEDED
- YYSTACK_RELOCATE (yyls);
-# endif
-# undef YYSTACK_RELOCATE
+
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
-#if YYLSP_NEEDED
- yylsp = yyls + yysize - 1;
-#endif
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
- if (yyssp >= yyss + yystacksize - 1)
+ if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
goto yybackup;
-
/*-----------.
| yybackup. |
`-----------*/
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
- if (yyn == YYFLAG)
+ if (yyn == YYPACT_NINF)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
- /* yychar is either YYEMPTY or YYEOF
- or a valid token in external form. */
-
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX;
}
- /* Convert token to internal form (in yychar1) for indexing tables with */
-
- if (yychar <= 0) /* This means end of input. */
+ if (yychar <= YYEOF)
{
- yychar1 = 0;
- yychar = YYEOF; /* Don't call YYLEX any more */
-
+ yychar = yytoken = YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
- yychar1 = YYTRANSLATE (yychar);
-
-#if YYDEBUG
- /* We have to keep this `#if YYDEBUG', since we use variables
- which are defined only if `YYDEBUG' is set. */
- if (yydebug)
- {
- YYFPRINTF (stderr, "Next token is %d (%s",
- yychar, yytname[yychar1]);
- /* Give the individual parser a way to print the precise
- meaning of a token, for further debugging info. */
-# ifdef YYPRINT
- YYPRINT (stderr, yychar, yylval);
-# endif
- YYFPRINTF (stderr, ")\n");
- }
-#endif
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
}
- yyn += yychar1;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault;
-
yyn = yytable[yyn];
-
- /* yyn is what to do for this token type in this state.
- Negative => reduce, -yyn is rule number.
- Positive => shift, yyn is new state.
- New state is final state => don't bother to shift,
- just return success.
- 0, or most negative number => error. */
-
- if (yyn < 0)
+ if (yyn <= 0)
{
- if (yyn == YYFLAG)
+ if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
- else if (yyn == 0)
- goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %d (%s), ",
- yychar, yytname[yychar1]));
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
-#if YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
+
/* Count tokens shifted since error; after three, turn off error
status. */
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
- Otherwise, the following line sets YYVAL to the semantic value of
- the lookahead token. This behavior is undocumented and Bison
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
users should not rely upon it. Assigning to YYVAL
unconditionally makes the parser a bit smaller, and it avoids a
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
-#if YYLSP_NEEDED
- /* Similarly for the default location. Let the user run additional
- commands if for instance locations are ranges. */
- yyloc = yylsp[1-yylen];
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-#endif
-
-#if YYDEBUG
- /* We have to keep this `#if YYDEBUG', since we use variables which
- are defined only if `YYDEBUG' is set. */
- if (yydebug)
- {
- int yyi;
-
- YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
- yyn, yyrline[yyn]);
-
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
- YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
- YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
- }
-#endif
-
- switch (yyn) {
-case 1:
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
#line 137 "./cond.y"
-{
+ {
COND_input* cond = (COND_input*) info;
cond->result = yyvsp[0].value;
- ;
- break;}
-case 2:
+ ;}
+ break;
+
+ case 3:
#line 145 "./cond.y"
-{
+ {
yyval.value = yyvsp[0].value;
- ;
- break;}
-case 3:
+ ;}
+ break;
+
+ case 4:
#line 149 "./cond.y"
-{
+ {
yyval.value = yyvsp[-2].value || yyvsp[0].value;
- ;
- break;}
-case 4:
+ ;}
+ break;
+
+ case 5:
#line 156 "./cond.y"
-{
+ {
yyval.value = yyvsp[0].value;
- ;
- break;}
-case 5:
+ ;}
+ break;
+
+ case 6:
#line 160 "./cond.y"
-{
+ {
yyval.value = yyvsp[-2].value && yyvsp[0].value;
- ;
- break;}
-case 6:
+ ;}
+ break;
+
+ case 7:
#line 167 "./cond.y"
-{
+ {
yyval.value = yyvsp[0].value;
- ;
- break;}
-case 7:
+ ;}
+ break;
+
+ case 8:
#line 171 "./cond.y"
-{
+ {
yyval.value = ! yyvsp[0].value;
- ;
- break;}
-case 8:
+ ;}
+ break;
+
+ case 9:
#line 179 "./cond.y"
-{
+ {
yyval.value = yyvsp[0].value;
- ;
- break;}
-case 9:
+ ;}
+ break;
+
+ case 10:
#line 183 "./cond.y"
-{
+ {
yyval.value = (yyvsp[0].string && yyvsp[0].string[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE;
- ;
- break;}
-case 10:
-#line 187 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 11:
+#line 188 "./cond.y"
+ {
yyval.value = yyvsp[-1].fn_comp_int( yyvsp[-2].value, yyvsp[0].value );
- ;
- break;}
-case 11:
-#line 191 "./cond.y"
-{
+ ;}
+ break;
+
+ case 12:
+#line 192 "./cond.y"
+ {
yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-2].string, yyvsp[0].string, FALSE );
- ;
- break;}
-case 12:
-#line 195 "./cond.y"
-{
+ msi_free( yyvsp[-2].string );
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 13:
+#line 198 "./cond.y"
+ {
yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-3].string, yyvsp[0].string, TRUE );
- ;
- break;}
-case 13:
-#line 199 "./cond.y"
-{
+ msi_free( yyvsp[-3].string );
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 14:
+#line 204 "./cond.y"
+ {
yyval.value = yyvsp[-1].fn_comp_m1( yyvsp[-2].string, yyvsp[0].value );
- ;
- break;}
-case 14:
-#line 203 "./cond.y"
-{
+ msi_free( yyvsp[-2].string );
+ ;}
+ break;
+
+ case 15:
+#line 209 "./cond.y"
+ {
yyval.value = yyvsp[-1].fn_comp_m2( yyvsp[-2].value, yyvsp[0].string );
- ;
- break;}
-case 15:
-#line 207 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 16:
+#line 214 "./cond.y"
+ {
yyval.value = yyvsp[-1].value;
- ;
- break;}
-case 16:
-#line 215 "./cond.y"
-{
+ ;}
+ break;
+
+ case 17:
+#line 222 "./cond.y"
+ {
yyval.fn_comp_int = comp_eq_i;
- ;
- break;}
-case 17:
-#line 219 "./cond.y"
-{
+ ;}
+ break;
+
+ case 18:
+#line 226 "./cond.y"
+ {
yyval.fn_comp_int = comp_ne_i;
- ;
- break;}
-case 18:
-#line 223 "./cond.y"
-{
+ ;}
+ break;
+
+ case 19:
+#line 230 "./cond.y"
+ {
yyval.fn_comp_int = comp_lt_i;
- ;
- break;}
-case 19:
-#line 227 "./cond.y"
-{
+ ;}
+ break;
+
+ case 20:
+#line 234 "./cond.y"
+ {
yyval.fn_comp_int = comp_gt_i;
- ;
- break;}
-case 20:
-#line 231 "./cond.y"
-{
+ ;}
+ break;
+
+ case 21:
+#line 238 "./cond.y"
+ {
yyval.fn_comp_int = comp_le_i;
- ;
- break;}
-case 21:
-#line 235 "./cond.y"
-{
+ ;}
+ break;
+
+ case 22:
+#line 242 "./cond.y"
+ {
yyval.fn_comp_int = comp_ge_i;
- ;
- break;}
-case 22:
-#line 240 "./cond.y"
-{
+ ;}
+ break;
+
+ case 23:
+#line 247 "./cond.y"
+ {
yyval.fn_comp_int = comp_bitand;
- ;
- break;}
-case 23:
-#line 244 "./cond.y"
-{
+ ;}
+ break;
+
+ case 24:
+#line 251 "./cond.y"
+ {
yyval.fn_comp_int = comp_highcomp;
- ;
- break;}
-case 24:
-#line 248 "./cond.y"
-{
+ ;}
+ break;
+
+ case 25:
+#line 255 "./cond.y"
+ {
yyval.fn_comp_int = comp_lowcomp;
- ;
- break;}
-case 25:
-#line 256 "./cond.y"
-{
+ ;}
+ break;
+
+ case 26:
+#line 263 "./cond.y"
+ {
yyval.fn_comp_str = comp_eq_s;
- ;
- break;}
-case 26:
-#line 260 "./cond.y"
-{
+ ;}
+ break;
+
+ case 27:
+#line 267 "./cond.y"
+ {
yyval.fn_comp_str = comp_ne_s;
- ;
- break;}
-case 27:
-#line 264 "./cond.y"
-{
+ ;}
+ break;
+
+ case 28:
+#line 271 "./cond.y"
+ {
yyval.fn_comp_str = comp_lt_s;
- ;
- break;}
-case 28:
-#line 268 "./cond.y"
-{
+ ;}
+ break;
+
+ case 29:
+#line 275 "./cond.y"
+ {
yyval.fn_comp_str = comp_gt_s;
- ;
- break;}
-case 29:
-#line 272 "./cond.y"
-{
+ ;}
+ break;
+
+ case 30:
+#line 279 "./cond.y"
+ {
yyval.fn_comp_str = comp_le_s;
- ;
- break;}
-case 30:
-#line 276 "./cond.y"
-{
+ ;}
+ break;
+
+ case 31:
+#line 283 "./cond.y"
+ {
yyval.fn_comp_str = comp_ge_s;
- ;
- break;}
-case 31:
-#line 281 "./cond.y"
-{
+ ;}
+ break;
+
+ case 32:
+#line 288 "./cond.y"
+ {
yyval.fn_comp_str = comp_substring;
- ;
- break;}
-case 32:
-#line 285 "./cond.y"
-{
+ ;}
+ break;
+
+ case 33:
+#line 292 "./cond.y"
+ {
yyval.fn_comp_str = comp_start;
- ;
- break;}
-case 33:
-#line 289 "./cond.y"
-{
+ ;}
+ break;
+
+ case 34:
+#line 296 "./cond.y"
+ {
yyval.fn_comp_str = comp_end;
- ;
- break;}
-case 34:
-#line 297 "./cond.y"
-{
+ ;}
+ break;
+
+ case 35:
+#line 304 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_eq_m1;
- ;
- break;}
-case 35:
-#line 301 "./cond.y"
-{
+ ;}
+ break;
+
+ case 36:
+#line 308 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_ne_m1;
- ;
- break;}
-case 36:
-#line 305 "./cond.y"
-{
+ ;}
+ break;
+
+ case 37:
+#line 312 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_lt_m1;
- ;
- break;}
-case 37:
-#line 309 "./cond.y"
-{
+ ;}
+ break;
+
+ case 38:
+#line 316 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_gt_m1;
- ;
- break;}
-case 38:
-#line 313 "./cond.y"
-{
+ ;}
+ break;
+
+ case 39:
+#line 320 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_le_m1;
- ;
- break;}
-case 39:
-#line 317 "./cond.y"
-{
+ ;}
+ break;
+
+ case 40:
+#line 324 "./cond.y"
+ {
yyval.fn_comp_m1 = comp_ge_m1;
- ;
- break;}
-case 40:
-#line 322 "./cond.y"
-{
+ ;}
+ break;
+
+ case 41:
+#line 329 "./cond.y"
+ {
yyval.fn_comp_m1 = 0;
- ;
- break;}
-case 41:
-#line 326 "./cond.y"
-{
+ ;}
+ break;
+
+ case 42:
+#line 333 "./cond.y"
+ {
yyval.fn_comp_m1 = 0;
- ;
- break;}
-case 42:
-#line 330 "./cond.y"
-{
+ ;}
+ break;
+
+ case 43:
+#line 337 "./cond.y"
+ {
yyval.fn_comp_m1 = 0;
- ;
- break;}
-case 43:
-#line 338 "./cond.y"
-{
+ ;}
+ break;
+
+ case 44:
+#line 345 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_eq_m2;
- ;
- break;}
-case 44:
-#line 342 "./cond.y"
-{
+ ;}
+ break;
+
+ case 45:
+#line 349 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_ne_m2;
- ;
- break;}
-case 45:
-#line 346 "./cond.y"
-{
+ ;}
+ break;
+
+ case 46:
+#line 353 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_lt_m2;
- ;
- break;}
-case 46:
-#line 350 "./cond.y"
-{
+ ;}
+ break;
+
+ case 47:
+#line 357 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_gt_m2;
- ;
- break;}
-case 47:
-#line 354 "./cond.y"
-{
+ ;}
+ break;
+
+ case 48:
+#line 361 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_le_m2;
- ;
- break;}
-case 48:
-#line 358 "./cond.y"
-{
+ ;}
+ break;
+
+ case 49:
+#line 365 "./cond.y"
+ {
yyval.fn_comp_m2 = comp_ge_m2;
- ;
- break;}
-case 49:
-#line 363 "./cond.y"
-{
- yyval.fn_comp_m2 = 0;
- ;
- break;}
-case 50:
-#line 367 "./cond.y"
-{
+ ;}
+ break;
+
+ case 50:
+#line 370 "./cond.y"
+ {
yyval.fn_comp_m2 = 0;
- ;
- break;}
-case 51:
-#line 371 "./cond.y"
-{
+ ;}
+ break;
+
+ case 51:
+#line 374 "./cond.y"
+ {
yyval.fn_comp_m2 = 0;
- ;
- break;}
-case 52:
+ ;}
+ break;
+
+ case 52:
#line 378 "./cond.y"
-{
- yyval.value = yyvsp[0].value;
- ;
- break;}
-case 53:
-#line 382 "./cond.y"
-{
+ {
+ yyval.fn_comp_m2 = 0;
+ ;}
+ break;
+
+ case 53:
+#line 385 "./cond.y"
+ {
yyval.value = yyvsp[0].value;
- ;
- break;}
-case 54:
+ ;}
+ break;
+
+ case 54:
#line 389 "./cond.y"
-{
- yyval.string = yyvsp[0].string;
- ;
- break;}
-case 55:
-#line 393 "./cond.y"
-{
+ {
+ yyval.value = yyvsp[0].value;
+ ;}
+ break;
+
+ case 55:
+#line 396 "./cond.y"
+ {
yyval.string = yyvsp[0].string;
- ;
- break;}
-case 56:
+ ;}
+ break;
+
+ case 56:
#line 400 "./cond.y"
-{
+ {
+ yyval.string = yyvsp[0].string;
+ ;}
+ break;
+
+ case 57:
+#line 407 "./cond.y"
+ {
yyval.string = COND_GetLiteral(&yyvsp[0].str);
if( !yyval.string )
YYABORT;
- ;
- break;}
-case 57:
-#line 409 "./cond.y"
-{
+ ;}
+ break;
+
+ case 58:
+#line 416 "./cond.y"
+ {
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action );
yyval.value = action;
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 58:
-#line 418 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 59:
+#line 425 "./cond.y"
+ {
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action );
yyval.value = install;
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 59:
-#line 427 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 60:
+#line 434 "./cond.y"
+ {
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action );
yyval.value = action;
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 60:
-#line 436 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 61:
+#line 443 "./cond.y"
+ {
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action );
yyval.value = install;
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 61:
-#line 448 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 62:
+#line 455 "./cond.y"
+ {
DWORD sz;
COND_input* cond = (COND_input*) info;
MSI_GetPropertyW(cond->package, yyvsp[0].string, NULL, &sz);
if (sz == 0)
{
- yyval.string = HeapAlloc( GetProcessHeap(), 0 ,sizeof(WCHAR));
+ yyval.string = msi_alloc( sizeof(WCHAR));
yyval.string[0] = 0;
}
else
{
sz ++;
- yyval.string = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR) );
+ yyval.string = msi_alloc( sz*sizeof (WCHAR) );
/* Lookup the identifier */
MSI_GetPropertyW(cond->package,yyvsp[0].string,yyval.string,&sz);
}
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 62:
-#line 471 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 63:
+#line 478 "./cond.y"
+ {
UINT len = GetEnvironmentVariableW( yyvsp[0].string, NULL, 0 );
if( len++ )
{
- yyval.string = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+ yyval.string = msi_alloc( len*sizeof (WCHAR) );
if( yyval.string )
GetEnvironmentVariableW( yyvsp[0].string, yyval.string, len );
}
- HeapFree( GetProcessHeap(), 0, yyvsp[0].string );
- ;
- break;}
-case 63:
-#line 485 "./cond.y"
-{
+ msi_free( yyvsp[0].string );
+ ;}
+ break;
+
+ case 64:
+#line 492 "./cond.y"
+ {
yyval.string = COND_GetString(&yyvsp[0].str);
if( !yyval.string )
YYABORT;
- ;
- break;}
-case 64:
-#line 494 "./cond.y"
-{
+ ;}
+ break;
+
+ case 65:
+#line 501 "./cond.y"
+ {
LPWSTR szNum = COND_GetString(&yyvsp[0].str);
if( !szNum )
YYABORT;
yyval.value = atoiW( szNum );
- HeapFree( GetProcessHeap(), 0, szNum );
- ;
- break;}
-}
+ msi_free( szNum );
+ ;}
+ break;
+
-#line 705 "/usr/share/bison/bison.simple"
+ }
+/* Line 1000 of yacc.c. */
+#line 1733 "cond.tab.c"
\f
yyvsp -= yylen;
yyssp -= yylen;
-#if YYLSP_NEEDED
- yylsp -= yylen;
-#endif
-#if YYDEBUG
- if (yydebug)
- {
- short *yyssp1 = yyss - 1;
- YYFPRINTF (stderr, "state stack now");
- while (yyssp1 != yyssp)
- YYFPRINTF (stderr, " %d", *++yyssp1);
- YYFPRINTF (stderr, "\n");
- }
-#endif
+
+ YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
-#if YYLSP_NEEDED
- *++yylsp = yyloc;
-#endif
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
yyn = yyr1[yyn];
- yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
- if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
- yystate = yydefgoto[yyn - YYNTBASE];
+ yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
if (!yyerrstatus)
{
++yynerrs;
-
-#ifdef YYERROR_VERBOSE
+#if YYERROR_VERBOSE
yyn = yypact[yystate];
- if (yyn > YYFLAG && yyn < YYLAST)
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
{
YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
char *yymsg;
- int yyx, yycount;
+ int yyx;
- yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
- if (yycheck[yyx + yyn] == yyx)
- yysize += yystrlen (yytname[yyx]) + 15, yycount++;
- yysize += yystrlen ("parse error, unexpected ") + 1;
- yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
- char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
- yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
if (yycount < 5)
{
- yycount = 0;
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *));
- yyx++)
- if (yycheck[yyx + yyn] == yyx)
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
- const char *yyq = ! yycount ? ", expecting " : " or ";
- yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yyprefix);
yyp = yystpcpy (yyp, yytname[yyx]);
- yycount++;
+ yyprefix = " or ";
}
}
yyerror (yymsg);
YYSTACK_FREE (yymsg);
}
else
- yyerror ("parse error; also virtual memory exhausted");
+ yyerror ("syntax error; also virtual memory exhausted");
}
else
-#endif /* defined (YYERROR_VERBOSE) */
- yyerror ("parse error");
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
}
- goto yyerrlab1;
-/*--------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action |
-`--------------------------------------------------*/
-yyerrlab1:
+
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
- /* return failure if at end of input */
- if (yychar == YYEOF)
- YYABORT;
- YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
- yychar, yytname[yychar1]));
- yychar = YYEMPTY;
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
}
/* Else will try to reuse lookahead token after shifting the error
token. */
-
- yyerrstatus = 3; /* Each real token shifted decrements this */
-
- goto yyerrhandle;
+ goto yyerrlab1;
-/*-------------------------------------------------------------------.
-| yyerrdefault -- current state does not do anything special for the |
-| error token. |
-`-------------------------------------------------------------------*/
-yyerrdefault:
-#if 0
- /* This is wrong; only states that explicitly want error tokens
- should shift them. */
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
- /* If its default is to accept any token, ok. Otherwise pop it. */
- yyn = yydefact[yystate];
- if (yyn)
- goto yydefault;
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
#endif
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
-/*---------------------------------------------------------------.
-| yyerrpop -- pop the current state because it cannot handle the |
-| error token |
-`---------------------------------------------------------------*/
-yyerrpop:
- if (yyssp == yyss)
- YYABORT;
- yyvsp--;
- yystate = *--yyssp;
-#if YYLSP_NEEDED
- yylsp--;
-#endif
-#if YYDEBUG
- if (yydebug)
- {
- short *yyssp1 = yyss - 1;
- YYFPRINTF (stderr, "Error: state stack now");
- while (yyssp1 != yyssp)
- YYFPRINTF (stderr, " %d", *++yyssp1);
- YYFPRINTF (stderr, "\n");
- }
-#endif
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
-/*--------------.
-| yyerrhandle. |
-`--------------*/
-yyerrhandle:
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yyerrdefault;
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
- yyn += YYTERROR;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
- goto yyerrdefault;
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
- yyn = yytable[yyn];
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrpop;
- yyn = -yyn;
- goto yyreduce;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
}
- else if (yyn == 0)
- goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
YYDPRINTF ((stderr, "Shifting error token, "));
*++yyvsp = yylval;
-#if YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
+
yystate = yyn;
goto yynewstate;
yyresult = 1;
goto yyreturn;
-/*---------------------------------------------.
-| yyoverflowab -- parser overflow comes here. |
-`---------------------------------------------*/
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
yyoverflowlab:
yyerror ("parser stack overflow");
yyresult = 2;
/* Fall through. */
+#endif
yyreturn:
#ifndef yyoverflow
#endif
return yyresult;
}
-#line 503 "./cond.y"
+
+
+#line 510 "./cond.y"
{
LPWSTR ret;
- ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );
+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) );
if( ret )
{
memcpy( ret, str->data, str->len * sizeof(WCHAR));
{
LPWSTR ret;
- ret = HeapAlloc( GetProcessHeap(), 0, (str->len-1) * sizeof (WCHAR) );
+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) );
if( ret )
{
memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
if( szCondition )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
- szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ szwCond = msi_alloc( len * sizeof (WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
}
r = MsiEvaluateConditionW( hInstall, szwCond );
- HeapFree( GetProcessHeap(), 0, szwCond );
+ msi_free( szwCond );
return r;
}
+
-#ifndef BISON_COND_TAB_H
-# define BISON_COND_TAB_H
+/* A Bison parser, made by GNU Bison 1.875c. */
-#ifndef YYSTYPE
-typedef union
-{
+/* Skeleton parser for Yacc-like parsing with Bison,
+ 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 {
+ COND_SPACE = 258,
+ COND_EOF = 259,
+ COND_OR = 260,
+ COND_AND = 261,
+ COND_NOT = 262,
+ COND_LT = 263,
+ COND_GT = 264,
+ COND_EQ = 265,
+ COND_LPAR = 266,
+ COND_RPAR = 267,
+ COND_TILDA = 268,
+ COND_PERCENT = 269,
+ COND_DOLLARS = 270,
+ COND_QUESTION = 271,
+ COND_AMPER = 272,
+ COND_EXCLAM = 273,
+ COND_IDENT = 274,
+ COND_NUMBER = 275,
+ COND_LITER = 276,
+ COND_ERROR = 277
+ };
+#endif
+#define COND_SPACE 258
+#define COND_EOF 259
+#define COND_OR 260
+#define COND_AND 261
+#define COND_NOT 262
+#define COND_LT 263
+#define COND_GT 264
+#define COND_EQ 265
+#define COND_LPAR 266
+#define COND_RPAR 267
+#define COND_TILDA 268
+#define COND_PERCENT 269
+#define COND_DOLLARS 270
+#define COND_QUESTION 271
+#define COND_AMPER 272
+#define COND_EXCLAM 273
+#define COND_IDENT 274
+#define COND_NUMBER 275
+#define COND_LITER 276
+#define COND_ERROR 277
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 106 "./cond.y"
+typedef union YYSTYPE {
struct cond_str str;
LPWSTR string;
INT value;
comp_str fn_comp_str;
comp_m1 fn_comp_m1;
comp_m2 fn_comp_m2;
-} yystype;
-# define YYSTYPE yystype
+} YYSTYPE;
+/* Line 1275 of yacc.c. */
+#line 91 "cond.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
-# define COND_SPACE 257
-# define COND_EOF 258
-# define COND_OR 259
-# define COND_AND 260
-# define COND_NOT 261
-# define COND_LT 262
-# define COND_GT 263
-# define COND_EQ 264
-# define COND_LPAR 265
-# define COND_RPAR 266
-# define COND_TILDA 267
-# define COND_PERCENT 268
-# define COND_DOLLARS 269
-# define COND_QUESTION 270
-# define COND_AMPER 271
-# define COND_EXCLAM 272
-# define COND_IDENT 273
-# define COND_NUMBER 274
-# define COND_LITER 275
-# define COND_ERROR 276
-
-
-#endif /* not BISON_COND_TAB_H */
+
+
+
+
+
-%{\r
-\r
-/*\r
- * Implementation of the Microsoft Installer (msi.dll)\r
- *\r
- * Copyright 2003 Mike McCormack for CodeWeavers\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-#include "config.h"\r
-\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wine/debug.h"\r
-#include "wine/unicode.h"\r
-\r
-#include "msi.h"\r
-#include "msiquery.h"\r
-#include "msipriv.h"\r
-\r
-#define YYLEX_PARAM info\r
-#define YYPARSE_PARAM info\r
-\r
-static int COND_error(const char *str);\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(msi);\r
-\r
-typedef struct tag_yyinput\r
-{\r
- MSIPACKAGE *package;\r
- LPCWSTR str;\r
- INT n;\r
- MSICONDITION result;\r
-} COND_input;\r
-\r
-struct cond_str {\r
- LPCWSTR data;\r
- INT len;\r
-};\r
-\r
-static LPWSTR COND_GetString( struct cond_str *str );\r
-static LPWSTR COND_GetLiteral( struct cond_str *str );\r
-static int COND_lex( void *COND_lval, COND_input *info);\r
-\r
-typedef INT (*comp_int)(INT a, INT b);\r
-typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);\r
-typedef INT (*comp_m1)(LPWSTR a,int b);\r
-typedef INT (*comp_m2)(int a,LPWSTR b);\r
-\r
-static INT comp_lt_i(INT a, INT b);\r
-static INT comp_gt_i(INT a, INT b);\r
-static INT comp_le_i(INT a, INT b);\r
-static INT comp_ge_i(INT a, INT b);\r
-static INT comp_eq_i(INT a, INT b);\r
-static INT comp_ne_i(INT a, INT b);\r
-static INT comp_bitand(INT a, INT b);\r
-static INT comp_highcomp(INT a, INT b);\r
-static INT comp_lowcomp(INT a, INT b);\r
-\r
-static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);\r
-static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);\r
-\r
-static INT comp_eq_m1(LPWSTR a, INT b);\r
-static INT comp_ne_m1(LPWSTR a, INT b);\r
-static INT comp_lt_m1(LPWSTR a, INT b);\r
-static INT comp_gt_m1(LPWSTR a, INT b);\r
-static INT comp_le_m1(LPWSTR a, INT b);\r
-static INT comp_ge_m1(LPWSTR a, INT b);\r
-\r
-static INT comp_eq_m2(INT a, LPWSTR b);\r
-static INT comp_ne_m2(INT a, LPWSTR b);\r
-static INT comp_lt_m2(INT a, LPWSTR b);\r
-static INT comp_gt_m2(INT a, LPWSTR b);\r
-static INT comp_le_m2(INT a, LPWSTR b);\r
-static INT comp_ge_m2(INT a, LPWSTR b);\r
-\r
-%}\r
-\r
-%pure-parser\r
-\r
-%union\r
-{\r
- struct cond_str str;\r
- LPWSTR string;\r
- INT value;\r
- comp_int fn_comp_int;\r
- comp_str fn_comp_str;\r
- comp_m1 fn_comp_m1;\r
- comp_m2 fn_comp_m2;\r
-}\r
-\r
-%token COND_SPACE COND_EOF COND_SPACE\r
-%token COND_OR COND_AND COND_NOT\r
-%token COND_LT COND_GT COND_EQ \r
-%token COND_LPAR COND_RPAR COND_TILDA\r
-%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM\r
-%token <str> COND_IDENT <str> COND_NUMBER <str> COND_LITER\r
-\r
-%nonassoc COND_EOF COND_ERROR\r
-\r
-%type <value> expression boolean_term boolean_factor \r
-%type <value> term value_i symbol_i integer\r
-%type <string> identifier value_s symbol_s literal\r
-%type <fn_comp_int> comp_op_i\r
-%type <fn_comp_str> comp_op_s \r
-%type <fn_comp_m1> comp_op_m1 \r
-%type <fn_comp_m2> comp_op_m2\r
-\r
-%%\r
-\r
-condition:\r
- expression\r
- {\r
- COND_input* cond = (COND_input*) info;\r
- cond->result = $1;\r
- }\r
- ;\r
-\r
-expression:\r
- boolean_term \r
- {\r
- $$ = $1;\r
- }\r
- | boolean_term COND_OR expression\r
- {\r
- $$ = $1 || $3;\r
- }\r
- ;\r
-\r
-boolean_term:\r
- boolean_factor\r
- {\r
- $$ = $1;\r
- }\r
- | boolean_term COND_AND boolean_factor\r
- {\r
- $$ = $1 && $3;\r
- }\r
- ;\r
-\r
-boolean_factor:\r
- term\r
- {\r
- $$ = $1;\r
- }\r
- | COND_NOT term\r
- {\r
- $$ = ! $2;\r
- }\r
- ;\r
-\r
-\r
-term:\r
- value_i\r
- {\r
- $$ = $1;\r
- }\r
- | value_s\r
- {\r
- $$ = ($1 && $1[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE;\r
- }\r
- | value_i comp_op_i value_i\r
- {\r
- $$ = $2( $1, $3 );\r
- }\r
- | value_s comp_op_s value_s\r
- {\r
- $$ = $2( $1, $3, FALSE );\r
- }\r
- | value_s COND_TILDA comp_op_s value_s\r
- {\r
- $$ = $3( $1, $4, TRUE );\r
- }\r
- | value_s comp_op_m1 value_i\r
- {\r
- $$ = $2( $1, $3 );\r
- }\r
- | value_i comp_op_m2 value_s\r
- {\r
- $$ = $2( $1, $3 );\r
- }\r
- | COND_LPAR expression COND_RPAR\r
- {\r
- $$ = $2;\r
- }\r
- ;\r
-\r
-comp_op_i:\r
- /* common functions */\r
- COND_EQ\r
- {\r
- $$ = comp_eq_i;\r
- }\r
- | COND_LT COND_GT\r
- {\r
- $$ = comp_ne_i;\r
- }\r
- | COND_LT\r
- {\r
- $$ = comp_lt_i;\r
- }\r
- | COND_GT\r
- {\r
- $$ = comp_gt_i;\r
- }\r
- | COND_LT COND_EQ\r
- {\r
- $$ = comp_le_i;\r
- }\r
- | COND_GT COND_EQ\r
- {\r
- $$ = comp_ge_i;\r
- }\r
- /*Int only*/\r
- | COND_GT COND_LT\r
- {\r
- $$ = comp_bitand;\r
- }\r
- | COND_LT COND_LT\r
- {\r
- $$ = comp_highcomp;\r
- }\r
- | COND_GT COND_GT\r
- {\r
- $$ = comp_lowcomp;\r
- }\r
- ;\r
-\r
-comp_op_s:\r
- /* common functions */\r
- COND_EQ\r
- {\r
- $$ = comp_eq_s;\r
- }\r
- | COND_LT COND_GT\r
- {\r
- $$ = comp_ne_s;\r
- }\r
- | COND_LT\r
- {\r
- $$ = comp_lt_s;\r
- }\r
- | COND_GT\r
- {\r
- $$ = comp_gt_s;\r
- }\r
- | COND_LT COND_EQ\r
- {\r
- $$ = comp_le_s;\r
- }\r
- | COND_GT COND_EQ\r
- {\r
- $$ = comp_ge_s;\r
- }\r
- /*string only*/\r
- | COND_GT COND_LT\r
- {\r
- $$ = comp_substring;\r
- }\r
- | COND_LT COND_LT\r
- {\r
- $$ = comp_start;\r
- }\r
- | COND_GT COND_GT\r
- {\r
- $$ = comp_end;\r
- }\r
- ;\r
-\r
-comp_op_m1:\r
- /* common functions */\r
- COND_EQ\r
- {\r
- $$ = comp_eq_m1;\r
- }\r
- | COND_LT COND_GT\r
- {\r
- $$ = comp_ne_m1;\r
- }\r
- | COND_LT\r
- {\r
- $$ = comp_lt_m1;\r
- }\r
- | COND_GT\r
- {\r
- $$ = comp_gt_m1;\r
- }\r
- | COND_LT COND_EQ\r
- {\r
- $$ = comp_le_m1;\r
- }\r
- | COND_GT COND_EQ\r
- {\r
- $$ = comp_ge_m1;\r
- }\r
- /*Not valid for mixed compares*/\r
- | COND_GT COND_LT\r
- {\r
- $$ = 0;\r
- }\r
- | COND_LT COND_LT\r
- {\r
- $$ = 0;\r
- }\r
- | COND_GT COND_GT\r
- {\r
- $$ = 0;\r
- }\r
- ;\r
-\r
-comp_op_m2:\r
- /* common functions */\r
- COND_EQ\r
- {\r
- $$ = comp_eq_m2;\r
- }\r
- | COND_LT COND_GT\r
- {\r
- $$ = comp_ne_m2;\r
- }\r
- | COND_LT\r
- {\r
- $$ = comp_lt_m2;\r
- }\r
- | COND_GT\r
- {\r
- $$ = comp_gt_m2;\r
- }\r
- | COND_LT COND_EQ\r
- {\r
- $$ = comp_le_m2;\r
- }\r
- | COND_GT COND_EQ\r
- {\r
- $$ = comp_ge_m2;\r
- }\r
- /*Not valid for mixed compares*/\r
- | COND_GT COND_LT\r
- {\r
- $$ = 0;\r
- }\r
- | COND_LT COND_LT\r
- {\r
- $$ = 0;\r
- }\r
- | COND_GT COND_GT\r
- {\r
- $$ = 0;\r
- }\r
- ;\r
-\r
-value_i:\r
- symbol_i\r
- {\r
- $$ = $1;\r
- }\r
- | integer\r
- {\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-value_s:\r
- symbol_s\r
- {\r
- $$ = $1;\r
- } \r
- | literal\r
- {\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-literal:\r
- COND_LITER\r
- {\r
- $$ = COND_GetLiteral(&$1);\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-symbol_i:\r
- COND_DOLLARS identifier\r
- {\r
- COND_input* cond = (COND_input*) info;\r
- INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;\r
- \r
- MSI_GetComponentStateW(cond->package, $2, &install, &action );\r
- $$ = action;\r
- HeapFree( GetProcessHeap(), 0, $2 );\r
- }\r
- | COND_QUESTION identifier\r
- {\r
- COND_input* cond = (COND_input*) info;\r
- INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;\r
- \r
- MSI_GetComponentStateW(cond->package, $2, &install, &action );\r
- $$ = install;\r
- HeapFree( GetProcessHeap(), 0, $2 );\r
- }\r
- | COND_AMPER identifier\r
- {\r
- COND_input* cond = (COND_input*) info;\r
- INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;\r
- \r
- MSI_GetFeatureStateW(cond->package, $2, &install, &action );\r
- $$ = action;\r
- HeapFree( GetProcessHeap(), 0, $2 );\r
- }\r
- | COND_EXCLAM identifier\r
- {\r
- COND_input* cond = (COND_input*) info;\r
- INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;\r
- \r
- MSI_GetFeatureStateW(cond->package, $2, &install, &action );\r
- $$ = install;\r
- HeapFree( GetProcessHeap(), 0, $2 );\r
- }\r
- ;\r
-\r
-symbol_s:\r
- identifier\r
- {\r
- DWORD sz;\r
- COND_input* cond = (COND_input*) info;\r
-\r
- sz = 0;\r
- MSI_GetPropertyW(cond->package, $1, NULL, &sz);\r
- if (sz == 0)\r
- {\r
- $$ = HeapAlloc( GetProcessHeap(), 0 ,sizeof(WCHAR));\r
- $$[0] = 0;\r
- }\r
- else\r
- {\r
- sz ++;\r
- $$ = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR) );\r
-\r
- /* Lookup the identifier */\r
-\r
- MSI_GetPropertyW(cond->package,$1,$$,&sz);\r
- }\r
- HeapFree( GetProcessHeap(), 0, $1 );\r
- }\r
- | COND_PERCENT identifier\r
- {\r
- UINT len = GetEnvironmentVariableW( $2, NULL, 0 );\r
- if( len++ )\r
- {\r
- $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );\r
- if( $$ )\r
- GetEnvironmentVariableW( $2, $$, len );\r
- }\r
- HeapFree( GetProcessHeap(), 0, $2 );\r
- }\r
- ;\r
-\r
-identifier:\r
- COND_IDENT\r
- {\r
- $$ = COND_GetString(&$1);\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-integer:\r
- COND_NUMBER\r
- {\r
- LPWSTR szNum = COND_GetString(&$1);\r
- if( !szNum )\r
- YYABORT;\r
- $$ = atoiW( szNum );\r
- HeapFree( GetProcessHeap(), 0, szNum );\r
- }\r
- ;\r
-\r
-%%\r
-\r
-\r
-static int COND_IsAlpha( WCHAR x )\r
-{\r
- return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||\r
- ( ( x >= 'a' ) && ( x <= 'z' ) ) ||\r
- ( ( x == '_' ) ) );\r
-}\r
-\r
-static int COND_IsNumber( WCHAR x )\r
-{\r
- return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') );\r
-}\r
-\r
-\r
-/* the mess of comparison functions */\r
-\r
-static INT comp_lt_i(INT a, INT b)\r
-{ return (a < b); }\r
-static INT comp_gt_i(INT a, INT b)\r
-{ return (a > b); }\r
-static INT comp_le_i(INT a, INT b)\r
-{ return (a <= b); }\r
-static INT comp_ge_i(INT a, INT b)\r
-{ return (a >= b); }\r
-static INT comp_eq_i(INT a, INT b)\r
-{ return (a == b); }\r
-static INT comp_ne_i(INT a, INT b)\r
-{ return (a != b); }\r
-static INT comp_bitand(INT a, INT b)\r
-{ return a & b;}\r
-static INT comp_highcomp(INT a, INT b)\r
-{ return HIWORD(a)==b; }\r
-static INT comp_lowcomp(INT a, INT b)\r
-{ return LOWORD(a)==b; }\r
-\r
-static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);}\r
-static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);}\r
-static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;}\r
-static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;}\r
-static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;}\r
-static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;}\r
-static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless)\r
-/* ERROR NOT WORKING REWRITE */\r
-{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;}\r
-static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ if (casless) return strncmpiW(a,b,strlenW(b))==0; \r
- else return strncmpW(a,b,strlenW(b))==0;}\r
-static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless)\r
-{ \r
- int i = strlenW(a); \r
- int j = strlenW(b); \r
- if (j>i)\r
- return 0;\r
- if (casless) return (!strcmpiW(&a[i-j-1],b));\r
- else return (!strcmpW(&a[i-j-1],b));\r
-}\r
-\r
-\r
-static INT comp_eq_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}\r
-static INT comp_ne_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}\r
-static INT comp_lt_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}\r
-static INT comp_gt_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}\r
-static INT comp_le_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}\r
-static INT comp_ge_m1(LPWSTR a, INT b)\r
-{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}\r
-\r
-static INT comp_eq_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}\r
-static INT comp_ne_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}\r
-static INT comp_lt_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}\r
-static INT comp_gt_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}\r
-static INT comp_le_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}\r
-static INT comp_ge_m2(INT a, LPWSTR b)\r
-{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}\r
-\r
-\r
-\r
-static int COND_IsIdent( WCHAR x )\r
-{\r
- return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) \r
- || ( x == '#' ) || (x == '.') );\r
-}\r
-\r
-static int COND_GetOne( struct cond_str *str, COND_input *cond )\r
-{\r
- static const WCHAR szNot[] = {'N','O','T',0};\r
- static const WCHAR szAnd[] = {'A','N','D',0};\r
- static const WCHAR szOr[] = {'O','R',0};\r
- WCHAR ch;\r
- int rc, len = 1;\r
-\r
- str->data = &cond->str[cond->n];\r
-\r
- ch = str->data[0];\r
- switch( ch )\r
- {\r
- case 0: return 0;\r
- case '(': rc = COND_LPAR; break;\r
- case ')': rc = COND_RPAR; break;\r
- case '&': rc = COND_AMPER; break;\r
- case '!': rc = COND_EXCLAM; break;\r
- case '$': rc = COND_DOLLARS; break;\r
- case '?': rc = COND_QUESTION; break;\r
- case '%': rc = COND_PERCENT; break;\r
- case ' ': rc = COND_SPACE; break;\r
- case '=': rc = COND_EQ; break;\r
- case '~': rc = COND_TILDA; break;\r
- case '<': rc = COND_LT; break;\r
- case '>': rc = COND_GT; break;\r
- case '"':\r
- {\r
- const WCHAR *ch2 = str->data + 1;\r
-\r
-\r
- while ( *ch2 && *ch2 != '"' )\r
- ++ch2;\r
- if (*ch2 == '"')\r
- {\r
- len = ch2 - str->data + 1;\r
- rc = COND_LITER;\r
- break;\r
- }\r
- }\r
- ERR("Unterminated string\n");\r
- rc = COND_ERROR;\r
- break;\r
- default: \r
- if( COND_IsAlpha( ch ) )\r
- {\r
- while( COND_IsIdent( str->data[len] ) )\r
- len++;\r
- rc = COND_IDENT;\r
- break;\r
- }\r
-\r
- if( COND_IsNumber( ch ) )\r
- {\r
- while( COND_IsNumber( str->data[len] ) )\r
- len++;\r
- rc = COND_NUMBER;\r
- break;\r
- }\r
-\r
- ERR("Got unknown character %c(%x)\n",ch,ch);\r
- rc = COND_ERROR;\r
- break;\r
- }\r
-\r
- /* keyword identifiers */\r
- if( rc == COND_IDENT )\r
- {\r
- if( (len==3) && (strncmpiW(str->data,szNot,len)==0) )\r
- rc = COND_NOT;\r
- else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) )\r
- rc = COND_AND;\r
- else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) )\r
- rc = COND_OR;\r
- }\r
-\r
- cond->n += len;\r
- str->len = len;\r
-\r
- return rc;\r
-}\r
-\r
-static int COND_lex( void *COND_lval, COND_input *cond )\r
-{\r
- int rc;\r
- struct cond_str *str = COND_lval;\r
-\r
- do {\r
- rc = COND_GetOne( str, cond );\r
- } while (rc == COND_SPACE);\r
- \r
- return rc;\r
-}\r
-\r
-static LPWSTR COND_GetString( struct cond_str *str )\r
-{\r
- LPWSTR ret;\r
-\r
- ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );\r
- if( ret )\r
- {\r
- memcpy( ret, str->data, str->len * sizeof(WCHAR));\r
- ret[str->len]=0;\r
- }\r
- TRACE("Got identifier %s\n",debugstr_w(ret));\r
- return ret;\r
-}\r
-\r
-static LPWSTR COND_GetLiteral( struct cond_str *str )\r
-{\r
- LPWSTR ret;\r
-\r
- ret = HeapAlloc( GetProcessHeap(), 0, (str->len-1) * sizeof (WCHAR) );\r
- if( ret )\r
- {\r
- memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );\r
- ret[str->len - 2]=0;\r
- }\r
- TRACE("Got literal %s\n",debugstr_w(ret));\r
- return ret;\r
-}\r
-\r
-static int COND_error(const char *str)\r
-{\r
- return 0;\r
-}\r
-\r
-MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )\r
-{\r
- COND_input cond;\r
- MSICONDITION r;\r
-\r
- cond.package = package;\r
- cond.str = szCondition;\r
- cond.n = 0;\r
- cond.result = -1;\r
- \r
- TRACE("Evaluating %s\n",debugstr_w(szCondition)); \r
-\r
- if ( szCondition == NULL || szCondition[0] == 0)\r
- r = MSICONDITION_NONE;\r
- else if ( !COND_parse( &cond ) )\r
- r = cond.result;\r
- else\r
- r = MSICONDITION_ERROR;\r
-\r
- TRACE("Evaluates to %i\n",r);\r
- return r;\r
-}\r
-\r
-MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )\r
-{\r
- MSIPACKAGE *package;\r
- UINT ret;\r
-\r
- package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);\r
- if( !package)\r
- return ERROR_INVALID_HANDLE;\r
- ret = MSI_EvaluateConditionW( package, szCondition );\r
- msiobj_release( &package->hdr );\r
- return ret;\r
-}\r
-\r
-MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )\r
-{\r
- LPWSTR szwCond = NULL;\r
- MSICONDITION r;\r
-\r
- if( szCondition )\r
- {\r
- UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );\r
- szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );\r
- MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );\r
- }\r
-\r
- r = MsiEvaluateConditionW( hInstall, szwCond );\r
-\r
- HeapFree( GetProcessHeap(), 0, szwCond );\r
-\r
- return r;\r
-}\r
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2003 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+ MSIPACKAGE *package;
+ LPCWSTR str;
+ INT n;
+ MSICONDITION result;
+} COND_input;
+
+struct cond_str {
+ LPCWSTR data;
+ INT len;
+};
+
+static LPWSTR COND_GetString( struct cond_str *str );
+static LPWSTR COND_GetLiteral( struct cond_str *str );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
+typedef INT (*comp_m1)(LPWSTR a,int b);
+typedef INT (*comp_m2)(int a,LPWSTR b);
+
+static INT comp_lt_i(INT a, INT b);
+static INT comp_gt_i(INT a, INT b);
+static INT comp_le_i(INT a, INT b);
+static INT comp_ge_i(INT a, INT b);
+static INT comp_eq_i(INT a, INT b);
+static INT comp_ne_i(INT a, INT b);
+static INT comp_bitand(INT a, INT b);
+static INT comp_highcomp(INT a, INT b);
+static INT comp_lowcomp(INT a, INT b);
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
+
+static INT comp_eq_m1(LPWSTR a, INT b);
+static INT comp_ne_m1(LPWSTR a, INT b);
+static INT comp_lt_m1(LPWSTR a, INT b);
+static INT comp_gt_m1(LPWSTR a, INT b);
+static INT comp_le_m1(LPWSTR a, INT b);
+static INT comp_ge_m1(LPWSTR a, INT b);
+
+static INT comp_eq_m2(INT a, LPWSTR b);
+static INT comp_ne_m2(INT a, LPWSTR b);
+static INT comp_lt_m2(INT a, LPWSTR b);
+static INT comp_gt_m2(INT a, LPWSTR b);
+static INT comp_le_m2(INT a, LPWSTR b);
+static INT comp_ge_m2(INT a, LPWSTR b);
+
+%}
+
+%pure-parser
+
+%union
+{
+ struct cond_str str;
+ LPWSTR string;
+ INT value;
+ comp_int fn_comp_int;
+ comp_str fn_comp_str;
+ comp_m1 fn_comp_m1;
+ comp_m2 fn_comp_m2;
+}
+
+%token COND_SPACE COND_EOF COND_SPACE
+%token COND_OR COND_AND COND_NOT
+%token COND_LT COND_GT COND_EQ
+%token COND_LPAR COND_RPAR COND_TILDA
+%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
+%token <str> COND_IDENT <str> COND_NUMBER <str> COND_LITER
+
+%nonassoc COND_EOF COND_ERROR
+
+%type <value> expression boolean_term boolean_factor
+%type <value> term value_i symbol_i integer
+%type <string> identifier value_s symbol_s literal
+%type <fn_comp_int> comp_op_i
+%type <fn_comp_str> comp_op_s
+%type <fn_comp_m1> comp_op_m1
+%type <fn_comp_m2> comp_op_m2
+
+%%
+
+condition:
+ expression
+ {
+ COND_input* cond = (COND_input*) info;
+ cond->result = $1;
+ }
+ ;
+
+expression:
+ boolean_term
+ {
+ $$ = $1;
+ }
+ | boolean_term COND_OR expression
+ {
+ $$ = $1 || $3;
+ }
+ ;
+
+boolean_term:
+ boolean_factor
+ {
+ $$ = $1;
+ }
+ | boolean_term COND_AND boolean_factor
+ {
+ $$ = $1 && $3;
+ }
+ ;
+
+boolean_factor:
+ term
+ {
+ $$ = $1;
+ }
+ | COND_NOT term
+ {
+ $$ = ! $2;
+ }
+ ;
+
+
+term:
+ value_i
+ {
+ $$ = $1;
+ }
+ | value_s
+ {
+ $$ = ($1 && $1[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE;
+ msi_free( $1 );
+ }
+ | value_i comp_op_i value_i
+ {
+ $$ = $2( $1, $3 );
+ }
+ | value_s comp_op_s value_s
+ {
+ $$ = $2( $1, $3, FALSE );
+ msi_free( $1 );
+ msi_free( $3 );
+ }
+ | value_s COND_TILDA comp_op_s value_s
+ {
+ $$ = $3( $1, $4, TRUE );
+ msi_free( $1 );
+ msi_free( $4 );
+ }
+ | value_s comp_op_m1 value_i
+ {
+ $$ = $2( $1, $3 );
+ msi_free( $1 );
+ }
+ | value_i comp_op_m2 value_s
+ {
+ $$ = $2( $1, $3 );
+ msi_free( $3 );
+ }
+ | COND_LPAR expression COND_RPAR
+ {
+ $$ = $2;
+ }
+ ;
+
+comp_op_i:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_i;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_i;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_i;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_i;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_i;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_i;
+ }
+ /*Int only*/
+ | COND_GT COND_LT
+ {
+ $$ = comp_bitand;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = comp_highcomp;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = comp_lowcomp;
+ }
+ ;
+
+comp_op_s:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_s;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_s;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_s;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_s;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_s;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_s;
+ }
+ /*string only*/
+ | COND_GT COND_LT
+ {
+ $$ = comp_substring;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = comp_start;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = comp_end;
+ }
+ ;
+
+comp_op_m1:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_m1;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_m1;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_m1;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_m1;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_m1;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_m1;
+ }
+ /*Not valid for mixed compares*/
+ | COND_GT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = 0;
+ }
+ ;
+
+comp_op_m2:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_m2;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_m2;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_m2;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_m2;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_m2;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_m2;
+ }
+ /*Not valid for mixed compares*/
+ | COND_GT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = 0;
+ }
+ ;
+
+value_i:
+ symbol_i
+ {
+ $$ = $1;
+ }
+ | integer
+ {
+ $$ = $1;
+ }
+ ;
+
+value_s:
+ symbol_s
+ {
+ $$ = $1;
+ }
+ | literal
+ {
+ $$ = $1;
+ }
+ ;
+
+literal:
+ COND_LITER
+ {
+ $$ = COND_GetLiteral(&$1);
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+symbol_i:
+ COND_DOLLARS identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetComponentStateW(cond->package, $2, &install, &action );
+ $$ = action;
+ msi_free( $2 );
+ }
+ | COND_QUESTION identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetComponentStateW(cond->package, $2, &install, &action );
+ $$ = install;
+ msi_free( $2 );
+ }
+ | COND_AMPER identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+ $$ = action;
+ msi_free( $2 );
+ }
+ | COND_EXCLAM identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+ $$ = install;
+ msi_free( $2 );
+ }
+ ;
+
+symbol_s:
+ identifier
+ {
+ DWORD sz;
+ COND_input* cond = (COND_input*) info;
+
+ sz = 0;
+ MSI_GetPropertyW(cond->package, $1, NULL, &sz);
+ if (sz == 0)
+ {
+ $$ = msi_alloc( sizeof(WCHAR));
+ $$[0] = 0;
+ }
+ else
+ {
+ sz ++;
+ $$ = msi_alloc( sz*sizeof (WCHAR) );
+
+ /* Lookup the identifier */
+
+ MSI_GetPropertyW(cond->package,$1,$$,&sz);
+ }
+ msi_free( $1 );
+ }
+ | COND_PERCENT identifier
+ {
+ UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
+ if( len++ )
+ {
+ $$ = msi_alloc( len*sizeof (WCHAR) );
+ if( $$ )
+ GetEnvironmentVariableW( $2, $$, len );
+ }
+ msi_free( $2 );
+ }
+ ;
+
+identifier:
+ COND_IDENT
+ {
+ $$ = COND_GetString(&$1);
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+integer:
+ COND_NUMBER
+ {
+ LPWSTR szNum = COND_GetString(&$1);
+ if( !szNum )
+ YYABORT;
+ $$ = atoiW( szNum );
+ msi_free( szNum );
+ }
+ ;
+
+%%
+
+
+static int COND_IsAlpha( WCHAR x )
+{
+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+ ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
+ ( ( x == '_' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') );
+}
+
+
+/* the mess of comparison functions */
+
+static INT comp_lt_i(INT a, INT b)
+{ return (a < b); }
+static INT comp_gt_i(INT a, INT b)
+{ return (a > b); }
+static INT comp_le_i(INT a, INT b)
+{ return (a <= b); }
+static INT comp_ge_i(INT a, INT b)
+{ return (a >= b); }
+static INT comp_eq_i(INT a, INT b)
+{ return (a == b); }
+static INT comp_ne_i(INT a, INT b)
+{ return (a != b); }
+static INT comp_bitand(INT a, INT b)
+{ return a & b;}
+static INT comp_highcomp(INT a, INT b)
+{ return HIWORD(a)==b; }
+static INT comp_lowcomp(INT a, INT b)
+{ return LOWORD(a)==b; }
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);}
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);}
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;}
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;}
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;}
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;}
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless)
+/* ERROR NOT WORKING REWRITE */
+{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;}
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strncmpiW(a,b,strlenW(b))==0;
+ else return strncmpW(a,b,strlenW(b))==0;}
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless)
+{
+ int i = strlenW(a);
+ int j = strlenW(b);
+ if (j>i)
+ return 0;
+ if (casless) return (!strcmpiW(&a[i-j-1],b));
+ else return (!strcmpW(&a[i-j-1],b));
+}
+
+
+static INT comp_eq_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}
+static INT comp_ne_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}
+static INT comp_lt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}
+static INT comp_gt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}
+static INT comp_le_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}
+static INT comp_ge_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}
+
+static INT comp_eq_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}
+static INT comp_ne_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}
+static INT comp_lt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}
+static INT comp_gt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}
+static INT comp_le_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}
+static INT comp_ge_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}
+
+
+
+static int COND_IsIdent( WCHAR x )
+{
+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' )
+ || ( x == '#' ) || (x == '.') );
+}
+
+static int COND_GetOne( struct cond_str *str, COND_input *cond )
+{
+ static const WCHAR szNot[] = {'N','O','T',0};
+ static const WCHAR szAnd[] = {'A','N','D',0};
+ static const WCHAR szOr[] = {'O','R',0};
+ WCHAR ch;
+ int rc, len = 1;
+
+ str->data = &cond->str[cond->n];
+
+ ch = str->data[0];
+ switch( ch )
+ {
+ case 0: return 0;
+ case '(': rc = COND_LPAR; break;
+ case ')': rc = COND_RPAR; break;
+ case '&': rc = COND_AMPER; break;
+ case '!': rc = COND_EXCLAM; break;
+ case '$': rc = COND_DOLLARS; break;
+ case '?': rc = COND_QUESTION; break;
+ case '%': rc = COND_PERCENT; break;
+ case ' ': rc = COND_SPACE; break;
+ case '=': rc = COND_EQ; break;
+ case '~': rc = COND_TILDA; break;
+ case '<': rc = COND_LT; break;
+ case '>': rc = COND_GT; break;
+ case '"':
+ {
+ const WCHAR *ch2 = str->data + 1;
+
+
+ while ( *ch2 && *ch2 != '"' )
+ ++ch2;
+ if (*ch2 == '"')
+ {
+ len = ch2 - str->data + 1;
+ rc = COND_LITER;
+ break;
+ }
+ }
+ ERR("Unterminated string\n");
+ rc = COND_ERROR;
+ break;
+ default:
+ if( COND_IsAlpha( ch ) )
+ {
+ while( COND_IsIdent( str->data[len] ) )
+ len++;
+ rc = COND_IDENT;
+ break;
+ }
+
+ if( COND_IsNumber( ch ) )
+ {
+ while( COND_IsNumber( str->data[len] ) )
+ len++;
+ rc = COND_NUMBER;
+ break;
+ }
+
+ ERR("Got unknown character %c(%x)\n",ch,ch);
+ rc = COND_ERROR;
+ break;
+ }
+
+ /* keyword identifiers */
+ if( rc == COND_IDENT )
+ {
+ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) )
+ rc = COND_NOT;
+ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) )
+ rc = COND_AND;
+ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) )
+ rc = COND_OR;
+ }
+
+ cond->n += len;
+ str->len = len;
+
+ return rc;
+}
+
+static int COND_lex( void *COND_lval, COND_input *cond )
+{
+ int rc;
+ struct cond_str *str = COND_lval;
+
+ do {
+ rc = COND_GetOne( str, cond );
+ } while (rc == COND_SPACE);
+
+ return rc;
+}
+
+static LPWSTR COND_GetString( struct cond_str *str )
+{
+ LPWSTR ret;
+
+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) );
+ if( ret )
+ {
+ memcpy( ret, str->data, str->len * sizeof(WCHAR));
+ ret[str->len]=0;
+ }
+ TRACE("Got identifier %s\n",debugstr_w(ret));
+ return ret;
+}
+
+static LPWSTR COND_GetLiteral( struct cond_str *str )
+{
+ LPWSTR ret;
+
+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) );
+ if( ret )
+ {
+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
+ ret[str->len - 2]=0;
+ }
+ TRACE("Got literal %s\n",debugstr_w(ret));
+ return ret;
+}
+
+static int COND_error(const char *str)
+{
+ return 0;
+}
+
+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
+{
+ COND_input cond;
+ MSICONDITION r;
+
+ cond.package = package;
+ cond.str = szCondition;
+ cond.n = 0;
+ cond.result = -1;
+
+ TRACE("Evaluating %s\n",debugstr_w(szCondition));
+
+ if ( szCondition == NULL || szCondition[0] == 0)
+ r = MSICONDITION_NONE;
+ else if ( !COND_parse( &cond ) )
+ r = cond.result;
+ else
+ r = MSICONDITION_ERROR;
+
+ TRACE("Evaluates to %i\n",r);
+ return r;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
+{
+ MSIPACKAGE *package;
+ UINT ret;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_EvaluateConditionW( package, szCondition );
+ msiobj_release( &package->hdr );
+ return ret;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
+{
+ LPWSTR szwCond = NULL;
+ MSICONDITION r;
+
+ if( szCondition )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
+ szwCond = msi_alloc( len * sizeof (WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
+ }
+
+ r = MsiEvaluateConditionW( hInstall, szwCond );
+
+ msi_free( szwCond );
+
+ return r;
+}
static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
MSIVIEW *tv = NULL;
- MSIRECORD *rec;
+ MSIRECORD *rec = NULL;
TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name),
cv->bIsTemp?"temporary":"permanent");
r = ERROR_SUCCESS;
err:
+ if (rec)
+ msiobj_release( &rec->hdr );
/* FIXME: remove values from the string table on error */
if( tv )
tv->ops->delete( tv );
TRACE("%p\n", cv );
msiobj_release( &cv->db->hdr );
- HeapFree( GetProcessHeap(), 0, cv );
+ msi_free( cv );
return ERROR_SUCCESS;
}
TRACE("%p\n", cv );
- cv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *cv );
+ cv = msi_alloc_zero( sizeof *cv );
if( !cv )
return ERROR_FUNCTION_FAILED;
typedef struct tagMSIRUNNINGACTION
{
+ struct list entry;
HANDLE handle;
BOOL process;
LPWSTR name;
{
FIXME("Rollback only action... rollbacks not supported yet\n");
schedule_action(package, ROLLBACK_SCRIPT, action);
- HeapFree(GetProcessHeap(),0,source);
- HeapFree(GetProcessHeap(),0,target);
- msiobj_release(&row->hdr);
- return ERROR_SUCCESS;
+ rc = ERROR_SUCCESS;
+ goto end;
}
if (!execute)
{
schedule_action(package, INSTALL_SCRIPT, action);
}
- HeapFree(GetProcessHeap(),0,source);
- HeapFree(GetProcessHeap(),0,target);
- msiobj_release(&row->hdr);
- return ERROR_SUCCESS;
+ rc = ERROR_SUCCESS;
+ goto end;
}
else
{
static const WCHAR szActionData[] = {
'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
static const WCHAR szBlank[] = {0};
- LPWSTR actiondata = load_dynamic_property(package,action,NULL);
+ LPWSTR actiondata = msi_dup_property( package, action );
if (actiondata)
MSI_SetPropertyW(package,szActionData,actiondata);
else
MSI_SetPropertyW(package,szActionData,szBlank);
+ msi_free(actiondata);
}
}
else if (!check_execution_scheduling_options(package,action,type))
- return ERROR_SUCCESS;
+ {
+ rc = ERROR_SUCCESS;
+ goto end;
+ }
switch (type & CUSTOM_ACTION_TYPE_MASK)
{
case 35: /* Directory set with formatted text. */
deformat_string(package,target,&deformated);
MSI_SetTargetPathW(package, source, deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
break;
case 51: /* Property set with formatted text. */
deformat_string(package,target,&deformated);
rc = MSI_SetPropertyW(package,source,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
break;
default:
FIXME("UNHANDLED ACTION TYPE %i (%s %s)\n",
debugstr_w(target));
}
- HeapFree(GetProcessHeap(),0,source);
- HeapFree(GetProcessHeap(),0,target);
+end:
+ msi_free(source);
+ msi_free(target);
msiobj_release(&row->hdr);
return rc;
}
static const WCHAR f1[] = {'m','s','i',0};
WCHAR fmt[MAX_PATH];
- if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz)
- != ERROR_SUCCESS)
+ if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz) != ERROR_SUCCESS)
GetTempPathW(MAX_PATH,fmt);
if (GetTempFileNameW(fmt,f1,0,tmp_file) == 0)
static void file_running_action(MSIPACKAGE* package, HANDLE Handle,
BOOL process, LPCWSTR name)
{
- MSIRUNNINGACTION *newbuf = NULL;
- INT count;
- count = package->RunningActionCount;
- package->RunningActionCount++;
- if (count != 0)
- newbuf = HeapReAlloc(GetProcessHeap(),0,
- package->RunningAction,
- package->RunningActionCount * sizeof(MSIRUNNINGACTION));
- else
- newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(MSIRUNNINGACTION));
+ MSIRUNNINGACTION *action;
+
+ action = msi_alloc( sizeof(MSIRUNNINGACTION) );
- newbuf[count].handle = Handle;
- newbuf[count].process = process;
- newbuf[count].name = strdupW(name);
+ action->handle = Handle;
+ action->process = process;
+ action->name = strdupW(name);
- package->RunningAction = newbuf;
+ list_add_tail( &package->RunningActions, &action->entry );
}
static UINT process_action_return_value(UINT type, HANDLE ThreadHandle)
}
CloseHandle(ThreadHandle);
- if (ProcessHandle);
+ if (ProcessHandle)
CloseHandle(ProcessHandle);
if (finished)
*finished = TRUE;
else
{
CloseHandle(ThreadHandle);
- if (ProcessHandle);
+ if (ProcessHandle)
CloseHandle(ProcessHandle);
}
if (finished)
MSIPACKAGE *package = stuff->package;
TRACE("Calling function %s\n", proc);
- hPackage = msiobj_findhandle( &package->hdr );
- if (hPackage )
+ hPackage = alloc_msihandle( &package->hdr );
+ if (hPackage)
{
- rc = fn(hPackage);
- msiobj_release( &package->hdr );
+ rc = fn( hPackage );
+ MsiCloseHandle( hPackage );
}
else
ERR("Handle for object %p not found\n", package );
else
ERR("Cannot load functon\n");
- HeapFree(GetProcessHeap(),0,proc);
+ msi_free(proc);
FreeLibrary(hModule);
}
else
ERR("Unable to load library\n");
msiobj_release( &stuff->package->hdr );
- HeapFree(GetProcessHeap(),0,stuff->source);
- HeapFree(GetProcessHeap(),0,stuff->target);
- HeapFree(GetProcessHeap(), 0, stuff);
+ msi_free(stuff->source);
+ msi_free(stuff->target);
+ msi_free(stuff);
return rc;
}
strcatW(tmp_file,dot);
}
- info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
+ info = msi_alloc( sizeof(*info) );
msiobj_addref( &package->hdr );
info->package = package;
info->target = strdupW(target);
if (deformated)
len += strlenW(deformated);
- cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
+ cmd = msi_alloc(sizeof(WCHAR)*len);
strcpyW(cmd,tmp_file);
if (deformated)
strcatW(cmd,spc);
strcatW(cmd,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
- HeapFree(GetProcessHeap(),0,cmd);
+ msi_free(cmd);
if ( !rc )
{
len += strlenW(deformated);
len += 2;
- cmd = HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
+ cmd = msi_alloc(len * sizeof(WCHAR));
lstrcpyW( cmd, file->TargetPath);
if (deformated)
strcatW(cmd, spc);
strcatW(cmd, deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
- HeapFree(GetProcessHeap(),0,cmd);
+ msi_free(cmd);
if ( !rc )
{
'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
'F','R','O','M',' ','`','E','r','r','o','r','`',' ',
'W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ',
- '\'','%','s','\'',0
+ '%','s',0
};
MSIRECORD *row = 0;
LPWSTR deformated = NULL;
else
MessageBoxW( NULL, deformated, NULL, MB_OK );
- HeapFree( GetProcessHeap(), 0, deformated );
+ msi_free( deformated );
return ERROR_FUNCTION_FAILED;
}
WCHAR *deformated;
WCHAR *cmd;
INT len;
- UINT prc;
static const WCHAR spc[] = {' ',0};
memset(&si,0,sizeof(STARTUPINFOW));
memset(&info,0,sizeof(PROCESS_INFORMATION));
- prop = load_dynamic_property(package,source,&prc);
+ prop = msi_dup_property( package, source );
if (!prop)
return ERROR_SUCCESS;
if (deformated)
len += strlenW(deformated);
- cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
+ cmd = msi_alloc(sizeof(WCHAR)*len);
strcpyW(cmd,prop);
if (deformated)
strcatW(cmd,spc);
strcatW(cmd,deformated);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
}
+ msi_free(prop);
TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
- HeapFree(GetProcessHeap(),0,cmd);
+ msi_free(cmd);
if ( !rc )
{
return ERROR_SUCCESS;
}
- prc = process_handle(package, type, info.hThread, info.hProcess, action,
- NULL);
-
- return prc;
+ return process_handle(package, type, info.hThread, info.hProcess, action, NULL);
}
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
return ERROR_FUNCTION_FAILED;
SetCurrentDirectoryW(filename);
- HeapFree(GetProcessHeap(),0,filename);
+ msi_free(filename);
deformat_string(package,target,&deformated);
rc = CreateProcessW(NULL, deformated, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(deformated);
if ( !rc )
{
void ACTION_FinishCustomActions(MSIPACKAGE* package)
{
- INT i;
+ struct list *item, *cursor;
DWORD rc;
- for (i = 0; i < package->RunningActionCount; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->RunningActions )
{
- TRACE("Checking on action %s\n",
- debugstr_w(package->RunningAction[i].name));
+ MSIRUNNINGACTION *action = LIST_ENTRY( item, MSIRUNNINGACTION, entry );
+
+ TRACE("Checking on action %s\n", debugstr_w(action->name));
- if (package->RunningAction[i].process)
- GetExitCodeProcess(package->RunningAction[i].handle, &rc);
+ list_remove( &action->entry );
+
+ if (action->process)
+ GetExitCodeProcess( action->handle, &rc );
else
- GetExitCodeThread(package->RunningAction[i].handle, &rc);
+ GetExitCodeThread( action->handle, &rc );
if (rc == STILL_ACTIVE)
{
- TRACE("Waiting on action %s\n",
- debugstr_w(package->RunningAction[i].name));
- msi_dialog_check_messages(package->RunningAction[i].handle);
+ TRACE("Waiting on action %s\n", debugstr_w( action->name) );
+ msi_dialog_check_messages( action->handle );
}
- HeapFree(GetProcessHeap(),0,package->RunningAction[i].name);
- CloseHandle(package->RunningAction[i].handle);
+ CloseHandle( action->handle );
+ msi_free( action->name );
+ msi_free( action );
}
-
- HeapFree(GetProcessHeap(),0,package->RunningAction);
}
DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID( CLSID_MsiPatch, 0x000c1086, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
/*
* .MSI file format
/* UINT len = lstrlenW( szPerist ) + 1; */
FIXME("don't support persist files yet\b");
return ERROR_INVALID_PARAMETER;
- /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
+ /* szMode = msi_alloc( len * sizeof (DWORD) ); */
}
else if( szPersist == MSIDBOPEN_READONLY )
{
goto end;
}
- if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
+ if ( !IsEqualGUID( &stat.clsid, &CLSID_MsiDatabase ) &&
+ !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) )
{
ERR("storage GUID is not a MSI database GUID %s\n",
debugstr_guid(&stat.clsid) );
goto end;
}
-
db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase );
if( !db )
db->storage = stg;
db->mode = szMode;
+ list_init( &db->tables );
- ret = load_string_table( db );
- if( ret != ERROR_SUCCESS )
+ db->strings = load_string_table( stg );
+ if( !db->strings )
goto end;
+ ret = ERROR_SUCCESS;
+
msiobj_addref( &db->hdr );
IStorage_AddRef( stg );
*pdb = db;
end:
if( HIWORD(szPersist) )
- HeapFree( GetProcessHeap(), 0, szwPersist );
- HeapFree( GetProcessHeap(), 0, szwDBPath );
+ msi_free( szwPersist );
+ msi_free( szwDBPath );
return r;
}
r = MsiDatabaseImportW( handle, path, file );
end:
- HeapFree( GetProcessHeap(), 0, path );
- HeapFree( GetProcessHeap(), 0, file );
+ msi_free( path );
+ msi_free( file );
return r;
}
r = MsiDatabaseExportW( handle, table, path, file );
end:
- HeapFree( GetProcessHeap(), 0, table );
- HeapFree( GetProcessHeap(), 0, path );
- HeapFree( GetProcessHeap(), 0, file );
+ msi_free( table );
+ msi_free( path );
+ msi_free( file );
return r;
}
if( dv->table )
dv->table->ops->delete( dv->table );
- HeapFree( GetProcessHeap(), 0, dv );
+ msi_free( dv );
return ERROR_SUCCESS;
}
TRACE("%p\n", dv );
- dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+ dv = msi_alloc_zero( sizeof *dv );
if( !dv )
return ERROR_FUNCTION_FAILED;
#include "ocidl.h"
#include "olectl.h"
#include "richedit.h"
+#include "commctrl.h"
#include "wine/debug.h"
#include "wine/unicode.h"
struct msi_control_tag
{
- struct msi_control_tag *next;
+ struct list entry;
HWND hwnd;
msi_handler handler;
LPWSTR property;
HBITMAP hBitmap;
HICON hIcon;
LPWSTR tabnext;
+ HMODULE hDll;
WCHAR name[1];
};
HWND hwnd;
LPWSTR default_font;
msi_font *font_list;
- msi_control *control_list;
+ struct list controls;
HWND hWndFocus;
WCHAR name[1];
};
static const WCHAR szEdit[] = { 'E','d','i','t',0 };
static const WCHAR szMaskedEdit[] = { 'M','a','s','k','e','d','E','d','i','t',0 };
static const WCHAR szPathEdit[] = { 'P','a','t','h','E','d','i','t',0 };
+static const WCHAR szProgressBar[] = {
+ 'P','r','o','g','r','e','s','s','B','a','r',0 };
static const WCHAR szRadioButtonGroup[] = {
'R','a','d','i','o','B','u','t','t','o','n','G','r','o','u','p',0 };
static const WCHAR szIcon[] = { 'I','c','o','n',0 };
static DWORD uiThreadId;
static HWND hMsiHiddenWindow;
-static HMODULE hRichedit;
static INT msi_dialog_scale_unit( msi_dialog *dialog, INT val )
{
if( !name )
return NULL;
- for( control = dialog->control_list; control; control = control->next )
+ LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry )
if( !strcmpW( control->name, name ) ) /* FIXME: case sensitive? */
- break;
- return control;
+ return control;
+ return NULL;
}
static msi_control *msi_dialog_find_control_by_hwnd( msi_dialog *dialog, HWND hwnd )
{
msi_control *control;
- for( control = dialog->control_list; control; control = control->next )
+ LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry )
if( hwnd == control->hwnd )
- break;
- return control;
+ return control;
+ return NULL;
+}
+
+static LPWSTR msi_get_deformatted_field( MSIPACKAGE *package, MSIRECORD *rec, int field )
+{
+ LPCWSTR str = MSI_RecordGetString( rec, field );
+ LPWSTR ret = NULL;
+
+ if (str)
+ deformat_string( package, str, &ret );
+ return ret;
}
/*
* Extract the {\style} string from the front of the text to display and
* update the pointer.
*/
-static LPWSTR msi_dialog_get_style( LPCWSTR *text )
+static LPWSTR msi_dialog_get_style( LPCWSTR p, LPCWSTR *rest )
{
LPWSTR ret = NULL;
- LPCWSTR p = *text, q;
+ LPCWSTR q, i;
DWORD len;
+ *rest = p;
+ if( !p )
+ return ret;
if( *p++ != '{' )
return ret;
q = strchrW( p, '}' );
if( !q )
return ret;
- *text = ++q;
- if( *p++ != '\\' )
- return ret;
- len = q - p;
+ if( *p == '\\' || *p == '&' )
+ p++;
+
+ /* little bit of sanity checking to stop us getting confused with RTF */
+ for( i=p; i<q; i++ )
+ if( *i == '}' || *i == '\\' )
+ return ret;
- ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ *rest = ++q;
+ len = q - p;
+
+ ret = msi_alloc( len*sizeof(WCHAR) );
if( !ret )
return ret;
memcpy( ret, p, len*sizeof(WCHAR) );
/* create a font and add it to the list */
name = MSI_RecordGetString( rec, 1 );
- font = HeapAlloc( GetProcessHeap(), 0,
- sizeof *font + strlenW( name )*sizeof (WCHAR) );
+ font = msi_alloc( sizeof *font + strlenW( name )*sizeof (WCHAR) );
strcpyW( font->name, name );
font->next = dialog->font_list;
dialog->font_list = font;
DWORD style, HWND parent )
{
DWORD x, y, width, height;
- LPWSTR font = NULL, title = NULL;
+ LPWSTR font = NULL, title_font = NULL;
+ LPCWSTR title = NULL;
msi_control *control;
style |= WS_CHILD;
- control = HeapAlloc( GetProcessHeap(), 0,
- sizeof *control + strlenW(name)*sizeof(WCHAR) );
+ control = msi_alloc( sizeof *control + strlenW(name)*sizeof(WCHAR) );
strcpyW( control->name, name );
- control->next = dialog->control_list;
- dialog->control_list = control;
+ list_add_head( &dialog->controls, &control->entry );
control->handler = NULL;
control->property = NULL;
control->value = NULL;
control->hBitmap = NULL;
control->hIcon = NULL;
+ control->hDll = NULL;
control->tabnext = strdupW( MSI_RecordGetString( rec, 11) );
x = MSI_RecordGetInteger( rec, 4 );
if( text )
{
- font = msi_dialog_get_style( &text );
- deformat_string( dialog->package, text, &title );
+ deformat_string( dialog->package, text, &title_font );
+ font = msi_dialog_get_style( title_font, &title );
}
control->hwnd = CreateWindowW( szCls, title, style,
msi_dialog_set_font( dialog, control->hwnd,
font ? font : dialog->default_font );
- HeapFree( GetProcessHeap(), 0, font );
- HeapFree( GetProcessHeap(), 0, title );
+ msi_free( title_font );
+ msi_free( font );
return control;
}
if( !r )
return path;
len = lstrlenW( tmp ) + 20;
- path = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ path = msi_alloc( len * sizeof (WCHAR) );
if( path )
{
r = GetTempFileNameW( tmp, prefix, 0, path );
if (!r)
{
- HeapFree( GetProcessHeap(), 0, path );
+ msi_free( path );
path = NULL;
}
}
msiobj_release( &rec->hdr );
}
- HeapFree( GetProcessHeap(), 0, tmp );
+ msi_free( tmp );
return himage;
}
if (!ctrl)
return;
if( lstrcmpW(attribute, szText) )
+ {
+ ERR("Attribute %s\n", debugstr_w(attribute));
return;
+ }
text = MSI_RecordGetString( rec , 1 );
SetWindowTextW( ctrl->hwnd, text );
msi_dialog_check_messages( NULL );
msi_text_on_settext( hWnd );
break;
case WM_NCDESTROY:
- HeapFree( GetProcessHeap(), 0, info );
+ msi_free( info );
RemovePropW( hWnd, szButtonData );
break;
}
if( !control )
return ERROR_FUNCTION_FAILED;
- info = HeapAlloc( GetProcessHeap(), 0, sizeof *info );
+ info = msi_alloc( sizeof *info );
if( !info )
return ERROR_SUCCESS;
{
msi_control *control;
UINT attributes, style;
- LPCWSTR text;
+ LPWSTR text;
TRACE("%p %p\n", dialog, rec);
control->handler = msi_dialog_button_handler;
/* set the icon */
- text = MSI_RecordGetString( rec, 10 );
+ text = msi_get_deformatted_field( dialog->package, rec, 10 );
control->hIcon = msi_load_icon( dialog->package->db, text, attributes );
if( attributes & msidbControlAttributesIcon )
SendMessageW( control->hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) control->hIcon );
+ msi_free( text );
return ERROR_SUCCESS;
}
'\'','%','s','\'',0
};
MSIRECORD *rec = NULL;
- LPCWSTR val = NULL;
LPWSTR ret = NULL;
/* find if there is a value associated with the checkbox */
if (!rec)
return ret;
- val = MSI_RecordGetString( rec, 2 );
- if (val)
+ ret = msi_get_deformatted_field( dialog->package, rec, 2 );
+ if( ret && !ret[0] )
{
- deformat_string( dialog->package, val, &ret );
- if( ret && !ret[0] )
- {
- HeapFree( GetProcessHeap(), 0, ret );
- ret = NULL;
- }
+ msi_free( ret );
+ ret = NULL;
}
msiobj_release( &rec->hdr );
if (ret)
return ret;
- ret = load_dynamic_property(dialog->package, prop, NULL);
+ ret = msi_dup_property( dialog->package, prop );
if( ret && !ret[0] )
{
- HeapFree( GetProcessHeap(), 0, ret );
+ msi_free( ret );
ret = NULL;
}
LPCWSTR text;
EDITSTREAM es;
DWORD style;
+ HMODULE hRichedit;
+
+ hRichedit = LoadLibraryA("riched20");
style = WS_BORDER | ES_MULTILINE | WS_VSCROLL |
ES_READONLY | ES_AUTOVSCROLL | WS_TABSTOP;
control = msi_dialog_add_control( dialog, rec, szRichEdit20W, style );
+ if (!control)
+ return ERROR_FUNCTION_FAILED;
+
+ control->hDll = hRichedit;
text = MSI_RecordGetString( rec, 10 );
info.string = strdupWtoA( text );
SendMessageW( control->hwnd, EM_STREAMIN, SF_RTF, (LPARAM) &es );
- HeapFree( GetProcessHeap(), 0, info.string );
+ msi_free( info.string );
return ERROR_SUCCESS;
}
{
UINT cx, cy, flags, style, attributes;
msi_control *control;
- LPCWSTR text;
+ LPWSTR text;
flags = LR_LOADFROMFILE;
style = SS_BITMAP | SS_LEFT | WS_GROUP;
}
control = msi_dialog_add_control( dialog, rec, szStatic, style );
- text = MSI_RecordGetString( rec, 10 );
cx = MSI_RecordGetInteger( rec, 6 );
cy = MSI_RecordGetInteger( rec, 7 );
cx = msi_dialog_scale_unit( dialog, cx );
cy = msi_dialog_scale_unit( dialog, cy );
+ text = msi_get_deformatted_field( dialog->package, rec, 10 );
control->hBitmap = msi_load_image( dialog->package->db, text,
IMAGE_BITMAP, cx, cy, flags );
if( control->hBitmap )
IMAGE_BITMAP, (LPARAM) control->hBitmap );
else
ERR("Failed to load bitmap %s\n", debugstr_w(text));
+
+ msi_free( text );
return ERROR_SUCCESS;
}
{
msi_control *control;
DWORD attributes;
- LPCWSTR text;
+ LPWSTR text;
TRACE("\n");
SS_ICON | SS_CENTERIMAGE | WS_GROUP );
attributes = MSI_RecordGetInteger( rec, 8 );
- text = MSI_RecordGetString( rec, 10 );
+ text = msi_get_deformatted_field( dialog->package, rec, 10 );
control->hIcon = msi_load_icon( dialog->package->db, text, attributes );
if( control->hIcon )
SendMessageW( control->hwnd, STM_SETICON, (WPARAM) control->hIcon, 0 );
else
ERR("Failed to load bitmap %s\n", debugstr_w(text));
+ msi_free( text );
return ERROR_SUCCESS;
}
prop = MSI_RecordGetString( rec, 9 );
if( prop )
control->property = strdupW( prop );
- val = load_dynamic_property( dialog->package, control->property, NULL );
+ val = msi_dup_property( dialog->package, control->property );
SetWindowTextW( control->hwnd, val );
- HeapFree( GetProcessHeap(), 0, val );
+ msi_free( val );
return ERROR_SUCCESS;
}
LPWSTR val;
UINT i, n, r;
- val = HeapAlloc( GetProcessHeap(), 0, (info->num_chars+1)*sizeof(WCHAR) );
+ val = msi_alloc( (info->num_chars+1)*sizeof(WCHAR) );
for( i=0, n=0; i<info->num_groups; i++ )
{
if( (info->group[i].len + n) > info->num_chars )
MSI_SetPropertyW( info->dialog->package, info->prop, val );
msi_dialog_evaluate_control_conditions( info->dialog );
}
- HeapFree( GetProcessHeap(), 0, val );
+ msi_free( val );
}
/* now move to the next control if necessary */
}
break;
case WM_NCDESTROY:
- HeapFree( GetProcessHeap(), 0, info->prop );
- HeapFree( GetProcessHeap(), 0, info );
+ msi_free( info->prop );
+ msi_free( info );
RemovePropW( hWnd, szButtonData );
break;
}
LPWSTR chunk = strdupW( p );
chunk[ info->group[i].len ] = 0;
SetWindowTextW( info->group[i].hwnd, chunk );
- HeapFree( GetProcessHeap(), 0, chunk );
+ msi_free( chunk );
}
else
{
if( !p )
return info;
- info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *info );
+ info = msi_alloc_zero( sizeof *info );
if( !info )
return info;
p++;
for( i=0; i<MASK_MAX_GROUPS; i++ )
{
+ while (*p=='-')
+ {
+ total++;
+ p++;
+ }
+
/* stop at the end of the string */
if( p[0] == 0 || p[0] == '>' )
break;
p += n;
}
- TRACE("%d characters in %d groups\n", total, info->num_groups );
+ TRACE("%d characters in %d groups\n", total, i );
if( i == MASK_MAX_GROUPS )
ERR("too many groups in PIDTemplate %s\n", debugstr_w(mask));
}
static void
-msi_maskedit_create_children( struct msi_maskedit_info *info )
+msi_maskedit_create_children( struct msi_maskedit_info *info, LPCWSTR font )
{
DWORD width, height, style, wx, ww;
- LPCWSTR text, font = NULL;
RECT rect;
HWND hwnd;
UINT i;
width = rect.right - rect.left;
height = rect.bottom - rect.top;
- if( text )
- font = msi_dialog_get_style( &text );
-
for( i = 0; i < info->num_groups; i++ )
{
wx = (info->group[i].ofs * width) / info->num_chars;
SendMessageW( hwnd, EM_LIMITTEXT, info->group[i].len, 0 );
msi_dialog_set_font( info->dialog, hwnd,
- font ? font : info->dialog->default_font );
+ font?font:info->dialog->default_font );
info->group[i].hwnd = hwnd;
}
}
/* office 2003 uses "73931<````=````=````=````=`````>@@@@@" */
static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec )
{
- const static WCHAR pidt[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
- LPWSTR mask = NULL, title = NULL, val = NULL;
+ LPWSTR font_mask, val = NULL, font;
struct msi_maskedit_info *info = NULL;
UINT ret = ERROR_SUCCESS;
msi_control *control;
- LPCWSTR prop;
+ LPCWSTR prop, mask;
+
+ TRACE("\n");
- mask = load_dynamic_property( dialog->package, pidt, NULL );
+ font_mask = msi_get_deformatted_field( dialog->package, rec, 10 );
+ font = msi_dialog_get_style( font_mask, &mask );
if( !mask )
{
- ERR("PIDTemplate is empty\n");
+ ERR("mask template is empty\n");
goto end;
}
if( prop )
info->prop = strdupW( prop );
- msi_maskedit_create_children( info );
+ msi_maskedit_create_children( info, font );
if( prop )
{
- val = load_dynamic_property( dialog->package, prop, NULL );
+ val = msi_dup_property( dialog->package, prop );
if( val )
{
msi_maskedit_set_text( info, val );
- HeapFree( GetProcessHeap(), 0, val );
+ msi_free( val );
}
}
end:
if( ret != ERROR_SUCCESS )
- HeapFree( GetProcessHeap(), 0, info );
- HeapFree( GetProcessHeap(), 0, title );
- HeapFree( GetProcessHeap(), 0, mask );
+ msi_free( info );
+ msi_free( font_mask );
+ msi_free( font );
return ret;
}
+/******************** Progress Bar *****************************************/
+
+static UINT msi_dialog_progress_bar( msi_dialog *dialog, MSIRECORD *rec )
+{
+ msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, WS_VISIBLE );
+ return ERROR_SUCCESS;
+}
+
/******************** Path Edit ********************************************/
static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec )
msi_dialog *dialog = group->dialog;
msi_control *control;
LPCWSTR prop, text, name;
- DWORD style;
- DWORD attributes = group->attributes;
+ DWORD style, attributes = group->attributes;
style = WS_CHILD | BS_AUTORADIOBUTTON | BS_MULTILINE | WS_TABSTOP;
name = MSI_RecordGetString( rec, 3 );
control = msi_dialog_create_window( dialog, rec, szButton, name, text,
style, group->parent->hwnd );
+ if (!control)
+ return ERROR_FUNCTION_FAILED;
control->handler = msi_dialog_radiogroup_handler;
prop = MSI_RecordGetString( rec, 1 );
{ szEdit, msi_dialog_edit_control },
{ szMaskedEdit, msi_dialog_maskedit_control },
{ szPathEdit, msi_dialog_pathedit_control },
+ { szProgressBar, msi_dialog_progress_bar },
{ szRadioButtonGroup, msi_dialog_radiogroup_control },
{ szIcon, msi_dialog_icon_control },
};
{
msi_control *control, *tab_next;
- for( control = dialog->control_list; control; control = control->next )
+ LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry )
{
tab_next = msi_dialog_find_control( dialog, control->tabnext );
if( !tab_next )
'D','e','f','a','u','l','t','U','I','F','o','n','t',0 };
msi_dialog *dialog = (msi_dialog*) cs->lpCreateParams;
MSIRECORD *rec = NULL;
- LPCWSTR text;
LPWSTR title = NULL;
SIZE size;
msi_dialog_adjust_dialog_size( dialog, &size );
dialog->attributes = MSI_RecordGetInteger( rec, 6 );
- text = MSI_RecordGetString( rec, 7 );
- dialog->default_font = load_dynamic_property( dialog->package, df, NULL );
+ dialog->default_font = msi_dup_property( dialog->package, df );
- deformat_string( dialog->package, text, &title );
+ title = msi_get_deformatted_field( dialog->package, rec, 7 );
SetWindowTextW( hwnd, title );
+ msi_free( title );
+
SetWindowPos( hwnd, 0, 0, 0, size.cx, size.cy,
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW );
- HeapFree( GetProcessHeap(), 0, title );
msi_dialog_build_font_list( dialog );
msi_dialog_fill_controls( dialog );
dialog->event_handler( dialog->package, event_fmt, arg_fmt, dialog );
- HeapFree( GetProcessHeap(), 0, event_fmt );
- HeapFree( GetProcessHeap(), 0, arg_fmt );
+ msi_free( event_fmt );
+ msi_free( arg_fmt );
return ERROR_SUCCESS;
}
UINT len;
len = strlenW(event);
- prop = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
+ prop = msi_alloc( len*sizeof(WCHAR));
strcpyW( prop, &event[1] );
p = strchrW( prop, ']' );
if( p && p[1] == 0 )
if( strcmpW( szNullArg, arg ) )
deformat_string( dialog->package, arg, &arg_fmt );
MSI_SetPropertyW( dialog->package, prop, arg_fmt );
+ msi_free( arg_fmt );
}
else
ERR("Badly formatted property string - what happens?\n");
- HeapFree( GetProcessHeap(), 0, prop );
+ msi_free( prop );
return ERROR_SUCCESS;
}
debugstr_w(control->property));
sz = 0x20;
- buf = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
+ buf = msi_alloc( sz*sizeof(WCHAR) );
while( buf )
{
r = GetWindowTextW( control->hwnd, buf, sz );
if( r < (sz-1) )
break;
- sz *= 2;
- buf = HeapReAlloc( GetProcessHeap(), 0, buf, sz*sizeof(WCHAR) );
+ sz *= 2;
+ buf = msi_realloc( buf, sz*sizeof(WCHAR) );
}
MSI_SetPropertyW( dialog->package, control->property, buf );
- HeapFree( GetProcessHeap(), 0, buf );
+ msi_free( buf );
return ERROR_SUCCESS;
}
TRACE("%p %s\n", package, debugstr_w(szDialogName));
/* allocate the structure for the dialog to use */
- dialog = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof *dialog + sizeof(WCHAR)*strlenW(szDialogName) );
+ dialog = msi_alloc_zero( sizeof *dialog + sizeof(WCHAR)*strlenW(szDialogName) );
if( !dialog )
return NULL;
strcpyW( dialog->name, szDialogName );
dialog->package = package;
dialog->event_handler = event_handler;
dialog->finished = 0;
+ list_init( &dialog->controls );
/* verify that the dialog exists */
rec = msi_get_dialog_record( dialog );
if( !rec )
{
- HeapFree( GetProcessHeap(), 0, dialog );
+ msiobj_release( &package->hdr );
+ msi_free( dialog );
return NULL;
}
dialog->attributes = MSI_RecordGetInteger( rec, 6 );
}
ShowWindow( hwnd, SW_SHOW );
- UpdateWindow( hwnd );
+ /* UpdateWindow( hwnd ); - and causes the transparent static controls not to paint */
if( dialog->attributes & msidbDialogAttributesModal )
{
if( dialog->hwnd )
ShowWindow( dialog->hwnd, SW_HIDE );
+ if( dialog->hwnd )
+ DestroyWindow( dialog->hwnd );
+
/* destroy the list of controls */
- while( dialog->control_list )
+ while( !list_empty( &dialog->controls ) )
{
- msi_control *t = dialog->control_list;
- dialog->control_list = t->next;
+ msi_control *t = LIST_ENTRY( list_head( &dialog->controls ),
+ msi_control, entry );
+ list_remove( &t->entry );
/* leave dialog->hwnd - destroying parent destroys child windows */
- HeapFree( GetProcessHeap(), 0, t->property );
- HeapFree( GetProcessHeap(), 0, t->value );
+ msi_free( t->property );
+ msi_free( t->value );
if( t->hBitmap )
DeleteObject( t->hBitmap );
if( t->hIcon )
DestroyIcon( t->hIcon );
- HeapFree( GetProcessHeap(), 0, t->tabnext );
- HeapFree( GetProcessHeap(), 0, t );
+ msi_free( t->tabnext );
+ msi_free( t );
+ if (t->hDll)
+ FreeLibrary( t->hDll );
}
/* destroy the list of fonts */
msi_font *t = dialog->font_list;
dialog->font_list = t->next;
DeleteObject( t->hfont );
- HeapFree( GetProcessHeap(), 0, t );
+ msi_free( t );
}
- HeapFree( GetProcessHeap(), 0, dialog->default_font );
-
- if( dialog->hwnd )
- DestroyWindow( dialog->hwnd );
+ msi_free( dialog->default_font );
msiobj_release( &dialog->package->hdr );
dialog->package = NULL;
- HeapFree( GetProcessHeap(), 0, dialog );
+ msi_free( dialog );
}
BOOL msi_dialog_register_class( void )
cls.hInstance = NULL;
cls.hIcon = LoadIconW(0, (LPWSTR)IDI_APPLICATION);
cls.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
- cls.hbrBackground = (HBRUSH)(COLOR_WINDOW);
+ cls.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
cls.lpszMenuName = NULL;
cls.lpszClassName = szMsiDialogClass;
if( !hMsiHiddenWindow )
return FALSE;
- hRichedit = LoadLibraryA("riched20");
-
return TRUE;
}
DestroyWindow( hMsiHiddenWindow );
UnregisterClassW( szMsiDialogClass, NULL );
uiThreadId = 0;
- FreeLibrary( hRichedit );
}
}
/* nothing found, so add one */
- *x = HeapAlloc( GetProcessHeap(), 0, sizeof (DISTINCTSET) );
+ *x = msi_alloc( sizeof (DISTINCTSET) );
if( *x )
{
(*x)->val = val;
{
DISTINCTSET *next = x->nextrow;
distinct_free( x->nextcol );
- HeapFree( GetProcessHeap(), 0, x );
+ msi_free( x );
x = next;
}
}
if( r != ERROR_SUCCESS )
return r;
- dv->translation = HeapAlloc( GetProcessHeap(), 0, r_count*sizeof(UINT) );
+ dv->translation = msi_alloc( r_count*sizeof(UINT) );
if( !dv->translation )
return ERROR_FUNCTION_FAILED;
if( !dv->table )
return ERROR_FUNCTION_FAILED;
- HeapFree( GetProcessHeap(), 0, dv->translation );
+ msi_free( dv->translation );
dv->translation = NULL;
dv->row_count = 0;
if( dv->table )
dv->table->ops->delete( dv->table );
- HeapFree( GetProcessHeap(), 0, dv->translation );
+ msi_free( dv->translation );
msiobj_release( &dv->db->hdr );
- HeapFree( GetProcessHeap(), 0, dv );
+ msi_free( dv );
return ERROR_SUCCESS;
}
return r;
}
- dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+ dv = msi_alloc_zero( sizeof *dv );
if( !dv )
return ERROR_FUNCTION_FAILED;
static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument,
msi_dialog* dialog)
{
- LPWSTR path = load_dynamic_property(package,argument, NULL);
+ LPWSTR path = msi_dup_property( package, argument );
+ UINT r;
/* failure to set the path halts the executing of control events */
- return MSI_SetTargetPathW(package, argument, path);
+ r = MSI_SetTargetPathW(package, argument, path);
+ msi_free(path);
+ return r;
}
/*
*/
static void free_subscriber( struct subscriber *sub )
{
- HeapFree(GetProcessHeap(),0,sub->event);
- HeapFree(GetProcessHeap(),0,sub->control);
- HeapFree(GetProcessHeap(),0,sub->attribute);
- HeapFree(GetProcessHeap(),0,sub);
+ msi_free(sub->event);
+ msi_free(sub->control);
+ msi_free(sub->attribute);
+ msi_free(sub);
}
VOID ControlEvent_SubscribeToEvent( MSIPACKAGE *package, LPCWSTR event,
{
struct subscriber *sub;
- sub = HeapAlloc(GetProcessHeap(),0,sizeof (*sub));
+ sub = msi_alloc(sizeof (*sub));
if( !sub )
return;
sub->event = strdupW(event);
package->next_dialog = NULL;
r = event_do_dialog( package, name, TRUE );
- HeapFree( GetProcessHeap(), 0, name );
+ msi_free( name );
}
if( r == ERROR_IO_PENDING )
LPWSTR wevent = strdupAtoW(Events[i].event);
if (lstrcmpW(wevent,event)==0)
{
- HeapFree(GetProcessHeap(),0,wevent);
+ msi_free(wevent);
rc = Events[i].handler(package,argument,dialog);
return rc;
}
- HeapFree(GetProcessHeap(),0,wevent);
+ msi_free(wevent);
i++;
}
FIXME("unhandled control event %s arg(%s)\n",
create_full_pathW(install_path);
folder->State = 2;
}
- HeapFree(GetProcessHeap(), 0, install_path);
+ msi_free(install_path);
return rc;
}
CloseHandle(the_file);
TRACE("wrote %li bytes to %s\n",write,debugstr_w(source));
end:
- HeapFree(GetProcessHeap(),0,data);
+ msi_free(data);
return rc;
}
static void * cabinet_alloc(ULONG cb)
{
- return HeapAlloc(GetProcessHeap(), 0, cb);
+ return msi_alloc(cb);
}
static void cabinet_free(void *pv)
{
- HeapFree(GetProcessHeap(), 0, pv);
+ msi_free(pv);
}
static INT_PTR cabinet_open(char *pszFile, int oflag, int pmode)
given_file = strdupAtoW(pfdin->psz1);
f = get_loaded_file(data->package, given_file);
+ msi_free(given_file);
if (!f)
{
- ERR("Unknown File in Cabinent (%s)\n",debugstr_w(given_file));
- HeapFree(GetProcessHeap(),0,given_file);
+ ERR("Unknown File in Cabinet (%s)\n",debugstr_a(pfdin->psz1));
return 0;
}
if (!((f->State == 1 || f->State == 2)))
{
- TRACE("Skipping extraction of %s\n",debugstr_w(given_file));
- HeapFree(GetProcessHeap(),0,given_file);
+ TRACE("Skipping extraction of %s\n",debugstr_a(pfdin->psz1));
return 0;
}
/* track this file so it can be deleted if not installed */
trackpath=strdupAtoW(file);
tracknametmp=strdupAtoW(strrchr(file,'\\')+1);
- trackname = HeapAlloc(GetProcessHeap(),0,(strlenW(tracknametmp) +
+ trackname = msi_alloc((strlenW(tracknametmp) +
strlenW(tmpprefix)+1) * sizeof(WCHAR));
strcpyW(trackname,tmpprefix);
track_tempfile(data->package, trackname, trackpath);
- HeapFree(GetProcessHeap(),0,trackpath);
- HeapFree(GetProcessHeap(),0,trackname);
- HeapFree(GetProcessHeap(),0,tracknametmp);
+ msi_free(trackpath);
+ msi_free(trackname);
+ msi_free(tracknametmp);
/* the UI chunk */
uirow=MSI_CreateRecord(9);
MSI_RecordSetInteger( uirow, 6, f->FileSize );
ui_actiondata(data->package,szInstallFiles,uirow);
msiobj_release( &uirow->hdr );
- HeapFree(GetProcessHeap(),0,uipath);
+ msi_free(uipath);
ui_progress( data->package, 2, f->FileSize, 0, 0);
if (!(cab_path = strdupWtoA( path )))
{
FDIDestroy(hfdi);
- HeapFree(GetProcessHeap(), 0, cabinet);
+ msi_free(cabinet);
return FALSE;
}
FDIDestroy(hfdi);
- HeapFree(GetProcessHeap(), 0, cabinet);
- HeapFree(GetProcessHeap(), 0, cab_path);
+ msi_free(cabinet);
+ msi_free(cab_path);
return ret;
}
LPWSTR p;
p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
file->SourcePath = build_directory_name(2, p, file->ShortName);
- HeapFree(GetProcessHeap(),0,p);
+ msi_free(p);
}
else
file->SourcePath = build_directory_name(2, path, file->File);
prompt = MSI_RecordGetString(row,3);
msg = generate_error_string(package, 1302, 1, prompt);
rc = MessageBoxW(NULL,msg,NULL,MB_OKCANCEL);
- HeapFree(GetProcessHeap(),0,volume);
- HeapFree(GetProcessHeap(),0,msg);
+ msi_free(volume);
+ msi_free(msg);
if (rc == IDOK)
ok = check_for_sourcefile(path);
else
return ERROR_INSTALL_USEREXIT;
}
- HeapFree(GetProcessHeap(),0,last_volume);
+ msi_free(last_volume);
last_volume = strdupW(volume);
return ERROR_SUCCESS;
}
-static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file,
- MSICOMPONENT* comp)
+struct media_info {
+ UINT last_sequence;
+ LPWSTR last_volume;
+ LPWSTR last_path;
+ DWORD count;
+ WCHAR source[MAX_PATH];
+};
+
+static struct media_info *create_media_info( void )
+{
+ struct media_info *mi;
+
+ mi = msi_alloc( sizeof *mi );
+ if (mi)
+ {
+ mi->last_sequence = 0;
+ mi->last_volume = NULL;
+ mi->last_path = NULL;
+ mi->count = 0;
+ mi->source[0] = 0;
+ }
+
+ return mi;
+}
+
+static void free_media_info( struct media_info *mi )
+{
+ msi_free( mi->last_path );
+ msi_free( mi );
+}
+
+static UINT ready_media_for_file( MSIPACKAGE *package, struct media_info *mi,
+ MSIFILE *file, MSICOMPONENT* comp )
{
UINT rc = ERROR_SUCCESS;
MSIRECORD * row = 0;
- static WCHAR source[MAX_PATH];
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
'`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
LPCWSTR cab, volume;
DWORD sz;
INT seq;
- static UINT last_sequence = 0;
- static LPWSTR last_volume = NULL;
- static LPWSTR last_path = NULL;
UINT type;
LPCWSTR prompt;
- static DWORD count = 0;
- /* cleanup signal */
- if (!package)
- {
- HeapFree(GetProcessHeap(),0,last_path);
- HeapFree(GetProcessHeap(),0,last_volume);
- last_sequence = 0;
- last_path = NULL;
- last_volume = NULL;
- count = 0;
- memset(source,0,sizeof(source));
- return ERROR_SUCCESS;
- }
-
- if (file->Sequence <= last_sequence)
+ if (file->Sequence <= mi->last_sequence)
{
- set_file_source(package,file,comp,last_path);
- TRACE("Media already ready (%u, %u)\n",file->Sequence,last_sequence);
+ set_file_source(package,file,comp,mi->last_path);
+ TRACE("Media already ready (%u, %u)\n",file->Sequence,mi->last_sequence);
return ERROR_SUCCESS;
}
- count ++;
+ mi->count ++;
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence);
if (!row)
{
}
seq = MSI_RecordGetInteger(row,2);
- last_sequence = seq;
+ mi->last_sequence = seq;
volume = MSI_RecordGetString(row, 5);
prompt = MSI_RecordGetString(row, 3);
- HeapFree(GetProcessHeap(),0,last_path);
- last_path = NULL;
+ msi_free(mi->last_path);
+ mi->last_path = NULL;
if (file->Attributes & msidbFileAttributesNoncompressed)
{
- last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
- set_file_source(package,file,comp,last_path);
- rc = ready_volume(package, file->SourcePath, last_volume, row,&type);
+ mi->last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
+ set_file_source(package,file,comp,mi->last_path);
+ rc = ready_volume(package, file->SourcePath, mi->last_volume, row,&type);
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume,
prompt);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
msiobj_release(&row->hdr);
return rc;
}
{
LPWSTR path;
- writeout_cabinet_stream(package,&cab[1],source);
- last_path = strdupW(source);
- *(strrchrW(last_path,'\\')+1)=0;
+ writeout_cabinet_stream(package,&cab[1],mi->source);
+ mi->last_path = strdupW(mi->source);
+ *(strrchrW(mi->last_path,'\\')+1)=0;
- path = load_dynamic_property(package,cszSourceDir,NULL);
+ path = msi_dup_property( package, cszSourceDir );
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count,
volume, prompt);
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
INSTALLPROPERTY_LASTUSEDSOURCEW, path);
- HeapFree(GetProcessHeap(),0,path);
+ msi_free(path);
}
else
{
sz = MAX_PATH;
- last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
- if (MSI_GetPropertyW(package, cszSourceDir, source, &sz))
+ mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR));
+ if (MSI_GetPropertyW(package, cszSourceDir, mi->source, &sz))
{
ERR("No Source dir defined \n");
rc = ERROR_FUNCTION_FAILED;
}
else
{
- strcpyW(last_path,source);
- strcatW(source,cab);
+ strcpyW(mi->last_path,mi->source);
+ strcatW(mi->source,cab);
- rc = ready_volume(package, source, last_volume, row, &type);
+ rc = ready_volume(package, mi->source, mi->last_volume, row, &type);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
type == DRIVE_RAMDISK)
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
/* extract the cab file into a folder in the temp folder */
sz = MAX_PATH;
- if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz)
+ if (MSI_GetPropertyW(package, cszTempFolder,mi->last_path, &sz)
!= ERROR_SUCCESS)
- GetTempPathW(MAX_PATH,last_path);
+ GetTempPathW(MAX_PATH,mi->last_path);
}
}
- rc = !extract_cabinet_file(package, source, last_path);
+ rc = !extract_cabinet_file(package, mi->source, mi->last_path);
}
else
{
sz = MAX_PATH;
- last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
- MSI_GetPropertyW(package,cszSourceDir,source,&sz);
- strcpyW(last_path,source);
- rc = ready_volume(package, last_path, last_volume, row, &type);
+ mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR));
+ MSI_GetPropertyW(package,cszSourceDir,mi->source,&sz);
+ strcpyW(mi->last_path,mi->source);
+ rc = ready_volume(package, mi->last_path, mi->last_volume, row, &type);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
type == DRIVE_RAMDISK)
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
- INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
}
- set_file_source(package, file, comp, last_path);
+ set_file_source(package, file, comp, mi->last_path);
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume,
prompt);
msiobj_release(&row->hdr);
*/
UINT ACTION_InstallFiles(MSIPACKAGE *package)
{
+ struct media_info *mi;
UINT rc = ERROR_SUCCESS;
LPWSTR ptr;
MSIFILE *file;
{
MSICOMPONENT* comp = NULL;
- if (file->Temporary)
- continue;
-
if (!ACTION_VerifyComponentForAction(package, file->Component,
INSTALLSTATE_LOCAL))
{
}
p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
- HeapFree(GetProcessHeap(),0,file->TargetPath);
+ msi_free(file->TargetPath);
file->TargetPath = build_directory_name(2, p, file->FileName);
- HeapFree(GetProcessHeap(),0,p);
+ msi_free(p);
}
}
+ mi = create_media_info();
+
/* Pass 2 */
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
- if (file->Temporary)
- continue;
-
if ((file->State == 1) || (file->State == 2))
{
TRACE("Pass 2: %s\n",debugstr_w(file->File));
- rc = ready_media_for_file( package, file, file->Component );
+ rc = ready_media_for_file( package, mi, file, file->Component );
if (rc != ERROR_SUCCESS)
{
ERR("Unable to ready media\n");
}
/* cleanup */
- ready_media_for_file(NULL, NULL, NULL);
+ free_media_info( mi );
return rc;
}
if (rc != ERROR_SUCCESS)
{
ERR("Original file unknown %s\n",debugstr_w(file_key));
- HeapFree(GetProcessHeap(),0,file_source);
+ msi_free(file_source);
return ERROR_SUCCESS;
}
if (!dest_path)
{
/* try a Property */
- dest_path = load_dynamic_property(package, destkey, NULL);
+ dest_path = msi_dup_property( package, destkey );
if (!dest_path)
{
FIXME("Unable to get destination folder, try AppSearch properties\n");
- HeapFree(GetProcessHeap(),0,file_source);
+ msi_free(file_source);
return ERROR_SUCCESS;
}
}
FIXME("We should track these duplicate files as well\n");
- HeapFree(GetProcessHeap(),0,dest_path);
- HeapFree(GetProcessHeap(),0,dest);
- HeapFree(GetProcessHeap(),0,file_source);
+ msi_free(dest_path);
+ msi_free(dest);
+ msi_free(file_source);
return ERROR_SUCCESS;
}
count = MSI_RecordGetFieldCount(record);
- rc = HeapAlloc(GetProcessHeap(),0,(11*count)*sizeof(WCHAR));
+ rc = msi_alloc((11*count)*sizeof(WCHAR));
rc[0] = 0;
for (i = 1; i <= count; i++)
{
if (!package)
return NULL;
- ERR("POORLY HANDLED DEFORMAT.. [$componentkey] \n");
+ FIXME("component key %s\n", debugstr_w(key));
comp = get_loaded_component(package,key);
if (comp)
{
{
*sz = (size-1) * sizeof (WCHAR);
size ++;
- value = HeapAlloc(GetProcessHeap(),0,size * sizeof(WCHAR));
+ value = msi_alloc(size * sizeof(WCHAR));
GetShortPathNameW( file->TargetPath, value, size );
}
else
if (sz > 0)
{
sz++;
- value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
+ value = msi_alloc(sz * sizeof(WCHAR));
GetEnvironmentVariableW(&key[1],value,sz);
*chunk = (strlenW(value)) * sizeof(WCHAR);
}
{
LPWSTR value;
- value = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*2);
+ value = msi_alloc(sizeof(WCHAR)*2);
value[0] = 0;
*chunk = sizeof(WCHAR);
return value;
{
LPWSTR value;
- value = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*2);
+ value = msi_alloc(sizeof(WCHAR)*2);
value[0] = key[0];
*chunk = sizeof(WCHAR);
static LPWSTR deformat_property(MSIPACKAGE* package, LPCWSTR key, DWORD* chunk)
{
- UINT rc;
LPWSTR value;
if (!package)
return NULL;
- value = load_dynamic_property(package,key, &rc);
+ value = msi_dup_property( package, key );
- if (rc == ERROR_SUCCESS)
+ if (value)
*chunk = (strlenW(value)) * sizeof(WCHAR);
return value;
*mark2 = &(*mark)[i];
i = *mark2 - *mark;
- *group = HeapAlloc(GetProcessHeap(),0,i*sizeof(WCHAR));
+ *group = msi_alloc(i*sizeof(WCHAR));
i -= 1;
memcpy(*group,&(*mark)[1],i*sizeof(WCHAR));
*mark2 = &(*mark)[i-1];
i = *mark2 - *mark;
- *key = HeapAlloc(GetProcessHeap(),0,i*sizeof(WCHAR));
+ *key = msi_alloc(i*sizeof(WCHAR));
/* do not have the [] in the key */
i -= 1;
memcpy(*key,&(*mark)[1],i*sizeof(WCHAR));
static LPWSTR deformat_group(MSIPACKAGE* package, LPWSTR group, DWORD len,
MSIRECORD* record, DWORD* size)
{
- LPWSTR value;
+ LPWSTR value = NULL;
LPCWSTR mark, mark2;
LPWSTR key;
BOOL nested;
if (!find_next_outermost_key(group, len, &key, &mark, &mark2, &nested))
{
*size = (len+2)*sizeof(WCHAR);
- value = HeapAlloc(GetProcessHeap(),0,*size);
+ value = msi_alloc(*size);
sprintfW(value,fmt,group);
/* do not return size of the null at the end */
*size = (len+1)*sizeof(WCHAR);
return value;
}
- HeapFree(GetProcessHeap(),0,key);
+ msi_free(key);
failcount = 0;
sz = deformat_string_internal(package, group, &value, strlenW(group),
record, &failcount);
{
LPWSTR v2;
- v2 = HeapAlloc(GetProcessHeap(),0,(sz+2)*sizeof(WCHAR));
+ v2 = msi_alloc((sz+2)*sizeof(WCHAR));
v2[0] = '{';
memcpy(&v2[1],value,sz*sizeof(WCHAR));
v2[sz+1]='}';
- HeapFree(GetProcessHeap(),0,value);
+ msi_free(value);
*size = (sz+2)*sizeof(WCHAR);
return v2;
}
else
{
+ msi_free(value);
*size = 0;
return NULL;
}
(scanW(ptr,'{',len) && !scanW(ptr,'}',len)))
{
/* not formatted */
- *data = HeapAlloc(GetProcessHeap(),0,(len*sizeof(WCHAR)));
+ *data = msi_alloc((len*sizeof(WCHAR)));
memcpy(*data,ptr,len*sizeof(WCHAR));
TRACE("Returning %s\n",debugstr_wn(*data,len));
return len;
{
value = deformat_group(package, key, strlenW(key)+1, record,
&chunk);
+ msi_free( key );
key = NULL;
nested = FALSE;
}
chunk = (len - (progress - ptr)) * sizeof(WCHAR);
TRACE("after chunk is %li + %li\n",size,chunk);
if (size)
- nd2 = HeapReAlloc(GetProcessHeap(),0,newdata,(size+chunk));
+ nd2 = msi_realloc(newdata,(size+chunk));
else
- nd2 = HeapAlloc(GetProcessHeap(),0,chunk);
+ nd2 = msi_alloc(chunk);
newdata = nd2;
memcpy(&newdata[size],progress,chunk);
TRACE("%i (%i) characters before marker\n",cnt,(mark-progress));
size += cnt * sizeof(WCHAR);
if (!old_size)
- tgt = HeapAlloc(GetProcessHeap(),0,size);
+ tgt = msi_alloc(size);
else
- tgt = HeapReAlloc(GetProcessHeap(),0,newdata,size);
+ tgt = msi_realloc(newdata,size);
newdata = tgt;
memcpy(&newdata[old_size],progress,(cnt * sizeof(WCHAR)));
}
deformat_string_internal(package, key, &value, strlenW(key)+1,
record, failcount);
- HeapFree(GetProcessHeap(),0,key);
+ msi_free(key);
key = value;
}
{
DWORD keylen = strlenW(key);
chunk = (keylen + 2)*sizeof(WCHAR);
- value = HeapAlloc(GetProcessHeap(),0,chunk);
+ value = msi_alloc(chunk);
value[0] = '[';
memcpy(&value[1],key,keylen*sizeof(WCHAR));
value[1+keylen] = ']';
else
{
static const WCHAR fmt[] = {'[','%','s',']',0};
- value = HeapAlloc(GetProcessHeap(),0,10);
+ value = msi_alloc(10);
sprintfW(value,fmt,key);
chunk = strlenW(value)*sizeof(WCHAR);
}
}
}
- HeapFree(GetProcessHeap(),0,key);
+ msi_free(key);
if (value!=NULL)
{
TRACE("value %s, chunk %li size %li\n",debugstr_w((LPWSTR)value),
chunk, size);
if (size)
- nd2= HeapReAlloc(GetProcessHeap(),0,newdata,(size + chunk));
+ nd2= msi_realloc(newdata,(size + chunk));
else
- nd2= HeapAlloc(GetProcessHeap(),0,chunk);
+ nd2= msi_alloc(chunk);
newdata = nd2;
memcpy(&newdata[size],value,chunk);
size+=chunk;
- HeapFree(GetProcessHeap(),0,value);
+ msi_free(value);
}
else if (failcount && *failcount >=0 )
(*failcount)++;
*size = len;
- HeapFree(GetProcessHeap(),0,rec);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(rec);
+ msi_free(deformated);
return rc;
}
*size = lenA;
- HeapFree(GetProcessHeap(),0,rec);
- HeapFree(GetProcessHeap(),0,deformated);
+ msi_free(rec);
+ msi_free(deformated);
return rc;
}
0, 0, &MSI_handle_cs,
{ &MSI_handle_cs_debug.ProcessLocksList,
&MSI_handle_cs_debug.ProcessLocksList },
- 0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
+ 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_handle_cs") }
};
static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
0, 0, &MSI_object_cs,
{ &MSI_object_cs_debug.ProcessLocksList,
&MSI_object_cs_debug.ProcessLocksList },
- 0, 0, { 0, (DWORD)(__FILE__ ": MSI_object_cs") }
+ 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_object_cs") }
};
static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 };
return (void*) ret;
}
-MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
-{
- MSIHANDLE ret = 0;
- UINT i;
-
- TRACE("%p\n", hdr);
-
- EnterCriticalSection( &MSI_handle_cs );
- for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
- if( msihandletable[i].obj == hdr )
- ret = i+1;
- LeaveCriticalSection( &MSI_handle_cs );
-
- TRACE("%p -> %ld\n", hdr, ret);
-
- msiobj_addref( hdr );
- return ret;
-}
-
void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
{
MSIOBJECTHDR *info;
- info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
+ info = msi_alloc_zero( size );
if( info )
{
info->magic = MSIHANDLE_MAGIC;
{
if( info->destructor )
info->destructor( info );
- HeapFree( GetProcessHeap(), 0, info );
+ msi_free( info );
TRACE("object %p destroyed\n", info);
}
return rc;
}
-UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
- LPWSTR *FilePath)
+LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
{
- LPWSTR SystemFolder;
- LPWSTR dest;
+ LPWSTR SystemFolder, dest, FilePath;
static const WCHAR szInstaller[] =
{'M','i','c','r','o','s','o','f','t','\\',
static const WCHAR szFolder[] =
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- SystemFolder = load_dynamic_property(package,szFolder,NULL);
+ SystemFolder = msi_dup_property( package, szFolder );
dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode);
create_full_pathW(dest);
- *FilePath = build_directory_name(2, dest, icon_name);
+ FilePath = build_directory_name(2, dest, icon_name);
- HeapFree(GetProcessHeap(),0,SystemFolder);
- HeapFree(GetProcessHeap(),0,dest);
- return ERROR_SUCCESS;
+ msi_free(SystemFolder);
+ msi_free(dest);
+ return FilePath;
}
WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
/* having an empty string is different than NULL */
if (sz == 0)
{
- ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));
+ ret = msi_alloc(sizeof(WCHAR));
ret[0] = 0;
return ret;
}
sz ++;
- ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
+ ret = msi_alloc(sz * sizeof (WCHAR));
rc = MSI_RecordGetStringW(row,index,ret,&sz);
if (rc!=ERROR_SUCCESS)
{
ERR("Unable to load dynamic string\n");
- HeapFree(GetProcessHeap(), 0, ret);
+ msi_free(ret);
ret = NULL;
}
return ret;
}
-LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc)
+LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop)
{
DWORD sz = 0;
LPWSTR str;
r = MSI_GetPropertyW(package, prop, NULL, &sz);
if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
- {
- if (rc)
- *rc = r;
return NULL;
- }
+
sz++;
- str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+ str = msi_alloc(sz*sizeof(WCHAR));
r = MSI_GetPropertyW(package, prop, str, &sz);
if (r != ERROR_SUCCESS)
{
- HeapFree(GetProcessHeap(),0,str);
+ msi_free(str);
str = NULL;
}
- if (rc)
- *rc = r;
return str;
}
int track_tempfile( MSIPACKAGE *package, LPCWSTR name, LPCWSTR path )
{
- MSIFILE *file;
+ MSITEMPFILE *temp;
if (!package)
- return -2;
+ return -1;
+
+ LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
+ {
+ if (lstrcmpW( name, temp->File )==0)
+ {
+ TRACE("tempfile %s already exists with path %s\n",
+ debugstr_w(temp->File), debugstr_w(temp->Path));
+ return -1;
+ }
+ }
- file = get_loaded_file( package, name );
- if (file)
+ temp = msi_alloc_zero( sizeof (MSITEMPFILE) );
+ if (!temp)
return -1;
- file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFILE) );
+ list_add_head( &package->tempfiles, &temp->entry );
- file->File = strdupW( name );
- file->TargetPath = strdupW( path );
- file->Temporary = TRUE;
+ temp->File = strdupW( name );
+ temp->Path = strdupW( path );
- TRACE("Tracking tempfile (%s)\n", debugstr_w( file->File ));
+ TRACE("adding tempfile %s with path %s\n",
+ debugstr_w(temp->File), debugstr_w(temp->Path));
return 0;
}
if (!source)
{
LPWSTR check_path;
- check_path = load_dynamic_property(package,cszTargetDir,NULL);
+ check_path = msi_dup_property( package, cszTargetDir );
if (!check_path)
{
- check_path = load_dynamic_property(package,cszRootDrive,NULL);
+ check_path = msi_dup_property( package, cszRootDrive );
if (set_prop)
MSI_SetPropertyW(package,cszTargetDir,check_path);
}
path = build_directory_name(2, check_path, NULL);
if (strcmpiW(path,check_path)!=0)
MSI_SetPropertyW(package,cszTargetDir,path);
+ msi_free(check_path);
}
else
{
- path = load_dynamic_property(package,cszSourceDir,NULL);
+ path = msi_dup_property( package, cszSourceDir );
if (!path)
{
- path = load_dynamic_property(package,cszDatabase,NULL);
+ path = msi_dup_property( package, cszDatabase );
if (path)
{
p = strrchrW(path,'\\');
TRACE(" (source)resolved into %s\n",debugstr_w(path));
f->ResolvedSource = strdupW( path );
}
- HeapFree(GetProcessHeap(),0,p);
+ msi_free(p);
}
return path;
}
if (size >= 0)
{
size++;
- *data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
+ *data = msi_alloc(size*sizeof(WCHAR));
if (size > 1)
MSI_FormatRecordW(package,rec,*data,&size);
else
count = package->script->ActionCount[script];
package->script->ActionCount[script]++;
if (count != 0)
- newbuf = HeapReAlloc(GetProcessHeap(),0,
- package->script->Actions[script],
+ newbuf = msi_realloc( package->script->Actions[script],
package->script->ActionCount[script]* sizeof(LPWSTR));
else
- newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(LPWSTR));
+ newbuf = msi_alloc( sizeof(LPWSTR));
newbuf[count] = strdupW(action);
package->script->Actions[script] = newbuf;
static void remove_tracked_tempfiles(MSIPACKAGE* package)
{
- MSIFILE *file;
-
- if (!package)
- return;
+ struct list *item, *cursor;
- LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
+ LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
{
- if (file->Temporary)
- {
- TRACE("Cleaning up %s\n", debugstr_w( file->TargetPath ));
- DeleteFileW( file->TargetPath );
- }
+ MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
+
+ list_remove( &temp->entry );
+ TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
+ DeleteFileW( temp->Path );
+ msi_free( temp->File );
+ msi_free( temp->Path );
+ msi_free( temp );
}
}
{
ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
list_remove( &cl->entry );
- HeapFree( GetProcessHeap(), 0, cl );
- }
- HeapFree( GetProcessHeap(), 0, feature );
+ msi_free( cl );
+ }
+ msi_free( feature->Feature );
+ msi_free( feature->Feature_Parent );
+ msi_free( feature->Directory );
+ msi_free( feature->Description );
+ msi_free( feature->Title );
+ msi_free( feature );
}
+void free_extension( MSIEXTENSION *ext )
+{
+ struct list *item, *cursor;
+
+ LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
+ {
+ MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
+
+ list_remove( &verb->entry );
+ msi_free( verb->Verb );
+ msi_free( verb->Command );
+ msi_free( verb->Argument );
+ msi_free( verb );
+ }
+
+ msi_free( ext->Extension );
+ msi_free( ext->ProgIDText );
+ msi_free( ext );
+}
/* Called when the package is being closed */
void ACTION_free_package_structures( MSIPACKAGE* package)
MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
list_remove( &folder->entry );
- HeapFree( GetProcessHeap(), 0, folder->Directory );
- HeapFree( GetProcessHeap(), 0, folder->TargetDefault );
- HeapFree( GetProcessHeap(), 0, folder->SourceDefault );
- HeapFree( GetProcessHeap(), 0, folder->ResolvedTarget );
- HeapFree( GetProcessHeap(), 0, folder->ResolvedSource );
- HeapFree( GetProcessHeap(), 0, folder->Property );
+ msi_free( folder->Directory );
+ msi_free( folder->TargetDefault );
+ msi_free( folder->SourceDefault );
+ msi_free( folder->ResolvedTarget );
+ msi_free( folder->ResolvedSource );
+ msi_free( folder->Property );
+ msi_free( folder );
}
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
list_remove( &comp->entry );
- HeapFree( GetProcessHeap(), 0, comp->FullKeypath );
- HeapFree( GetProcessHeap(), 0, comp );
+ msi_free( comp->Component );
+ msi_free( comp->ComponentId );
+ msi_free( comp->Directory );
+ msi_free( comp->Condition );
+ msi_free( comp->KeyPath );
+ msi_free( comp->FullKeypath );
+ msi_free( comp );
}
LIST_FOR_EACH_SAFE( item, cursor, &package->files )
MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
list_remove( &file->entry );
- HeapFree( GetProcessHeap(), 0, file->File );
- HeapFree( GetProcessHeap(), 0, file->FileName );
- HeapFree( GetProcessHeap(), 0, file->ShortName );
- HeapFree( GetProcessHeap(), 0, file->Version );
- HeapFree( GetProcessHeap(), 0, file->Language );
- HeapFree( GetProcessHeap(), 0, file->SourcePath );
- HeapFree( GetProcessHeap(), 0, file->TargetPath );
- HeapFree( GetProcessHeap(), 0, file );
+ msi_free( file->File );
+ msi_free( file->FileName );
+ msi_free( file->ShortName );
+ msi_free( file->Version );
+ msi_free( file->Language );
+ msi_free( file->SourcePath );
+ msi_free( file->TargetPath );
+ msi_free( file );
}
/* clean up extension, progid, class and verb structures */
MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
list_remove( &cls->entry );
- HeapFree( GetProcessHeap(), 0, cls->Description );
- HeapFree( GetProcessHeap(), 0, cls->FileTypeMask );
- HeapFree( GetProcessHeap(), 0, cls->IconPath );
- HeapFree( GetProcessHeap(), 0, cls->DefInprocHandler );
- HeapFree( GetProcessHeap(), 0, cls->DefInprocHandler32 );
- HeapFree( GetProcessHeap(), 0, cls->Argument );
- HeapFree( GetProcessHeap(), 0, cls->ProgIDText );
- HeapFree( GetProcessHeap(), 0, cls );
+ msi_free( cls->clsid );
+ msi_free( cls->Context );
+ msi_free( cls->Description );
+ msi_free( cls->FileTypeMask );
+ msi_free( cls->IconPath );
+ msi_free( cls->DefInprocHandler );
+ msi_free( cls->DefInprocHandler32 );
+ msi_free( cls->Argument );
+ msi_free( cls->ProgIDText );
+ msi_free( cls );
}
LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
list_remove( &ext->entry );
- HeapFree( GetProcessHeap(), 0, ext->ProgIDText );
- HeapFree( GetProcessHeap(), 0, ext );
+ free_extension( ext );
}
- for (i = 0; i < package->loaded_progids; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
{
- HeapFree(GetProcessHeap(),0,package->progids[i].ProgID);
- HeapFree(GetProcessHeap(),0,package->progids[i].Description);
- HeapFree(GetProcessHeap(),0,package->progids[i].IconPath);
- }
-
- if (package->progids && package->loaded_progids > 0)
- HeapFree(GetProcessHeap(),0,package->progids);
+ MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );
- for (i = 0; i < package->loaded_verbs; i++)
- {
- HeapFree(GetProcessHeap(),0,package->verbs[i].Verb);
- HeapFree(GetProcessHeap(),0,package->verbs[i].Command);
- HeapFree(GetProcessHeap(),0,package->verbs[i].Argument);
+ list_remove( &progid->entry );
+ msi_free( progid->ProgID );
+ msi_free( progid->Description );
+ msi_free( progid->IconPath );
+ msi_free( progid );
}
- if (package->verbs && package->loaded_verbs > 0)
- HeapFree(GetProcessHeap(),0,package->verbs);
-
LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
{
MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
list_remove( &mt->entry );
- HeapFree( GetProcessHeap(), 0, mt->ContentType );
- HeapFree( GetProcessHeap(), 0, mt );
+ msi_free( mt->clsid );
+ msi_free( mt->ContentType );
+ msi_free( mt );
}
LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
list_remove( &appid->entry );
- HeapFree( GetProcessHeap(), 0, appid->RemoteServerName );
- HeapFree( GetProcessHeap(), 0, appid->LocalServer );
- HeapFree( GetProcessHeap(), 0, appid->ServiceParameters );
- HeapFree( GetProcessHeap(), 0, appid->DllSurrogate );
- HeapFree( GetProcessHeap(), 0, appid );
+ msi_free( appid->AppID );
+ msi_free( appid->RemoteServerName );
+ msi_free( appid->LocalServer );
+ msi_free( appid->ServiceParameters );
+ msi_free( appid->DllSurrogate );
+ msi_free( appid );
}
if (package->script)
{
int j;
for (j = 0; j < package->script->ActionCount[i]; j++)
- HeapFree(GetProcessHeap(),0,package->script->Actions[i][j]);
+ msi_free(package->script->Actions[i][j]);
- HeapFree(GetProcessHeap(),0,package->script->Actions[i]);
+ msi_free(package->script->Actions[i]);
}
for (i = 0; i < package->script->UniqueActionsCount; i++)
- HeapFree(GetProcessHeap(),0,package->script->UniqueActions[i]);
+ msi_free(package->script->UniqueActions[i]);
- HeapFree(GetProcessHeap(),0,package->script->UniqueActions);
- HeapFree(GetProcessHeap(),0,package->script);
+ msi_free(package->script->UniqueActions);
+ msi_free(package->script);
}
- HeapFree(GetProcessHeap(),0,package->PackagePath);
- HeapFree(GetProcessHeap(),0,package->msiFilePath);
- HeapFree(GetProcessHeap(),0,package->ProductCode);
+ msi_free(package->PackagePath);
+ msi_free(package->ProductCode);
+ msi_free(package->ActionFormat);
+ msi_free(package->LastAction);
/* cleanup control event subscriptions */
ControlEvent_CleanupSubscriptions(package);
}
va_end(va);
- dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
+ dir = msi_alloc(sz*sizeof(WCHAR));
dir[0]=0;
va_start(va,count);
int len;
WCHAR *new_path;
- new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) *
- sizeof(WCHAR));
+ new_path = msi_alloc( (strlenW(path) + 1) * sizeof(WCHAR));
strcpyW(new_path, path);
new_path[len] = '\\';
}
- HeapFree(GetProcessHeap(), 0, new_path);
+ msi_free(new_path);
return ret;
}
}
/* update the cached actionformat */
- HeapFree(GetProcessHeap(),0,package->ActionFormat);
+ msi_free(package->ActionFormat);
package->ActionFormat = load_dynamic_stringW(row,3);
- HeapFree(GetProcessHeap(),0,package->LastAction);
+ msi_free(package->LastAction);
package->LastAction = strdupW(action);
msiobj_release(&row->hdr);
BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, MSICOMPONENT* comp,
INSTALLSTATE check )
{
+ if (!comp)
+ return FALSE;
+
if (comp->Installed == check)
return FALSE;
BOOL ACTION_VerifyFeatureForAction( MSIFEATURE* feature, INSTALLSTATE check )
{
+ if (!feature)
+ return FALSE;
+
if (feature->Installed == check)
return FALSE;
sz+=3;
sz *= sizeof(WCHAR);
- output = HeapAlloc(GetProcessHeap(),0,sz);
+ output = msi_alloc(sz);
memset(output,0,sz);
if (component)
if (!component->Enabled)
continue;
- else
+
+ if (newstate == INSTALLSTATE_LOCAL)
{
- if (newstate == INSTALLSTATE_LOCAL)
- {
- component->ActionRequest = INSTALLSTATE_LOCAL;
- component->Action = INSTALLSTATE_LOCAL;
- }
- else
- {
- ComponentList *clist;
- MSIFEATURE *f;
+ component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
+ }
+ else
+ {
+ ComponentList *clist;
+ MSIFEATURE *f;
- component->ActionRequest = newstate;
- component->Action = newstate;
+ component->ActionRequest = newstate;
+ component->Action = newstate;
- /*if any other feature wants is local we need to set it local*/
- LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
- {
- if ( component->ActionRequest != INSTALLSTATE_LOCAL )
- break;
+ /*if any other feature wants is local we need to set it local*/
+ LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
+ {
+ if ( component->ActionRequest != INSTALLSTATE_LOCAL )
+ break;
- LIST_FOR_EACH_ENTRY( clist, &f->Components, ComponentList, entry )
+ LIST_FOR_EACH_ENTRY( clist, &f->Components, ComponentList, entry )
+ {
+ if ( clist->component == component )
{
- if ( clist->component == component )
+ if (f->ActionRequest == INSTALLSTATE_LOCAL)
{
- if (f->ActionRequest == INSTALLSTATE_LOCAL)
- {
- TRACE("Saved by %s\n", debugstr_w(f->Feature));
- component->ActionRequest = INSTALLSTATE_LOCAL;
- component->Action = INSTALLSTATE_LOCAL;
- }
- break;
+ TRACE("Saved by %s\n", debugstr_w(f->Feature));
+ component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
}
+ break;
}
}
}
count = package->script->UniqueActionsCount;
package->script->UniqueActionsCount++;
if (count != 0)
- newbuf = HeapReAlloc(GetProcessHeap(),0,
- package->script->UniqueActions,
+ newbuf = msi_realloc( package->script->UniqueActions,
package->script->UniqueActionsCount* sizeof(LPWSTR));
else
- newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(LPWSTR));
+ newbuf = msi_alloc( sizeof(LPWSTR));
newbuf[count] = strdupW(action);
package->script->UniqueActions = newbuf;
- return ERROR_SUCCESS;
+ return ERROR_SUCCESS;
}
BOOL check_unique_action(MSIPACKAGE *package, LPCWSTR action)
if (size >= 0)
{
size++;
- data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
+ data = msi_alloc(size*sizeof(WCHAR));
if (size > 1)
MSI_FormatRecordW(package,rec,data,&size);
else
if( sv )
sv->ops->delete( sv );
msiobj_release( &iv->db->hdr );
- HeapFree( GetProcessHeap(), 0, iv );
+ msi_free( iv );
return ERROR_SUCCESS;
}
return r;
}
- iv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *iv );
+ iv = msi_alloc_zero( sizeof *iv );
if( !iv )
return ERROR_FUNCTION_FAILED;
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{
LPWSTR szwAction;
- UINT rc;
+ UINT ret;
- TRACE(" exteral attempt at action %s\n",szAction);
-
- if (!szAction)
- return ERROR_FUNCTION_FAILED;
- if (hInstall == 0)
- return ERROR_FUNCTION_FAILED;
+ TRACE("%s\n", debugstr_a(szAction));
szwAction = strdupAtoW(szAction);
-
- if (!szwAction)
+ if (szAction && !szwAction)
return ERROR_FUNCTION_FAILED;
-
- rc = MsiDoActionW(hInstall, szwAction);
- HeapFree(GetProcessHeap(),0,szwAction);
- return rc;
+ ret = MsiDoActionW( hInstall, szwAction );
+ msi_free( szwAction );
+ return ret;
}
/***********************************************************************
UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
{
MSIPACKAGE *package;
- UINT ret = ERROR_INVALID_HANDLE;
+ UINT ret;
- TRACE(" external attempt at action %s \n",debugstr_w(szAction));
+ TRACE("%s\n",debugstr_w(szAction));
+
+ if (!szAction)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ ret = ACTION_PerformUIAction( package, szAction );
+ msiobj_release( &package->hdr );
- package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
- if( package )
- {
- ret = ACTION_PerformUIAction(package,szAction);
- msiobj_release( &package->hdr );
- }
return ret;
}
/***********************************************************************
- * MsiGetTargetPathA (MSI.@)
+ * MsiSequenceA (MSI.@)
*/
-UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
- LPSTR szPathBuf, DWORD* pcchPathBuf)
+UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
{
- LPWSTR szwFolder;
- LPWSTR szwPathBuf;
- UINT rc;
-
- TRACE("getting folder %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);
+ LPWSTR szwTable;
+ UINT ret;
- if (!szFolder)
- return ERROR_FUNCTION_FAILED;
- if (hInstall == 0)
- return ERROR_FUNCTION_FAILED;
+ TRACE("%s\n", debugstr_a(szTable));
- szwFolder = strdupAtoW(szFolder);
-
- if (!szwFolder)
+ szwTable = strdupAtoW(szTable);
+ if (szTable && !szwTable)
return ERROR_FUNCTION_FAILED;
- szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));
-
- rc = MsiGetTargetPathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);
-
- WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,
- *pcchPathBuf, NULL, NULL );
-
- HeapFree(GetProcessHeap(),0,szwFolder);
- HeapFree(GetProcessHeap(),0,szwPathBuf);
-
- return rc;
+ ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
+ msi_free( szwTable );
+ return ret;
}
/***********************************************************************
-* MsiGetTargetPathW (MSI.@)
-*/
-UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
- szPathBuf, DWORD* pcchPathBuf)
+ * MsiSequenceW (MSI.@)
+ */
+UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
{
- LPWSTR path;
- UINT rc = ERROR_FUNCTION_FAILED;
MSIPACKAGE *package;
+ UINT ret;
- TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
+ TRACE("%s\n", debugstr_w(szTable));
- package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
if (!package)
return ERROR_INVALID_HANDLE;
- path = resolve_folder(package, szFolder, FALSE, FALSE, NULL);
+
+ ret = MSI_Sequence( package, szTable, iSequenceMode );
msiobj_release( &package->hdr );
+
+ return ret;
+}
- if (path && (strlenW(path) > *pcchPathBuf))
+static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
+{
+ UINT len, r = ERROR_SUCCESS;
+
+ if (awbuf->str.w && !sz )
+ return ERROR_INVALID_PARAMETER;
+
+ if (!sz)
+ return r;
+
+ if (awbuf->unicode)
{
- *pcchPathBuf = strlenW(path)+1;
- rc = ERROR_MORE_DATA;
+ len = lstrlenW( str );
+ if (awbuf->str.w)
+ lstrcpynW( awbuf->str.w, str, *sz );
}
- else if (path)
+ else
{
- *pcchPathBuf = strlenW(path)+1;
- strcpyW(szPathBuf,path);
- TRACE("Returning Path %s\n",debugstr_w(path));
- rc = ERROR_SUCCESS;
+ len = WideCharToMultiByte( CP_ACP, 0, str, -1,
+ awbuf->str.a, *sz, NULL, NULL );
+ len--;
}
- HeapFree(GetProcessHeap(),0,path);
-
- return rc;
+
+ if (len >= *sz)
+ r = ERROR_MORE_DATA;
+ *sz = len;
+ return r;
}
+/***********************************************************************
+ * MsiGetTargetPath (internal)
+ */
+UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
+ awstring *szPathBuf, DWORD* pcchPathBuf )
+{
+ MSIPACKAGE *package;
+ LPWSTR path;
+ UINT r;
+
+ if (!szFolder)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
+ msiobj_release( &package->hdr );
+
+ if (!path)
+ return ERROR_DIRECTORY;
+
+ r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
+ msi_free( path );
+ return r;
+}
/***********************************************************************
-* MsiGetSourcePathA (MSI.@)
-*/
-UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
- LPSTR szPathBuf, DWORD* pcchPathBuf)
+ * MsiGetTargetPathA (MSI.@)
+ */
+UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
+ LPSTR szPathBuf, DWORD* pcchPathBuf )
{
LPWSTR szwFolder;
- LPWSTR szwPathBuf;
- UINT rc;
-
- TRACE("getting source %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);
+ awstring path;
+ UINT r;
- if (!szFolder)
- return ERROR_FUNCTION_FAILED;
- if (hInstall == 0)
- return ERROR_FUNCTION_FAILED;
+ TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
szwFolder = strdupAtoW(szFolder);
- if (!szwFolder)
+ if (szFolder && !szwFolder)
return ERROR_FUNCTION_FAILED;
- szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));
+ path.unicode = FALSE;
+ path.str.a = szPathBuf;
- rc = MsiGetSourcePathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);
+ r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
- WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,
- *pcchPathBuf, NULL, NULL );
+ msi_free( szwFolder );
- HeapFree(GetProcessHeap(),0,szwFolder);
- HeapFree(GetProcessHeap(),0,szwPathBuf);
+ return r;
+}
- return rc;
+/***********************************************************************
+ * MsiGetTargetPathW (MSI.@)
+ */
+UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
+ LPWSTR szPathBuf, DWORD* pcchPathBuf )
+{
+ awstring path;
+
+ TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
+
+ path.unicode = TRUE;
+ path.str.w = szPathBuf;
+
+ return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
}
/***********************************************************************
-* MsiGetSourcePathW (MSI.@)
-*/
-UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
- szPathBuf, DWORD* pcchPathBuf)
+ * MsiGetSourcePath (internal)
+ */
+static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
+ awstring *szPathBuf, DWORD* pcchPathBuf )
{
- LPWSTR path;
- UINT rc = ERROR_FUNCTION_FAILED;
MSIPACKAGE *package;
+ LPWSTR path;
+ UINT r;
- TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
+ TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
+
+ if (!szFolder)
+ return ERROR_INVALID_PARAMETER;
package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
- if( !package )
+ if (!package)
return ERROR_INVALID_HANDLE;
- path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
- msiobj_release( &package->hdr );
- if (path && strlenW(path) > *pcchPathBuf)
+ if (szPathBuf->str.w && !pcchPathBuf )
{
- *pcchPathBuf = strlenW(path)+1;
- rc = ERROR_MORE_DATA;
- }
- else if (path)
- {
- *pcchPathBuf = strlenW(path)+1;
- strcpyW(szPathBuf,path);
- TRACE("Returning Path %s\n",debugstr_w(path));
- rc = ERROR_SUCCESS;
+ msiobj_release( &package->hdr );
+ return ERROR_INVALID_PARAMETER;
}
- HeapFree(GetProcessHeap(),0,path);
-
- return rc;
+
+ path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
+ msiobj_release( &package->hdr );
+
+ TRACE("path = %s\n",debugstr_w(path));
+ if (!path)
+ return ERROR_DIRECTORY;
+
+ r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
+ msi_free( path );
+ return r;
}
+/***********************************************************************
+ * MsiGetSourcePathA (MSI.@)
+ */
+UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
+ LPSTR szPathBuf, DWORD* pcchPathBuf )
+{
+ LPWSTR folder;
+ awstring str;
+ UINT r;
+
+ TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
+
+ str.unicode = FALSE;
+ str.str.a = szPathBuf;
+
+ folder = strdupAtoW( szFolder );
+ r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
+ msi_free( folder );
+
+ return r;
+}
+
+/***********************************************************************
+ * MsiGetSourcePathW (MSI.@)
+ */
+UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
+ LPWSTR szPathBuf, DWORD* pcchPathBuf )
+{
+ awstring str;
+
+ TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
+
+ str.unicode = TRUE;
+ str.str.w = szPathBuf;
+
+ return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
+}
/***********************************************************************
* MsiSetTargetPathA (MSI.@)
szwFolderPath = strdupAtoW(szFolderPath);
if (!szwFolderPath)
{
- HeapFree(GetProcessHeap(),0,szwFolder);
+ msi_free(szwFolder);
return ERROR_FUNCTION_FAILED;
}
rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);
- HeapFree(GetProcessHeap(),0,szwFolder);
- HeapFree(GetProcessHeap(),0,szwFolderPath);
+ msi_free(szwFolder);
+ msi_free(szwFolderPath);
return rc;
}
RemoveDirectoryW(szFolderPath);
}
- HeapFree(GetProcessHeap(),0,folder->Property);
+ msi_free(folder->Property);
folder->Property = build_directory_name(2, szFolderPath, NULL);
if (lstrcmpiW(path, folder->Property) == 0)
* Resolved Target has not really changed, so just
* set this folder and do not recalculate everything.
*/
- HeapFree(GetProcessHeap(),0,folder->ResolvedTarget);
+ msi_free(folder->ResolvedTarget);
folder->ResolvedTarget = NULL;
path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
- HeapFree(GetProcessHeap(),0,path2);
+ msi_free(path2);
}
else
{
LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
{
- HeapFree( GetProcessHeap(),0,f->ResolvedTarget);
+ msi_free(f->ResolvedTarget);
f->ResolvedTarget=NULL;
}
LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
{
path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
- HeapFree(GetProcessHeap(),0,path2);
+ msi_free(path2);
}
}
- HeapFree(GetProcessHeap(),0,path);
+ msi_free(path);
return ERROR_SUCCESS;
}
rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
- HeapFree(GetProcessHeap(),0,szwFeature);
+ msi_free(szwFeature);
return rc;
}
rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
- HeapFree( GetProcessHeap(), 0 , szwFeature);
+ msi_free( szwFeature);
return rc;
}
rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
- HeapFree(GetProcessHeap(), 0, szwComponent);
+ msi_free(szwComponent);
return rc;
}
rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
- HeapFree( GetProcessHeap(), 0 , szwComponent);
+ msi_free( szwComponent);
return rc;
}
if (!package)
return ERROR_INVALID_HANDLE;
- buffer = load_dynamic_property(package,szProductLanguage,NULL);
+ buffer = msi_dup_property( package, szProductLanguage );
langid = atoiW(buffer);
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
msiobj_release (&package->hdr);
return langid;
}
r = MsiOpenProductW( szwProd, phProduct );
- HeapFree( GetProcessHeap(), 0, szwProd );
+ msi_free( szwProd );
return r;
}
-UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
+static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
{
LPWSTR path = NULL;
UINT r;
HKEY hKeyProduct = NULL;
DWORD count, type;
- TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
+ TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
if( r != ERROR_SUCCESS )
}
/* now alloc and fetch the path of the database to open */
- path = HeapAlloc( GetProcessHeap(), 0, count );
+ path = msi_alloc( count );
if( !path )
goto end;
goto end;
}
- r = MsiOpenPackageW( path, phProduct );
+ r = MSI_OpenPackageW( path, ppackage );
end:
- HeapFree( GetProcessHeap(), 0, path );
+ msi_free( path );
if( hKeyProduct )
RegCloseKey( hKeyProduct );
return r;
}
+UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
+{
+ MSIPACKAGE *package = NULL;
+ UINT r;
+
+ r = MSI_OpenProductW( szProduct, &package );
+ if( r == ERROR_SUCCESS )
+ {
+ *phProduct = alloc_msihandle( &package->hdr );
+ msiobj_release( &package->hdr );
+ }
+ return r;
+}
+
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
LPCSTR szTransforms, LANGID lgidLanguage)
{
r = MsiInstallProductW( szwPath, szwCommand );
end:
- HeapFree( GetProcessHeap(), 0, szwPath );
- HeapFree( GetProcessHeap(), 0, szwCommand );
+ msi_free( szwPath );
+ msi_free( szwCommand );
return r;
}
{
MSIPACKAGE *package = NULL;
UINT r;
- MSIHANDLE handle;
- WCHAR path[MAX_PATH];
- WCHAR filename[MAX_PATH];
- static const WCHAR szMSI[] = {'M','S','I',0};
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
- r = MsiVerifyPackageW(szPackagePath);
- if (r != ERROR_SUCCESS)
- return r;
-
- /* copy the msi file to a temp file to pervent locking a CD
- * with a multi disc install
- */
- GetTempPathW(MAX_PATH, path);
- GetTempFileNameW(path, szMSI, 0, filename);
-
- CopyFileW(szPackagePath, filename, FALSE);
-
- TRACE("Opening relocated package %s\n",debugstr_w(filename));
- r = MSI_OpenPackageW(filename, &package);
- if (r != ERROR_SUCCESS)
+ r = MSI_OpenPackageW( szPackagePath, &package );
+ if (r == ERROR_SUCCESS)
{
- DeleteFileW(filename);
- return r;
+ r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
+ msiobj_release( &package->hdr );
}
- handle = alloc_msihandle( &package->hdr );
-
- r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine,
- filename);
-
- MsiCloseHandle(handle);
- msiobj_release( &package->hdr );
-
- DeleteFileW(filename);
return r;
}
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
- MSIHANDLE handle = -1;
- MSIPACKAGE* package;
- UINT rc;
+ MSIPACKAGE* package = NULL;
+ UINT r;
DWORD sz;
WCHAR sourcepath[MAX_PATH];
WCHAR filename[MAX_PATH];
MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
- strcatW(sourcepath,filename);
+ lstrcatW(sourcepath,filename);
/*
* ok 1, we need to find the msi file for this product.
* 4, cleanupany runonce entry.
*/
- rc = MsiOpenProductW(szProduct,&handle);
- if (rc != ERROR_SUCCESS)
- goto end;
-
- package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
- if (!package)
- {
- rc = ERROR_INVALID_HANDLE;
- goto end;
- }
+ r = MSI_OpenProductW( szProduct, &package );
+ if (r != ERROR_SUCCESS)
+ return r;
- sz = lstrlenW(szInstalled);
+ sz = lstrlenW(szInstalled) + 1;
if (szCommandLine)
sz += lstrlenW(szCommandLine);
- commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
+ commandline = msi_alloc(sz * sizeof(WCHAR));
+ if (!commandline )
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto end;
+ }
+ commandline[0] = 0;
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
- else
- commandline[0] = 0;
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
lstrcatW(commandline,szInstalled);
- rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
+ r = MSI_InstallPackage( package, sourcepath, commandline );
- msiobj_release( &package->hdr );
+ msi_free(commandline);
- HeapFree(GetProcessHeap(),0,commandline);
end:
- if (handle != -1)
- MsiCloseHandle(handle);
+ msiobj_release( &package->hdr );
- return rc;
+ return r;
}
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
szwCommandLine );
end:
- HeapFree( GetProcessHeap(), 0, szwProduct );
- HeapFree( GetProcessHeap(), 0, szwCommandLine);
+ msi_free( szwProduct );
+ msi_free( szwCommandLine);
return r;
}
}
r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
- HeapFree( GetProcessHeap(), 0, szwProduct );
+ msi_free( szwProduct );
return r;
}
if( ERROR_SUCCESS == r )
WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
- HeapFree( GetProcessHeap(), 0, szwComponent );
+ msi_free( szwComponent );
return r;
}
if( szBuffer )
{
- szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
+ szwBuffer = msi_alloc( (*pcchValueBuf) * sizeof(WCHAR) );
pcchwValueBuf = *pcchValueBuf;
if( !szwBuffer )
goto end;
&pcchwValueBuf );
if( ERROR_SUCCESS == r )
+ {
+ INT old_len = *pcchValueBuf;
*pcchValueBuf = WideCharToMultiByte(CP_ACP, 0, szwBuffer, pcchwValueBuf,
szBuffer, *pcchValueBuf, NULL, NULL);
+ if (old_len > *pcchValueBuf)
+ szBuffer[*pcchValueBuf]=0;
+ }
end:
- HeapFree( GetProcessHeap(), 0, szwProduct );
- HeapFree( GetProcessHeap(), 0, szwAttribute );
- HeapFree( GetProcessHeap(), 0, szwBuffer );
+ msi_free( szwProduct );
+ msi_free( szwAttribute );
+ msi_free( szwBuffer );
return r;
}
return ERROR_OUTOFMEMORY;
}
r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
- HeapFree( GetProcessHeap(), 0, szwLogFile );
+ msi_free( szwLogFile );
return r;
}
return ERROR_OUTOFMEMORY;
}
r = MsiQueryProductStateW( szwProduct );
- HeapFree( GetProcessHeap(), 0, szwProduct );
+ msi_free( szwProduct );
return r;
}
LANGID r;
DWORD len;
- bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
+ bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
if( r )
{
else
r = 0;
}
- HeapFree(GetProcessHeap(), 0, bufW);
+ msi_free(bufW);
return r;
}
r = MsiVerifyPackageW( szPack );
- HeapFree( GetProcessHeap(), 0, szPack );
+ msi_free( szPack );
return r;
}
szwComponent = strdupAtoW( szComponent );
if( !szwComponent )
{
- HeapFree( GetProcessHeap(), 0, szwProduct);
+ msi_free( szwProduct);
return ERROR_OUTOFMEMORY;
}
}
if( pcchBuf && *pcchBuf > 0 )
{
- lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
+ lpwPathBuf = msi_alloc( *pcchBuf * sizeof(WCHAR));
incoming_len = *pcchBuf;
}
else
rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
- HeapFree( GetProcessHeap(), 0, szwProduct);
- HeapFree( GetProcessHeap(), 0, szwComponent);
+ msi_free( szwProduct);
+ msi_free( szwComponent);
if (lpwPathBuf)
{
if (rc != INSTALLSTATE_UNKNOWN)
WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
lpPathBuf, incoming_len, NULL, NULL);
- HeapFree( GetProcessHeap(), 0, lpwPathBuf);
+ msi_free( lpwPathBuf);
}
return rc;
goto end;
sz += sizeof(WCHAR);
- path = HeapAlloc( GetProcessHeap(), 0, sz );
+ path = msi_alloc( sz );
if( !path )
goto end;
}
end:
- HeapFree(GetProcessHeap(), 0, path );
+ msi_free(path );
RegCloseKey(hkey);
return rrc;
}
szwFeature = strdupAtoW( szFeature );
if( !szwFeature)
{
- HeapFree( GetProcessHeap(), 0, szwProduct);
+ msi_free( szwProduct);
return ERROR_OUTOFMEMORY;
}
}
rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
- HeapFree( GetProcessHeap(), 0, szwProduct);
- HeapFree( GetProcessHeap(), 0, szwFeature);
+ msi_free( szwProduct);
+ msi_free( szwFeature);
return rc;
}
if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
{
- lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
+ lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
if( !lpwVersionBuff )
goto end;
}
if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
{
- lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
+ lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
if( !lpwLangBuff )
goto end;
}
lpLangBuf, *pcchLangBuf, NULL, NULL);
end:
- HeapFree(GetProcessHeap(), 0, szwFilePath);
- HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
- HeapFree(GetProcessHeap(), 0, lpwLangBuff);
+ msi_free(szwFilePath);
+ msi_free(lpwVersionBuff);
+ msi_free(lpwLangBuff);
return ret;
}
if( !dwVerLen )
return GetLastError();
- lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
+ lpVer = msi_alloc(dwVerLen);
if( !lpVer )
{
ret = ERROR_OUTOFMEMORY;
}
end:
- HeapFree(GetProcessHeap(), 0, lpVer);
+ msi_free(lpVer);
return ret;
}
return ERROR_INDEX_ABSENT;
}
- info = HeapAlloc(GetProcessHeap(),0,sz);
+ info = msi_alloc(sz);
rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
if (rc != ERROR_SUCCESS)
{
RegCloseKey(hkey);
- HeapFree(GetProcessHeap(),0,info);
+ msi_free(info);
return ERROR_INDEX_ABSENT;
}
else
{
RegCloseKey(hkey);
- HeapFree(GetProcessHeap(),0,info);
+ msi_free(info);
return ERROR_INDEX_ABSENT;
}
rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
RegCloseKey(hkey);
- HeapFree(GetProcessHeap(),0,info);
- HeapFree(GetProcessHeap(),0,product);
- HeapFree(GetProcessHeap(),0,component);
+ msi_free(info);
+ msi_free(product);
+ msi_free(component);
if (rc == INSTALLSTATE_LOCAL)
return ERROR_SUCCESS;
szwComponent= strdupAtoW( szComponent);
szwQualifier= strdupAtoW( szQualifier);
- lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
+ lpwPathBuf = msi_alloc(*pcchPathBuf * sizeof(WCHAR));
pcchwPathBuf = *pcchPathBuf;
rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
dwInstallMode, lpwPathBuf, &pcchwPathBuf);
- HeapFree(GetProcessHeap(),0,szwComponent);
- HeapFree(GetProcessHeap(),0,szwQualifier);
+ msi_free(szwComponent);
+ msi_free(szwQualifier);
*pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
lpPathBuf, *pcchPathBuf, NULL, NULL);
- HeapFree(GetProcessHeap(),0,lpwPathBuf);
+ msi_free(lpwPathBuf);
return rc;
}
return rc;
}
-UINT WINAPI MsiConfigureFeatureW(LPWSTR szProduct, LPWSTR szFeature, INSTALLSTATE eInstallState)
+/***********************************************************************
+ * MsiConfigureFeatureA [MSI.@]
+ */
+UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
{
- FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
+ FIXME("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
return ERROR_SUCCESS;
}
-
+/***********************************************************************
+ * MsiConfigureFeatureW [MSI.@]
+ */
+UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
+{
+ FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
+ return ERROR_SUCCESS;
+}
UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
{
LPSTR szProductCode, LPSTR szFeatureId,
LPSTR szComponentCode )
{
- FIXME("\n");
- return ERROR_CALL_NOT_IMPLEMENTED;
+ LPWSTR target;
+ const int len = MAX_FEATURE_CHARS+1;
+ WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
+ UINT r;
+
+ target = strdupAtoW( szShortcutTarget );
+ if (szShortcutTarget && !target )
+ return ERROR_OUTOFMEMORY;
+ product[0] = 0;
+ feature[0] = 0;
+ component[0] = 0;
+ r = MsiGetShortcutTargetW( target, product, feature, component );
+ msi_free( target );
+ if (r == ERROR_SUCCESS)
+ {
+ WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
+ WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
+ WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
+ }
+ return r;
}
UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
LPWSTR szProductCode, LPWSTR szFeatureId,
LPWSTR szComponentCode )
{
- FIXME("\n");
+ FIXME("%s\n", debugstr_w(szShortcutTarget));
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
DWORD dwReinstallMode )
{
+ MSIPACKAGE* package = NULL;
+ UINT r;
+ DWORD sz;
+ WCHAR sourcepath[MAX_PATH];
+ WCHAR filename[MAX_PATH];
+ static const WCHAR szInstalled[] = {
+ ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
+ static const WCHAR fmt[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
+ static const WCHAR REINSTALLMODE[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
+ WCHAR reinstallmode[11];
+ LPWSTR ptr;
+ LPWSTR commandline;
+
FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
dwReinstallMode);
- return ERROR_SUCCESS;
+
+ memset(reinstallmode,0,sizeof(reinstallmode));
+ ptr = reinstallmode;
+
+ if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
+ { *ptr = 'p'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
+ { *ptr = 'o'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
+ { *ptr = 'w'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
+ { *ptr = 'd'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
+ { *ptr = 'c'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
+ { *ptr = 'a'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_USERDATA)
+ { *ptr = 'u'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
+ { *ptr = 'm'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
+ { *ptr = 's'; ptr++; }
+ if (dwReinstallMode & REINSTALLMODE_PACKAGE)
+ { *ptr = 'v'; ptr++; }
+
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
+ &sz);
+
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+ strcatW(sourcepath,filename);
+
+ if (dwReinstallMode & REINSTALLMODE_PACKAGE)
+ r = MSI_OpenPackageW( sourcepath, &package );
+ else
+ r = MSI_OpenProductW( szProduct, &package );
+
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ MSI_SetPropertyW(package,REINSTALLMODE,reinstallmode);
+
+ sz = lstrlenW(szInstalled);
+ sz += lstrlenW(fmt);
+ sz += lstrlenW(szFeature);
+
+ commandline = msi_alloc(sz * sizeof(WCHAR));
+
+ sprintfW(commandline,fmt,szFeature);
+ lstrcatW(commandline,szInstalled);
+
+ r = MSI_InstallPackage( package, sourcepath, commandline );
+
+ msiobj_release( &package->hdr );
+
+ msi_free(commandline);
+
+ return r;
}
UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
DWORD dwReinstallMode )
{
- FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
+ LPWSTR wszProduct;
+ LPWSTR wszFeature;
+ UINT rc;
+
+ TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
dwReinstallMode);
- return ERROR_SUCCESS;
+
+ wszProduct = strdupAtoW(szProduct);
+ wszFeature = strdupAtoW(szFeature);
+
+ rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
+
+ msi_free(wszProduct);
+ msi_free(wszFeature);
+ return rc;
+}
+
+/***********************************************************************
+ * MsiEnumPatchesA [MSI.@]
+ */
+UINT WINAPI MsiEnumPatchesA( LPCSTR szProduct, DWORD iPatchIndex,
+ LPSTR lpPatchBuf, LPSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
+{
+ FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct),
+ iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
+ return ERROR_NO_MORE_ITEMS;
+}
+
+/***********************************************************************
+ * MsiEnumPatchesW [MSI.@]
+ */
+UINT WINAPI MsiEnumPatchesW( LPCWSTR szProduct, DWORD iPatchIndex,
+ LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
+{
+ FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct),
+ iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
+ return ERROR_NO_MORE_ITEMS;
}
-/*\r
- * Resources for MSI\r
- *\r
- * Copyright 2005 Mike McCormack\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-\r
-LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL\r
-\r
-#include "version.rc"\r
-\r
-#include "msi_De.rc"\r
-#include "msi_En.rc"\r
-#include "msi_Es.rc"\r
-#include "msi_Fr.rc"\r
-#include "msi_Nl.rc"\r
-#include "msi_Pt.rc"\r
-#include "msi_Ru.rc"\r
+/*
+ * Resources for MSI
+ *
+ * Copyright 2005 Mike McCormack
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winnls.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#include "version.rc"
+
+#include "msi_Bg.rc"
+#include "msi_De.rc"
+#include "msi_En.rc"
+#include "msi_Es.rc"
+#include "msi_Fi.rc"
+#include "msi_Fr.rc"
+#include "msi_Nl.rc"
+#include "msi_No.rc"
+#include "msi_Pt.rc"
+#include "msi_Ru.rc"
8 stdcall MsiCloseHandle(long)
9 stdcall MsiCollectUserInfoA(str)
10 stdcall MsiCollectUserInfoW(wstr)
-11 stub MsiConfigureFeatureA
+11 stdcall MsiConfigureFeatureA(str str long)
12 stub MsiConfigureFeatureFromDescriptorA
13 stub MsiConfigureFeatureFromDescriptorW
-14 stdcall MsiConfigureFeatureW(str str ptr)
+14 stdcall MsiConfigureFeatureW(wstr wstr ptr)
15 stdcall MsiConfigureProductA(str long long)
16 stdcall MsiConfigureProductW(wstr long long)
17 stdcall MsiCreateRecord(long)
129 stdcall MsiReinstallFeatureW(wstr wstr long)
130 stdcall MsiReinstallProductA(str long)
131 stdcall MsiReinstallProductW(wstr long)
-132 stub MsiSequenceA
-133 stub MsiSequenceW
+132 stdcall MsiSequenceA(long str long)
+133 stdcall MsiSequenceW(long wstr long)
134 stdcall MsiSetComponentStateA(long str long)
135 stdcall MsiSetComponentStateW(long wstr long)
136 stdcall MsiSetExternalUIA(ptr long ptr)
177 stub MsiAdvertiseScriptW
178 stub MsiGetPatchInfoA
179 stub MsiGetPatchInfoW
-180 stub MsiEnumPatchesA
-181 stub MsiEnumPatchesW
+180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
+181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
182 stdcall -private DllGetVersion(ptr)
183 stub MsiGetProductCodeFromPackageCodeA
184 stub MsiGetProductCodeFromPackageCodeW
--- /dev/null
+/*
+ * Bulgarian resources for MSI
+ *
+ * Copyright 2005 Milko Krachounov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+ 5 "ïúòÿò %s íå å íàìåðåí"
+ 9 "ïîñòàâåòå äèñê %s"
+ 10 "íåêîðåêòíè ïàðàìåòðè"
+ 11 "âúâåäåòå ïàïêàòà, êîÿòî ñúäúðæà %s"
+ 12 "èçòî÷íèêà çà èíñòàëàöèÿ íà ôóíêöèîíàëíîñòòà ëèïñâà"
+ 13 "ìðåæîâîòî óñòðîéñòâà íóæíî çà ôóíêöèîíàëíîñòòà ëèïñâà "
+ 14 "ôóíêöèîíàëíîñò îò:"
+ 15 "èçáåðåòå ïàïêàòà, êîÿòî ñúäúðæà %s"
+}
-/*\r
- * English resources for MSI\r
- *\r
- * Copyright 2005 Mike McCormack\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
-\r
-STRINGTABLE DISCARDABLE\r
-{\r
- 5 "path %s not found"\r
- 9 "insert disk %s"\r
- 10 "bad parameters"\r
- 11 "enter which folder contains %s"\r
- 12 "install source for feature missing"\r
- 13 "network drive for feature missing"\r
- 14 "feature from:"\r
- 15 "choose which folder contains %s"\r
-}\r
+/*
+ * English resources for MSI
+ *
+ * Copyright 2005 Mike McCormack
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+ 5 "path %s not found"
+ 9 "insert disk %s"
+ 10 "bad parameters"
+ 11 "enter which folder contains %s"
+ 12 "install source for feature missing"
+ 13 "network drive for feature missing"
+ 14 "feature from:"
+ 15 "choose which folder contains %s"
+}
--- /dev/null
+/*
+ * Finnish resources for MSI
+ *
+ * Copyright 2005 Kimmo Myllyvirta
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+ 5 "Polkua %s ei löydy."
+ 9 "Anna levy %s"
+ 10 "Virheelliset parametrit."
+ 11 "Anna kansio, joka sisältää %s"
+ 12 "Ominaisuuden asennuslähde puuttuu."
+ 13 "Ominaisuuden verkkolevy puuttuu."
+ 14 "Ominaisuus:"
+ 15 "Valitse kansio, joka sisältää %s"
+}
--- /dev/null
+/*
+ * Norwegian Bokmål resources for MSI
+ *
+ * Copyright 2005 Alexander N. Sørnes <alex@thehandofagony.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
+
+STRINGTABLE DISCARDABLE
+{
+ 5 "Fant ikke stien '%s'."
+ 9 "Sett i disk '%s'"
+ 10 "Gale parametere."
+ 11 "Oppgi katalogen som inneholder '%s'."
+ 12 "Egenskapens installasjonskilde mangler."
+ 13 "Egenskapens nettverksstasjon mangler."
+ 14 "Egenskap fra::"
+ 15 "Velg katalogen som inneholder '%s'."
+}
-/*\r
- * Russian resources for MSI\r
- *\r
- * Copyright 2005 Mikhail Y. Zvyozdochkin\r
- * Aleksey Bragin\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT\r
-\r
-STRINGTABLE DISCARDABLE\r
-{\r
- 5 "ïóòü %s íå íàéäåí"\r
- 9 "âñòàâüòå äèñê %s"\r
- 10 "íåâåðíûå ïàðàìåòðû"\r
- 11 "ââåäèòå, êàêàÿ ïàïêà ñîäåðæèò %s"\r
- 12 "íåäîñòóïåí èñòî÷íèê óñòàíîâêè (ñúåìíûé èëè êîìïàêò-äèñê íå âñòàâëåí â äèñêîâîä)"\r
- 13 "íåäîñòóïåí ñåòåâîé äèñê, ñîäåðæàùèé íåîáõîäèìûé ôàéë"\r
- 14 "ôóíêöèîíàëüíîñòü èç:"\r
- 15 "âûáåðèòå, êàêàÿ ïàïêà ñîäåðæèò %s"\r
-}\r
+/*
+ * Russian resources for MSI
+ *
+ * Copyright 2005 Mikhail Y. Zvyozdochkin
+ * Aleksey Bragin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+ 5 "ïóòü %s íå íàéäåí"
+ 9 "âñòàâüòå äèñê %s"
+ 10 "íåâåðíûå ïàðàìåòðû"
+ 11 "ââåäèòå, êàêàÿ ïàïêà ñîäåðæèò %s"
+ 12 "íåäîñòóïåí èñòî÷íèê óñòàíîâêè (ñúåìíûé èëè êîìïàêò-äèñê íå âñòàâëåí â äèñêîâîä)"
+ 13 "íåäîñòóïåí ñåòåâîé äèñê, ñîäåðæàùèé íåîáõîäèìûé ôàéë"
+ 14 "ôóíêöèîíàëüíîñòü èç:"
+ 15 "âûáåðèòå, êàêàÿ ïàïêà ñîäåðæèò %s"
+}
#define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100
+#define MSITYPE_LOCALIZABLE 0x200
#define MSITYPE_STRING 0x0800
#define MSITYPE_NULLABLE 0x1000
#define MSITYPE_KEY 0x2000
-#define MSITYPE_BINARY 0x8900
+#define MSITYPE_IS_BINARY(type) (((type) & ~MSITYPE_NULLABLE) == (MSITYPE_STRING|MSITYPE_VALID))
struct tagMSITABLE;
typedef struct tagMSITABLE MSITABLE;
UINT type;
LONG refcount;
msihandledestructor destructor;
- struct tagMSIOBJECTHDR *next;
- struct tagMSIOBJECTHDR *prev;
};
typedef struct tagMSIDATABASE
IStorage *storage;
string_table *strings;
LPCWSTR mode;
- MSITABLE *first_table, *last_table;
+ struct list tables;
} MSIDATABASE;
typedef struct tagMSIVIEW MSIVIEW;
struct list components;
struct list features;
struct list files;
+ struct list tempfiles;
struct list folders;
LPWSTR ActionFormat;
LPWSTR LastAction;
struct list classes;
struct list extensions;
- struct tagMSIPROGID *progids;
- UINT loaded_progids;
- struct tagMSIVERB *verbs;
- UINT loaded_verbs;
+ struct list progids;
struct list mimes;
struct list appids;
struct tagMSISCRIPT *script;
- struct tagMSIRUNNINGACTION *RunningAction;
- UINT RunningActionCount;
+ struct list RunningActions;
LPWSTR PackagePath;
- LPWSTR msiFilePath;
LPWSTR ProductCode;
UINT CurrentInstallState;
#define MSIHANDLE_MAGIC 0x4d434923
#define MSIMAXHANDLES 0xf0
-#define MSISUMINFO_OFFSET 0x30LL
-
DEFINE_GUID(CLSID_IMsiServer, 0x000C101C,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(CLSID_IMsiServerX1, 0x000C103E,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(CLSID_IMsiServerX2, 0x000C1090,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+typedef struct {
+ BOOL unicode;
+ union {
+ LPSTR a;
+ LPWSTR w;
+ } str;
+} awstring;
+
+typedef struct {
+ BOOL unicode;
+ union {
+ LPCSTR a;
+ LPCWSTR w;
+ } str;
+} awcstring;
/* handle functions */
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
extern int msiobj_release(MSIOBJECTHDR *);
extern void msiobj_lock(MSIOBJECTHDR *);
extern void msiobj_unlock(MSIOBJECTHDR *);
-extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
-/* add this table to the list of cached tables in the database */
-extern void add_table(MSIDATABASE *db, MSITABLE *table);
-extern void remove_table( MSIDATABASE *db, MSITABLE *table );
-extern void free_table( MSIDATABASE *db, MSITABLE *table );
extern void free_cached_tables( MSIDATABASE *db );
-extern UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
-extern UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
-extern UINT load_string_table( MSIDATABASE *db );
+extern string_table *load_string_table( IStorage *stg );
extern UINT MSI_CommitTables( MSIDATABASE *db );
extern HRESULT init_string_table( IStorage *stg );
USHORT **pdata, UINT *psz );
/* action internals */
-extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR, LPCWSTR );
+extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern void ACTION_free_package_structures( MSIPACKAGE* );
extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR);
+extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode );
/* record internals */
extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
+extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
+extern LONG msi_reg_set_val_dword( HKEY hkey, LPCWSTR name, DWORD val );
+
/* msi dialog interface */
typedef UINT (*msi_dialog_event_handler)( MSIPACKAGE*, LPCWSTR, LPCWSTR, msi_dialog* );
extern msi_dialog *msi_dialog_create( MSIPACKAGE*, LPCWSTR, msi_dialog_event_handler );
extern LPVOID gUIContext;
extern WCHAR gszLogFile[MAX_PATH];
+/* memory allocation macro functions */
+static inline void *msi_alloc( size_t len )
+{
+ return HeapAlloc( GetProcessHeap(), 0, len );
+}
+
+static inline void *msi_alloc_zero( size_t len )
+{
+ return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
+}
+
+static inline void *msi_realloc( void *mem, size_t len )
+{
+ return HeapReAlloc( GetProcessHeap(), 0, mem, len );
+}
+
+static inline void *msi_realloc_zero( void *mem, size_t len )
+{
+ return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len );
+}
+
+static inline BOOL msi_free( void *mem )
+{
+ return HeapFree( GetProcessHeap(), 0, mem );
+}
+
inline static char *strdupWtoA( LPCWSTR str )
{
LPSTR ret = NULL;
- if (str)
- {
- DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL
-);
- if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
- WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
- }
+ DWORD len;
+
+ if (!str) return ret;
+ len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
+ ret = msi_alloc( len );
+ if (ret)
+ WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
return ret;
}
inline static LPWSTR strdupAtoW( LPCSTR str )
{
LPWSTR ret = NULL;
- if (str)
- {
- DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
- if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
- MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
- }
+ DWORD len;
+
+ if (!str) return ret;
+ len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ ret = msi_alloc( len * sizeof(WCHAR) );
+ if (ret)
+ MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
return ret;
}
{
LPWSTR dest;
if (!src) return NULL;
- dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src)+1)*sizeof(WCHAR));
- lstrcpyW(dest, src);
+ dest = msi_alloc( (lstrlenW(src)+1)*sizeof(WCHAR) );
+ if (dest)
+ lstrcpyW(dest, src);
return dest;
}
LIST_FOR_EACH_SAFE( ptr, t, &query->mem )
{
- HeapFree( GetProcessHeap(), 0, ptr );
+ msi_free( ptr );
}
}
if( r != ERROR_SUCCESS )
return r;
x = lstrcmpW( name, col_name );
- HeapFree( GetProcessHeap(), 0, col_name );
+ msi_free( col_name );
if( !x )
{
*n = i;
r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
- HeapFree( GetProcessHeap(), 0, szwQuery );
+ msi_free( szwQuery );
return r;
}
return r;
}
-static UINT MSI_OpenQueryV( MSIDATABASE *db, MSIQUERY **view,
- LPCWSTR fmt, va_list args )
+UINT MSI_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ... )
{
- LPWSTR szQuery;
- LPCWSTR p;
- UINT sz, rc;
- va_list va;
+ UINT r;
+ int size = 100, res;
+ LPWSTR query;
- /* figure out how much space we need to allocate */
- va = args;
- sz = lstrlenW(fmt) + 1;
- p = fmt;
- while (*p)
+ /* construct the string */
+ for (;;)
{
- p = strchrW(p, '%');
- if (!p)
- break;
- p++;
- switch (*p)
- {
- case 's': /* a string */
- sz += lstrlenW(va_arg(va,LPCWSTR));
- break;
- case 'd':
- case 'i': /* an integer -2147483648 seems to be longest */
- sz += 3*sizeof(int);
- (void)va_arg(va,int);
- break;
- case '%': /* a single % - leave it alone */
- break;
- default:
- FIXME("Unhandled character type %c\n",*p);
- }
- p++;
+ va_list va;
+ query = msi_alloc( size*sizeof(WCHAR) );
+ va_start(va, fmt);
+ res = vsnprintfW(query, size, fmt, va);
+ va_end(va);
+ if (res == -1) size *= 2;
+ else if (res >= size) size = res + 1;
+ else break;
+ msi_free( query );
}
-
- /* construct the string */
- szQuery = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
- va = args;
- vsnprintfW(szQuery, sz, fmt, va);
-
/* perform the query */
- rc = MSI_DatabaseOpenViewW(db, szQuery, view);
- HeapFree(GetProcessHeap(), 0, szQuery);
- return rc;
-}
-
-UINT MSI_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ... )
-{
- UINT r;
- va_list va;
-
- va_start(va, fmt);
- r = MSI_OpenQueryV( db, view, fmt, va );
- va_end(va);
-
+ r = MSI_DatabaseOpenViewW(db, query, view);
+ msi_free(query);
return r;
}
r = MSI_ViewFetch( view, &rec );
if( r != ERROR_SUCCESS )
break;
- r = func( rec, param );
+ if (func)
+ r = func( rec, param );
msiobj_release( &rec->hdr );
if( r != ERROR_SUCCESS )
break;
MSIRECORD *rec = NULL;
MSIQUERY *view = NULL;
UINT r;
- va_list va;
+ int size = 100, res;
+ LPWSTR query;
- va_start(va, fmt);
- r = MSI_OpenQueryV( db, &view, fmt, va );
- va_end(va);
+ /* construct the string */
+ for (;;)
+ {
+ va_list va;
+ query = msi_alloc( size*sizeof(WCHAR) );
+ va_start(va, fmt);
+ res = vsnprintfW(query, size, fmt, va);
+ va_end(va);
+ if (res == -1) size *= 2;
+ else if (res >= size) size = res + 1;
+ else break;
+ msi_free( query );
+ }
+ /* perform the query */
+ r = MSI_DatabaseOpenViewW(db, query, &view);
+ msi_free(query);
if( r == ERROR_SUCCESS )
{
ERR("Error getting column type for %d\n", i );
continue;
}
- if (( type != MSITYPE_BINARY) && (type != (MSITYPE_BINARY |
- MSITYPE_NULLABLE)))
+ if (!MSITYPE_IS_BINARY(type))
{
ret = view->ops->fetch_int( view, query->row, i, &ival );
if( ret )
sval = MSI_makestring( query->db, ival );
MSI_RecordSetStringW( rec, i, sval );
- HeapFree( GetProcessHeap(), 0, sval );
+ msi_free( sval );
}
else
{
return ret;
}
+static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, UINT type )
+{
+ static const WCHAR fmt[] = { '%','d',0 };
+ WCHAR szType[0x10];
+
+ if (MSITYPE_IS_BINARY(type))
+ szType[0] = 'v';
+ else if (type & MSITYPE_LOCALIZABLE)
+ szType[0] = 'l';
+ else if (type & MSITYPE_STRING)
+ szType[0] = 's';
+ else
+ szType[0] = 'i';
+ if (type & MSITYPE_NULLABLE)
+ szType[0] &= ~0x20;
+
+ sprintfW( &szType[1], fmt, (type&0xff) );
+
+ TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
+
+ return MSI_RecordSetStringW( rec, field, szType );
+}
+
UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
{
MSIVIEW *view = NULL;
TRACE("%ld %d %p\n", hView, info, hRec);
+ if( !hRec )
+ return ERROR_INVALID_PARAMETER;
+
+ if( info != MSICOLINFO_NAMES && info != MSICOLINFO_TYPES )
+ return ERROR_INVALID_PARAMETER;
+
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query )
return ERROR_INVALID_HANDLE;
r = view->ops->get_column_info( view, i+1, &name, &type );
if( r != ERROR_SUCCESS )
continue;
- MSI_RecordSetStringW( rec, i+1, name );
- HeapFree( GetProcessHeap(), 0, name );
+ if (info == MSICOLINFO_NAMES)
+ MSI_RecordSetStringW( rec, i+1, name );
+ else
+ msi_set_record_type_string( rec, i+1, type);
+ msi_free( name );
}
*hRec = alloc_msihandle( &rec->hdr );
return r;
}
-UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
- LPCSTR szTransformFile, int iErrorCond)
+DEFINE_GUID( CLSID_MsiTransform, 0x000c1082, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+static UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
+ LPCWSTR szTransformFile, int iErrorCond )
{
- FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UINT r;
+ IStorage *stg = NULL;
+
+ TRACE("%p %s %d\n", db, debugstr_w(szTransformFile), iErrorCond);
+
+ r = StgOpenStorage( szTransformFile, NULL,
+ STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
+ if( r )
+ return r;
+
+ if( TRACE_ON( msi ) )
+ enum_stream_names( stg );
+
+ /* r = table_apply_transform( db, stg ); */
+ FIXME("should apply transform %s\n", debugstr_w(szTransformFile) );
+
+ IStorage_Release( stg );
+
+ return r;
}
UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
LPCWSTR szTransformFile, int iErrorCond)
{
- FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ MSIDATABASE *db;
+ UINT r;
+
+ db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
+ if( !db )
+ return ERROR_INVALID_HANDLE;
+
+ r = MSI_DatabaseApplyTransformW( db, szTransformFile, iErrorCond );
+ msiobj_release( &db->hdr );
+ return r;
+}
+
+UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
+ LPCSTR szTransformFile, int iErrorCond)
+{
+ LPWSTR wstr;
+ UINT ret;
+
+ TRACE("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
+
+ wstr = strdupAtoW( szTransformFile );
+ if( szTransformFile && !wstr )
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ ret = MsiDatabaseApplyTransformW( hdb, wstr, iErrorCond);
+
+ msi_free( wstr );
+
+ return ret;
}
UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
return ERROR_OUTOFMEMORY;
}
r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
- HeapFree( GetProcessHeap(), 0, szwTable );
+ msi_free( szwTable );
return r;
}
if( r != ERROR_SUCCESS )
return r;
- ov->reorder = HeapAlloc( GetProcessHeap(), 0, num_rows*sizeof(UINT) );
+ ov->reorder = msi_alloc( num_rows*sizeof(UINT) );
if( !ov->reorder )
return ERROR_FUNCTION_FAILED;
if( !ov->table )
return ERROR_FUNCTION_FAILED;
- HeapFree( GetProcessHeap(), 0, ov->reorder );
+ msi_free( ov->reorder );
ov->reorder = NULL;
return ov->table->ops->close( ov->table );
if( ov->table )
ov->table->ops->delete( ov->table );
- HeapFree( GetProcessHeap(), 0, ov->reorder );
+ msi_free( ov->reorder );
ov->reorder = NULL;
msiobj_release( &ov->db->hdr );
- HeapFree( GetProcessHeap(), 0, ov );
+ msi_free( ov );
return ERROR_SUCCESS;
}
return r;
}
- ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof *ov + sizeof (UINT) * count );
+ ov = msi_alloc_zero( sizeof *ov + sizeof (UINT) * count );
if( !ov )
return ERROR_FUNCTION_FAILED;
list_init( &package->components );
list_init( &package->features );
list_init( &package->files );
+ list_init( &package->tempfiles );
list_init( &package->folders );
package->ActionFormat = NULL;
package->LastAction = NULL;
list_init( &package->classes );
list_init( &package->mimes );
list_init( &package->extensions );
+ list_init( &package->progids );
+ list_init( &package->RunningActions );
/* OK, here is where we do a slew of things to the database to
* prep for all that is to come as a package */
return package;
}
+/*
+ * copy_package_to_temp [internal]
+ *
+ * copy the msi file to a temp file to prevent locking a CD
+ * with a multi disc install
+ *
+ * FIXME: I think this is wrong, and instead of copying the package,
+ * we should read all the tables to memory, then open the
+ * database to read binary streams on demand.
+ */
+static LPCWSTR copy_package_to_temp( LPCWSTR szPackage, LPWSTR filename )
+{
+ WCHAR path[MAX_PATH];
+ static const WCHAR szMSI[] = {'M','S','I',0};
+
+ GetTempPathW( MAX_PATH, path );
+ GetTempFileNameW( path, szMSI, 0, filename );
+
+ if( !CopyFileW( szPackage, filename, FALSE ) )
+ {
+ ERR("failed to copy package to temp path %s\n", debugstr_w(filename) );
+ return szPackage;
+ }
+
+ TRACE("Opening relocated package %s\n", debugstr_w( filename ));
+ return filename;
+}
+
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
MSIDATABASE *db = NULL;
MSIHANDLE handle;
DWORD size;
static const WCHAR szProductCode[]= {'P','r','o','d','u','c','t','C','o','d','e',0};
+ UINT r;
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
}
else
{
- UINT r = MSI_OpenDatabaseW(szPackage, MSIDBOPEN_READONLY, &db);
+ WCHAR temppath[MAX_PATH];
+ LPCWSTR file = copy_package_to_temp( szPackage, temppath );
+
+ r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &db );
+
+ if (file != szPackage)
+ DeleteFileW( file );
+
if( r != ERROR_SUCCESS )
return r;
}
size = 0;
MSI_GetPropertyW(package,szProductCode,NULL,&size);
size ++;
- package->ProductCode = HeapAlloc(GetProcessHeap(),0,size * sizeof(WCHAR));
+ package->ProductCode = msi_alloc(size * sizeof(WCHAR));
MSI_GetPropertyW(package,szProductCode,package->ProductCode, &size);
*pPackage = package;
{
MSIPACKAGE *package = NULL;
UINT ret;
- WCHAR path[MAX_PATH];
- WCHAR filename[MAX_PATH];
- static const WCHAR szMSI[] = {'M','S','I',0};
-
- TRACE("%s %08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
- /* copy the msi file to a temp file to pervent locking a CD
- * with a multi disc install
- */
- if( szPackage[0] == '#' )
- strcpyW(filename,szPackage);
- else
- {
- GetTempPathW(MAX_PATH, path);
- GetTempFileNameW(path, szMSI, 0, filename);
+ TRACE("%s %08lx %p\n", debugstr_w(szPackage), dwOptions, phPackage );
- CopyFileW(szPackage, filename, FALSE);
-
- TRACE("Opening relocated package %s\n",debugstr_w(filename));
- }
-
if( dwOptions )
FIXME("dwOptions %08lx not supported\n", dwOptions);
- ret = MSI_OpenPackageW( filename, &package);
+ ret = MSI_OpenPackageW( szPackage, &package );
if( ret == ERROR_SUCCESS )
{
*phPackage = alloc_msihandle( &package->hdr );
msiobj_release( &package->hdr );
}
- if( szPackage[0] != '#' )
- DeleteFileW(filename);
-
return ret;
}
ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage );
- HeapFree( GetProcessHeap(), 0, szwPack );
+ msi_free( szwPack );
return ret;
}
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
log_type |= 0x800;
- message = HeapAlloc(GetProcessHeap(),0,1*sizeof (WCHAR));
+ message = msi_alloc(1*sizeof (WCHAR));
message[0]=0;
msg_field = MSI_RecordGetFieldCount(record);
for (i = 1; i <= msg_field; i++)
MSI_RecordGetStringW(record,i,NULL,&sz);
sz+=4;
total_size+=sz*sizeof(WCHAR);
- tmp = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
- message = HeapReAlloc(GetProcessHeap(),0,message,total_size*sizeof (WCHAR));
+ tmp = msi_alloc(sz*sizeof(WCHAR));
+ message = msi_realloc(message,total_size*sizeof (WCHAR));
MSI_RecordGetStringW(record,i,tmp,&sz);
if (msg_field > 1)
strcatW(message,space);
- HeapFree(GetProcessHeap(),0,tmp);
+ msi_free(tmp);
}
TRACE("(%p %lx %lx %s)\n",gUIHandlerA, gUIFilter, log_type,
/* convert it to ASCII */
len = WideCharToMultiByte( CP_ACP, 0, message, -1,
NULL, 0, NULL, NULL );
- msg = HeapAlloc( GetProcessHeap(), 0, len );
+ msg = msi_alloc( len );
WideCharToMultiByte( CP_ACP, 0, message, -1,
msg, len, NULL, NULL );
CloseHandle(log_file);
}
}
- HeapFree( GetProcessHeap(), 0, msg );
+ msi_free( msg );
- HeapFree(GetProcessHeap(),0,message);
+ msi_free( message);
return ERROR_SUCCESS;
}
hr = MsiSetPropertyW( hInstall, szwName, szwValue);
end:
- HeapFree( GetProcessHeap(), 0, szwName );
- HeapFree( GetProcessHeap(), 0, szwValue );
+ msi_free( szwName );
+ msi_free( szwValue );
return hr;
}
MSI_RecordSetStringW(row,2,szValue);
}
-
rc = MSI_DatabaseOpenViewW(package->db,Query,&view);
- if (rc!= ERROR_SUCCESS)
+ if (rc == ERROR_SUCCESS)
{
- msiobj_release(&row->hdr);
- return rc;
- }
-
- rc = MSI_ViewExecute(view,row);
+ rc = MSI_ViewExecute(view,row);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ }
msiobj_release(&row->hdr);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
return rc;
}
return ERROR_INVALID_PARAMETER;
sz = sizeof select + strlenW(szName)*sizeof(WCHAR);
- query = HeapAlloc(GetProcessHeap(), 0, sz);
+ query = msi_alloc( sz);
sprintfW(query,select,szName);
rc = MSI_DatabaseOpenViewW(package->db, query, &view);
- HeapFree(GetProcessHeap(), 0, query);
+ msi_free(query);
if (rc == ERROR_SUCCESS)
{
rc = MSI_ViewExecute(view, 0);
*pchValueBuf = 0;
TRACE("property not found\n");
}
- HeapFree( GetProcessHeap(), 0, szwName );
+ msi_free( szwName );
return rc;
}
return ERROR_OUTOFMEMORY;
}
r = MsiPreviewDialogW( hPreview, strW );
- HeapFree( GetProcessHeap(), 0, strW );
+ msi_free( strW );
return r;
}
case MSIFIELD_INT:
break;
case MSIFIELD_WSTR:
- HeapFree( GetProcessHeap(), 0, field->u.szwVal);
+ msi_free( field->u.szwVal);
break;
case MSIFIELD_STREAM:
IStream_Release( field->u.stream );
return ERROR_OUTOFMEMORY;
}
ret = MsiRecordSetStreamW(hRecord, iField, wstr);
- HeapFree(GetProcessHeap(),0,wstr);
+ msi_free(wstr);
return ret;
}
WideCharToMultiByte( CP_ACP, 0, component, MAX_FEATURE_CHARS+1,
szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
- HeapFree( GetProcessHeap(), 0, str );
+ msi_free( str );
return r;
}
szParent, GUID_SIZE, NULL, NULL);
}
- HeapFree( GetProcessHeap(), 0, szwProduct);
+ msi_free( szwProduct);
return r;
}
szProduct, GUID_SIZE, NULL, NULL);
}
- HeapFree( GetProcessHeap(), 0, szwComponent);
+ msi_free( szwComponent);
return r;
}
szwComponent = strdupAtoW(szComponent);
if (lpQualifierBuf)
- lpwQualifierBuf = HeapAlloc(GetProcessHeap(),0, (*pcchQualifierBuf) *
- sizeof(WCHAR));
+ lpwQualifierBuf = msi_alloc( (*pcchQualifierBuf) * sizeof(WCHAR));
else
lpwQualifierBuf = NULL;
pcchwQualifierBuf = 0;
if (lpApplicationDataBuf)
- lpwApplicationDataBuf = HeapAlloc(GetProcessHeap(),0 ,
- (*pcchApplicationDataBuf) * sizeof(WCHAR));
+ lpwApplicationDataBuf = msi_alloc( (*pcchApplicationDataBuf) * sizeof(WCHAR));
else
lpwApplicationDataBuf = NULL;
*pcchApplicationDataBuf = length - 1;
}
- HeapFree(GetProcessHeap(),0,lpwApplicationDataBuf);
- HeapFree(GetProcessHeap(),0,lpwQualifierBuf);
- HeapFree(GetProcessHeap(),0,szwComponent);
+ msi_free(lpwApplicationDataBuf);
+ msi_free(lpwQualifierBuf);
+ msi_free(szwComponent);
return rc;
}
return ERROR_UNKNOWN_COMPONENT;
full_buffer_size = (52 * sizeof(WCHAR)) + actual_pcchApplicationDataBuf;
- full_buffer = HeapAlloc(GetProcessHeap(),0,full_buffer_size);
+ full_buffer = msi_alloc(full_buffer_size);
rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL,
NULL, (LPBYTE)full_buffer, &full_buffer_size);
if (rc == ERROR_MORE_DATA)
{
- HeapFree(GetProcessHeap(),0,full_buffer);
+ msi_free(full_buffer);
full_buffer_size+=sizeof(WCHAR);
- full_buffer = HeapAlloc(GetProcessHeap(),0,full_buffer_size);
+ full_buffer = msi_alloc(full_buffer_size);
rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL,
NULL, (LPBYTE)full_buffer, &full_buffer_size);
}
debugstr_w(lpApplicationDataBuf));
}
- HeapFree(GetProcessHeap(),0,full_buffer);
+ msi_free(full_buffer);
return rc;
}
WideCharToMultiByte( CP_ACP, 0, productW, GUID_SIZE,
lpProductBuf, GUID_SIZE, NULL, NULL );
}
- HeapFree(GetProcessHeap(), 0, szwUpgradeCode);
+ msi_free( szwUpgradeCode);
return r;
}
if( sv->table )
sv->table->ops->delete( sv->table );
+ sv->table = NULL;
- HeapFree( GetProcessHeap(), 0, sv );
+ msi_free( sv );
return ERROR_SUCCESS;
}
return r;
}
- sv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof *sv + count*sizeof (UINT) );
+ sv = msi_alloc_zero( sizeof *sv + count*sizeof (UINT) );
if( !sv )
return ERROR_FUNCTION_FAILED;
columns = columns->next;
}
- if( r != ERROR_SUCCESS )
- {
- sv->view.ops->delete( &sv->view );
- sv = NULL;
- }
-
- *view = &sv->view;
+ if( r == ERROR_SUCCESS )
+ *view = &sv->view;
+ else
+ msi_free( sv );
return r;
}
rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
if (rc != ERROR_NO_MORE_ITEMS)
{
- val = HeapAlloc(GetProcessHeap(),0,val_size);
+ val = msi_alloc(val_size);
RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
&val_size);
if (lstrcmpiW(szSource,val)==0)
else
strcpyW(ss->szIndex,szIndex);
- HeapFree(GetProcessHeap(),0,val);
+ msi_free(val);
index ++;
}
}
else
{
LPWSTR ptr;
- buffer = HeapAlloc(GetProcessHeap(),0,size);
+ buffer = msi_alloc(size);
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
0, 0, (LPBYTE)buffer,&size);
ptr = strchrW(buffer,';');
else
rc = ERROR_SUCCESS;
}
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
}
}
else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
rc = ERROR_UNKNOWN_PROPERTY;
else
{
- buffer = HeapAlloc(GetProcessHeap(),0,size);
+ buffer = msi_alloc(size);
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
0, 0, (LPBYTE)buffer,&size);
if (*pcchValue < 1)
szValue[0] = buffer[0];
rc = ERROR_SUCCESS;
}
- HeapFree(GetProcessHeap(),0,buffer);
+ msi_free(buffer);
}
}
else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
ERR("Unknown source type! 0x%lx\n",dwOptions);
size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
- buffer = HeapAlloc(GetProcessHeap(),0,size);
+ buffer = msi_alloc(size);
sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
REG_EXPAND_SZ, (LPBYTE)buffer, size);
if (rc != ERROR_SUCCESS)
rc = ERROR_UNKNOWN_PROPERTY;
- HeapFree( GetProcessHeap(), 0, buffer );
+ msi_free( buffer );
}
else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
{
rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
else
{
- ERR("Unknown media type!\n");
+ ERR("unknown media type: %08lx\n", dwOptions);
RegCloseKey(sourcekey);
return ERROR_FUNCTION_FAILED;
}
DWORD current_index = atoiW(source_struct.szIndex);
/* found the source */
if (dwIndex > 0 && current_index != dwIndex)
- FIXME("Need to reorder the souces! UNHANDLED\n");
+ FIXME("Need to reorder the sources!\n");
}
else
{
current_index = atoiW(source_struct.szIndex);
/* new source */
if (dwIndex > 0 && dwIndex < current_index)
- FIXME("Need to reorder the souces! UNHANDLED\n");
+ FIXME("Need to reorder the sources!\n");
current_index ++;
sprintfW(source_struct.szIndex,fmt,current_index);
size *=sizeof(WCHAR);
- buffer = HeapAlloc(GetProcessHeap(),0,size);
+ buffer = msi_alloc(size);
sprintfW(buffer,disk_fmt,pt1,pt2);
RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
- HeapFree( GetProcessHeap(), 0, buffer );
+ msi_free( buffer );
RegCloseKey(sourcekey);
RegCloseKey(mediakey);
-/* A Bison parser, made from ./sql.y
- by GNU bison 1.35. */
+/* A Bison parser, made by GNU Bison 1.875c. */
-#define YYBISON 1 /* Identify Bison output. */
+/* Skeleton parser for Yacc-like parsing with Bison,
+ 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. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
#define yyparse SQL_parse
-#define yylex SQL_lex
+#define yylex SQL_lex
#define yyerror SQL_error
-#define yylval SQL_lval
-#define yychar SQL_char
+#define yylval SQL_lval
+#define yychar SQL_char
#define yydebug SQL_debug
#define yynerrs SQL_nerrs
-# 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
+
+/* 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
+
+
+
+
+/* Copy the first part of user declarations. */
#line 1 "./sql.y"
static struct expr * EXPR_wildcard( void *info );
-#line 71 "./sql.y"
-#ifndef YYSTYPE
-typedef union
-{
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 72 "./sql.y"
+typedef union YYSTYPE {
struct sql_str str;
LPWSTR string;
column_info *column_list;
struct expr *expr;
USHORT column_type;
int integer;
-} yystype;
-# define YYSTYPE yystype
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+#line 453 "sql.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-
-
-#define YYFINAL 127
-#define YYFLAG -32768
-#define YYNTBASE 147
-
-/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
-#define YYTRANSLATE(x) ((unsigned)(x) <= 400 ? yytranslate[x] : 177)
-
-/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
-static const short yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
- 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
- 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
- 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
- 146
-};
-
-#if YYDEBUG
-static const short yyprhs[] =
-{
- 0, 0, 2, 4, 6, 8, 10, 12, 23, 35,
- 42, 50, 57, 60, 65, 69, 71, 74, 76, 79,
- 81, 85, 87, 92, 94, 96, 98, 100, 102, 104,
- 109, 111, 114, 118, 121, 123, 127, 129, 131, 135,
- 138, 142, 146, 150, 154, 158, 162, 166, 170, 174,
- 178, 182, 187, 189, 191, 193, 197, 199, 203, 207,
- 209, 212, 214, 216, 218, 222, 224, 226, 228
-};
-static const short yyrhs[] =
-{
- 148, 0, 160, 0, 150, 0, 149, 0, 151, 0,
- 152, 0, 67, 72, 174, 83, 163, 110, 134, 83,
- 168, 110, 0, 67, 72, 174, 83, 163, 110, 134,
- 83, 168, 110, 122, 0, 31, 121, 174, 83, 153,
- 110, 0, 31, 121, 174, 83, 153, 110, 59, 0,
- 130, 174, 114, 169, 137, 166, 0, 35, 164, 0,
- 154, 102, 77, 163, 0, 154, 24, 155, 0, 155,
- 0, 173, 156, 0, 157, 0, 157, 86, 0, 158,
- 0, 158, 90, 92, 0, 19, 0, 19, 83, 159,
- 110, 0, 82, 0, 115, 0, 69, 0, 81, 0,
- 93, 0, 176, 0, 161, 99, 16, 163, 0, 161,
- 0, 112, 162, 0, 112, 38, 162, 0, 163, 164,
- 0, 173, 0, 173, 24, 163, 0, 118, 0, 165,
- 0, 165, 137, 166, 0, 52, 174, 0, 83, 166,
- 110, 0, 172, 45, 172, 0, 166, 7, 166, 0,
- 166, 97, 166, 0, 172, 45, 167, 0, 172, 57,
- 167, 0, 172, 85, 167, 0, 172, 78, 167, 0,
- 172, 54, 167, 0, 172, 89, 167, 0, 172, 73,
- 92, 0, 172, 73, 90, 92, 0, 172, 0, 171,
- 0, 171, 0, 171, 24, 168, 0, 170, 0, 170,
- 24, 169, 0, 173, 45, 171, 0, 176, 0, 88,
- 176, 0, 120, 0, 138, 0, 173, 0, 174, 39,
- 175, 0, 175, 0, 175, 0, 66, 0, 70, 0
-};
-
-#endif
-
-#if YYDEBUG
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const short yyrline[] =
-{
- 0, 137, 145, 147, 148, 149, 150, 153, 165, 177,
- 190, 204, 217, 230, 240, 251, 257, 265, 270, 277,
- 282, 288, 293, 297, 301, 305, 309, 313, 319, 328,
- 341, 344, 349, 360, 376, 378, 382, 388, 390, 402,
- 415, 422, 428, 434, 440, 446, 452, 458, 464, 470,
- 476, 482, 490, 492, 495, 503, 513, 515, 522, 530,
- 537, 543, 549, 557, 566, 573, 581, 588, 597
-};
-#endif
-
-
-#if (YYDEBUG) || defined YYERROR_VERBOSE
-
-/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
-static const char *const yytname[] =
-{
- "$", "error", "$undefined.", "TK_ABORT", "TK_AFTER", "TK_AGG_FUNCTION",
- "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", "TK_BEGIN",
- "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY",
- "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER",
- "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT",
- "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE",
- "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE",
- "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP",
- "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT",
- "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM",
- "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING",
- "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN",
- "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD",
- "TK_INT", "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL",
- "TK_JOIN", "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT",
- "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT",
- "TK_LOCALIZABLE", "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT",
- "TK_NOTNULL", "TK_NULL", "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON",
- "TK_OR", "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA",
- "TK_PRIMARY", "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE",
- "TK_RESTRICT", "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT",
- "TK_SELECT", "TK_SEMI", "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE",
- "TK_STAR", "TK_STATEMENT", "TK_STRING", "TK_TABLE", "TK_TEMP",
- "TK_THEN", "TK_TRANSACTION", "TK_TRIGGER", "TK_UMINUS",
- "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", "TK_UPDATE", "TK_UPLUS",
- "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", "TK_WHEN", "TK_WHERE",
- "TK_WILDCARD", "END_OF_FILE", "ILLEGAL", "SPACE", "UNCLOSED_STRING",
- "COMMENT", "FUNCTION", "COLUMN", "AGG_FUNCTION.", "query", "onequery",
- "oneinsert", "onecreate", "oneupdate", "onedelete", "table_def",
- "column_def", "column_and_type", "column_type", "data_type_l",
- "data_type", "data_count", "oneselect", "unorderedsel", "selectfrom",
- "selcollist", "from", "fromtable", "expr", "val", "constlist",
- "update_assign_list", "column_assignment", "const_val", "column_val",
- "column", "table", "id", "number", 0
-};
-#endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const short yyr1[] =
-{
- 0, 147, 148, 148, 148, 148, 148, 149, 149, 150,
- 150, 151, 152, 153, 154, 154, 155, 156, 156, 157,
- 157, 158, 158, 158, 158, 158, 158, 158, 159, 160,
- 160, 161, 161, 162, 163, 163, 163, 164, 164, 165,
- 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
- 166, 166, 167, 167, 168, 168, 169, 169, 170, 171,
- 171, 171, 171, 172, 173, 173, 174, 175, 176
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const short yyr2[] =
-{
- 0, 1, 1, 1, 1, 1, 1, 10, 11, 6,
- 7, 6, 2, 4, 3, 1, 2, 1, 2, 1,
- 3, 1, 4, 1, 1, 1, 1, 1, 1, 4,
- 1, 2, 3, 2, 1, 3, 1, 1, 3, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 4, 1, 1, 1, 3, 1, 3, 3, 1,
- 2, 1, 1, 1, 3, 1, 1, 1, 1
-};
-
-/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
- doesn't specify something else to do. Zero means the default is an
- error. */
-static const short yydefact[] =
-{
- 0, 0, 0, 0, 0, 0, 1, 4, 3, 5,
- 6, 2, 30, 0, 0, 12, 37, 0, 0, 67,
- 36, 31, 0, 34, 0, 65, 0, 66, 0, 0,
- 39, 0, 0, 32, 33, 0, 0, 0, 0, 0,
- 0, 38, 0, 63, 0, 35, 64, 0, 56, 0,
- 29, 0, 0, 15, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 0, 0, 21, 25, 26, 23, 27, 24, 16, 17,
- 19, 40, 42, 43, 68, 0, 61, 62, 44, 53,
- 41, 59, 48, 52, 45, 0, 50, 47, 46, 49,
- 0, 11, 57, 58, 10, 14, 0, 0, 18, 0,
- 60, 51, 0, 13, 0, 28, 20, 0, 22, 0,
- 54, 7, 0, 8, 55, 0, 0, 0
-};
-
-static const short yydefgoto[] =
-{
- 125, 6, 7, 8, 9, 10, 51, 52, 53, 78,
- 79, 80, 114, 11, 12, 21, 22, 15, 16, 41,
- 88, 119, 47, 48, 89, 42, 43, 24, 25, 91
-};
-static const short yypact[] =
-{
- -28, -106, -27, -52, -32, -42,-32768,-32768,-32768,-32768,
- -32768,-32768, -70, -42, -42,-32768, -97, -42, -48,-32768,
- -32768,-32768, -27, 7, 2, 5, -62,-32768, 40, -23,
- -32768, -55, -22,-32768,-32768, -48, -42, -42, -48, -42,
- -55, -3, 0,-32768, -48,-32768,-32768, -65, 43, 29,
- -32768, -34, -19,-32768, -18, -7, -55, -55, -58, -58,
- -58, -37, -58, -58, -58, -31, -55, -42, -61, 23,
- -42, 10, 8,-32768,-32768,-32768,-32768,-32768,-32768, 6,
- 3,-32768, -3, -3,-32768, 18,-32768,-32768,-32768,-32768,
- -32768,-32768,-32768,-32768,-32768, 16,-32768,-32768,-32768,-32768,
- -33, -3,-32768,-32768,-32768,-32768, -48, 18,-32768, 20,
- -32768,-32768, 30,-32768, 4,-32768,-32768, -61,-32768, 11,
- 91, -6, -61,-32768,-32768, 117, 118,-32768
-};
-
-static const short yypgoto[] =
-{
- -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 49,-32768,
- -32768,-32768,-32768,-32768,-32768, 102, -25, 100,-32768, -8,
- 36, 1, 57,-32768, -51, 47, -2, 9, 33, -64
-};
-
-
-#define YYLAST 124
-
-
-static const short yytable[] =
-{
- 56, 72, 23, 1, 56, 70, 18, 2, 19, 84,
- 45, 19, 84, 50, 26, 13, 23, 103, 19, 65,
- 17, 110, 29, 30, 19, 14, 32, 85, 40, 28,
- 85, 35, 55, 23, 19, 49, 23, 54, 27, 3,
- 31, 36, 23, 115, -66, 58, 27, 27, 82, 83,
- 27, 73, 37, 95, 59, 96, 38, 60, 101, 86,
- 39, 44, 86, 74, 75, 49, 120, 67, 54, 46,
- 20, 120, 66, 61, 68, 76, 69, 87, 62, 100,
- 87, 113, 104, 71, 4, 63, 20, 106, 84, 64,
- 57, 107, 108, 109, 57, 92, 94, 77, 97, 98,
- 99, 112, 5, 81, 23, 90, 93, 93, 111, 93,
- 93, 93, 116, 117, 118, 122, 123, 126, 127, 105,
- 33, 121, 34, 124, 102
-};
-
-static const short yycheck[] =
-{
- 7, 19, 4, 31, 7, 24, 38, 35, 66, 70,
- 35, 66, 70, 38, 5, 121, 18, 68, 66, 44,
- 72, 85, 13, 14, 66, 52, 17, 88, 83, 99,
- 88, 24, 40, 35, 66, 37, 38, 39, 5, 67,
- 137, 39, 44, 107, 39, 45, 13, 14, 56, 57,
- 17, 69, 114, 90, 54, 92, 16, 57, 66, 120,
- 83, 83, 120, 81, 82, 67, 117, 24, 70, 36,
- 118, 122, 137, 73, 45, 93, 110, 138, 78, 110,
- 138, 106, 59, 102, 112, 85, 118, 77, 70, 89,
- 97, 83, 86, 90, 97, 59, 60, 115, 62, 63,
- 64, 134, 130, 110, 106, 58, 59, 60, 92, 62,
- 63, 64, 92, 83, 110, 24, 122, 0, 0, 70,
- 18, 110, 22, 122, 67
-};
-#define YYPURE 1
-
-/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/bison/bison.simple"
-
-/* Skeleton output parser for bison,
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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. */
+/* Copy the second part of user declarations. */
-/* 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. */
-/* This is the parser code that is written into each bison parser when
- the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
+/* Line 214 of yacc.c. */
+#line 465 "sql.tab.c"
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
-#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
/* The parser invokes alloca or malloc; define the necessary symbols. */
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
# else
-# ifndef YYSTACK_USE_ALLOCA
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
# endif
# endif
# endif
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
-# define YYSTACK_ALLOC malloc
-# define YYSTACK_FREE free
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
# endif
-#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
#if (! defined (yyoverflow) \
&& (! defined (__cplusplus) \
- || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
short yyss;
YYSTYPE yyvs;
-# if YYLSP_NEEDED
- YYLTYPE yyls;
-# endif
-};
+ };
/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
-# if YYLSP_NEEDED
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAX)
-# else
-# define YYSTACK_BYTES(N) \
+# define YYSTACK_BYTES(N) \
((N) * (sizeof (short) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAX)
-# endif
+ + YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if 1 < __GNUC__
+# if defined (__GNUC__) && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (0)
#endif
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 29
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 124
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 147
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 31
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 69
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 127
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 401
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 26,
+ 38, 45, 53, 60, 63, 68, 72, 74, 77, 79,
+ 82, 84, 88, 90, 95, 97, 99, 101, 103, 105,
+ 107, 112, 114, 117, 121, 124, 126, 130, 132, 134,
+ 138, 141, 145, 149, 153, 157, 161, 165, 169, 173,
+ 177, 181, 185, 190, 192, 194, 196, 200, 202, 206,
+ 210, 212, 215, 217, 219, 221, 225, 227, 229, 231
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short yyrhs[] =
+{
+ 148, 0, -1, 149, -1, 161, -1, 151, -1, 150,
+ -1, 152, -1, 153, -1, 67, 72, 175, 83, 164,
+ 110, 134, 83, 169, 110, -1, 67, 72, 175, 83,
+ 164, 110, 134, 83, 169, 110, 122, -1, 31, 121,
+ 175, 83, 154, 110, -1, 31, 121, 175, 83, 154,
+ 110, 59, -1, 130, 175, 114, 170, 137, 167, -1,
+ 35, 165, -1, 155, 102, 77, 164, -1, 155, 24,
+ 156, -1, 156, -1, 174, 157, -1, 158, -1, 158,
+ 86, -1, 159, -1, 159, 90, 92, -1, 19, -1,
+ 19, 83, 160, 110, -1, 82, -1, 115, -1, 69,
+ -1, 81, -1, 93, -1, 177, -1, 162, 99, 16,
+ 164, -1, 162, -1, 112, 163, -1, 112, 38, 163,
+ -1, 164, 165, -1, 174, -1, 174, 24, 164, -1,
+ 118, -1, 166, -1, 166, 137, 167, -1, 52, 175,
+ -1, 83, 167, 110, -1, 173, 45, 173, -1, 167,
+ 7, 167, -1, 167, 97, 167, -1, 173, 45, 168,
+ -1, 173, 57, 168, -1, 173, 85, 168, -1, 173,
+ 78, 168, -1, 173, 54, 168, -1, 173, 89, 168,
+ -1, 173, 73, 92, -1, 173, 73, 90, 92, -1,
+ 173, -1, 172, -1, 172, -1, 172, 24, 169, -1,
+ 171, -1, 171, 24, 170, -1, 174, 45, 172, -1,
+ 177, -1, 88, 177, -1, 120, -1, 138, -1, 174,
+ -1, 175, 39, 176, -1, 176, -1, 176, -1, 66,
+ -1, 70, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 138, 138, 146, 147, 148, 149, 150, 154, 165,
+ 178, 190, 205, 218, 231, 241, 251, 258, 266, 270,
+ 277, 281, 288, 292, 296, 300, 304, 308, 312, 319,
+ 328, 340, 344, 348, 364, 385, 386, 390, 397, 398,
+ 414, 427, 433, 439, 445, 451, 457, 463, 469, 475,
+ 481, 487, 493, 502, 503, 507, 514, 525, 526, 534,
+ 542, 548, 554, 560, 569, 578, 584, 593, 600, 609
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER",
+ "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE",
+ "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY",
+ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER",
+ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT",
+ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE",
+ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE",
+ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP",
+ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT",
+ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM",
+ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING",
+ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN",
+ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT",
+ "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN",
+ "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG",
+ "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE",
+ "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL",
+ "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR",
+ "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY",
+ "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT",
+ "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI",
+ "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT",
+ "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION",
+ "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE",
+ "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW",
+ "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN",
+ "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL",
+ "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate",
+ "oneupdate", "onedelete", "table_def", "column_def", "column_and_type",
+ "column_type", "data_type_l", "data_type", "data_count", "oneselect",
+ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr",
+ "val", "constlist", "update_assign_list", "column_assignment",
+ "const_val", "column_val", "column", "table", "id", "number", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 147, 148, 149, 149, 149, 149, 149, 150, 150,
+ 151, 151, 152, 153, 154, 155, 155, 156, 157, 157,
+ 158, 158, 159, 159, 159, 159, 159, 159, 159, 160,
+ 161, 161, 162, 162, 163, 164, 164, 164, 165, 165,
+ 166, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+ 167, 167, 167, 168, 168, 169, 169, 170, 170, 171,
+ 172, 172, 172, 172, 173, 174, 174, 175, 176, 177
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 1, 1, 1, 1, 1, 10, 11,
+ 6, 7, 6, 2, 4, 3, 1, 2, 1, 2,
+ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1,
+ 4, 1, 2, 3, 2, 1, 3, 1, 1, 3,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3,
+ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 2, 5, 4,
+ 6, 7, 3, 31, 0, 0, 13, 38, 0, 0,
+ 68, 37, 32, 0, 35, 0, 66, 0, 67, 1,
+ 0, 0, 40, 0, 0, 33, 34, 0, 0, 0,
+ 0, 0, 0, 39, 0, 64, 0, 36, 65, 0,
+ 57, 0, 30, 0, 0, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 0, 0, 22, 26, 27, 24, 28, 25,
+ 17, 18, 20, 41, 43, 44, 69, 0, 62, 63,
+ 45, 54, 42, 60, 49, 53, 46, 0, 51, 48,
+ 47, 50, 0, 12, 58, 59, 11, 15, 0, 0,
+ 19, 0, 61, 52, 0, 14, 0, 29, 21, 0,
+ 23, 0, 55, 8, 0, 9, 56
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 6, 7, 8, 9, 10, 11, 53, 54, 55,
+ 80, 81, 82, 116, 12, 13, 22, 23, 16, 17,
+ 43, 90, 121, 49, 50, 91, 44, 45, 25, 26,
+ 93
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -111
+static const yysigned_char yypact[] =
+{
+ -28, -110, -38, -46, -32, -42, 29, -111, -111, -111,
+ -111, -111, -111, -67, -42, -42, -111, -99, -42, -48,
+ -111, -111, -111, -38, 17, 7, 11, -62, -111, -111,
+ 37, -22, -111, -43, -16, -111, -111, -48, -42, -42,
+ -48, -42, -43, -3, -29, -111, -48, -111, -111, -68,
+ 48, 28, -111, -36, -19, -111, -18, -5, -43, -43,
+ -58, -58, -58, -70, -58, -58, -58, -34, -43, -42,
+ -61, 20, -42, 5, 2, -111, -111, -111, -111, -111,
+ -111, 1, -2, -111, -3, -3, -111, 19, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -1, -111, -111,
+ -111, -111, -41, -3, -111, -111, -111, -111, -48, 19,
+ -111, 3, -111, -111, 13, -111, -12, -111, -111, -61,
+ -111, -9, 91, -13, -61, -111, -111
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, 47,
+ -111, -111, -111, -111, -111, -111, 101, -27, 98, -111,
+ -11, 52, 0, 53, -111, -53, 46, -4, 85, 40,
+ -66
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -68
+static const yysigned_char yytable[] =
+{
+ 24, 74, 58, 1, 58, 72, 19, 2, 20, 86,
+ 47, 14, 86, 52, 15, 24, 60, 105, 20, 67,
+ 97, 112, 98, 20, 20, 61, 18, 87, 62, 29,
+ 87, 57, 30, 24, 20, 51, 24, 56, 33, 3,
+ 42, 37, 24, 117, 63, 28, 38, 84, 85, 64,
+ -67, 75, 39, 40, 28, 28, 65, 103, 28, 88,
+ 66, 41, 88, 76, 77, 51, 122, 46, 56, 68,
+ 21, 122, 69, 70, 71, 78, 102, 89, 48, 106,
+ 89, 115, 108, 73, 4, 109, 21, 110, 111, 86,
+ 27, 113, 59, 114, 59, 118, 119, 79, 120, 31,
+ 32, 123, 5, 34, 24, 83, 92, 95, 95, 125,
+ 95, 95, 95, 94, 96, 124, 99, 100, 101, 107,
+ 35, 36, 104, 0, 126
+};
+
+static const short yycheck[] =
+{
+ 4, 19, 7, 31, 7, 24, 38, 35, 66, 70,
+ 37, 121, 70, 40, 52, 19, 45, 70, 66, 46,
+ 90, 87, 92, 66, 66, 54, 72, 88, 57, 0,
+ 88, 42, 99, 37, 66, 39, 40, 41, 137, 67,
+ 83, 24, 46, 109, 73, 5, 39, 58, 59, 78,
+ 39, 69, 114, 16, 14, 15, 85, 68, 18, 120,
+ 89, 83, 120, 81, 82, 69, 119, 83, 72, 137,
+ 118, 124, 24, 45, 110, 93, 110, 138, 38, 59,
+ 138, 108, 77, 102, 112, 83, 118, 86, 90, 70,
+ 5, 92, 97, 134, 97, 92, 83, 115, 110, 14,
+ 15, 110, 130, 18, 108, 110, 60, 61, 62, 122,
+ 64, 65, 66, 61, 62, 24, 64, 65, 66, 72,
+ 19, 23, 69, -1, 124
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 31, 35, 67, 112, 130, 148, 149, 150, 151,
+ 152, 153, 161, 162, 121, 52, 165, 166, 72, 38,
+ 66, 118, 163, 164, 174, 175, 176, 175, 176, 0,
+ 99, 175, 175, 137, 175, 163, 165, 24, 39, 114,
+ 16, 83, 83, 167, 173, 174, 83, 164, 176, 170,
+ 171, 174, 164, 154, 155, 156, 174, 167, 7, 97,
+ 45, 54, 57, 73, 78, 85, 89, 164, 137, 24,
+ 45, 110, 24, 102, 19, 69, 81, 82, 93, 115,
+ 157, 158, 159, 110, 167, 167, 70, 88, 120, 138,
+ 168, 172, 173, 177, 168, 173, 168, 90, 92, 168,
+ 168, 168, 110, 167, 170, 172, 59, 156, 77, 83,
+ 86, 90, 177, 92, 134, 164, 160, 177, 92, 83,
+ 110, 169, 172, 110, 24, 122, 169
+};
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
# define YYSIZE_T __SIZE_TYPE__
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY -2
+#define YYEMPTY (-2)
#define YYEOF 0
+
#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
+
#define YYFAIL goto yyerrlab
+
#define YYRECOVERING() (!!yyerrstatus)
+
#define YYBACKUP(Token, Value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ \
yychar = (Token); \
yylval = (Value); \
- yychar1 = YYTRANSLATE (yychar); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ \
- yyerror ("syntax error: cannot back up"); \
+ yyerror ("syntax error: cannot back up");\
YYERROR; \
} \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
-
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run).
-
- When YYLLOC_DEFAULT is run, CURRENT is set the location of the
- first token. By default, to implement support for ranges, extend
- its range to the last symbol. */
+ are run). */
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
#endif
-
/* YYLEX -- calling `yylex' with the right arguments. */
-#if YYPURE
-# if YYLSP_NEEDED
-# ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-# else
-# define YYLEX yylex (&yylval, &yylloc)
-# endif
-# else /* !YYLSP_NEEDED */
-# ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-# else
-# define YYLEX yylex (&yylval)
-# endif
-# endif /* !YYLSP_NEEDED */
-#else /* !YYPURE */
-# define YYLEX yylex ()
-#endif /* !YYPURE */
-
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
/* Enable debugging if requested. */
#if YYDEBUG
if (yydebug) \
YYFPRINTF Args; \
} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
+
/* YYINITDEPTH -- initial size of the parser's stacks. */
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if YYMAXDEPTH == 0
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
# undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
+
\f
-#ifdef YYERROR_VERBOSE
+
+#if YYERROR_VERBOSE
# ifndef yystrlen
# if defined (__GLIBC__) && defined (_STRING_H)
}
# endif
# endif
-#endif
+
+#endif /* !YYERROR_VERBOSE */
+
\f
-#line 315 "/usr/share/bison/bison.simple"
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
- into yyparse. The argument should have type void *.
- It should actually point to an object.
- Grammar actions can access the variable by casting it
- to the proper pointer type. */
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
# if defined (__STDC__) || defined (__cplusplus)
-# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-# define YYPARSE_PARAM_DECL
+int yyparse (void *YYPARSE_PARAM);
# else
-# define YYPARSE_PARAM_ARG YYPARSE_PARAM
-# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+int yyparse ();
# endif
-#else /* !YYPARSE_PARAM */
-# define YYPARSE_PARAM_ARG
-# define YYPARSE_PARAM_DECL
-#endif /* !YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-# ifdef YYPARSE_PARAM
-int yyparse (void *);
-# else
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
int yyparse (void);
-# endif
+#else
+int yyparse ();
#endif
+#endif /* ! YYPARSE_PARAM */
+
-/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
- variables are global, or local to YYPARSE. */
-
-#define YY_DECL_NON_LSP_VARIABLES \
-/* The lookahead symbol. */ \
-int yychar; \
- \
-/* The semantic value of the lookahead symbol. */ \
-YYSTYPE yylval; \
- \
-/* Number of parse errors so far. */ \
-int yynerrs;
-#if YYLSP_NEEDED
-# define YY_DECL_VARIABLES \
-YY_DECL_NON_LSP_VARIABLES \
- \
-/* Location data for the lookahead symbol. */ \
-YYLTYPE yylloc;
-#else
-# define YY_DECL_VARIABLES \
-YY_DECL_NON_LSP_VARIABLES
-#endif
-/* If nonreentrant, generate the variables here. */
-#if !YYPURE
-YY_DECL_VARIABLES
-#endif /* !YYPURE */
+/*----------.
+| yyparse. |
+`----------*/
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
int
-yyparse (YYPARSE_PARAM_ARG)
- YYPARSE_PARAM_DECL
+yyparse ()
+
+#endif
+#endif
{
- /* If reentrant, generate the variables here. */
-#if YYPURE
- YY_DECL_VARIABLES
-#endif /* !YYPURE */
+ /* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
register int yystate;
register int yyn;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Lookahead token as an internal (translated) token number. */
- int yychar1 = 0;
+ int yytoken = 0;
/* Three stacks and their tools:
`yyss': related to states,
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
- /* The state stack. */
+ /* The state stack. */
short yyssa[YYINITDEPTH];
short *yyss = yyssa;
register short *yyssp;
YYSTYPE *yyvs = yyvsa;
register YYSTYPE *yyvsp;
-#if YYLSP_NEEDED
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
-#endif
-#if YYLSP_NEEDED
-# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
-#else
-# define YYPOPSTACK (yyvsp--, yyssp--)
-#endif
- YYSIZE_T yystacksize = YYINITDEPTH;
+#define YYPOPSTACK (yyvsp--, yyssp--)
+ YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
-#if YYLSP_NEEDED
- YYLTYPE yyloc;
-#endif
+
/* When reducing, the number of symbols on the RHS of the reduced
- rule. */
+ rule. */
int yylen;
YYDPRINTF ((stderr, "Starting parse\n"));
yyssp = yyss;
yyvsp = yyvs;
-#if YYLSP_NEEDED
- yylsp = yyls;
-#endif
+
goto yysetstate;
/*------------------------------------------------------------.
yysetstate:
*yyssp = yystate;
- if (yyssp >= yyss + yystacksize - 1)
+ if (yyss + yystacksize - 1 <= yyssp)
{
/* Get the current used size of the three stacks, in elements. */
YYSIZE_T yysize = yyssp - yyss + 1;
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. */
-# if YYLSP_NEEDED
- YYLTYPE *yyls1 = yyls;
- /* This used to be a conditional around just the two extra args,
- but that might be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
- &yystacksize);
- yyls = yyls1;
-# else
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
yyoverflow ("parser stack overflow",
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
-# endif
+
yyss = yyss1;
yyvs = yyvs1;
}
goto yyoverflowlab;
# else
/* Extend the stack our own way. */
- if (yystacksize >= YYMAXDEPTH)
+ if (YYMAXDEPTH <= yystacksize)
goto yyoverflowlab;
yystacksize *= 2;
- if (yystacksize > YYMAXDEPTH)
+ if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
goto yyoverflowlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
-# if YYLSP_NEEDED
- YYSTACK_RELOCATE (yyls);
-# endif
-# undef YYSTACK_RELOCATE
+
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
-#if YYLSP_NEEDED
- yylsp = yyls + yysize - 1;
-#endif
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
- if (yyssp >= yyss + yystacksize - 1)
+ if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
goto yybackup;
-
/*-----------.
| yybackup. |
`-----------*/
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
- if (yyn == YYFLAG)
+ if (yyn == YYPACT_NINF)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
- /* yychar is either YYEMPTY or YYEOF
- or a valid token in external form. */
-
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX;
}
- /* Convert token to internal form (in yychar1) for indexing tables with */
-
- if (yychar <= 0) /* This means end of input. */
+ if (yychar <= YYEOF)
{
- yychar1 = 0;
- yychar = YYEOF; /* Don't call YYLEX any more */
-
+ yychar = yytoken = YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
- yychar1 = YYTRANSLATE (yychar);
-
-#if YYDEBUG
- /* We have to keep this `#if YYDEBUG', since we use variables
- which are defined only if `YYDEBUG' is set. */
- if (yydebug)
- {
- YYFPRINTF (stderr, "Next token is %d (%s",
- yychar, yytname[yychar1]);
- /* Give the individual parser a way to print the precise
- meaning of a token, for further debugging info. */
-# ifdef YYPRINT
- YYPRINT (stderr, yychar, yylval);
-# endif
- YYFPRINTF (stderr, ")\n");
- }
-#endif
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
}
- yyn += yychar1;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault;
-
yyn = yytable[yyn];
-
- /* yyn is what to do for this token type in this state.
- Negative => reduce, -yyn is rule number.
- Positive => shift, yyn is new state.
- New state is final state => don't bother to shift,
- just return success.
- 0, or most negative number => error. */
-
- if (yyn < 0)
+ if (yyn <= 0)
{
- if (yyn == YYFLAG)
+ if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
- else if (yyn == 0)
- goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %d (%s), ",
- yychar, yytname[yychar1]));
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
-#if YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
+
/* Count tokens shifted since error; after three, turn off error
status. */
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
- Otherwise, the following line sets YYVAL to the semantic value of
- the lookahead token. This behavior is undocumented and Bison
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
users should not rely upon it. Assigning to YYVAL
unconditionally makes the parser a bit smaller, and it avoids a
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
-#if YYLSP_NEEDED
- /* Similarly for the default location. Let the user run additional
- commands if for instance locations are ranges. */
- yyloc = yylsp[1-yylen];
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-#endif
-#if YYDEBUG
- /* We have to keep this `#if YYDEBUG', since we use variables which
- are defined only if `YYDEBUG' is set. */
- if (yydebug)
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
{
- int yyi;
-
- YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
- yyn, yyrline[yyn]);
-
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
- YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
- YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
- }
-#endif
-
- switch (yyn) {
-
-case 1:
+ case 2:
#line 139 "./sql.y"
-{
+ {
SQL_input* sql = (SQL_input*) info;
*sql->view = yyvsp[0].query;
- ;
- break;}
-case 7:
+ ;}
+ break;
+
+ case 8:
#line 155 "./sql.y"
-{
+ {
SQL_input *sql = (SQL_input*) info;
MSIVIEW *insert = NULL;
UINT r;
if( !insert )
YYABORT;
yyval.query = insert;
- ;
- break;}
-case 8:
+ ;}
+ break;
+
+ case 9:
#line 166 "./sql.y"
-{
+ {
SQL_input *sql = (SQL_input*) info;
MSIVIEW *insert = NULL;
if( !insert )
YYABORT;
yyval.query = insert;
- ;
- break;}
-case 9:
+ ;}
+ break;
+
+ case 10:
#line 179 "./sql.y"
-{
+ {
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create = NULL;
if( !create )
YYABORT;
yyval.query = create;
- ;
- break;}
-case 10:
+ ;}
+ break;
+
+ case 11:
#line 191 "./sql.y"
-{
+ {
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create = NULL;
if( !create )
YYABORT;
yyval.query = create;
- ;
- break;}
-case 11:
+ ;}
+ break;
+
+ case 12:
#line 206 "./sql.y"
-{
+ {
SQL_input* sql = (SQL_input*) info;
MSIVIEW *update = NULL;
if( !update )
YYABORT;
yyval.query = update;
- ;
- break;}
-case 12:
+ ;}
+ break;
+
+ case 13:
#line 219 "./sql.y"
-{
+ {
SQL_input* sql = (SQL_input*) info;
MSIVIEW *delete = NULL;
if( !delete )
YYABORT;
yyval.query = delete;
- ;
- break;}
-case 13:
+ ;}
+ break;
+
+ case 14:
#line 232 "./sql.y"
-{
+ {
if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) )
yyval.column_list = yyvsp[-3].column_list;
else
yyval.column_list = NULL;
- ;
- break;}
-case 14:
+ ;}
+ break;
+
+ case 15:
#line 242 "./sql.y"
-{
+ {
column_info *ci;
for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next )
ci->next = yyvsp[0].column_list;
yyval.column_list = yyvsp[-2].column_list;
- ;
- break;}
-case 15:
+ ;}
+ break;
+
+ case 16:
#line 252 "./sql.y"
-{
+ {
yyval.column_list = yyvsp[0].column_list;
- ;
- break;}
-case 16:
+ ;}
+ break;
+
+ case 17:
#line 259 "./sql.y"
-{
+ {
yyval.column_list = yyvsp[-1].column_list;
- yyval.column_list->type = yyvsp[0].column_type;
- ;
- break;}
-case 17:
+ yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID;
+ ;}
+ break;
+
+ case 18:
#line 267 "./sql.y"
-{
- yyval.column_type = yyvsp[0].column_type | MSITYPE_VALID;
- ;
- break;}
-case 18:
+ {
+ yyval.column_type = yyvsp[0].column_type;
+ ;}
+ break;
+
+ case 19:
#line 271 "./sql.y"
-{
- FIXME("LOCALIZABLE ignored\n");
- yyval.column_type = yyvsp[-1].column_type | MSITYPE_VALID;
- ;
- break;}
-case 19:
-#line 279 "./sql.y"
-{
+ {
+ yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE;
+ ;}
+ break;
+
+ case 20:
+#line 278 "./sql.y"
+ {
yyval.column_type |= MSITYPE_NULLABLE;
- ;
- break;}
-case 20:
-#line 283 "./sql.y"
-{
+ ;}
+ break;
+
+ case 21:
+#line 282 "./sql.y"
+ {
yyval.column_type = yyvsp[-2].column_type;
- ;
- break;}
-case 21:
-#line 290 "./sql.y"
-{
+ ;}
+ break;
+
+ case 22:
+#line 289 "./sql.y"
+ {
yyval.column_type = MSITYPE_STRING | 1;
- ;
- break;}
-case 22:
-#line 294 "./sql.y"
-{
+ ;}
+ break;
+
+ case 23:
+#line 293 "./sql.y"
+ {
yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type;
- ;
- break;}
-case 23:
-#line 298 "./sql.y"
-{
+ ;}
+ break;
+
+ case 24:
+#line 297 "./sql.y"
+ {
yyval.column_type = 2;
- ;
- break;}
-case 24:
-#line 302 "./sql.y"
-{
+ ;}
+ break;
+
+ case 25:
+#line 301 "./sql.y"
+ {
yyval.column_type = 2;
- ;
- break;}
-case 25:
-#line 306 "./sql.y"
-{
+ ;}
+ break;
+
+ case 26:
+#line 305 "./sql.y"
+ {
yyval.column_type = 2;
- ;
- break;}
-case 26:
-#line 310 "./sql.y"
-{
+ ;}
+ break;
+
+ case 27:
+#line 309 "./sql.y"
+ {
yyval.column_type = 4;
- ;
- break;}
-case 27:
-#line 314 "./sql.y"
-{
- yyval.column_type = 0;
- ;
- break;}
-case 28:
-#line 321 "./sql.y"
-{
+ ;}
+ break;
+
+ case 28:
+#line 313 "./sql.y"
+ {
+ yyval.column_type = MSITYPE_STRING | MSITYPE_VALID;
+ ;}
+ break;
+
+ case 29:
+#line 320 "./sql.y"
+ {
if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) )
YYABORT;
yyval.column_type = yyvsp[0].integer;
- ;
- break;}
-case 29:
-#line 330 "./sql.y"
-{
+ ;}
+ break;
+
+ case 30:
+#line 329 "./sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
yyval.query = NULL;
yyval.query = yyvsp[-3].query;
if( !yyval.query )
YYABORT;
- ;
- break;}
-case 31:
-#line 346 "./sql.y"
-{
+ ;}
+ break;
+
+ case 32:
+#line 345 "./sql.y"
+ {
yyval.query = yyvsp[0].query;
- ;
- break;}
-case 32:
-#line 350 "./sql.y"
-{
+ ;}
+ break;
+
+ case 33:
+#line 349 "./sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
+ UINT r;
yyval.query = NULL;
- DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query );
- if( !yyval.query )
+ r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query );
+ if (r != ERROR_SUCCESS)
+ {
+ yyvsp[0].query->ops->delete(yyvsp[0].query);
YYABORT;
- ;
- break;}
-case 33:
-#line 362 "./sql.y"
-{
+ }
+ ;}
+ break;
+
+ case 34:
+#line 365 "./sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
+ UINT r;
yyval.query = NULL;
if( yyvsp[-1].column_list )
- SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list );
+ {
+ r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list );
+ if (r != ERROR_SUCCESS)
+ {
+ yyvsp[0].query->ops->delete(yyvsp[0].query);
+ YYABORT;
+ }
+ }
else
yyval.query = yyvsp[0].query;
+ ;}
+ break;
- if( !yyval.query )
- YYABORT;
- ;
- break;}
-case 35:
-#line 379 "./sql.y"
-{
+ case 36:
+#line 387 "./sql.y"
+ {
yyvsp[-2].column_list->next = yyvsp[0].column_list;
- ;
- break;}
-case 36:
-#line 383 "./sql.y"
-{
- yyval.column_list = NULL;
- ;
- break;}
-case 38:
+ ;}
+ break;
+
+ case 37:
#line 391 "./sql.y"
-{
+ {
+ yyval.column_list = NULL;
+ ;}
+ break;
+
+ case 39:
+#line 399 "./sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
UINT r;
yyval.query = NULL;
r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr );
- if( r != ERROR_SUCCESS || !yyval.query )
+ if( r != ERROR_SUCCESS )
+ {
+ yyvsp[-2].query->ops->delete( yyvsp[-2].query );
YYABORT;
- ;
- break;}
-case 39:
-#line 404 "./sql.y"
-{
+ }
+ ;}
+ break;
+
+ case 40:
+#line 415 "./sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
UINT r;
r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query );
if( r != ERROR_SUCCESS || !yyval.query )
YYABORT;
- ;
- break;}
-case 40:
-#line 417 "./sql.y"
-{
+ ;}
+ break;
+
+ case 41:
+#line 428 "./sql.y"
+ {
yyval.expr = yyvsp[-1].expr;
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 41:
-#line 423 "./sql.y"
-{
+ ;}
+ break;
+
+ case 42:
+#line 434 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 42:
-#line 429 "./sql.y"
-{
+ ;}
+ break;
+
+ case 43:
+#line 440 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 43:
-#line 435 "./sql.y"
-{
+ ;}
+ break;
+
+ case 44:
+#line 446 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 44:
-#line 441 "./sql.y"
-{
+ ;}
+ break;
+
+ case 45:
+#line 452 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 45:
-#line 447 "./sql.y"
-{
+ ;}
+ break;
+
+ case 46:
+#line 458 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 46:
-#line 453 "./sql.y"
-{
+ ;}
+ break;
+
+ case 47:
+#line 464 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 47:
-#line 459 "./sql.y"
-{
+ ;}
+ break;
+
+ case 48:
+#line 470 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 48:
-#line 465 "./sql.y"
-{
+ ;}
+ break;
+
+ case 49:
+#line 476 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 49:
-#line 471 "./sql.y"
-{
+ ;}
+ break;
+
+ case 50:
+#line 482 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 50:
-#line 477 "./sql.y"
-{
+ ;}
+ break;
+
+ case 51:
+#line 488 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 51:
-#line 483 "./sql.y"
-{
+ ;}
+ break;
+
+ case 52:
+#line 494 "./sql.y"
+ {
yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 54:
-#line 497 "./sql.y"
-{
+ ;}
+ break;
+
+ case 55:
+#line 508 "./sql.y"
+ {
yyval.column_list = parser_alloc_column( info, NULL, NULL );
if( !yyval.column_list )
YYABORT;
yyval.column_list->val = yyvsp[0].expr;
- ;
- break;}
-case 55:
-#line 504 "./sql.y"
-{
+ ;}
+ break;
+
+ case 56:
+#line 515 "./sql.y"
+ {
yyval.column_list = parser_alloc_column( info, NULL, NULL );
if( !yyval.column_list )
YYABORT;
yyval.column_list->val = yyvsp[-2].expr;
yyval.column_list->next = yyvsp[0].column_list;
- ;
- break;}
-case 57:
-#line 516 "./sql.y"
-{
+ ;}
+ break;
+
+ case 58:
+#line 527 "./sql.y"
+ {
yyval.column_list = yyvsp[-2].column_list;
yyval.column_list->next = yyvsp[0].column_list;
- ;
- break;}
-case 58:
-#line 524 "./sql.y"
-{
+ ;}
+ break;
+
+ case 59:
+#line 535 "./sql.y"
+ {
yyval.column_list = yyvsp[-2].column_list;
yyval.column_list->val = yyvsp[0].expr;
- ;
- break;}
-case 59:
-#line 532 "./sql.y"
-{
+ ;}
+ break;
+
+ case 60:
+#line 543 "./sql.y"
+ {
yyval.expr = EXPR_ival( info, yyvsp[0].integer );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 60:
-#line 538 "./sql.y"
-{
+ ;}
+ break;
+
+ case 61:
+#line 549 "./sql.y"
+ {
yyval.expr = EXPR_ival( info, -yyvsp[0].integer );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 61:
-#line 544 "./sql.y"
-{
+ ;}
+ break;
+
+ case 62:
+#line 555 "./sql.y"
+ {
yyval.expr = EXPR_sval( info, &yyvsp[0].str );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 62:
-#line 550 "./sql.y"
-{
+ ;}
+ break;
+
+ case 63:
+#line 561 "./sql.y"
+ {
yyval.expr = EXPR_wildcard( info );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 63:
-#line 559 "./sql.y"
-{
+ ;}
+ break;
+
+ case 64:
+#line 570 "./sql.y"
+ {
yyval.expr = EXPR_column( info, yyvsp[0].column_list );
if( !yyval.expr )
YYABORT;
- ;
- break;}
-case 64:
-#line 568 "./sql.y"
-{
+ ;}
+ break;
+
+ case 65:
+#line 579 "./sql.y"
+ {
yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string );
if( !yyval.column_list )
YYABORT;
- ;
- break;}
-case 65:
-#line 574 "./sql.y"
-{
+ ;}
+ break;
+
+ case 66:
+#line 585 "./sql.y"
+ {
yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string );
if( !yyval.column_list )
YYABORT;
- ;
- break;}
-case 66:
-#line 583 "./sql.y"
-{
+ ;}
+ break;
+
+ case 67:
+#line 594 "./sql.y"
+ {
yyval.string = yyvsp[0].string;
- ;
- break;}
-case 67:
-#line 590 "./sql.y"
-{
+ ;}
+ break;
+
+ case 68:
+#line 601 "./sql.y"
+ {
yyval.string = SQL_getstring( info, &yyvsp[0].str );
if( !yyval.string )
YYABORT;
- ;
- break;}
-case 68:
-#line 599 "./sql.y"
-{
+ ;}
+ break;
+
+ case 69:
+#line 610 "./sql.y"
+ {
yyval.integer = SQL_getint( info );
- ;
- break;}
-}
+ ;}
+ break;
-#line 705 "/usr/share/bison/bison.simple"
+ }
+
+/* Line 1000 of yacc.c. */
+#line 2054 "sql.tab.c"
\f
yyvsp -= yylen;
yyssp -= yylen;
-#if YYLSP_NEEDED
- yylsp -= yylen;
-#endif
-#if YYDEBUG
- if (yydebug)
- {
- short *yyssp1 = yyss - 1;
- YYFPRINTF (stderr, "state stack now");
- while (yyssp1 != yyssp)
- YYFPRINTF (stderr, " %d", *++yyssp1);
- YYFPRINTF (stderr, "\n");
- }
-#endif
+
+ YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
-#if YYLSP_NEEDED
- *++yylsp = yyloc;
-#endif
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
yyn = yyr1[yyn];
- yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
- if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
- yystate = yydefgoto[yyn - YYNTBASE];
+ yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
if (!yyerrstatus)
{
++yynerrs;
-
-#ifdef YYERROR_VERBOSE
+#if YYERROR_VERBOSE
yyn = yypact[yystate];
- if (yyn > YYFLAG && yyn < YYLAST)
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
{
YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
char *yymsg;
- int yyx, yycount;
+ int yyx;
- yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
- if (yycheck[yyx + yyn] == yyx)
- yysize += yystrlen (yytname[yyx]) + 15, yycount++;
- yysize += yystrlen ("parse error, unexpected ") + 1;
- yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
- char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
- yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
if (yycount < 5)
{
- yycount = 0;
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *));
- yyx++)
- if (yycheck[yyx + yyn] == yyx)
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
- const char *yyq = ! yycount ? ", expecting " : " or ";
- yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yyprefix);
yyp = yystpcpy (yyp, yytname[yyx]);
- yycount++;
+ yyprefix = " or ";
}
}
yyerror (yymsg);
YYSTACK_FREE (yymsg);
}
else
- yyerror ("parse error; also virtual memory exhausted");
+ yyerror ("syntax error; also virtual memory exhausted");
}
else
-#endif /* defined (YYERROR_VERBOSE) */
- yyerror ("parse error");
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
}
- goto yyerrlab1;
-/*--------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action |
-`--------------------------------------------------*/
-yyerrlab1:
+
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
- /* return failure if at end of input */
- if (yychar == YYEOF)
- YYABORT;
- YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
- yychar, yytname[yychar1]));
- yychar = YYEMPTY;
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
}
/* Else will try to reuse lookahead token after shifting the error
token. */
-
- yyerrstatus = 3; /* Each real token shifted decrements this */
-
- goto yyerrhandle;
+ goto yyerrlab1;
-/*-------------------------------------------------------------------.
-| yyerrdefault -- current state does not do anything special for the |
-| error token. |
-`-------------------------------------------------------------------*/
-yyerrdefault:
-#if 0
- /* This is wrong; only states that explicitly want error tokens
- should shift them. */
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
- /* If its default is to accept any token, ok. Otherwise pop it. */
- yyn = yydefact[yystate];
- if (yyn)
- goto yydefault;
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
#endif
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
-/*---------------------------------------------------------------.
-| yyerrpop -- pop the current state because it cannot handle the |
-| error token |
-`---------------------------------------------------------------*/
-yyerrpop:
- if (yyssp == yyss)
- YYABORT;
- yyvsp--;
- yystate = *--yyssp;
-#if YYLSP_NEEDED
- yylsp--;
-#endif
-#if YYDEBUG
- if (yydebug)
- {
- short *yyssp1 = yyss - 1;
- YYFPRINTF (stderr, "Error: state stack now");
- while (yyssp1 != yyssp)
- YYFPRINTF (stderr, " %d", *++yyssp1);
- YYFPRINTF (stderr, "\n");
- }
-#endif
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
-/*--------------.
-| yyerrhandle. |
-`--------------*/
-yyerrhandle:
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yyerrdefault;
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
- yyn += YYTERROR;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
- goto yyerrdefault;
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
- yyn = yytable[yyn];
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrpop;
- yyn = -yyn;
- goto yyreduce;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
}
- else if (yyn == 0)
- goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
YYDPRINTF ((stderr, "Shifting error token, "));
*++yyvsp = yylval;
-#if YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
+
yystate = yyn;
goto yynewstate;
yyresult = 1;
goto yyreturn;
-/*---------------------------------------------.
-| yyoverflowab -- parser overflow comes here. |
-`---------------------------------------------*/
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
yyoverflowlab:
yyerror ("parser stack overflow");
yyresult = 2;
/* Fall through. */
+#endif
yyreturn:
#ifndef yyoverflow
#endif
return yyresult;
}
-#line 604 "./sql.y"
+
+
+#line 615 "./sql.y"
static void *parser_alloc( void *info, unsigned int sz )
SQL_input* sql = (SQL_input*) info;
struct list *mem;
- mem = HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) + sz );
+ mem = msi_alloc( sizeof (struct list) + sz );
list_add_tail( sql->mem, mem );
return &mem[1];
}
if( ! sql->command[sql->n] )
return 0; /* end of input */
- TRACE("string : %s\n", debugstr_w(&sql->command[sql->n]));
+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */
sql->len = sqliteGetToken( &sql->command[sql->n], &token );
if( sql->len==0 )
break;
}
while( token == TK_SPACE );
- TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len));
+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
return token;
}
TRACE("Parse returned %d\n", r);
if( r )
{
- if( *sql.view )
- (*sql.view)->ops->delete( *sql.view );
*sql.view = NULL;
return ERROR_BAD_QUERY_SYNTAX;
}
return ERROR_SUCCESS;
}
+
-#ifndef BISON_SQL_TAB_H
-# define BISON_SQL_TAB_H
+/* A Bison parser, made by GNU Bison 1.875c. */
-#ifndef YYSTYPE
-typedef union
-{
+/* Skeleton parser for Yacc-like parsing with Bison,
+ 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 72 "./sql.y"
+typedef union YYSTYPE {
struct sql_str str;
LPWSTR string;
column_info *column_list;
struct expr *expr;
USHORT column_type;
int integer;
-} yystype;
-# define YYSTYPE yystype
+} YYSTYPE;
+/* Line 1275 of yacc.c. */
+#line 337 "sql.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#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 */
+
+
+
-%{\r
-\r
-/*\r
- * Implementation of the Microsoft Installer (msi.dll)\r
- *\r
- * Copyright 2002-2004 Mike McCormack for CodeWeavers\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-\r
-#include "config.h"\r
-\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "query.h"\r
-#include "wine/list.h"\r
-#include "wine/debug.h"\r
-\r
-#define YYLEX_PARAM info\r
-#define YYPARSE_PARAM info\r
-\r
-extern int SQL_error(const char *str);\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(msi);\r
-\r
-typedef struct tag_SQL_input\r
-{\r
- MSIDATABASE *db;\r
- LPCWSTR command;\r
- DWORD n, len;\r
- MSIVIEW **view; /* view structure for the resulting query */\r
- struct list *mem;\r
-} SQL_input;\r
-\r
-static LPWSTR SQL_getstring( void *info, struct sql_str *str );\r
-static INT SQL_getint( void *info );\r
-static int SQL_lex( void *SQL_lval, SQL_input *info );\r
-\r
-static void *parser_alloc( void *info, unsigned int sz );\r
-static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );\r
-\r
-static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);\r
-\r
-static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );\r
-static struct expr * EXPR_column( void *info, column_info *column );\r
-static struct expr * EXPR_ival( void *info, int val );\r
-static struct expr * EXPR_sval( void *info, struct sql_str * );\r
-static struct expr * EXPR_wildcard( void *info );\r
-\r
-%}\r
-\r
-%pure-parser\r
-\r
-%union\r
-{\r
- struct sql_str str;\r
- LPWSTR string;\r
- column_info *column_list;\r
- MSIVIEW *query;\r
- struct expr *expr;\r
- USHORT column_type;\r
- int integer;\r
-}\r
-\r
-%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC\r
-%token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY\r
-%token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN\r
-%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT \r
-%token TK_CONSTRAINT TK_COPY TK_CREATE\r
-%token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC\r
-%token TK_DISTINCT TK_DOT TK_DROP TK_EACH\r
-%token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN\r
-%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION\r
-%token TK_GE TK_GLOB TK_GROUP TK_GT\r
-%token TK_HAVING TK_HOLD\r
-%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY\r
-%token <str> TK_ID \r
-%token TK_INSERT TK_INSTEAD TK_INT \r
-%token <str> TK_INTEGER\r
-%token TK_INTERSECT TK_INTO TK_IS\r
-%token TK_ISNULL\r
-%token TK_JOIN TK_JOIN_KW\r
-%token TK_KEY\r
-%token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT\r
-%token TK_LOCALIZABLE\r
-%token TK_MATCH TK_MINUS\r
-%token TK_NE TK_NOT TK_NOTNULL TK_NULL\r
-%token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER\r
-%token TK_PLUS TK_PRAGMA TK_PRIMARY\r
-%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK\r
-%token TK_ROW TK_RP TK_RSHIFT\r
-%token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT \r
-%token <str> TK_STRING\r
-%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER\r
-%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE\r
-%token TK_UPDATE TK_UPLUS TK_USING\r
-%token TK_VACUUM TK_VALUES TK_VIEW\r
-%token TK_WHEN TK_WHERE TK_WILDCARD\r
-\r
-/*\r
- * These are extra tokens used by the lexer but never seen by the\r
- * parser. We put them in a rule so that the parser generator will\r
- * add them to the parse.h output file.\r
- *\r
- */\r
-%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION\r
- COLUMN AGG_FUNCTION.\r
-\r
-%type <string> table id\r
-%type <column_list> selcollist column column_and_type column_def table_def\r
-%type <column_list> column_assignment update_assign_list constlist\r
-%type <query> query from fromtable selectfrom unorderedsel\r
-%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert\r
-%type <expr> expr val column_val const_val\r
-%type <column_type> column_type data_type data_type_l data_count\r
-%type <integer> number\r
-\r
-%%\r
-\r
-query:\r
- onequery\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- *sql->view = $1;\r
- }\r
- ;\r
-\r
-onequery:\r
- oneselect\r
- | onecreate\r
- | oneinsert\r
- | oneupdate\r
- | onedelete\r
- ;\r
-\r
-oneinsert:\r
- TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP\r
- {\r
- SQL_input *sql = (SQL_input*) info;\r
- MSIVIEW *insert = NULL; \r
- UINT r;\r
-\r
- r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); \r
- if( !insert )\r
- YYABORT;\r
- $$ = insert;\r
- }\r
- | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP\r
- {\r
- SQL_input *sql = (SQL_input*) info;\r
- MSIVIEW *insert = NULL; \r
-\r
- INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); \r
- if( !insert )\r
- YYABORT;\r
- $$ = insert;\r
- }\r
- ;\r
-\r
-onecreate:\r
- TK_CREATE TK_TABLE table TK_LP table_def TK_RP\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *create = NULL; \r
-\r
- if( !$5 )\r
- YYABORT;\r
- CREATE_CreateView( sql->db, &create, $3, $5, FALSE );\r
- if( !create )\r
- YYABORT;\r
- $$ = create;\r
- }\r
- | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *create = NULL; \r
-\r
- if( !$5 )\r
- YYABORT;\r
- CREATE_CreateView( sql->db, &create, $3, $5, TRUE );\r
- if( !create )\r
- YYABORT;\r
- $$ = create;\r
- }\r
- ;\r
-\r
-oneupdate:\r
- TK_UPDATE table TK_SET update_assign_list TK_WHERE expr\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *update = NULL; \r
-\r
- UPDATE_CreateView( sql->db, &update, $2, $4, $6 );\r
- if( !update )\r
- YYABORT;\r
- $$ = update;\r
- }\r
- ;\r
-\r
-onedelete:\r
- TK_DELETE from\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *delete = NULL; \r
-\r
- DELETE_CreateView( sql->db, &delete, $2 );\r
- if( !delete )\r
- YYABORT;\r
- $$ = delete;\r
- }\r
- ;\r
-\r
-table_def:\r
- column_def TK_PRIMARY TK_KEY selcollist\r
- {\r
- if( SQL_MarkPrimaryKeys( $1, $4 ) )\r
- $$ = $1;\r
- else\r
- $$ = NULL;\r
- }\r
- ;\r
-\r
-column_def:\r
- column_def TK_COMMA column_and_type\r
- {\r
- column_info *ci;\r
-\r
- for( ci = $1; ci->next; ci = ci->next )\r
- ;\r
-\r
- ci->next = $3;\r
- $$ = $1;\r
- }\r
- | column_and_type\r
- {\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-column_and_type:\r
- column column_type\r
- {\r
- $$ = $1;\r
- $$->type = $2;\r
- }\r
- ;\r
-\r
-column_type:\r
- data_type_l\r
- {\r
- $$ = $1 | MSITYPE_VALID;\r
- }\r
- | data_type_l TK_LOCALIZABLE\r
- {\r
- FIXME("LOCALIZABLE ignored\n");\r
- $$ = $1 | MSITYPE_VALID;\r
- }\r
- ;\r
-\r
-data_type_l:\r
- data_type\r
- {\r
- $$ |= MSITYPE_NULLABLE;\r
- }\r
- | data_type TK_NOT TK_NULL\r
- {\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-data_type:\r
- TK_CHAR\r
- {\r
- $$ = MSITYPE_STRING | 1;\r
- }\r
- | TK_CHAR TK_LP data_count TK_RP\r
- {\r
- $$ = MSITYPE_STRING | 0x400 | $3;\r
- }\r
- | TK_LONGCHAR\r
- {\r
- $$ = 2;\r
- }\r
- | TK_SHORT\r
- {\r
- $$ = 2;\r
- }\r
- | TK_INT\r
- {\r
- $$ = 2;\r
- }\r
- | TK_LONG\r
- {\r
- $$ = 4;\r
- }\r
- | TK_OBJECT\r
- {\r
- $$ = 0;\r
- }\r
- ;\r
-\r
-data_count:\r
- number\r
- {\r
- if( ( $1 > 255 ) || ( $1 < 0 ) )\r
- YYABORT;\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-oneselect:\r
- unorderedsel TK_ORDER TK_BY selcollist\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
-\r
- $$ = NULL;\r
- if( $4 )\r
- ORDER_CreateView( sql->db, &$$, $1, $4 );\r
- else\r
- $$ = $1;\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | unorderedsel\r
- ;\r
-\r
-unorderedsel:\r
- TK_SELECT selectfrom\r
- {\r
- $$ = $2;\r
- }\r
- | TK_SELECT TK_DISTINCT selectfrom\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
-\r
- $$ = NULL;\r
- DISTINCT_CreateView( sql->db, &$$, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-selectfrom:\r
- selcollist from \r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
-\r
- $$ = NULL;\r
- if( $1 )\r
- SELECT_CreateView( sql->db, &$$, $2, $1 );\r
- else\r
- $$ = $2;\r
-\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-selcollist:\r
- column \r
- | column TK_COMMA selcollist\r
- { \r
- $1->next = $3;\r
- }\r
- | TK_STAR\r
- {\r
- $$ = NULL;\r
- }\r
- ;\r
-\r
-from:\r
- fromtable\r
- | fromtable TK_WHERE expr\r
- { \r
- SQL_input* sql = (SQL_input*) info;\r
- UINT r;\r
-\r
- $$ = NULL;\r
- r = WHERE_CreateView( sql->db, &$$, $1, $3 );\r
- if( r != ERROR_SUCCESS || !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-fromtable:\r
- TK_FROM table\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- UINT r;\r
-\r
- $$ = NULL;\r
- r = TABLE_CreateView( sql->db, $2, &$$ );\r
- if( r != ERROR_SUCCESS || !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-expr:\r
- TK_LP expr TK_RP\r
- {\r
- $$ = $2;\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_EQ column_val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_EQ, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | expr TK_AND expr\r
- {\r
- $$ = EXPR_complex( info, $1, OP_AND, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | expr TK_OR expr\r
- {\r
- $$ = EXPR_complex( info, $1, OP_OR, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_EQ val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_EQ, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_GT val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_GT, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_LT val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_LT, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_LE val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_LE, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_GE val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_GE, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_NE val\r
- {\r
- $$ = EXPR_complex( info, $1, OP_NE, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_IS TK_NULL\r
- {\r
- $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | column_val TK_IS TK_NOT TK_NULL\r
- {\r
- $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-val:\r
- column_val\r
- | const_val\r
- ;\r
-\r
-constlist:\r
- const_val\r
- {\r
- $$ = parser_alloc_column( info, NULL, NULL );\r
- if( !$$ )\r
- YYABORT;\r
- $$->val = $1;\r
- }\r
- | const_val TK_COMMA constlist\r
- {\r
- $$ = parser_alloc_column( info, NULL, NULL );\r
- if( !$$ )\r
- YYABORT;\r
- $$->val = $1;\r
- $$->next = $3;\r
- }\r
- ;\r
-\r
-update_assign_list:\r
- column_assignment\r
- | column_assignment TK_COMMA update_assign_list\r
- {\r
- $$ = $1;\r
- $$->next = $3;\r
- }\r
- ;\r
-\r
-column_assignment:\r
- column TK_EQ const_val\r
- {\r
- $$ = $1;\r
- $$->val = $3;\r
- }\r
- ;\r
-\r
-const_val:\r
- number\r
- {\r
- $$ = EXPR_ival( info, $1 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | TK_MINUS number\r
- {\r
- $$ = EXPR_ival( info, -$2 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | TK_STRING\r
- {\r
- $$ = EXPR_sval( info, &$1 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | TK_WILDCARD\r
- {\r
- $$ = EXPR_wildcard( info );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-column_val:\r
- column \r
- {\r
- $$ = EXPR_column( info, $1 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-column:\r
- table TK_DOT id\r
- {\r
- $$ = parser_alloc_column( info, $1, $3 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- | id\r
- {\r
- $$ = parser_alloc_column( info, NULL, $1 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-table:\r
- id\r
- {\r
- $$ = $1;\r
- }\r
- ;\r
-\r
-id:\r
- TK_ID\r
- {\r
- $$ = SQL_getstring( info, &$1 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- ;\r
-\r
-number:\r
- TK_INTEGER\r
- {\r
- $$ = SQL_getint( info );\r
- }\r
- ;\r
-\r
-%%\r
-\r
-static void *parser_alloc( void *info, unsigned int sz )\r
-{\r
- SQL_input* sql = (SQL_input*) info;\r
- struct list *mem;\r
-\r
- mem = HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) + sz );\r
- list_add_tail( sql->mem, mem );\r
- return &mem[1];\r
-}\r
-\r
-static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )\r
-{\r
- column_info *col;\r
-\r
- col = parser_alloc( info, sizeof (*col) );\r
- if( col )\r
- {\r
- col->table = table;\r
- col->column = column;\r
- col->val = NULL;\r
- col->type = 0;\r
- col->next = NULL;\r
- }\r
-\r
- return col;\r
-}\r
-\r
-int SQL_lex( void *SQL_lval, SQL_input *sql )\r
-{\r
- int token;\r
- struct sql_str * str = SQL_lval;\r
-\r
- do\r
- {\r
- sql->n += sql->len;\r
- if( ! sql->command[sql->n] )\r
- return 0; /* end of input */\r
-\r
- TRACE("string : %s\n", debugstr_w(&sql->command[sql->n]));\r
- sql->len = sqliteGetToken( &sql->command[sql->n], &token );\r
- if( sql->len==0 )\r
- break;\r
- str->data = &sql->command[sql->n];\r
- str->len = sql->len;\r
- }\r
- while( token == TK_SPACE );\r
-\r
- TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len));\r
- \r
- return token;\r
-}\r
-\r
-LPWSTR SQL_getstring( void *info, struct sql_str *strdata )\r
-{\r
- LPCWSTR p = strdata->data;\r
- UINT len = strdata->len;\r
- LPWSTR str;\r
-\r
- /* if there's quotes, remove them */\r
- if( ( (p[0]=='`') && (p[len-1]=='`') ) || \r
- ( (p[0]=='\'') && (p[len-1]=='\'') ) )\r
- {\r
- p++;\r
- len -= 2;\r
- }\r
- str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );\r
- if( !str )\r
- return str;\r
- memcpy( str, p, len*sizeof(WCHAR) );\r
- str[len]=0;\r
-\r
- return str;\r
-}\r
-\r
-INT SQL_getint( void *info )\r
-{\r
- SQL_input* sql = (SQL_input*) info;\r
- LPCWSTR p = &sql->command[sql->n];\r
- INT i, r = 0;\r
-\r
- for( i=0; i<sql->len; i++ )\r
- {\r
- if( '0' > p[i] || '9' < p[i] )\r
- {\r
- ERR("should only be numbers here!\n");\r
- break;\r
- }\r
- r = (p[i]-'0') + r*10;\r
- }\r
-\r
- return r;\r
-}\r
-\r
-int SQL_error( const char *str )\r
-{\r
- return 0;\r
-}\r
-\r
-static struct expr * EXPR_wildcard( void *info )\r
-{\r
- struct expr *e = parser_alloc( info, sizeof *e );\r
- if( e )\r
- {\r
- e->type = EXPR_WILDCARD;\r
- }\r
- return e;\r
-}\r
-\r
-static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )\r
-{\r
- struct expr *e = parser_alloc( info, sizeof *e );\r
- if( e )\r
- {\r
- e->type = EXPR_COMPLEX;\r
- e->u.expr.left = l;\r
- e->u.expr.op = op;\r
- e->u.expr.right = r;\r
- }\r
- return e;\r
-}\r
-\r
-static struct expr * EXPR_column( void *info, column_info *column )\r
-{\r
- struct expr *e = parser_alloc( info, sizeof *e );\r
- if( e )\r
- {\r
- e->type = EXPR_COLUMN;\r
- e->u.sval = column->column;\r
- }\r
- return e;\r
-}\r
-\r
-static struct expr * EXPR_ival( void *info, int val )\r
-{\r
- struct expr *e = parser_alloc( info, sizeof *e );\r
- if( e )\r
- {\r
- e->type = EXPR_IVAL;\r
- e->u.ival = val;\r
- }\r
- return e;\r
-}\r
-\r
-static struct expr * EXPR_sval( void *info, struct sql_str *str )\r
-{\r
- struct expr *e = parser_alloc( info, sizeof *e );\r
- if( e )\r
- {\r
- e->type = EXPR_SVAL;\r
- e->u.sval = SQL_getstring( info, str );\r
- }\r
- return e;\r
-}\r
-\r
-static BOOL SQL_MarkPrimaryKeys( column_info *cols,\r
- column_info *keys )\r
-{\r
- column_info *k;\r
- BOOL found = TRUE;\r
-\r
- for( k = keys; k && found; k = k->next )\r
- {\r
- column_info *c;\r
-\r
- found = FALSE;\r
- for( c = cols; c && !found; c = c->next )\r
- {\r
- if( lstrcmpW( k->column, c->column ) )\r
- continue;\r
- c->type |= MSITYPE_KEY;\r
- found = TRUE;\r
- }\r
- }\r
-\r
- return found;\r
-}\r
-\r
-UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,\r
- struct list *mem )\r
-{\r
- SQL_input sql;\r
- int r;\r
-\r
- *phview = NULL;\r
-\r
- sql.db = db;\r
- sql.command = command;\r
- sql.n = 0;\r
- sql.len = 0;\r
- sql.view = phview;\r
- sql.mem = mem;\r
-\r
- r = SQL_parse(&sql);\r
-\r
- TRACE("Parse returned %d\n", r);\r
- if( r )\r
- {\r
- if( *sql.view )\r
- (*sql.view)->ops->delete( *sql.view );\r
- *sql.view = NULL;\r
- return ERROR_BAD_QUERY_SYNTAX;\r
- }\r
-\r
- return ERROR_SUCCESS;\r
-}\r
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "query.h"
+#include "wine/list.h"
+#include "wine/debug.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+extern int SQL_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_SQL_input
+{
+ MSIDATABASE *db;
+ LPCWSTR command;
+ DWORD n, len;
+ MSIVIEW **view; /* view structure for the resulting query */
+ struct list *mem;
+} SQL_input;
+
+static LPWSTR SQL_getstring( void *info, struct sql_str *str );
+static INT SQL_getint( void *info );
+static int SQL_lex( void *SQL_lval, SQL_input *info );
+
+static void *parser_alloc( void *info, unsigned int sz );
+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
+
+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
+
+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_column( void *info, column_info *column );
+static struct expr * EXPR_ival( void *info, int val );
+static struct expr * EXPR_sval( void *info, struct sql_str * );
+static struct expr * EXPR_wildcard( void *info );
+
+%}
+
+%pure-parser
+
+%union
+{
+ struct sql_str str;
+ LPWSTR string;
+ column_info *column_list;
+ MSIVIEW *query;
+ struct expr *expr;
+ USHORT column_type;
+ int integer;
+}
+
+%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC
+%token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY
+%token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
+%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT
+%token TK_CONSTRAINT TK_COPY TK_CREATE
+%token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC
+%token TK_DISTINCT TK_DOT TK_DROP TK_EACH
+%token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN
+%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION
+%token TK_GE TK_GLOB TK_GROUP TK_GT
+%token TK_HAVING TK_HOLD
+%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
+%token <str> TK_ID
+%token TK_INSERT TK_INSTEAD TK_INT
+%token <str> TK_INTEGER
+%token TK_INTERSECT TK_INTO TK_IS
+%token TK_ISNULL
+%token TK_JOIN TK_JOIN_KW
+%token TK_KEY
+%token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT
+%token TK_LOCALIZABLE
+%token TK_MATCH TK_MINUS
+%token TK_NE TK_NOT TK_NOTNULL TK_NULL
+%token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
+%token TK_PLUS TK_PRAGMA TK_PRIMARY
+%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
+%token TK_ROW TK_RP TK_RSHIFT
+%token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT
+%token <str> TK_STRING
+%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER
+%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
+%token TK_UPDATE TK_UPLUS TK_USING
+%token TK_VACUUM TK_VALUES TK_VIEW
+%token TK_WHEN TK_WHERE TK_WILDCARD
+
+/*
+ * These are extra tokens used by the lexer but never seen by the
+ * parser. We put them in a rule so that the parser generator will
+ * add them to the parse.h output file.
+ *
+ */
+%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
+ COLUMN AGG_FUNCTION.
+
+%type <string> table id
+%type <column_list> selcollist column column_and_type column_def table_def
+%type <column_list> column_assignment update_assign_list constlist
+%type <query> query from fromtable selectfrom unorderedsel
+%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert
+%type <expr> expr val column_val const_val
+%type <column_type> column_type data_type data_type_l data_count
+%type <integer> number
+
+%%
+
+query:
+ onequery
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
+ ;
+
+onequery:
+ oneselect
+ | onecreate
+ | oneinsert
+ | oneupdate
+ | onedelete
+ ;
+
+oneinsert:
+ TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
+ {
+ SQL_input *sql = (SQL_input*) info;
+ MSIVIEW *insert = NULL;
+ UINT r;
+
+ r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
+ if( !insert )
+ YYABORT;
+ $$ = insert;
+ }
+ | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP
+ {
+ SQL_input *sql = (SQL_input*) info;
+ MSIVIEW *insert = NULL;
+
+ INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
+ if( !insert )
+ YYABORT;
+ $$ = insert;
+ }
+ ;
+
+onecreate:
+ TK_CREATE TK_TABLE table TK_LP table_def TK_RP
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *create = NULL;
+
+ if( !$5 )
+ YYABORT;
+ CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
+ if( !create )
+ YYABORT;
+ $$ = create;
+ }
+ | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *create = NULL;
+
+ if( !$5 )
+ YYABORT;
+ CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
+ if( !create )
+ YYABORT;
+ $$ = create;
+ }
+ ;
+
+oneupdate:
+ TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *update = NULL;
+
+ UPDATE_CreateView( sql->db, &update, $2, $4, $6 );
+ if( !update )
+ YYABORT;
+ $$ = update;
+ }
+ ;
+
+onedelete:
+ TK_DELETE from
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *delete = NULL;
+
+ DELETE_CreateView( sql->db, &delete, $2 );
+ if( !delete )
+ YYABORT;
+ $$ = delete;
+ }
+ ;
+
+table_def:
+ column_def TK_PRIMARY TK_KEY selcollist
+ {
+ if( SQL_MarkPrimaryKeys( $1, $4 ) )
+ $$ = $1;
+ else
+ $$ = NULL;
+ }
+ ;
+
+column_def:
+ column_def TK_COMMA column_and_type
+ {
+ column_info *ci;
+
+ for( ci = $1; ci->next; ci = ci->next )
+ ;
+
+ ci->next = $3;
+ $$ = $1;
+ }
+ | column_and_type
+ {
+ $$ = $1;
+ }
+ ;
+
+column_and_type:
+ column column_type
+ {
+ $$ = $1;
+ $$->type = $2 | MSITYPE_VALID;
+ }
+ ;
+
+column_type:
+ data_type_l
+ {
+ $$ = $1;
+ }
+ | data_type_l TK_LOCALIZABLE
+ {
+ $$ = $1 | MSITYPE_LOCALIZABLE;
+ }
+ ;
+
+data_type_l:
+ data_type
+ {
+ $$ |= MSITYPE_NULLABLE;
+ }
+ | data_type TK_NOT TK_NULL
+ {
+ $$ = $1;
+ }
+ ;
+
+data_type:
+ TK_CHAR
+ {
+ $$ = MSITYPE_STRING | 1;
+ }
+ | TK_CHAR TK_LP data_count TK_RP
+ {
+ $$ = MSITYPE_STRING | 0x400 | $3;
+ }
+ | TK_LONGCHAR
+ {
+ $$ = 2;
+ }
+ | TK_SHORT
+ {
+ $$ = 2;
+ }
+ | TK_INT
+ {
+ $$ = 2;
+ }
+ | TK_LONG
+ {
+ $$ = 4;
+ }
+ | TK_OBJECT
+ {
+ $$ = MSITYPE_STRING | MSITYPE_VALID;
+ }
+ ;
+
+data_count:
+ number
+ {
+ if( ( $1 > 255 ) || ( $1 < 0 ) )
+ YYABORT;
+ $$ = $1;
+ }
+ ;
+
+oneselect:
+ unorderedsel TK_ORDER TK_BY selcollist
+ {
+ SQL_input* sql = (SQL_input*) info;
+
+ $$ = NULL;
+ if( $4 )
+ ORDER_CreateView( sql->db, &$$, $1, $4 );
+ else
+ $$ = $1;
+ if( !$$ )
+ YYABORT;
+ }
+ | unorderedsel
+ ;
+
+unorderedsel:
+ TK_SELECT selectfrom
+ {
+ $$ = $2;
+ }
+ | TK_SELECT TK_DISTINCT selectfrom
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ $$ = NULL;
+ r = DISTINCT_CreateView( sql->db, &$$, $3 );
+ if (r != ERROR_SUCCESS)
+ {
+ $3->ops->delete($3);
+ YYABORT;
+ }
+ }
+ ;
+
+selectfrom:
+ selcollist from
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ $$ = NULL;
+ if( $1 )
+ {
+ r = SELECT_CreateView( sql->db, &$$, $2, $1 );
+ if (r != ERROR_SUCCESS)
+ {
+ $2->ops->delete($2);
+ YYABORT;
+ }
+ }
+ else
+ $$ = $2;
+ }
+ ;
+
+selcollist:
+ column
+ | column TK_COMMA selcollist
+ {
+ $1->next = $3;
+ }
+ | TK_STAR
+ {
+ $$ = NULL;
+ }
+ ;
+
+from:
+ fromtable
+ | fromtable TK_WHERE expr
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ $$ = NULL;
+ r = WHERE_CreateView( sql->db, &$$, $1, $3 );
+ if( r != ERROR_SUCCESS )
+ {
+ $1->ops->delete( $1 );
+ YYABORT;
+ }
+ }
+ ;
+
+fromtable:
+ TK_FROM table
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ $$ = NULL;
+ r = TABLE_CreateView( sql->db, $2, &$$ );
+ if( r != ERROR_SUCCESS || !$$ )
+ YYABORT;
+ }
+ ;
+
+expr:
+ TK_LP expr TK_RP
+ {
+ $$ = $2;
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_EQ column_val
+ {
+ $$ = EXPR_complex( info, $1, OP_EQ, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | expr TK_AND expr
+ {
+ $$ = EXPR_complex( info, $1, OP_AND, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | expr TK_OR expr
+ {
+ $$ = EXPR_complex( info, $1, OP_OR, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_EQ val
+ {
+ $$ = EXPR_complex( info, $1, OP_EQ, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_GT val
+ {
+ $$ = EXPR_complex( info, $1, OP_GT, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_LT val
+ {
+ $$ = EXPR_complex( info, $1, OP_LT, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_LE val
+ {
+ $$ = EXPR_complex( info, $1, OP_LE, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_GE val
+ {
+ $$ = EXPR_complex( info, $1, OP_GE, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_NE val
+ {
+ $$ = EXPR_complex( info, $1, OP_NE, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_IS TK_NULL
+ {
+ $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );
+ if( !$$ )
+ YYABORT;
+ }
+ | column_val TK_IS TK_NOT TK_NULL
+ {
+ $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+val:
+ column_val
+ | const_val
+ ;
+
+constlist:
+ const_val
+ {
+ $$ = parser_alloc_column( info, NULL, NULL );
+ if( !$$ )
+ YYABORT;
+ $$->val = $1;
+ }
+ | const_val TK_COMMA constlist
+ {
+ $$ = parser_alloc_column( info, NULL, NULL );
+ if( !$$ )
+ YYABORT;
+ $$->val = $1;
+ $$->next = $3;
+ }
+ ;
+
+update_assign_list:
+ column_assignment
+ | column_assignment TK_COMMA update_assign_list
+ {
+ $$ = $1;
+ $$->next = $3;
+ }
+ ;
+
+column_assignment:
+ column TK_EQ const_val
+ {
+ $$ = $1;
+ $$->val = $3;
+ }
+ ;
+
+const_val:
+ number
+ {
+ $$ = EXPR_ival( info, $1 );
+ if( !$$ )
+ YYABORT;
+ }
+ | TK_MINUS number
+ {
+ $$ = EXPR_ival( info, -$2 );
+ if( !$$ )
+ YYABORT;
+ }
+ | TK_STRING
+ {
+ $$ = EXPR_sval( info, &$1 );
+ if( !$$ )
+ YYABORT;
+ }
+ | TK_WILDCARD
+ {
+ $$ = EXPR_wildcard( info );
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+column_val:
+ column
+ {
+ $$ = EXPR_column( info, $1 );
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+column:
+ table TK_DOT id
+ {
+ $$ = parser_alloc_column( info, $1, $3 );
+ if( !$$ )
+ YYABORT;
+ }
+ | id
+ {
+ $$ = parser_alloc_column( info, NULL, $1 );
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+table:
+ id
+ {
+ $$ = $1;
+ }
+ ;
+
+id:
+ TK_ID
+ {
+ $$ = SQL_getstring( info, &$1 );
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+number:
+ TK_INTEGER
+ {
+ $$ = SQL_getint( info );
+ }
+ ;
+
+%%
+
+static void *parser_alloc( void *info, unsigned int sz )
+{
+ SQL_input* sql = (SQL_input*) info;
+ struct list *mem;
+
+ mem = msi_alloc( sizeof (struct list) + sz );
+ list_add_tail( sql->mem, mem );
+ return &mem[1];
+}
+
+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )
+{
+ column_info *col;
+
+ col = parser_alloc( info, sizeof (*col) );
+ if( col )
+ {
+ col->table = table;
+ col->column = column;
+ col->val = NULL;
+ col->type = 0;
+ col->next = NULL;
+ }
+
+ return col;
+}
+
+int SQL_lex( void *SQL_lval, SQL_input *sql )
+{
+ int token;
+ struct sql_str * str = SQL_lval;
+
+ do
+ {
+ sql->n += sql->len;
+ if( ! sql->command[sql->n] )
+ return 0; /* end of input */
+
+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */
+ sql->len = sqliteGetToken( &sql->command[sql->n], &token );
+ if( sql->len==0 )
+ break;
+ str->data = &sql->command[sql->n];
+ str->len = sql->len;
+ }
+ while( token == TK_SPACE );
+
+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
+
+ return token;
+}
+
+LPWSTR SQL_getstring( void *info, struct sql_str *strdata )
+{
+ LPCWSTR p = strdata->data;
+ UINT len = strdata->len;
+ LPWSTR str;
+
+ /* if there's quotes, remove them */
+ if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
+ ( (p[0]=='\'') && (p[len-1]=='\'') ) )
+ {
+ p++;
+ len -= 2;
+ }
+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );
+ if( !str )
+ return str;
+ memcpy( str, p, len*sizeof(WCHAR) );
+ str[len]=0;
+
+ return str;
+}
+
+INT SQL_getint( void *info )
+{
+ SQL_input* sql = (SQL_input*) info;
+ LPCWSTR p = &sql->command[sql->n];
+ INT i, r = 0;
+
+ for( i=0; i<sql->len; i++ )
+ {
+ if( '0' > p[i] || '9' < p[i] )
+ {
+ ERR("should only be numbers here!\n");
+ break;
+ }
+ r = (p[i]-'0') + r*10;
+ }
+
+ return r;
+}
+
+int SQL_error( const char *str )
+{
+ return 0;
+}
+
+static struct expr * EXPR_wildcard( void *info )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_WILDCARD;
+ }
+ return e;
+}
+
+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_COMPLEX;
+ e->u.expr.left = l;
+ e->u.expr.op = op;
+ e->u.expr.right = r;
+ }
+ return e;
+}
+
+static struct expr * EXPR_column( void *info, column_info *column )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_COLUMN;
+ e->u.sval = column->column;
+ }
+ return e;
+}
+
+static struct expr * EXPR_ival( void *info, int val )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_IVAL;
+ e->u.ival = val;
+ }
+ return e;
+}
+
+static struct expr * EXPR_sval( void *info, struct sql_str *str )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_SVAL;
+ e->u.sval = SQL_getstring( info, str );
+ }
+ return e;
+}
+
+static BOOL SQL_MarkPrimaryKeys( column_info *cols,
+ column_info *keys )
+{
+ column_info *k;
+ BOOL found = TRUE;
+
+ for( k = keys; k && found; k = k->next )
+ {
+ column_info *c;
+
+ found = FALSE;
+ for( c = cols; c && !found; c = c->next )
+ {
+ if( lstrcmpW( k->column, c->column ) )
+ continue;
+ c->type |= MSITYPE_KEY;
+ found = TRUE;
+ }
+ }
+
+ return found;
+}
+
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
+ struct list *mem )
+{
+ SQL_input sql;
+ int r;
+
+ *phview = NULL;
+
+ sql.db = db;
+ sql.command = command;
+ sql.n = 0;
+ sql.len = 0;
+ sql.view = phview;
+ sql.mem = mem;
+
+ r = SQL_parse(&sql);
+
+ TRACE("Parse returned %d\n", r);
+ if( r )
+ {
+ *sql.view = NULL;
+ return ERROR_BAD_QUERY_SYNTAX;
+ }
+
+ return ERROR_SUCCESS;
+}
{
string_table *st;
- st = HeapAlloc( GetProcessHeap(), 0, sizeof (string_table) );
+ st = msi_alloc( sizeof (string_table) );
if( !st )
return NULL;
- st->strings = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof (msistring) * entries );
+ if( entries < 1 )
+ entries = 1;
+ st->strings = msi_alloc_zero( sizeof (msistring) * entries );
if( !st )
{
- HeapFree( GetProcessHeap(), 0, st );
+ msi_free( st );
return NULL;
}
- if( entries < 1 )
- entries = 1;
st->maxcount = entries;
st->freeslot = 1;
st->codepage = codepage;
for( i=0; i<st->maxcount; i++ )
{
if( st->strings[i].refcount )
- HeapFree( GetProcessHeap(), 0, st->strings[i].str );
+ msi_free( st->strings[i].str );
}
- HeapFree( GetProcessHeap(), 0, st->strings );
- HeapFree( GetProcessHeap(), 0, st );
+ msi_free( st->strings );
+ msi_free( st );
}
static int st_find_free_entry( string_table *st )
/* dynamically resize */
sz = st->maxcount + 1 + st->maxcount/2;
- p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- st->strings, sz*sizeof(msistring) );
+ p = msi_realloc_zero( st->strings, sz*sizeof(msistring) );
if( !p )
return -1;
st->strings = p;
if( len < 0 )
len = strlen(data);
sz = MultiByteToWideChar( st->codepage, 0, data, len, NULL, 0 );
- st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (sz+1)*sizeof(WCHAR) );
+ st->strings[n].str = msi_alloc( (sz+1)*sizeof(WCHAR) );
if( !st->strings[n].str )
return -1;
MultiByteToWideChar( st->codepage, 0, data, len, st->strings[n].str, sz );
len = strlenW(data);
TRACE("%s, n = %d len = %d\n", debugstr_w(data), n, len );
- st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
+ st->strings[n].str = msi_alloc( (len+1)*sizeof(WCHAR) );
if( !st->strings[n].str )
return -1;
TRACE("%d\n",__LINE__);
sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
if( sz <= 0 )
return r;
- str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
+ str = msi_alloc( sz*sizeof(WCHAR) );
if( !str )
return ERROR_NOT_ENOUGH_MEMORY;
MultiByteToWideChar( st->codepage, 0, buffer, -1, str, sz );
r = msi_string2idW( st, str, id );
- HeapFree( GetProcessHeap(), 0, str );
+ msi_free( str );
return r;
}
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
-typedef struct {
- BOOL unicode;
- union {
- LPSTR a;
- LPWSTR w;
- } str;
-} awstring;
-
-typedef struct {
- BOOL unicode;
- union {
- LPCSTR a;
- LPCWSTR w;
- } str;
-} awcstring;
-
typedef struct tagMSISUMMARYINFO
{
MSIOBJECTHDR hdr;
static void free_prop( PROPVARIANT *prop )
{
if (prop->vt == VT_LPSTR )
- HeapFree( GetProcessHeap(), 0, prop->u.pszVal );
+ msi_free( prop->u.pszVal );
prop->vt = VT_EMPTY;
}
if( type == VT_LPSTR )
{
- LPSTR str = HeapAlloc( GetProcessHeap(), 0, propdata->u.str.len );
+ LPSTR str = msi_alloc( propdata->u.str.len );
memcpy( str, propdata->u.str.str, propdata->u.str.len );
str[ propdata->u.str.len - 1 ] = 0;
property->u.pszVal = str;
return ret;
}
- data = HeapAlloc( GetProcessHeap(), 0, section_hdr.cbSection);
+ data = msi_alloc( section_hdr.cbSection);
if( !data )
return ret;
else
ERR("failed to read properties %ld %ld\n", count, sz);
- HeapFree( GetProcessHeap(), 0, data );
+ msi_free( data );
return ret;
}
section_hdr.cbSection += sz;
}
- data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, section_hdr.cbSection );
+ data = msi_alloc_zero( section_hdr.cbSection );
sz = 0;
memcpy( &data[sz], §ion_hdr, sizeof section_hdr );
sz += write_property_to_data( &si->property[i], &data[sz] );
r = IStream_Write( stm, data, sz, &count );
- HeapFree( GetProcessHeap(), 0, data );
+ msi_free( data );
if( FAILED(r) || count != sz )
return ret;
ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, pHandle);
- HeapFree( GetProcessHeap(), 0, szwDatabase );
+ msi_free( szwDatabase );
return ret;
}
{
MSISUMMARYINFO *si;
PROPVARIANT *prop;
+ UINT ret = ERROR_SUCCESS;
TRACE("%ld %d %p %p %p %p %p\n", handle, uiProperty, puiDataType,
piValue, pftValue, str, pcchValueBuf);
{
len = MultiByteToWideChar( CP_ACP, 0, prop->u.pszVal, -1,
str->str.w, *pcchValueBuf );
+ len--;
}
else
{
if( str->str.a )
lstrcpynA(str->str.a, prop->u.pszVal, *pcchValueBuf );
}
+ if (len >= *pcchValueBuf)
+ ret = ERROR_MORE_DATA;
*pcchValueBuf = len;
}
break;
break;
}
msiobj_release( &si->hdr );
- return ERROR_SUCCESS;
+ return ret;
}
UINT WINAPI MsiSummaryInfoGetPropertyA(
{
len = WideCharToMultiByte( CP_ACP, 0, str->str.w, -1,
NULL, 0, NULL, NULL );
- prop->u.pszVal = HeapAlloc( GetProcessHeap(), 0, len );
+ prop->u.pszVal = msi_alloc( len );
WideCharToMultiByte( CP_ACP, 0, str->str.w, -1,
prop->u.pszVal, len, NULL, NULL );
}
else
{
len = lstrlenA( str->str.a ) + 1;
- prop->u.pszVal = HeapAlloc( GetProcessHeap(), 0, len );
+ prop->u.pszVal = msi_alloc( len );
lstrcpyA( prop->u.pszVal, str->str.a );
}
break;
/*
* Implementation of the Microsoft Installer (msi.dll)
*
- * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ * Copyright 2002-2005 Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
typedef struct tagMSICOLUMNINFO
{
- LPWSTR tablename;
+ LPCWSTR tablename;
UINT number;
- LPWSTR colname;
+ LPCWSTR colname;
UINT type;
UINT offset;
} MSICOLUMNINFO;
struct tagMSITABLE
{
USHORT **data;
- UINT ref_count;
UINT row_count;
- struct tagMSITABLE *next;
- struct tagMSITABLE *prev;
+ struct list entry;
WCHAR name[1];
};
MSICOLUMNINFO **pcols, UINT *pcount );
static UINT get_tablecolumns( MSIDATABASE *db,
LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz);
+static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count );
-static inline UINT bytes_per_column( MSICOLUMNINFO *col )
+static inline UINT bytes_per_column( const MSICOLUMNINFO *col )
{
if( col->type & MSITYPE_STRING )
return 2;
if( !bTable )
count = lstrlenW( in )+2;
- out = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) );
+ out = msi_alloc( count*sizeof(WCHAR) );
p = out;
if( bTable )
*p++ = ch;
}
ERR("Failed to encode stream name (%s)\n",debugstr_w(in));
- HeapFree( GetProcessHeap(), 0, out );
+ msi_free( out );
return NULL;
}
r = IStorage_OpenStream(stg, encname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
- HeapFree( GetProcessHeap(), 0, encname );
+ msi_free( encname );
if( FAILED( r ) )
{
WARN("open stream failed r = %08lx - empty table?\n",r);
}
sz = stat.cbSize.QuadPart;
- data = HeapAlloc( GetProcessHeap(), 0, sz );
+ data = msi_alloc( sz );
if( !data )
{
WARN("couldn't allocate memory r=%08lx!\n",r);
r = IStream_Read(stm, data, sz, &count );
if( FAILED( r ) || ( count != sz ) )
{
- HeapFree( GetProcessHeap(), 0, data );
+ msi_free( data );
WARN("read stream failed r = %08lx!\n",r);
goto end;
}
r = IStorage_OpenStream(db->storage, encname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm);
- HeapFree( GetProcessHeap(), 0, encname );
+ msi_free( encname );
if( FAILED( r ) )
{
WARN("open stream failed r = %08lx - empty table?\n",r);
}
sz = stat.cbSize.QuadPart;
- data = HeapAlloc( GetProcessHeap(), 0, sz );
+ data = msi_alloc( sz );
if( !data )
{
WARN("couldn't allocate memory r=%08lx!\n",r);
r = IStream_Read(stm, data, sz, &count );
if( FAILED( r ) || ( count != sz ) )
{
- HeapFree( GetProcessHeap(), 0, data );
+ msi_free( data );
WARN("read stream failed r = %08lx!\n",r);
goto end;
}
r = IStorage_CreateStream( stg, encname,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
}
- HeapFree( GetProcessHeap(), 0, encname );
+ msi_free( encname );
if( FAILED( r ) )
{
WARN("open stream failed r = %08lx\n",r);
return ret;
}
-static UINT read_table_from_storage( MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+static void free_table( MSITABLE *table )
+{
+ int i;
+ for( i=0; i<table->row_count; i++ )
+ msi_free( table->data[i] );
+ msi_free( table->data );
+ msi_free( table );
+}
+
+static UINT msi_table_get_row_size( const MSICOLUMNINFO *cols, UINT count )
+{
+ const MSICOLUMNINFO *last_col = &cols[count-1];
+ if (!count)
+ return 0;
+ return last_col->offset + bytes_per_column( last_col );
+}
+
+/* add this table to the list of cached tables in the database */
+static MSITABLE *read_table_from_storage( IStorage *stg, LPCWSTR name,
+ const MSICOLUMNINFO *cols, UINT num_cols )
{
MSITABLE *t;
USHORT *rawdata = NULL;
- UINT rawsize = 0, r, i, j, row_size = 0, num_cols = 0;
- MSICOLUMNINFO *cols, *last_col;
+ UINT rawsize = 0, i, j, row_size = 0;
TRACE("%s\n",debugstr_w(name));
/* nonexistent tables should be interpreted as empty tables */
- t = HeapAlloc( GetProcessHeap(), 0,
- sizeof (MSITABLE) + lstrlenW(name)*sizeof (WCHAR) );
+ t = msi_alloc( sizeof (MSITABLE) + lstrlenW(name)*sizeof (WCHAR) );
if( !t )
- return ERROR_NOT_ENOUGH_MEMORY;
+ return t;
- r = table_get_column_info( db, name, &cols, &num_cols );
- if( r != ERROR_SUCCESS )
- {
- HeapFree( GetProcessHeap(), 0, t );
- return r;
- }
- last_col = &cols[num_cols-1];
- row_size = last_col->offset + bytes_per_column( last_col );
+ row_size = msi_table_get_row_size( cols, num_cols );
t->row_count = 0;
t->data = NULL;
lstrcpyW( t->name, name );
- t->ref_count = 1;
- *ptable = t;
/* if we can't read the table, just assume that it's empty */
- read_stream_data( db->storage, name, &rawdata, &rawsize );
+ read_stream_data( stg, name, &rawdata, &rawsize );
if( !rawdata )
- return ERROR_SUCCESS;
+ return t;
TRACE("Read %d bytes\n", rawsize );
if( rawsize % row_size )
{
WARN("Table size is invalid %d/%d\n", rawsize, row_size );
- return ERROR_FUNCTION_FAILED;
+ goto err;
}
t->row_count = rawsize / row_size;
- t->data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- t->row_count * sizeof (USHORT*) );
+ t->data = msi_alloc_zero( t->row_count * sizeof (USHORT*) );
if( !t->data )
- return ERROR_NOT_ENOUGH_MEMORY; /* FIXME: memory leak */
+ goto err;
/* transpose all the data */
TRACE("Transposing data from %d columns\n", t->row_count );
for( i=0; i<t->row_count; i++ )
{
- t->data[i] = HeapAlloc( GetProcessHeap(), 0, row_size );
+ t->data[i] = msi_alloc( row_size );
if( !t->data[i] )
- return ERROR_NOT_ENOUGH_MEMORY; /* FIXME: memory leak */
+ goto err;
+
for( j=0; j<num_cols; j++ )
{
UINT ofs = cols[j].offset/2;
break;
default:
ERR("oops - unknown column width %d\n", n);
- return ERROR_FUNCTION_FAILED;
+ goto err;
}
}
}
- HeapFree( GetProcessHeap(), 0, cols );
- HeapFree( GetProcessHeap(), 0, rawdata );
-
- return ERROR_SUCCESS;
-}
-
-/* add this table to the list of cached tables in the database */
-void add_table(MSIDATABASE *db, MSITABLE *table)
-{
- table->next = db->first_table;
- table->prev = NULL;
- if( db->first_table )
- db->first_table->prev = table;
- else
- db->last_table = table;
- db->first_table = table;
-}
-
-/* remove from the list of cached tables */
-void remove_table( MSIDATABASE *db, MSITABLE *table )
-{
- if( table->next )
- table->next->prev = table->prev;
- else
- db->last_table = table->prev;
- if( table->prev )
- table->prev->next = table->next;
- else
- db->first_table = table->next;
- table->next = NULL;
- table->prev = NULL;
-}
-
-static void release_table( MSIDATABASE *db, MSITABLE *table )
-{
- if( !table->ref_count )
- ERR("Trying to destroy table with refcount 0\n");
- table->ref_count --;
- if( !table->ref_count )
- {
- remove_table( db, table );
- HeapFree( GetProcessHeap(), 0, table->data );
- HeapFree( GetProcessHeap(), 0, table );
- TRACE("Destroyed table %s\n", debugstr_w(table->name));
- }
+ msi_free( rawdata );
+ return t;
+err:
+ msi_free( rawdata );
+ free_table( t );
+ return NULL;
}
void free_cached_tables( MSIDATABASE *db )
{
- while( db->first_table )
+ while( !list_empty( &db->tables ) )
{
- MSITABLE *t = db->first_table;
+ MSITABLE *t = LIST_ENTRY( list_head( &db->tables ), MSITABLE, entry );
- if ( --t->ref_count )
- ERR("table ref count not zero for %s\n", debugstr_w(t->name));
- remove_table( db, t );
- HeapFree( GetProcessHeap(), 0, t->data );
- HeapFree( GetProcessHeap(), 0, t );
+ list_remove( &t->entry );
+ free_table( t );
}
}
-UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+static MSITABLE *find_cached_table( MSIDATABASE *db, LPCWSTR name )
{
MSITABLE *t;
- for( t = db->first_table; t; t=t->next )
- {
+ LIST_FOR_EACH_ENTRY( t, &db->tables, MSITABLE, entry )
if( !lstrcmpW( name, t->name ) )
- {
- *ptable = t;
- return ERROR_SUCCESS;
- }
- }
+ return t;
- return ERROR_FUNCTION_FAILED;
+ return NULL;
}
static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO **pcols, UINT *pcount )
{
- UINT r, column_count;
+ UINT r, column_count = 0;
MSICOLUMNINFO *columns;
/* get the number of columns in this table */
TRACE("Table %s found\n", debugstr_w(name) );
- columns = HeapAlloc( GetProcessHeap(), 0, column_count*sizeof (MSICOLUMNINFO));
+ columns = msi_alloc( column_count*sizeof (MSICOLUMNINFO) );
if( !columns )
return ERROR_FUNCTION_FAILED;
r = get_tablecolumns( db, name, columns, &column_count );
if( r != ERROR_SUCCESS )
{
- HeapFree( GetProcessHeap(), 0, columns );
+ msi_free( columns );
return ERROR_FUNCTION_FAILED;
}
return r;
}
-UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+static MSITABLE *get_table( MSIDATABASE *db, LPCWSTR name,
+ const MSICOLUMNINFO *cols, UINT num_cols )
{
- UINT r;
-
- *ptable = NULL;
+ MSITABLE *table;
/* first, see if the table is cached */
- r = find_cached_table( db, name, ptable );
- if( r == ERROR_SUCCESS )
- {
- (*ptable)->ref_count++;
- return r;
- }
-
- r = read_table_from_storage( db, name, ptable );
- if( r != ERROR_SUCCESS )
- return r;
+ table = find_cached_table( db, name );
+ if( table )
+ return table;
- /* add the table to the list */
- add_table( db, *ptable );
- (*ptable)->ref_count++;
+ table = read_table_from_storage( db->storage, name, cols, num_cols );
+ if( table )
+ list_add_head( &db->tables, &table->entry );
- return ERROR_SUCCESS;
+ return table;
}
static UINT save_table( MSIDATABASE *db, MSITABLE *t )
{
USHORT *rawdata = NULL, *p;
UINT rawsize, r, i, j, row_size, num_cols = 0;
- MSICOLUMNINFO *cols, *last_col;
+ MSICOLUMNINFO *cols = NULL;
TRACE("Saving %s\n", debugstr_w( t->name ) );
if( r != ERROR_SUCCESS )
return r;
- last_col = &cols[num_cols-1];
- row_size = last_col->offset + bytes_per_column( last_col );
+ row_size = msi_table_get_row_size( cols, num_cols );
rawsize = t->row_count * row_size;
- rawdata = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, rawsize );
+ rawdata = msi_alloc_zero( rawsize );
if( !rawdata )
- return ERROR_NOT_ENOUGH_MEMORY;
+ {
+ r = ERROR_NOT_ENOUGH_MEMORY;
+ goto err;
+ }
p = rawdata;
for( i=0; i<num_cols; i++ )
TRACE("writing %d bytes\n", rawsize);
r = write_stream_data( db->storage, t->name, rawdata, rawsize );
- HeapFree( GetProcessHeap(), 0, rawdata );
+err:
+ msi_free_colinfo( cols, num_cols );
+ msi_free( cols );
+ msi_free( rawdata );
return r;
}
/* create the StringPool stream... add the zero string to it*/
r = IStorage_CreateStream( stg, encname,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
- HeapFree( GetProcessHeap(), 0, encname );
+ msi_free( encname );
if( r )
{
TRACE("Failed\n");
encname = encode_streamname(TRUE, szStringData );
r = IStorage_CreateStream( stg, encname,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
- HeapFree( GetProcessHeap(), 0, encname );
+ msi_free( encname );
if( r )
{
TRACE("Failed\n");
return r;
}
-UINT load_string_table( MSIDATABASE *db )
+string_table *load_string_table( IStorage *stg )
{
+ string_table *st = NULL;
CHAR *data;
USHORT *pool;
- UINT r, ret = ERROR_FUNCTION_FAILED, datasize = 0, poolsize = 0, codepage;
+ UINT r, datasize = 0, poolsize = 0, codepage;
DWORD i, count, offset, len, n;
static const WCHAR szStringData[] = {
'_','S','t','r','i','n','g','D','a','t','a',0 };
static const WCHAR szStringPool[] = {
'_','S','t','r','i','n','g','P','o','o','l',0 };
- if( db->strings )
- {
- msi_destroy_stringtable( db->strings );
- db->strings = NULL;
- }
-
- r = read_stream_data( db->storage, szStringPool, &pool, &poolsize );
+ r = read_stream_data( stg, szStringPool, &pool, &poolsize );
if( r != ERROR_SUCCESS)
goto end;
- r = read_stream_data( db->storage, szStringData, (USHORT**)&data, &datasize );
+ r = read_stream_data( stg, szStringData, (USHORT**)&data, &datasize );
if( r != ERROR_SUCCESS)
goto end;
codepage = pool[0] | ( pool[1] << 16 );
else
codepage = CP_ACP;
- db->strings = msi_init_stringtable( count, codepage );
+ st = msi_init_stringtable( count, codepage );
offset = 0;
n = 1;
/* don't add the high word of a string's length as a string */
if ( len || !pool[i*2+1] )
{
- r = msi_addstring( db->strings, n, data+offset, len, pool[i*2+1] );
+ r = msi_addstring( st, n, data+offset, len, pool[i*2+1] );
if( r != n )
ERR("Failed to add string %ld\n", n );
n++;
TRACE("Loaded %ld strings\n", count);
- ret = ERROR_SUCCESS;
-
end:
- HeapFree( GetProcessHeap(), 0, pool );
- HeapFree( GetProcessHeap(), 0, data );
+ msi_free( pool );
+ msi_free( data );
- return ret;
+ return st;
}
static UINT save_string_table( MSIDATABASE *db )
datasize = msi_string_totalsize( db->strings, &count );
poolsize = count*2*sizeof(USHORT);
- pool = HeapAlloc( GetProcessHeap(), 0, poolsize );
+ pool = msi_alloc( poolsize );
if( ! pool )
{
WARN("Failed to alloc pool %d bytes\n", poolsize );
goto err;
}
- data = HeapAlloc( GetProcessHeap(), 0, datasize );
+ data = msi_alloc( datasize );
if( ! data )
{
WARN("Failed to alloc data %d bytes\n", poolsize );
}
if( sz && (sz < (datasize - used ) ) )
sz--;
- TRACE("adding %u bytes %s\n", sz, data+used );
+ TRACE("adding %u bytes %s\n", sz, debugstr_a(data+used) );
pool[ i*2 ] = sz;
pool[ i*2 + 1 ] = msi_id_refcount( db->strings, i );
used += sz;
ret = ERROR_SUCCESS;
err:
- HeapFree( GetProcessHeap(), 0, data );
- HeapFree( GetProcessHeap(), 0, pool );
+ msi_free( data );
+ msi_free( pool );
return ret;
}
static const WCHAR szNumber[] = { 'N','u','m','b','e','r',0 };
static const WCHAR szType[] = { 'T','y','p','e',0 };
-struct standard_table {
- LPCWSTR tablename;
- LPCWSTR columnname;
- UINT number;
- UINT type;
-} MSI_standard_tables[] =
-{
- { szTables, szName, 1, MSITYPE_VALID | MSITYPE_STRING | 32},
- { szColumns, szTable, 1, MSITYPE_VALID | MSITYPE_STRING | 32},
- { szColumns, szNumber, 2, MSITYPE_VALID | 2},
- { szColumns, szName, 3, MSITYPE_VALID | MSITYPE_STRING | 32},
- { szColumns, szType, 4, MSITYPE_VALID | 2},
+static const MSICOLUMNINFO _Columns_cols[4] = {
+ { szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | 64, 0 },
+ { szColumns, 2, szNumber, MSITYPE_VALID | 2, 2 },
+ { szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4 },
+ { szColumns, 4, szType, MSITYPE_VALID | 2, 6 },
+};
+static const MSICOLUMNINFO _Tables_cols[1] = {
+ { szTables, 1, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 0 },
};
-#define STANDARD_TABLE_COUNT \
- (sizeof(MSI_standard_tables)/sizeof(struct standard_table))
-
-static UINT get_defaulttablecolumns( LPCWSTR szTable, MSICOLUMNINFO *colinfo, UINT *sz)
+static UINT get_defaulttablecolumns( LPCWSTR name, MSICOLUMNINFO *colinfo, UINT *sz)
{
- DWORD i, n=0;
+ const MSICOLUMNINFO *p;
+ DWORD i, n;
- for(i=0; i<STANDARD_TABLE_COUNT; i++)
+ TRACE("%s\n", debugstr_w(name));
+
+ if (!lstrcmpW( name, szTables ))
{
- if( lstrcmpW( szTable, MSI_standard_tables[i].tablename ) )
- continue;
- if(colinfo && (n < *sz) )
+ p = _Tables_cols;
+ n = 1;
+ }
+ else if (!lstrcmpW( name, szColumns ))
+ {
+ p = _Columns_cols;
+ n = 4;
+ }
+ else
+ return ERROR_FUNCTION_FAILED;
+
+ /* duplicate the string data so we can free it in msi_free_colinfo */
+ for (i=0; i<n; i++)
+ {
+ if (colinfo && (i < *sz) )
{
- colinfo[n].tablename = strdupW(MSI_standard_tables[i].tablename);
- colinfo[n].colname = strdupW(MSI_standard_tables[i].columnname);
- colinfo[n].number = MSI_standard_tables[i].number;
- colinfo[n].type = MSI_standard_tables[i].type;
- /* ERR("Table %s has column %s\n",debugstr_w(colinfo[n].tablename),
- debugstr_w(colinfo[n].colname)); */
- if( n )
- colinfo[n].offset = colinfo[n-1].offset
- + bytes_per_column( &colinfo[n-1] );
- else
- colinfo[n].offset = 0;
+ memcpy( &colinfo[i], &p[i], sizeof(MSICOLUMNINFO) );
+ colinfo[i].tablename = strdupW( p[i].tablename );
+ colinfo[i].colname = strdupW( p[i].colname );
}
- n++;
- if( colinfo && (n >= *sz) )
+ if( colinfo && (i >= *sz) )
break;
}
*sz = n;
return ERROR_SUCCESS;
}
+static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count )
+{
+ UINT i;
+
+ for( i=0; i<count; i++ )
+ {
+ msi_free( (LPWSTR) colinfo[i].tablename );
+ msi_free( (LPWSTR) colinfo[i].colname );
+ }
+}
+
LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid)
{
UINT sz=0, r;
r = msi_id2stringW( db->strings, stringid, NULL, &sz );
if( r != ERROR_SUCCESS )
return NULL;
- str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR));
+ str = msi_alloc( sz*sizeof (WCHAR) );
if( !str )
return str;
r = msi_id2stringW( db->strings, stringid, str, &sz );
if( r == ERROR_SUCCESS )
return str;
- HeapFree( GetProcessHeap(), 0, str );
+ msi_free( str );
return NULL;
}
{
UINT r, i, n=0, table_id, count, maxcount = *sz;
MSITABLE *table = NULL;
- static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
/* first check if there is a default table with that name */
r = get_defaulttablecolumns( szTableName, colinfo, sz );
if( ( r == ERROR_SUCCESS ) && *sz )
return r;
- r = get_table( db, szColumns, &table);
- if( r != ERROR_SUCCESS )
+ table = get_table( db, szColumns, _Columns_cols, 4 );
+ if( !table )
{
- WARN("table %s not available\n", debugstr_w(szColumns));
- return r;
+ ERR("couldn't load _Columns table\n");
+ return ERROR_FUNCTION_FAILED;
}
/* convert table and column names to IDs from the string table */
r = msi_string2idW( db->strings, szTableName, &table_id );
if( r != ERROR_SUCCESS )
{
- release_table( db, table );
WARN("Couldn't find id for %s\n", debugstr_w(szTableName));
return r;
}
colinfo[n].tablename = MSI_makestring( db, table_id );
colinfo[n].number = table->data[ i ][ 1 ] - (1<<15);
colinfo[n].colname = MSI_makestring( db, id );
- colinfo[n].type = table->data[ i ] [ 3 ];
+ colinfo[n].type = table->data[ i ] [ 3 ] ^ 0x8000;
/* this assumes that columns are in order in the table */
if( n )
colinfo[n].offset = colinfo[n-1].offset
}
*sz = n;
- release_table( db, table );
-
return ERROR_SUCCESS;
}
/* try to find the table name in the _Tables table */
BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name )
{
- static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
- static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
UINT r, table_id = 0, i, count;
MSITABLE *table = NULL;
return FALSE;
}
- r = get_table( db, szTables, &table);
- if( r != ERROR_SUCCESS )
+ table = get_table( db, szTables, _Tables_cols, 1 );
+ if( !table )
{
TRACE("table %s not available\n", debugstr_w(szTables));
return FALSE;
if( table->data[ i ][ 0 ] == table_id )
break;
- release_table( db, table );
-
if (i!=count)
return TRUE;
return ERROR_INVALID_PARAMETER;
len = lstrlenW( tv->name ) + 2 + lstrlenW( sval );
- full_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ 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 )
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
- HeapFree( GetProcessHeap(), 0, full_name );
- HeapFree( GetProcessHeap(), 0, sval );
+ msi_free( full_name );
+ msi_free( sval );
return r;
}
if( !tv->table )
return ERROR_INVALID_PARAMETER;
- row = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, tv->row_size );
+ row = msi_alloc_zero( tv->row_size );
if( !row )
return ERROR_NOT_ENOUGH_MEMORY;
sz = (tv->table->row_count + 1) * sizeof (UINT*);
if( tv->table->data )
- p = HeapReAlloc( GetProcessHeap(), 0, tv->table->data, sz );
+ p = msi_realloc( tv->table->data, sz );
else
- p = HeapAlloc( GetProcessHeap(), 0, sz );
+ p = msi_alloc( sz );
if( !p )
{
- HeapFree( GetProcessHeap(), 0, row );
+ msi_free( row );
return ERROR_NOT_ENOUGH_MEMORY;
}
static UINT TABLE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
- UINT r;
TRACE("%p %p\n", tv, record);
- if( tv->table )
- {
- release_table( tv->db, tv->table );
- tv->table = NULL;
- }
-
- r = get_table( tv->db, tv->name, &tv->table );
- if( r != ERROR_SUCCESS )
- return r;
+ TRACE("There are %d columns\n", tv->num_cols );
+ tv->table = get_table( tv->db, tv->name, tv->columns, tv->num_cols );
+ if( !tv->table )
+ return ERROR_FUNCTION_FAILED;
return ERROR_SUCCESS;
}
if( !tv->table )
return ERROR_FUNCTION_FAILED;
- release_table( tv->db, tv->table );
tv->table = NULL;
return ERROR_SUCCESS;
TRACE("%p\n", view );
- if( tv->table )
- release_table( tv->db, tv->table );
tv->table = NULL;
if( tv->columns )
{
- UINT i;
- for( i=0; i<tv->num_cols; i++)
- {
- HeapFree( GetProcessHeap(), 0, tv->columns[i].colname );
- HeapFree( GetProcessHeap(), 0, tv->columns[i].tablename );
- }
- HeapFree( GetProcessHeap(), 0, tv->columns );
+ msi_free_colinfo( tv->columns, tv->num_cols );
+ msi_free( tv->columns );
}
tv->columns = NULL;
- HeapFree( GetProcessHeap(), 0, tv );
+ msi_free( tv );
return ERROR_SUCCESS;
}
{
MSITABLEVIEW *tv ;
UINT r, sz, column_count;
- MSICOLUMNINFO *columns, *last_col;
+ MSICOLUMNINFO *columns;
TRACE("%p %s %p\n", db, debugstr_w(name), view );
TRACE("Table found\n");
sz = sizeof *tv + lstrlenW(name)*sizeof name[0] ;
- tv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sz );
+ tv = msi_alloc_zero( sz );
if( !tv )
return ERROR_FUNCTION_FAILED;
- columns = HeapAlloc( GetProcessHeap(), 0, column_count*sizeof (MSICOLUMNINFO));
+ columns = msi_alloc( column_count*sizeof (MSICOLUMNINFO));
if( !columns )
{
- HeapFree( GetProcessHeap(), 0, tv );
+ msi_free( tv );
return ERROR_FUNCTION_FAILED;
}
r = get_tablecolumns( db, name, columns, &column_count );
if( r != ERROR_SUCCESS )
{
- HeapFree( GetProcessHeap(), 0, columns );
- HeapFree( GetProcessHeap(), 0, tv );
+ msi_free( columns );
+ msi_free( tv );
return ERROR_FUNCTION_FAILED;
}
TRACE("Table has %d columns\n", column_count);
- last_col = &columns[column_count-1];
-
/* fill the structure */
tv->view.ops = &table_ops;
tv->db = db;
tv->columns = columns;
tv->num_cols = column_count;
tv->table = NULL;
- tv->row_size = last_col->offset + bytes_per_column( last_col );
+ tv->row_size = msi_table_get_row_size( columns, column_count );
- TRACE("one row is %d bytes\n", tv->row_size );
+ TRACE("%s one row is %d bytes\n", debugstr_w(name), tv->row_size );
*view = (MSIVIEW*) tv;
lstrcpyW( tv->name, name );
return r;
}
- for( table = db->first_table; table; table = table->next )
+ LIST_FOR_EACH_ENTRY( table, &db->tables, MSITABLE, entry )
{
r = save_table( db, table );
if( r != ERROR_SUCCESS )
if( wv )
wv->ops->delete( wv );
msiobj_release( &uv->db->hdr );
- HeapFree( GetProcessHeap(), 0, uv );
+ msi_free( uv );
return ERROR_SUCCESS;
}
r = WHERE_CreateView( db, &wv, tv, expr );
if( r != ERROR_SUCCESS )
{
- if( sv )
- sv->ops->delete( tv );
+ tv->ops->delete( tv );
return r;
}
r = SELECT_CreateView( db, &sv, wv, columns );
if( r != ERROR_SUCCESS )
{
- if( tv )
- tv->ops->delete( sv );
+ wv->ops->delete( wv );
return r;
}
- uv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *uv );
+ uv = msi_alloc_zero( sizeof *uv );
if( !uv )
return ERROR_FUNCTION_FAILED;
DWORD len;
static const WCHAR separator[] = {';',0};
- prop = load_dynamic_property(package, action_property, NULL);
+ prop = msi_dup_property(package, action_property );
if (prop)
len = strlenW(prop);
else
/*null*/
len++;
- newprop = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+ newprop = msi_alloc( len*sizeof(WCHAR) );
if (prop)
{
MSI_SetPropertyW(package, action_property, newprop);
TRACE("Found Related Product... %s now %s\n",debugstr_w(action_property),
debugstr_w(newprop));
- HeapFree(GetProcessHeap(),0,prop);
- HeapFree(GetProcessHeap(),0,newprop);
+ msi_free( prop );
+ msi_free( newprop );
}
static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param)
-/*\r
- * Copyright (c) 2004 Christian Costa\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"\r
-#define WINE_FILENAME_STR "msi.dll"\r
-#define WINE_FILEVERSION 3,1,4000,2435\r
-#define WINE_FILEVERSION_STR "3.1.4000.2435"\r
-#define WINE_PRODUCTVERSION 3,1,4000,2435\r
-#define WINE_PRODUCTVERSION_STR "3.1.4000.2435"\r
-\r
-#include "wine/wine_common_ver.rc"\r
+/*
+ * Copyright (c) 2004 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"
+#define WINE_FILENAME_STR "msi.dll"
+#define WINE_FILEVERSION 3,1,4000,2435
+#define WINE_FILEVERSION_STR "3.1.4000.2435"
+#define WINE_PRODUCTVERSION 3,1,4000,2435
+#define WINE_PRODUCTVERSION_STR "3.1.4000.2435"
+
+#include "wine/wine_common_ver.rc"
if( r != ERROR_SUCCESS )
return r;
- wv->reorder = HeapAlloc( GetProcessHeap(), 0, count*sizeof(UINT) );
+ msi_free( wv->reorder );
+ wv->reorder = msi_alloc( count*sizeof(UINT) );
if( !wv->reorder )
return ERROR_FUNCTION_FAILED;
if( !wv->table )
return ERROR_FUNCTION_FAILED;
- HeapFree( GetProcessHeap(), 0, wv->reorder );
+ msi_free( wv->reorder );
wv->reorder = NULL;
return wv->table->ops->close( wv->table );
if( wv->table )
wv->table->ops->delete( wv->table );
+ wv->table = 0;
- HeapFree( GetProcessHeap(), 0, wv->reorder );
+ msi_free( wv->reorder );
wv->reorder = NULL;
wv->row_count = 0;
msiobj_release( &wv->db->hdr );
- HeapFree( GetProcessHeap(), 0, wv );
+ msi_free( wv );
return ERROR_SUCCESS;
}
MSIWHEREVIEW *wv = NULL;
UINT count = 0, r, valid = 0;
- TRACE("%p\n", wv );
+ TRACE("%p\n", table );
r = table->ops->get_dimensions( table, NULL, &count );
if( r != ERROR_SUCCESS )
return ERROR_FUNCTION_FAILED;
}
- wv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *wv );
+ wv = msi_alloc_zero( sizeof *wv );
if( !wv )
return ERROR_FUNCTION_FAILED;
UINT WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE, LPWSTR);
#define MsiDatabaseIsTablePersistent WINELIB_NAME_AW(MsiDatabaseIsTablePersistent)
+UINT WINAPI MsiSequenceA(MSIHANDLE, LPCSTR, INT);
+UINT WINAPI MsiSequenceW(MSIHANDLE, LPCWSTR, INT);
+#define MsiSequence WINELIB_NAME_AW(MsiSequence)
+
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE);
UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE,UINT*);