diff --git a/reactos/lib/msi/action.c b/reactos/lib/msi/action.c index 37c2011dd99..3c3e411e01b 100644 --- a/reactos/lib/msi/action.c +++ b/reactos/lib/msi/action.c @@ -55,36 +55,6 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran); 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 */ @@ -262,89 +232,15 @@ const static WCHAR szWriteEnvironmentStrings[] = {'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[]; /******************************************************** @@ -399,7 +295,7 @@ static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) 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, @@ -431,15 +327,90 @@ 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}; @@ -448,13 +419,11 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, 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; @@ -469,95 +438,32 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, } 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) + msi_parse_command_line( package, szCommandLine ); + + if ( msi_get_property_int(package, szUILevel, 0) >= INSTALLUILEVEL_REDUCED ) { - LPWSTR ptr,ptr2; - ptr = (LPWSTR)szCommandLine; - - while (*ptr) + package->script->InWhatSequence |= SEQUENCE_UI; + rc = ACTION_ProcessUISequence(package); + ui = TRUE; + if (rc == ERROR_SUCCESS) { - 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; - - 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++; + package->script->InWhatSequence |= SEQUENCE_EXEC; + rc = ACTION_ProcessExecSequence(package,TRUE); } } - - sz = 10; - if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS) - { - if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED) - { - 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); - } - } - else - rc = ACTION_ProcessExecSequence(package,FALSE); - } else rc = ACTION_ProcessExecSequence(package,FALSE); @@ -692,6 +598,40 @@ static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param) 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; @@ -818,7 +758,7 @@ static BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action, } else { - FIXME("UNHANDLED Standard Action %s\n",debugstr_w(action)); + FIXME("unhandled standard action %s\n",debugstr_w(action)); *rc = ERROR_SUCCESS; } } @@ -868,7 +808,7 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, BOOL force) 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; } @@ -892,7 +832,7 @@ UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action) 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; } @@ -939,7 +879,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) folder->State = 3; - HeapFree(GetProcessHeap(),0,full_path); + msi_free(full_path); return ERROR_SUCCESS; } @@ -971,33 +911,21 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package) 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); + comp->Component = load_dynamic_stringW( row, 1 ); - TRACE("Loading Component %s\n", - debugstr_w(comp->Component)); - - 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; @@ -1017,7 +945,7 @@ static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp ) { ComponentList *cl; - cl = HeapAlloc( GetProcessHeap(), 0, sizeof (*cl) ); + cl = msi_alloc( sizeof (*cl) ); if ( !cl ) return ERROR_NOT_ENOUGH_MEMORY; cl->component = comp; @@ -1084,7 +1012,6 @@ static UINT load_feature(MSIRECORD * row, LPVOID param) { 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','_','`', @@ -1098,38 +1025,25 @@ static UINT load_feature(MSIRECORD * row, LPVOID param) /* 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; @@ -1161,7 +1075,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param) /* 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; @@ -1185,7 +1099,6 @@ static UINT load_file(MSIRECORD *row, LPVOID param) 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)); @@ -1277,11 +1190,11 @@ static UINT execute_script(MSIPACKAGE *package, UINT script ) 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; @@ -1316,7 +1229,7 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir ) 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; @@ -1360,7 +1273,7 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir ) if (targetdir) { TRACE(" TargetDefault = %s\n",debugstr_w(targetdir)); - HeapFree(GetProcessHeap(),0, folder->TargetDefault); + msi_free( folder->TargetDefault); folder->TargetDefault = strdupW(targetdir); } @@ -1370,7 +1283,7 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir ) 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); @@ -1384,7 +1297,7 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir ) 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); @@ -1439,56 +1352,52 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property, 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[] = @@ -1504,14 +1413,7 @@ static UINT SetFeatureStates(MSIPACKAGE *package) 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 @@ -1659,7 +1561,7 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param) 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; } @@ -1736,81 +1638,74 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - MSICOMPONENT* comp = NULL; + MSICOMPONENT* comp = file->Component; + LPWSTR p; - comp = file->Component; - - if (file->Temporary == TRUE) + if (!comp) continue; - if (comp) + /* calculate target */ + p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); + + msi_free(file->TargetPath); + + TRACE("file %s is named %s\n", + debugstr_w(file->File),debugstr_w(file->FileName)); + + file->TargetPath = build_directory_name(2, p, file->FileName); + + msi_free(p); + + TRACE("file %s resolves to %s\n", + debugstr_w(file->File),debugstr_w(file->TargetPath)); + + if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { - LPWSTR p; + file->State = 1; + comp->Cost += file->FileSize; + continue; + } - /* calculate target */ - p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); + 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; - HeapFree(GetProcessHeap(),0,file->TargetPath); + TRACE("Version comparison.. \n"); + versize = GetFileVersionInfoSizeW(file->TargetPath,&handle); + version = msi_alloc(versize); + GetFileVersionInfoW(file->TargetPath, 0, versize, version); - TRACE("file %s is named %s\n", - debugstr_w(file->File),debugstr_w(file->FileName)); + VerQueryValueW(version, (LPWSTR)name, (LPVOID*)&lpVer, &sz); - file->TargetPath = build_directory_name(2, p, file->FileName); + sprintfW(filever,name_fmt, + HIWORD(lpVer->dwFileVersionMS), + LOWORD(lpVer->dwFileVersionMS), + HIWORD(lpVer->dwFileVersionLS), + LOWORD(lpVer->dwFileVersionLS)); - HeapFree(GetProcessHeap(),0,p); - - TRACE("file %s resolves to %s\n", - debugstr_w(file->File),debugstr_w(file->TargetPath)); - - if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) + 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"); @@ -1826,7 +1721,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) 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) @@ -1839,11 +1734,10 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) 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); @@ -1875,7 +1769,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, else *size = strlenW(ptr)/2; - data = HeapAlloc(GetProcessHeap(),0,*size); + data = msi_alloc(*size); byte[0] = '0'; byte[1] = 'x'; @@ -1900,7 +1794,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, data[count] = (BYTE)strtol(byte,NULL,0); count ++; } - HeapFree(GetProcessHeap(),0,deformated); + msi_free(deformated); TRACE("Data %li bytes(%i)\n",*size,count); } @@ -1913,7 +1807,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, *type=REG_DWORD; *size = sizeof(DWORD); - data = HeapAlloc(GetProcessHeap(),0,*size); + data = msi_alloc(*size); p = deformated; if (*p == '-') p++; @@ -1930,7 +1824,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, *(LPDWORD)data = d; TRACE("DWORD %li\n",*(LPDWORD)data); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(deformated); } } else @@ -2032,7 +1926,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) 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; @@ -2043,7 +1937,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) root_key = HKEY_CURRENT_USER; szRoot = szHCU; } - HeapFree(GetProcessHeap(),0,all_users); + msi_free(all_users); } break; case 0: root_key = HKEY_CLASSES_ROOT; @@ -2069,18 +1963,18 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) 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) @@ -2136,9 +2030,9 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) 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; } @@ -2185,47 +2079,25 @@ static UINT ACTION_InstallValidate(MSIPACKAGE *package) '`','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 ) @@ -2254,7 +2126,7 @@ static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param) 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; } @@ -2284,11 +2156,9 @@ static UINT ACTION_LaunchConditions(MSIPACKAGE *package) 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; @@ -2318,15 +2188,15 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp ) 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; @@ -2382,8 +2252,7 @@ static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count) 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); @@ -2400,7 +2269,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) BOOL write = FALSE; /* only refcount DLLs */ - if (comp->KeyPath[0]==0 || + if (comp->KeyPath == NULL || comp->Attributes & msidbComponentAttributesRegistryKeyPath || comp->Attributes & msidbComponentAttributesODBCDataSource) write = FALSE; @@ -2450,8 +2319,6 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - if (file->Temporary) - continue; if (file->Component == comp) ACTION_WriteSharedDLLsCount( file->TargetPath, count ); } @@ -2497,15 +2364,14 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) 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 ); @@ -2526,21 +2392,18 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) 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); @@ -2549,7 +2412,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) 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 ); } @@ -2615,7 +2478,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, 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); } @@ -2623,7 +2486,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, 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; @@ -2636,7 +2499,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, return FALSE; } - HeapFree(GetProcessHeap(),0,tl_struct->path); + msi_free(tl_struct->path); tl_struct->path = NULL; ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr); @@ -2681,7 +2544,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) 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; @@ -2699,7 +2562,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) 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", @@ -2712,14 +2575,14 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) } 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)); @@ -2812,7 +2675,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) 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,'[')) @@ -2820,15 +2683,12 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) 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)) @@ -2837,7 +2697,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) 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)) @@ -2851,16 +2711,16 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) 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)) @@ -2872,13 +2732,13 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) 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 ); @@ -2921,8 +2781,8 @@ static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = (MSIPACKAGE*)param; HANDLE the_file; - LPWSTR FilePath=NULL; - LPCWSTR FileName=NULL; + LPWSTR FilePath; + LPCWSTR FileName; CHAR buffer[1024]; DWORD sz; UINT rc; @@ -2934,7 +2794,7 @@ static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) 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)); @@ -2944,7 +2804,7 @@ static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) 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; } @@ -2963,7 +2823,7 @@ static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) WriteFile(the_file,buffer,sz,&write,NULL); } while (sz == 1024); - HeapFree(GetProcessHeap(),0,FilePath); + msi_free(FilePath); CloseHandle(the_file); return ERROR_SUCCESS; @@ -3019,39 +2879,29 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) 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"); @@ -3071,9 +2921,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) 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 { @@ -3139,10 +2987,10 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param) { 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) { @@ -3186,11 +3034,11 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param) 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; } @@ -3241,7 +3089,7 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param) 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); @@ -3253,7 +3101,7 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param) if (brc) msi_dialog_check_messages(info.hProcess); - HeapFree(GetProcessHeap(),0,FullName); + msi_free(FullName); return ERROR_SUCCESS; } @@ -3315,10 +3163,10 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { 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 ) @@ -3327,7 +3175,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) 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); @@ -3336,32 +3184,35 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) 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); } } @@ -3371,14 +3222,72 @@ end: 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] = { @@ -3417,14 +3326,6 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) {'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[] = @@ -3443,8 +3344,6 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) 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; @@ -3456,114 +3355,63 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) /* 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); + + 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 ); } - HeapFree(GetProcessHeap(),0,buffer); + 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: @@ -3631,8 +3479,7 @@ static UINT ACTION_ForceReboot(MSIPACKAGE *package) '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; @@ -3644,8 +3491,7 @@ static UINT ACTION_ForceReboot(MSIPACKAGE *package) 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)); @@ -3653,8 +3499,7 @@ static UINT ACTION_ForceReboot(MSIPACKAGE *package) 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; @@ -3683,7 +3528,7 @@ UINT ACTION_ResolveSource(MSIPACKAGE* package) 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); @@ -3702,7 +3547,7 @@ UINT ACTION_ResolveSource(MSIPACKAGE* package) } attrib = GetFileAttributesW(package->PackagePath); } - HeapFree(GetProcessHeap(),0,prompt); + msi_free(prompt); rc = ERROR_SUCCESS; } else @@ -3717,7 +3562,6 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) LPWSTR buffer; LPWSTR productid; UINT rc,i; - DWORD size; static const WCHAR szPropKeys[][80] = { @@ -3738,8 +3582,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) 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; @@ -3747,22 +3590,15 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) 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; @@ -3775,13 +3611,13 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package) 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; } @@ -3892,19 +3728,18 @@ static LPWSTR load_ttfname_from(LPCWSTR filename) 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); } } @@ -3924,7 +3759,6 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) 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','\\', @@ -3966,12 +3800,11 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) 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; @@ -4046,19 +3879,19 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) 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; } @@ -4085,3 +3918,212 @@ static UINT ACTION_PublishComponents(MSIPACKAGE *package) 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}, +}; diff --git a/reactos/lib/msi/action.h b/reactos/lib/msi/action.h index b01036c934e..d2e03e2af7f 100644 --- a/reactos/lib/msi/action.h +++ b/reactos/lib/msi/action.h @@ -23,18 +23,16 @@ #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; @@ -50,12 +48,12 @@ typedef struct tagMSICOMPONENT { 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; @@ -114,15 +112,22 @@ typedef struct tagMSIFILE /* 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; @@ -131,13 +136,15 @@ typedef struct tagMSIAPPID 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; @@ -157,34 +164,34 @@ typedef struct tagMSIMIME MSIMIME; 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; @@ -196,7 +203,7 @@ struct tagMSIMIME 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; @@ -244,7 +251,7 @@ extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package); /* 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 ); @@ -253,7 +260,7 @@ extern MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file ); 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); diff --git a/reactos/lib/msi/appsearch.c b/reactos/lib/msi/appsearch.c index 4f080fa4c61..91c41d5f126 100644 --- a/reactos/lib/msi/appsearch.c +++ b/reactos/lib/msi/appsearch.c @@ -124,14 +124,14 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig, { 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) @@ -325,7 +325,7 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, BOOL *appFound, /* 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) { @@ -347,14 +347,13 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, BOOL *appFound, 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; @@ -362,20 +361,17 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, BOOL *appFound, /* 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" */ - 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; @@ -390,12 +386,12 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, BOOL *appFound, *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); @@ -449,7 +445,7 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, BOOL *appFound, 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); @@ -549,7 +545,7 @@ static UINT ACTION_FileVersionMatches(MSISIGNATURE *sig, LPCWSTR filePath, if (size) { - LPVOID buf = HeapAlloc(GetProcessHeap(), 0, size); + LPVOID buf = msi_alloc( size); if (buf) { @@ -592,7 +588,7 @@ static UINT ACTION_FileVersionMatches(MSISIGNATURE *sig, LPCWSTR filePath, else *matches = TRUE; } - HeapFree(GetProcessHeap(), 0, buf); + msi_free( buf); } else rc = ERROR_OUTOFMEMORY; @@ -671,8 +667,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, BOOL *appFound, * 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 */ @@ -726,7 +721,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, BOOL *appFound, FindClose(hFind); } } - HeapFree(GetProcessHeap(), 0, buf); + msi_free(buf); } else rc = ERROR_OUTOFMEMORY; @@ -965,8 +960,8 @@ UINT ACTION_AppSearch(MSIPACKAGE *package) } } } - HeapFree(GetProcessHeap(), 0, sig.File); - HeapFree(GetProcessHeap(), 0, sig.Languages); + msi_free( sig.File); + msi_free( sig.Languages); msiobj_release(&row->hdr); } diff --git a/reactos/lib/msi/classes.c b/reactos/lib/msi/classes.c index b2b640bca1a..c83453131cd 100644 --- a/reactos/lib/msi/classes.c +++ b/reactos/lib/msi/classes.c @@ -56,18 +56,16 @@ extern const WCHAR szUnregisterProgIdInfo[]; 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); @@ -117,39 +115,36 @@ static MSIAPPID *load_given_appid( MSIPACKAGE *package, LPCWSTR name ) 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)) { @@ -158,99 +153,96 @@ static INT load_progid(MSIPACKAGE* package, MSIRECORD *row) 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; - FIXME("BAD BAD need to determing if we are really the CurVer\n"); + while (parent->Parent && parent->Parent != parent) + parent = parent->Parent; - package->progids[index].CurVerIndex = pindex; - package->progids[pindex].VersionIndIndex = index; + FIXME("need to determing if we are really the CurVer\n"); + + 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); @@ -268,22 +260,20 @@ static MSICLASS *load_class( MSIPACKAGE* package, MSIRECORD *row ) 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)) @@ -310,8 +300,7 @@ static MSICLASS *load_class( MSIPACKAGE* package, MSIRECORD *row ) } else { - cls->DefInprocHandler32 = load_dynamic_stringW( - row, 10); + cls->DefInprocHandler32 = load_dynamic_stringW( row, 10); reduce_to_longfilename(cls->DefInprocHandler32); } } @@ -347,7 +336,7 @@ static MSICLASS *load_given_class(MSIPACKAGE *package, LPCWSTR classid) /* 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; @@ -368,13 +357,12 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR extensio 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; @@ -384,9 +372,8 @@ static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row ) 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 ); @@ -429,22 +416,26 @@ static MSIMIME *load_given_mime( MSIPACKAGE *package, LPCWSTR mime ) 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; - sz = 256; - MSI_RecordGetStringW( row, 1, ext->Extension, &sz ); + list_init( &ext->verbs ); + + list_add_tail( &package->extensions, &ext->entry ); + + 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 ); @@ -452,8 +443,6 @@ static MSIEXTENSION *load_extension( MSIPACKAGE* package, MSIRECORD *row ) buffer = MSI_RecordGetString(row,5); ext->Feature = get_loaded_feature( package, buffer ); - list_add_tail( &package->extensions, &ext->entry ); - return ext; } @@ -498,49 +487,36 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR name ) static UINT iterate_load_verb(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = (MSIPACKAGE*)param; - DWORD index = package->loaded_verbs; + MSIVERB *verb; LPCWSTR buffer; + MSIEXTENSION *extension; + + buffer = MSI_RecordGetString(row,1); + extension = load_given_extension( package, buffer ); + if (!extension) + { + ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer)); + return ERROR_SUCCESS; + } /* 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)); + verb = msi_alloc_zero( sizeof(MSIVERB) ); + if (!verb) + return ERROR_OUTOFMEMORY; - memset(&package->verbs[index],0,sizeof(MSIVERB)); - - buffer = MSI_RecordGetString(row,1); - package->verbs[index].Extension = load_given_extension(package,buffer); - if (package->verbs[index].Extension == NULL && buffer) - ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer)); - - 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); + 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; } @@ -562,7 +538,7 @@ static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param) 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; @@ -724,7 +700,7 @@ static void load_classes_and_such(MSIPACKAGE *package) 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); @@ -735,25 +711,24 @@ static void load_classes_and_such(MSIPACKAGE *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 ) @@ -763,84 +738,82 @@ 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; } @@ -900,23 +873,21 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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 ); @@ -927,7 +898,6 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) */ if (strcmpiW( cls->Context, szInprocServer32 )!=0) { - sz = 0; sz = GetShortPathNameW( file->TargetPath, NULL, 0 ); if (sz == 0) { @@ -944,7 +914,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) size += sizeof(WCHAR); } - argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR)); + argument = msi_alloc( size + sizeof(WCHAR)); GetShortPathNameW( file->TargetPath, argument, sz ); if (cls->Argument) @@ -964,7 +934,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) size += sizeof(WCHAR); } - argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR)); + argument = msi_alloc( size + sizeof(WCHAR)); strcpyW( argument, file->TargetPath ); if (cls->Argument) @@ -976,36 +946,27 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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 ); } } @@ -1013,8 +974,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) { 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 ); } @@ -1024,12 +984,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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) @@ -1037,24 +992,15 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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); + {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; - RegCreateKeyW(hkey2,szInproc32,&hkey3); - RegSetValueExW(hkey3,NULL,0,REG_SZ, - (LPBYTE)cls->DefInprocHandler32,size); - RegCloseKey(hkey3); + msi_reg_set_subkey_val( hkey2, szInproc32, NULL, cls->DefInprocHandler32 ); } RegCloseKey(hkey2); @@ -1071,15 +1017,11 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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; @@ -1092,7 +1034,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) 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); } @@ -1107,42 +1049,27 @@ static UINT register_progid_base(MSIPACKAGE* package, MSIPROGID* progid, 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; } @@ -1151,12 +1078,12 @@ static UINT register_progid(MSIPACKAGE *package, MSIPROGID* progid, { 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}; @@ -1173,44 +1100,21 @@ static UINT register_progid(MSIPACKAGE *package, MSIPROGID* progid, 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); } @@ -1219,7 +1123,7 @@ static UINT register_progid(MSIPACKAGE *package, MSIPROGID* progid, UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package) { - INT i; + MSIPROGID *progid; MSIRECORD *uirow; if (!package) @@ -1227,31 +1131,29 @@ UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *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; @@ -1280,15 +1182,14 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, 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); @@ -1299,7 +1200,7 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, 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); @@ -1310,22 +1211,18 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, 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) @@ -1334,11 +1231,8 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, { *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; @@ -1365,7 +1259,7 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry ) { - WCHAR extension[257]; + LPWSTR extension; MSIFEATURE *feature; if (!ext->Component) @@ -1394,56 +1288,53 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) /* 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); @@ -1461,7 +1352,6 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) { static const WCHAR szExten[] = {'E','x','t','e','n','s','i','o','n',0 }; - HKEY hkey; MSIRECORD *uirow; MSIMIME *mt; @@ -1472,7 +1362,7 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry ) { - WCHAR extension[257]; + LPWSTR extension; LPCWSTR exten; LPCWSTR mime; static const WCHAR fmt[] = @@ -1497,25 +1387,20 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) 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); diff --git a/reactos/lib/msi/cond.tab.c b/reactos/lib/msi/cond.tab.c index ae49cc09d5a..3cbed28a594 100644 --- a/reactos/lib/msi/cond.tab.c +++ b/reactos/lib/msi/cond.tab.c @@ -1,36 +1,114 @@ -/* 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" @@ -133,10 +211,23 @@ static INT comp_le_m2(INT a, LPWSTR b); 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; @@ -144,25 +235,146 @@ typedef union 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 + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 253 "cond.tab.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + 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 -#define YYFINAL 74 -#define YYFLAG -32768 -#define YYNTBASE 23 +/* 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 token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 39) +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 277 -/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ -static const char yytranslate[] = +#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, @@ -189,323 +401,213 @@ static const char yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, + 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 }; -#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 - -/* 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 -}; - -/* 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 -}; - +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -37 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 + -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[] = { - -32768, -1,-32768, -8, 25,-32768, -14,-32768,-32768, -11, - -35,-32768,-32768,-32768, 134,-32768 + -37, -37, -2, -37, -6, 39, -37, 0, -37, -37, + -34, -36, -37, -37, -37, 129, -37 }; - -#define YYLAST 151 - - -static const short yytable[] = +/* 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[] = { - 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 + 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 short yycheck[] = +static const yysigned_char 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 + 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 }; -#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) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = { - short yyss; - YYSTYPE yyvs; -# if YYLSP_NEEDED - YYLTYPE yyls; -# endif + 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 }; -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAX (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) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - - #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif @@ -524,29 +626,35 @@ union yyalloc #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) @@ -554,41 +662,24 @@ 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 @@ -603,13 +694,93 @@ do { \ 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 @@ -622,15 +793,17 @@ int yydebug; 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 + -#ifdef YYERROR_VERBOSE + +#if YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) @@ -680,78 +853,126 @@ yystpcpy (yydest, yysrc) } # endif # endif -#endif + +#endif /* !YYERROR_VERBOSE */ + -#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; + } +} + + +/* 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 -#endif - -/* 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 +int yyparse (); #endif +#endif /* ! YYPARSE_PARAM */ -/* 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 (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL +yyparse (void) +#else +int +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; @@ -759,7 +980,7 @@ yyparse (YYPARSE_PARAM_ARG) /* 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, @@ -769,7 +990,7 @@ yyparse (YYPARSE_PARAM_ARG) 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; @@ -779,31 +1000,19 @@ yyparse (YYPARSE_PARAM_ARG) 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 + +#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")); @@ -820,9 +1029,7 @@ yyparse (YYPARSE_PARAM_ARG) yyssp = yyss; yyvsp = yyvs; -#if YYLSP_NEEDED - yylsp = yyls; -#endif + goto yysetstate; /*------------------------------------------------------------. @@ -837,7 +1044,7 @@ yyparse (YYPARSE_PARAM_ARG) 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; @@ -850,24 +1057,17 @@ yyparse (YYPARSE_PARAM_ARG) 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. */ + 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), - &yyls1, yysize * sizeof (*yylsp), + &yystacksize); - yyls = yyls1; -# else - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); -# endif + yyss = yyss1; yyvs = yyvs1; } @@ -876,10 +1076,10 @@ yyparse (YYPARSE_PARAM_ARG) 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; { @@ -890,10 +1090,8 @@ yyparse (YYPARSE_PARAM_ARG) 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); } @@ -902,14 +1100,12 @@ yyparse (YYPARSE_PARAM_ARG) 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; } @@ -917,7 +1113,6 @@ yyparse (YYPARSE_PARAM_ARG) goto yybackup; - /*-----------. | yybackup. | `-----------*/ @@ -930,88 +1125,55 @@ 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. */ @@ -1042,425 +1204,470 @@ yyreduce: /* 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 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" -{ + ;} + break; + + case 50: +#line 370 "./cond.y" + { yyval.fn_comp_m2 = 0; - ; - break;} -case 50: -#line 367 "./cond.y" -{ + ;} + break; + + case 51: +#line 374 "./cond.y" + { yyval.fn_comp_m2 = 0; - ; - break;} -case 51: -#line 371 "./cond.y" -{ - yyval.fn_comp_m2 = 0; - ; - break;} -case 52: + ;} + break; + + case 52: #line 378 "./cond.y" -{ + { + yyval.fn_comp_m2 = 0; + ;} + break; + + case 53: +#line 385 "./cond.y" + { yyval.value = yyvsp[0].value; - ; - break;} -case 53: -#line 382 "./cond.y" -{ - yyval.value = yyvsp[0].value; - ; - break;} -case 54: + ;} + break; + + case 54: #line 389 "./cond.y" -{ + { + yyval.value = yyvsp[0].value; + ;} + break; + + case 55: +#line 396 "./cond.y" + { yyval.string = yyvsp[0].string; - ; - break;} -case 55: -#line 393 "./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; @@ -1468,78 +1675,70 @@ case 61: 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" 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 @@ -1547,11 +1746,11 @@ case 64: 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; @@ -1564,145 +1763,151 @@ yyerrlab: 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) +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "Error: state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); } -#endif - -/*--------------. -| yyerrhandle. | -`--------------*/ -yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; @@ -1710,9 +1915,7 @@ yyerrhandle: YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif + yystate = yyn; goto yynewstate; @@ -1732,13 +1935,15 @@ yyabortlab: 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 @@ -1747,7 +1952,9 @@ yyreturn: #endif return yyresult; } -#line 503 "./cond.y" + + +#line 510 "./cond.y" @@ -1946,7 +2153,7 @@ static LPWSTR COND_GetString( struct cond_str *str ) { 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)); @@ -1960,7 +2167,7 @@ static LPWSTR COND_GetLiteral( struct cond_str *str ) { 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) ); @@ -2019,13 +2226,14 @@ MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szConditio 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; } + diff --git a/reactos/lib/msi/cond.tab.h b/reactos/lib/msi/cond.tab.h index d6099930466..f37273b3993 100644 --- a/reactos/lib/msi/cond.tab.h +++ b/reactos/lib/msi/cond.tab.h @@ -1,9 +1,83 @@ -#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; @@ -11,30 +85,15 @@ typedef union 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 */ + + + diff --git a/reactos/lib/msi/cond.y b/reactos/lib/msi/cond.y index 5cb921bfe37..977f81afc70 100644 --- a/reactos/lib/msi/cond.y +++ b/reactos/lib/msi/cond.y @@ -1,783 +1,790 @@ -%{ - -/* - * 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 -#include -#include - -#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 COND_IDENT COND_NUMBER COND_LITER - -%nonassoc COND_EOF COND_ERROR - -%type expression boolean_term boolean_factor -%type term value_i symbol_i integer -%type identifier value_s symbol_s literal -%type comp_op_i -%type comp_op_s -%type comp_op_m1 -%type 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; - } - | value_i comp_op_i value_i - { - $$ = $2( $1, $3 ); - } - | value_s comp_op_s value_s - { - $$ = $2( $1, $3, FALSE ); - } - | value_s COND_TILDA comp_op_s value_s - { - $$ = $3( $1, $4, TRUE ); - } - | value_s comp_op_m1 value_i - { - $$ = $2( $1, $3 ); - } - | value_i comp_op_m2 value_s - { - $$ = $2( $1, $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; - HeapFree( GetProcessHeap(), 0, $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; - HeapFree( GetProcessHeap(), 0, $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; - HeapFree( GetProcessHeap(), 0, $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; - HeapFree( GetProcessHeap(), 0, $2 ); - } - ; - -symbol_s: - identifier - { - DWORD sz; - COND_input* cond = (COND_input*) info; - - sz = 0; - MSI_GetPropertyW(cond->package, $1, NULL, &sz); - if (sz == 0) - { - $$ = HeapAlloc( GetProcessHeap(), 0 ,sizeof(WCHAR)); - $$[0] = 0; - } - else - { - sz ++; - $$ = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR) ); - - /* Lookup the identifier */ - - MSI_GetPropertyW(cond->package,$1,$$,&sz); - } - HeapFree( GetProcessHeap(), 0, $1 ); - } - | COND_PERCENT identifier - { - UINT len = GetEnvironmentVariableW( $2, NULL, 0 ); - if( len++ ) - { - $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) ); - if( $$ ) - GetEnvironmentVariableW( $2, $$, len ); - } - HeapFree( GetProcessHeap(), 0, $2 ); - } - ; - -identifier: - COND_IDENT - { - $$ = COND_GetString(&$1); - if( !$$ ) - YYABORT; - } - ; - -integer: - COND_NUMBER - { - LPWSTR szNum = COND_GetString(&$1); - if( !szNum ) - YYABORT; - $$ = atoiW( szNum ); - HeapFree( GetProcessHeap(), 0, 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_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 = HeapAlloc( GetProcessHeap(), 0, (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 = HeapAlloc( GetProcessHeap(), 0, (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 = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len ); - } - - r = MsiEvaluateConditionW( hInstall, szwCond ); - - HeapFree( GetProcessHeap(), 0, szwCond ); - - return 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 +#include +#include + +#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 COND_IDENT COND_NUMBER COND_LITER + +%nonassoc COND_EOF COND_ERROR + +%type expression boolean_term boolean_factor +%type term value_i symbol_i integer +%type identifier value_s symbol_s literal +%type comp_op_i +%type comp_op_s +%type comp_op_m1 +%type 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_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; +} diff --git a/reactos/lib/msi/create.c b/reactos/lib/msi/create.c index e442361071a..2e98a2cec1a 100644 --- a/reactos/lib/msi/create.c +++ b/reactos/lib/msi/create.c @@ -64,7 +64,7 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 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"); @@ -148,6 +148,8 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 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 ); @@ -199,7 +201,7 @@ static UINT CREATE_delete( struct tagMSIVIEW *view ) TRACE("%p\n", cv ); msiobj_release( &cv->db->hdr ); - HeapFree( GetProcessHeap(), 0, cv ); + msi_free( cv ); return ERROR_SUCCESS; } @@ -226,7 +228,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, TRACE("%p\n", cv ); - cv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *cv ); + cv = msi_alloc_zero( sizeof *cv ); if( !cv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/lib/msi/custom.c b/reactos/lib/msi/custom.c index d2a81fa534b..efb40c5777f 100644 --- a/reactos/lib/msi/custom.c +++ b/reactos/lib/msi/custom.c @@ -57,6 +57,7 @@ static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0}; typedef struct tagMSIRUNNINGACTION { + struct list entry; HANDLE handle; BOOL process; LPWSTR name; @@ -153,10 +154,8 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) { 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) { @@ -171,10 +170,8 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL 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 { @@ -183,15 +180,19 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) 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) { @@ -216,12 +217,12 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) 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", @@ -229,8 +230,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) debugstr_w(target)); } - HeapFree(GetProcessHeap(),0,source); - HeapFree(GetProcessHeap(),0,target); +end: + msi_free(source); + msi_free(target); msiobj_release(&row->hdr); return rc; } @@ -243,8 +245,7 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source, 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) @@ -300,22 +301,15 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source, 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; - newbuf[count].handle = Handle; - newbuf[count].process = process; - newbuf[count].name = strdupW(name); + action = msi_alloc( sizeof(MSIRUNNINGACTION) ); - package->RunningAction = newbuf; + action->handle = Handle; + action->process = process; + action->name = strdupW(name); + + list_add_tail( &package->RunningActions, &action->entry ); } static UINT process_action_return_value(UINT type, HANDLE ThreadHandle) @@ -373,7 +367,7 @@ static UINT process_handle(MSIPACKAGE* package, UINT type, } CloseHandle(ThreadHandle); - if (ProcessHandle); + if (ProcessHandle) CloseHandle(ProcessHandle); if (finished) *finished = TRUE; @@ -395,7 +389,7 @@ static UINT process_handle(MSIPACKAGE* package, UINT type, else { CloseHandle(ThreadHandle); - if (ProcessHandle); + if (ProcessHandle) CloseHandle(ProcessHandle); } if (finished) @@ -436,11 +430,11 @@ static DWORD WINAPI ACTION_CallDllFunction(thread_struct *stuff) 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 ); @@ -448,15 +442,15 @@ static DWORD WINAPI ACTION_CallDllFunction(thread_struct *stuff) 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; } @@ -498,7 +492,7 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source, 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); @@ -541,7 +535,7 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, if (deformated) len += strlenW(deformated); - cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len); + cmd = msi_alloc(sizeof(WCHAR)*len); strcpyW(cmd,tmp_file); if (deformated) @@ -549,7 +543,7 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, strcatW(cmd,spc); strcatW(cmd,deformated); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(deformated); } TRACE("executing exe %s \n",debugstr_w(cmd)); @@ -557,7 +551,7 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, c_collen, &si, &info); - HeapFree(GetProcessHeap(),0,cmd); + msi_free(cmd); if ( !rc ) { @@ -602,7 +596,7 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source, len += strlenW(deformated); len += 2; - cmd = HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR)); + cmd = msi_alloc(len * sizeof(WCHAR)); lstrcpyW( cmd, file->TargetPath); if (deformated) @@ -610,7 +604,7 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source, strcatW(cmd, spc); strcatW(cmd, deformated); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(deformated); } TRACE("executing exe %s \n",debugstr_w(cmd)); @@ -618,7 +612,7 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source, rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, c_collen, &si, &info); - HeapFree(GetProcessHeap(),0,cmd); + msi_free(cmd); if ( !rc ) { @@ -639,7 +633,7 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source, '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; @@ -657,7 +651,7 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source, else MessageBoxW( NULL, deformated, NULL, MB_OK ); - HeapFree( GetProcessHeap(), 0, deformated ); + msi_free( deformated ); return ERROR_FUNCTION_FAILED; } @@ -672,13 +666,12 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, 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; @@ -687,7 +680,7 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, if (deformated) len += strlenW(deformated); - cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len); + cmd = msi_alloc(sizeof(WCHAR)*len); strcpyW(cmd,prop); if (deformated) @@ -695,15 +688,16 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, 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 ) { @@ -711,10 +705,7 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, 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, @@ -734,7 +725,7 @@ 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); @@ -745,7 +736,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, rc = CreateProcessW(NULL, deformated, NULL, NULL, FALSE, 0, NULL, c_collen, &si, &info); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(deformated); if ( !rc ) { @@ -762,29 +753,30 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, 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 ); - if (package->RunningAction[i].process) - GetExitCodeProcess(package->RunningAction[i].handle, &rc); + TRACE("Checking on action %s\n", debugstr_w(action->name)); + + 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); } diff --git a/reactos/lib/msi/database.c b/reactos/lib/msi/database.c index aa94a232638..d4a965561d5 100644 --- a/reactos/lib/msi/database.c +++ b/reactos/lib/msi/database.c @@ -48,6 +48,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); 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 @@ -91,7 +93,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) /* 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 ) { @@ -132,14 +134,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) 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 ) @@ -153,11 +155,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) 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; @@ -215,8 +220,8 @@ UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB) end: if( HIWORD(szPersist) ) - HeapFree( GetProcessHeap(), 0, szwPersist ); - HeapFree( GetProcessHeap(), 0, szwDBPath ); + msi_free( szwPersist ); + msi_free( szwDBPath ); return r; } @@ -271,8 +276,8 @@ UINT WINAPI MsiDatabaseImportA( MSIHANDLE handle, r = MsiDatabaseImportW( handle, path, file ); end: - HeapFree( GetProcessHeap(), 0, path ); - HeapFree( GetProcessHeap(), 0, file ); + msi_free( path ); + msi_free( file ); return r; } @@ -339,9 +344,9 @@ UINT WINAPI MsiDatabaseExportA( MSIHANDLE handle, LPCSTR szTable, 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; } diff --git a/reactos/lib/msi/delete.c b/reactos/lib/msi/delete.c index 46eab5fd826..d42bf600649 100644 --- a/reactos/lib/msi/delete.c +++ b/reactos/lib/msi/delete.c @@ -177,7 +177,7 @@ static UINT DELETE_delete( struct tagMSIVIEW *view ) if( dv->table ) dv->table->ops->delete( dv->table ); - HeapFree( GetProcessHeap(), 0, dv ); + msi_free( dv ); return ERROR_SUCCESS; } @@ -203,7 +203,7 @@ UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) TRACE("%p\n", dv ); - dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv ); + dv = msi_alloc_zero( sizeof *dv ); if( !dv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/lib/msi/dialog.c b/reactos/lib/msi/dialog.c index be98cbc9f7a..7a9c20d8974 100644 --- a/reactos/lib/msi/dialog.c +++ b/reactos/lib/msi/dialog.c @@ -33,6 +33,7 @@ #include "ocidl.h" #include "olectl.h" #include "richedit.h" +#include "commctrl.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -48,7 +49,7 @@ typedef UINT (*msi_handler)( msi_dialog *, msi_control *, WPARAM ); struct msi_control_tag { - struct msi_control_tag *next; + struct list entry; HWND hwnd; msi_handler handler; LPWSTR property; @@ -56,6 +57,7 @@ struct msi_control_tag HBITMAP hBitmap; HICON hIcon; LPWSTR tabnext; + HMODULE hDll; WCHAR name[1]; }; @@ -76,7 +78,7 @@ struct msi_dialog_tag HWND hwnd; LPWSTR default_font; msi_font *font_list; - msi_control *control_list; + struct list controls; HWND hWndFocus; WCHAR name[1]; }; @@ -114,6 +116,8 @@ static const WCHAR szComboBox[] = { 'C','o','m','b','o','B','o','x',0 }; 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 }; @@ -134,7 +138,6 @@ static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, static DWORD uiThreadId; static HWND hMsiHiddenWindow; -static HMODULE hRichedit; static INT msi_dialog_scale_unit( msi_dialog *dialog, INT val ) { @@ -147,20 +150,30 @@ static msi_control *msi_dialog_find_control( msi_dialog *dialog, LPCWSTR name ) 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; } /* @@ -169,23 +182,32 @@ static msi_control *msi_dialog_find_control_by_hwnd( msi_dialog *dialog, HWND hw * 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; iname, name ); font->next = dialog->font_list; dialog->font_list = font; @@ -288,21 +309,21 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, 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 ); @@ -317,8 +338,8 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, 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, @@ -330,8 +351,8 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, 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; } @@ -359,13 +380,13 @@ static LPWSTR msi_create_tmp_path(void) 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; } } @@ -399,7 +420,7 @@ static HANDLE msi_load_image( MSIDATABASE *db, LPCWSTR name, UINT type, msiobj_release( &rec->hdr ); } - HeapFree( GetProcessHeap(), 0, tmp ); + msi_free( tmp ); return himage; } @@ -438,7 +459,10 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, 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 ); @@ -534,7 +558,7 @@ MSIText_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) msi_text_on_settext( hWnd ); break; case WM_NCDESTROY: - HeapFree( GetProcessHeap(), 0, info ); + msi_free( info ); RemovePropW( hWnd, szButtonData ); break; } @@ -553,7 +577,7 @@ static UINT msi_dialog_text_control( msi_dialog *dialog, MSIRECORD *rec ) if( !control ) return ERROR_FUNCTION_FAILED; - info = HeapAlloc( GetProcessHeap(), 0, sizeof *info ); + info = msi_alloc( sizeof *info ); if( !info ) return ERROR_SUCCESS; @@ -572,7 +596,7 @@ static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; UINT attributes, style; - LPCWSTR text; + LPWSTR text; TRACE("%p %p\n", dialog, rec); @@ -588,10 +612,11 @@ static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *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; } @@ -606,7 +631,6 @@ static LPWSTR msi_get_checkbox_value( msi_dialog *dialog, LPCWSTR prop ) '\'','%','s','\'',0 }; MSIRECORD *rec = NULL; - LPCWSTR val = NULL; LPWSTR ret = NULL; /* find if there is a value associated with the checkbox */ @@ -614,24 +638,20 @@ static LPWSTR msi_get_checkbox_value( msi_dialog *dialog, LPCWSTR prop ) 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; } @@ -702,10 +722,17 @@ static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec ) 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 ); @@ -718,7 +745,7 @@ static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec ) SendMessageW( control->hwnd, EM_STREAMIN, SF_RTF, (LPARAM) &es ); - HeapFree( GetProcessHeap(), 0, info.string ); + msi_free( info.string ); return ERROR_SUCCESS; } @@ -727,7 +754,7 @@ static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec ) { UINT cx, cy, flags, style, attributes; msi_control *control; - LPCWSTR text; + LPWSTR text; flags = LR_LOADFROMFILE; style = SS_BITMAP | SS_LEFT | WS_GROUP; @@ -740,12 +767,12 @@ static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec ) } 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 ) @@ -753,6 +780,8 @@ static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec ) IMAGE_BITMAP, (LPARAM) control->hBitmap ); else ERR("Failed to load bitmap %s\n", debugstr_w(text)); + + msi_free( text ); return ERROR_SUCCESS; } @@ -761,7 +790,7 @@ static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; DWORD attributes; - LPCWSTR text; + LPWSTR text; TRACE("\n"); @@ -769,12 +798,13 @@ static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec ) 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; } @@ -799,9 +829,9 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec ) 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; } @@ -833,7 +863,7 @@ static void msi_mask_control_change( struct msi_maskedit_info *info ) 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; inum_groups; i++ ) { if( (info->group[i].len + n) > info->num_chars ) @@ -857,7 +887,7 @@ static void msi_mask_control_change( struct msi_maskedit_info *info ) 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 */ @@ -904,8 +934,8 @@ MSIMaskedEdit_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } break; case WM_NCDESTROY: - HeapFree( GetProcessHeap(), 0, info->prop ); - HeapFree( GetProcessHeap(), 0, info ); + msi_free( info->prop ); + msi_free( info ); RemovePropW( hWnd, szButtonData ); break; } @@ -928,7 +958,7 @@ msi_maskedit_set_text( struct msi_maskedit_info *info, LPCWSTR text ) LPWSTR chunk = strdupW( p ); chunk[ info->group[i].len ] = 0; SetWindowTextW( info->group[i].hwnd, chunk ); - HeapFree( GetProcessHeap(), 0, chunk ); + msi_free( chunk ); } else { @@ -954,13 +984,19 @@ static struct msi_maskedit_info * msi_dialog_parse_groups( LPCWSTR mask ) 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' ) break; @@ -980,7 +1016,7 @@ static struct msi_maskedit_info * msi_dialog_parse_groups( LPCWSTR mask ) 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)); @@ -991,10 +1027,9 @@ static struct msi_maskedit_info * msi_dialog_parse_groups( LPCWSTR 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; @@ -1006,9 +1041,6 @@ msi_maskedit_create_children( struct msi_maskedit_info *info ) 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; @@ -1025,7 +1057,7 @@ msi_maskedit_create_children( struct msi_maskedit_info *info ) 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; } } @@ -1033,17 +1065,19 @@ msi_maskedit_create_children( struct msi_maskedit_info *info ) /* 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; - mask = load_dynamic_property( dialog->package, pidt, NULL ); + TRACE("\n"); + + 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; } @@ -1077,26 +1111,34 @@ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec ) 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 ) @@ -1112,8 +1154,7 @@ static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param ) 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 ); @@ -1125,6 +1166,8 @@ static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param ) 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 ); @@ -1197,6 +1240,7 @@ struct control_handler msi_dialog_handler[] = { 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 }, }; @@ -1394,7 +1438,7 @@ static UINT msi_dialog_set_tab_order( msi_dialog *dialog ) { 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 ) @@ -1422,7 +1466,6 @@ static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) '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; @@ -1445,16 +1488,16 @@ static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) 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 ); @@ -1477,8 +1520,8 @@ static UINT msi_dialog_send_event( msi_dialog *dialog, LPCWSTR event, LPCWSTR ar 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; } @@ -1490,7 +1533,7 @@ static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR 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 ) @@ -1499,10 +1542,11 @@ static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR 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; } @@ -1633,19 +1677,19 @@ static UINT msi_dialog_edit_handler( msi_dialog *dialog, 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; } @@ -1772,8 +1816,7 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package, LPCWSTR szDialogName, 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 ); @@ -1781,12 +1824,14 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package, LPCWSTR 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 ); @@ -1866,7 +1911,7 @@ UINT msi_dialog_run_message_loop( msi_dialog *dialog ) } ShowWindow( hwnd, SW_SHOW ); - UpdateWindow( hwnd ); + /* UpdateWindow( hwnd ); - and causes the transparent static controls not to paint */ if( dialog->attributes & msidbDialogAttributesModal ) { @@ -1901,20 +1946,26 @@ void msi_dialog_destroy( msi_dialog *dialog ) 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 */ @@ -1923,16 +1974,13 @@ void msi_dialog_destroy( msi_dialog *dialog ) 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 ) @@ -1944,7 +1992,7 @@ 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; @@ -1964,8 +2012,6 @@ BOOL msi_dialog_register_class( void ) if( !hMsiHiddenWindow ) return FALSE; - hRichedit = LoadLibraryA("riched20"); - return TRUE; } @@ -1974,5 +2020,4 @@ void msi_dialog_unregister_class( void ) DestroyWindow( hMsiHiddenWindow ); UnregisterClassW( szMsiDialogClass, NULL ); uiThreadId = 0; - FreeLibrary( hRichedit ); } diff --git a/reactos/lib/msi/distinct.c b/reactos/lib/msi/distinct.c index 64fa5ef9755..7ecd48d20fa 100644 --- a/reactos/lib/msi/distinct.c +++ b/reactos/lib/msi/distinct.c @@ -67,7 +67,7 @@ static DISTINCTSET ** distinct_insert( DISTINCTSET **x, UINT val, UINT row ) } /* nothing found, so add one */ - *x = HeapAlloc( GetProcessHeap(), 0, sizeof (DISTINCTSET) ); + *x = msi_alloc( sizeof (DISTINCTSET) ); if( *x ) { (*x)->val = val; @@ -85,7 +85,7 @@ static void distinct_free( DISTINCTSET *x ) { DISTINCTSET *next = x->nextrow; distinct_free( x->nextcol ); - HeapFree( GetProcessHeap(), 0, x ); + msi_free( x ); x = next; } } @@ -126,7 +126,7 @@ static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 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; @@ -178,7 +178,7 @@ static UINT DISTINCT_close( struct tagMSIVIEW *view ) if( !dv->table ) return ERROR_FUNCTION_FAILED; - HeapFree( GetProcessHeap(), 0, dv->translation ); + msi_free( dv->translation ); dv->translation = NULL; dv->row_count = 0; @@ -239,9 +239,9 @@ static UINT DISTINCT_delete( struct tagMSIVIEW *view ) 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; } @@ -275,7 +275,7 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) return r; } - dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv ); + dv = msi_alloc_zero( sizeof *dv ); if( !dv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/lib/msi/events.c b/reactos/lib/msi/events.c index 559f857a72c..08a85c66496 100644 --- a/reactos/lib/msi/events.c +++ b/reactos/lib/msi/events.c @@ -235,9 +235,12 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, 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; } /* @@ -245,10 +248,10 @@ static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument, */ 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, @@ -256,7 +259,7 @@ 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); @@ -349,7 +352,7 @@ UINT ACTION_DialogBox( MSIPACKAGE* package, LPCWSTR szDialogName ) package->next_dialog = NULL; r = event_do_dialog( package, name, TRUE ); - HeapFree( GetProcessHeap(), 0, name ); + msi_free( name ); } if( r == ERROR_IO_PENDING ) @@ -386,11 +389,11 @@ UINT ControlEvent_HandleControlEvent(MSIPACKAGE *package, LPCWSTR event, 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", diff --git a/reactos/lib/msi/files.c b/reactos/lib/msi/files.c index 25102899a23..c292833191e 100644 --- a/reactos/lib/msi/files.c +++ b/reactos/lib/msi/files.c @@ -72,7 +72,7 @@ static UINT create_component_directory( MSIPACKAGE* package, MSICOMPONENT *comp create_full_pathW(install_path); folder->State = 2; } - HeapFree(GetProcessHeap(), 0, install_path); + msi_free(install_path); return rc; } @@ -115,7 +115,7 @@ static UINT writeout_cabinet_stream(MSIPACKAGE *package, LPCWSTR stream_name, CloseHandle(the_file); TRACE("wrote %li bytes to %s\n",write,debugstr_w(source)); end: - HeapFree(GetProcessHeap(),0,data); + msi_free(data); return rc; } @@ -129,12 +129,12 @@ typedef struct 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) @@ -214,18 +214,17 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) 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; } @@ -238,7 +237,7 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) /* 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); @@ -246,9 +245,9 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) 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); @@ -259,7 +258,7 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) 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); @@ -324,7 +323,7 @@ static BOOL extract_cabinet_file(MSIPACKAGE* package, LPCWSTR source, if (!(cab_path = strdupWtoA( path ))) { FDIDestroy(hfdi); - HeapFree(GetProcessHeap(), 0, cabinet); + msi_free(cabinet); return FALSE; } @@ -338,8 +337,8 @@ static BOOL extract_cabinet_file(MSIPACKAGE* package, LPCWSTR source, FDIDestroy(hfdi); - HeapFree(GetProcessHeap(), 0, cabinet); - HeapFree(GetProcessHeap(), 0, cab_path); + msi_free(cabinet); + msi_free(cab_path); return ret; } @@ -352,7 +351,7 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, MSICOMPONENT* 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); @@ -419,25 +418,55 @@ static UINT ready_volume(MSIPACKAGE* package, LPCWSTR path, LPWSTR last_volume, 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',' ', @@ -447,34 +476,17 @@ static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file, 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) + if (file->Sequence <= mi->last_sequence) { - 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)); + set_file_source(package,file,comp,mi->last_path); + TRACE("Media already ready (%u, %u)\n",file->Sequence,mi->last_sequence); return ERROR_SUCCESS; } - if (file->Sequence <= last_sequence) - { - set_file_source(package,file,comp,last_path); - TRACE("Media already ready (%u, %u)\n",file->Sequence,last_sequence); - return ERROR_SUCCESS; - } - - count ++; + mi->count ++; row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence); if (!row) { @@ -483,22 +495,22 @@ static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file, } 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 || @@ -506,12 +518,12 @@ static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file, 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; } @@ -525,14 +537,14 @@ static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file, { 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, @@ -540,68 +552,68 @@ static UINT ready_media_for_file(MSIPACKAGE *package, MSIFILE *file, 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); @@ -643,6 +655,7 @@ static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key, */ UINT ACTION_InstallFiles(MSIPACKAGE *package) { + struct media_info *mi; UINT rc = ERROR_SUCCESS; LPWSTR ptr; MSIFILE *file; @@ -670,9 +683,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) { MSICOMPONENT* comp = NULL; - if (file->Temporary) - continue; - if (!ACTION_VerifyComponentForAction(package, file->Component, INSTALLSTATE_LOCAL)) { @@ -702,24 +712,23 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) } 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"); @@ -771,7 +780,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) } /* cleanup */ - ready_media_for_file(NULL, NULL, NULL); + free_media_info( mi ); return rc; } @@ -814,7 +823,7 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param) 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; } @@ -843,11 +852,11 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param) 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; } } @@ -868,9 +877,9 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param) 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; } diff --git a/reactos/lib/msi/format.c b/reactos/lib/msi/format.c index df7c0e3c056..9bcfc7f9cd2 100644 --- a/reactos/lib/msi/format.c +++ b/reactos/lib/msi/format.c @@ -56,7 +56,7 @@ static LPWSTR build_default_format(MSIRECORD* record) 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++) { @@ -85,7 +85,7 @@ static LPWSTR deformat_component(MSIPACKAGE* package, LPCWSTR key, DWORD* sz) 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) { @@ -124,7 +124,7 @@ static LPWSTR deformat_file(MSIPACKAGE* package, LPCWSTR key, DWORD* sz, { *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 @@ -150,7 +150,7 @@ static LPWSTR deformat_environment(MSIPACKAGE* package, LPCWSTR key, 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); } @@ -168,7 +168,7 @@ static LPWSTR deformat_NULL(DWORD* chunk) { LPWSTR value; - value = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*2); + value = msi_alloc(sizeof(WCHAR)*2); value[0] = 0; *chunk = sizeof(WCHAR); return value; @@ -178,7 +178,7 @@ static LPWSTR deformat_escape(LPCWSTR key, DWORD* chunk) { LPWSTR value; - value = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*2); + value = msi_alloc(sizeof(WCHAR)*2); value[0] = key[0]; *chunk = sizeof(WCHAR); @@ -219,15 +219,14 @@ static LPWSTR deformat_index(MSIRECORD* record, LPCWSTR key, DWORD* chunk ) 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; @@ -261,7 +260,7 @@ static BOOL find_next_group(LPCWSTR source, DWORD len_remaining, *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)); @@ -307,7 +306,7 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining, *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)); @@ -320,7 +319,7 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining, 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; @@ -338,14 +337,14 @@ static LPWSTR deformat_group(MSIPACKAGE* package, LPWSTR group, DWORD len, 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); @@ -358,17 +357,18 @@ static LPWSTR deformat_group(MSIPACKAGE* package, LPWSTR group, DWORD len, { 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; } @@ -408,7 +408,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, (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; @@ -424,6 +424,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, { value = deformat_group(package, key, strlenW(key)+1, record, &chunk); + msi_free( key ); key = NULL; nested = FALSE; } @@ -438,9 +439,9 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 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); @@ -456,9 +457,9 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 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))); } @@ -471,7 +472,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, deformat_string_internal(package, key, &value, strlenW(key)+1, record, failcount); - HeapFree(GetProcessHeap(),0,key); + msi_free(key); key = value; } @@ -495,7 +496,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, { 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] = ']'; @@ -533,7 +534,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 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); } @@ -543,7 +544,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, } } - HeapFree(GetProcessHeap(),0,key); + msi_free(key); if (value!=NULL) { @@ -551,13 +552,13 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 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)++; @@ -615,8 +616,8 @@ UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer, *size = len; - HeapFree(GetProcessHeap(),0,rec); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(rec); + msi_free(deformated); return rc; } @@ -659,8 +660,8 @@ UINT MSI_FormatRecordA( MSIPACKAGE* package, MSIRECORD* record, LPSTR buffer, *size = lenA; - HeapFree(GetProcessHeap(),0,rec); - HeapFree(GetProcessHeap(),0,deformated); + msi_free(rec); + msi_free(deformated); return rc; } diff --git a/reactos/lib/msi/handle.c b/reactos/lib/msi/handle.c index 9ecfd053870..52c24395303 100644 --- a/reactos/lib/msi/handle.c +++ b/reactos/lib/msi/handle.c @@ -37,7 +37,7 @@ static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug = 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 }; @@ -47,7 +47,7 @@ static CRITICAL_SECTION_DEBUG MSI_object_cs_debug = 0, 0, &MSI_object_cs, { &MSI_object_cs_debug.ProcessLocksList, &MSI_object_cs_debug.ProcessLocksList }, - 0, 0, { 0, (DWORD)(__FILE__ ": MSI_object_cs") } + 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_object_cs") } }; static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 }; @@ -109,30 +109,11 @@ out: 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 %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; @@ -190,7 +171,7 @@ int msiobj_release( MSIOBJECTHDR *info ) { if( info->destructor ) info->destructor( info ); - HeapFree( GetProcessHeap(), 0, info ); + msi_free( info ); TRACE("object %p destroyed\n", info); } diff --git a/reactos/lib/msi/helpers.c b/reactos/lib/msi/helpers.c index 21432e2b092..fc466ba7a20 100644 --- a/reactos/lib/msi/helpers.c +++ b/reactos/lib/msi/helpers.c @@ -84,11 +84,9 @@ DWORD build_version_dword(LPCWSTR version_string) 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','\\', @@ -96,17 +94,17 @@ UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, 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) @@ -124,24 +122,24 @@ 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; @@ -149,21 +147,16 @@ LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc) 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; } @@ -205,22 +198,32 @@ MSIFILE* get_loaded_file( MSIPACKAGE* package, LPCWSTR key ) int track_tempfile( MSIPACKAGE *package, LPCWSTR name, LPCWSTR path ) { - MSIFILE *file; + MSITEMPFILE *temp; if (!package) - return -2; - - file = get_loaded_file( package, name ); - if (file) return -1; - file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFILE) ); + 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->File = strdupW( name ); - file->TargetPath = strdupW( path ); - file->Temporary = TRUE; + temp = msi_alloc_zero( sizeof (MSITEMPFILE) ); + if (!temp) + return -1; - TRACE("Tracking tempfile (%s)\n", debugstr_w( file->File )); + list_add_head( &package->tempfiles, &temp->entry ); + + temp->File = strdupW( name ); + temp->Path = strdupW( path ); + + TRACE("adding tempfile %s with path %s\n", + debugstr_w(temp->File), debugstr_w(temp->Path)); return 0; } @@ -254,10 +257,10 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 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); } @@ -266,13 +269,14 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 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,'\\'); @@ -341,7 +345,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, TRACE(" (source)resolved into %s\n",debugstr_w(path)); f->ResolvedSource = strdupW( path ); } - HeapFree(GetProcessHeap(),0,p); + msi_free(p); } return path; } @@ -359,7 +363,7 @@ DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ) 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 @@ -388,11 +392,10 @@ UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action) 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; @@ -402,18 +405,18 @@ UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action) static void remove_tracked_tempfiles(MSIPACKAGE* package) { - MSIFILE *file; + struct list *item, *cursor; - if (!package) - return; - - 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 ); } } @@ -425,11 +428,35 @@ static void free_feature( MSIFEATURE *feature ) { ComponentList *cl = LIST_ENTRY( item, ComponentList, entry ); list_remove( &cl->entry ); - HeapFree( GetProcessHeap(), 0, cl ); + msi_free( cl ); } - HeapFree( GetProcessHeap(), 0, feature ); + 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) @@ -453,12 +480,13 @@ 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 ) @@ -466,8 +494,13 @@ void ACTION_free_package_structures( MSIPACKAGE* package) 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 ) @@ -475,14 +508,14 @@ void ACTION_free_package_structures( MSIPACKAGE* package) 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 */ @@ -491,14 +524,16 @@ void ACTION_free_package_structures( MSIPACKAGE* package) 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 ) @@ -506,37 +541,28 @@ void ACTION_free_package_structures( MSIPACKAGE* package) 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); + MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry ); + + list_remove( &progid->entry ); + msi_free( progid->ProgID ); + msi_free( progid->Description ); + msi_free( progid->IconPath ); + msi_free( progid ); } - if (package->progids && package->loaded_progids > 0) - HeapFree(GetProcessHeap(),0,package->progids); - - 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); - } - - 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 ) @@ -544,11 +570,12 @@ void ACTION_free_package_structures( MSIPACKAGE* package) 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) @@ -557,21 +584,22 @@ void ACTION_free_package_structures( MSIPACKAGE* package) { 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); @@ -612,7 +640,7 @@ LPWSTR build_directory_name(DWORD count, ...) } va_end(va); - dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR)); + dir = msi_alloc(sz*sizeof(WCHAR)); dir[0]=0; va_start(va,count); @@ -641,8 +669,7 @@ BOOL create_full_pathW(const WCHAR *path) 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); @@ -678,7 +705,7 @@ BOOL create_full_pathW(const WCHAR *path) new_path[len] = '\\'; } - HeapFree(GetProcessHeap(), 0, new_path); + msi_free(new_path); return ret; } @@ -723,10 +750,10 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) } /* 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); @@ -749,6 +776,9 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, MSICOMPONENT* comp, INSTALLSTATE check ) { + if (!comp) + return FALSE; + if (comp->Installed == check) return FALSE; @@ -760,6 +790,9 @@ BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, MSICOMPONENT* comp, BOOL ACTION_VerifyFeatureForAction( MSIFEATURE* feature, INSTALLSTATE check ) { + if (!feature) + return FALSE; + if (feature->Installed == check) return FALSE; @@ -822,7 +855,7 @@ LPWSTR create_component_advertise_string(MSIPACKAGE* package, sz+=3; sz *= sizeof(WCHAR); - output = HeapAlloc(GetProcessHeap(),0,sz); + output = msi_alloc(sz); memset(output,0,sz); if (component) @@ -856,39 +889,37 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) 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 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 ) { - if ( component->ActionRequest != INSTALLSTATE_LOCAL ) - break; - - 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; } } } @@ -912,16 +943,15 @@ UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action) 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) @@ -973,7 +1003,7 @@ WCHAR* generate_error_string(MSIPACKAGE *package, UINT error, DWORD count, ... ) 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 diff --git a/reactos/lib/msi/insert.c b/reactos/lib/msi/insert.c index 7e317bb30ce..5d9fcb90ebf 100644 --- a/reactos/lib/msi/insert.c +++ b/reactos/lib/msi/insert.c @@ -209,7 +209,7 @@ static UINT INSERT_delete( struct tagMSIVIEW *view ) if( sv ) sv->ops->delete( sv ); msiobj_release( &iv->db->hdr ); - HeapFree( GetProcessHeap(), 0, iv ); + msi_free( iv ); return ERROR_SUCCESS; } @@ -250,7 +250,7 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, return r; } - iv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *iv ); + iv = msi_alloc_zero( sizeof *iv ); if( !iv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/lib/msi/install.c b/reactos/lib/msi/install.c index 94a7acfff97..2098cb2fc14 100644 --- a/reactos/lib/msi/install.c +++ b/reactos/lib/msi/install.c @@ -41,24 +41,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); 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; } /*********************************************************************** @@ -67,159 +60,235 @@ UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) 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; } +/*********************************************************************** + * MsiSequenceA (MSI.@) + */ +UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode ) +{ + LPWSTR szwTable; + UINT ret; + + TRACE("%s\n", debugstr_a(szTable)); + + szwTable = strdupAtoW(szTable); + if (szTable && !szwTable) + return ERROR_FUNCTION_FAILED; + + ret = MsiSequenceW( hInstall, szwTable, iSequenceMode ); + msi_free( szwTable ); + return ret; +} + +/*********************************************************************** + * MsiSequenceW (MSI.@) + */ +UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode ) +{ + MSIPACKAGE *package; + UINT ret; + + TRACE("%s\n", debugstr_w(szTable)); + + package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); + if (!package) + return ERROR_INVALID_HANDLE; + + ret = MSI_Sequence( package, szTable, iSequenceMode ); + msiobj_release( &package->hdr ); + + return ret; +} + +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) + { + len = lstrlenW( str ); + if (awbuf->str.w) + lstrcpynW( awbuf->str.w, str, *sz ); + } + else + { + len = WideCharToMultiByte( CP_ACP, 0, str, -1, + awbuf->str.a, *sz, NULL, NULL ); + len--; + } + + 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; +} + /*********************************************************************** * MsiGetTargetPathA (MSI.@) */ UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, - LPSTR szPathBuf, DWORD* pcchPathBuf) + LPSTR szPathBuf, DWORD* pcchPathBuf ) { LPWSTR szwFolder; - LPWSTR szwPathBuf; - UINT rc; + awstring path; + UINT r; - TRACE("getting folder %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf); - - 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 = MsiGetTargetPathW(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 rc; + return r; } /*********************************************************************** -* MsiGetTargetPathW (MSI.@) -*/ -UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR - szPathBuf, DWORD* pcchPathBuf) + * MsiGetTargetPathW (MSI.@) + */ +UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, + LPWSTR szPathBuf, DWORD* pcchPathBuf ) { - LPWSTR path; - UINT rc = ERROR_FUNCTION_FAILED; - MSIPACKAGE *package; + awstring path; - TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf); + TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf); + + path.unicode = TRUE; + path.str.w = szPathBuf; + + return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf ); +} + +/*********************************************************************** + * MsiGetSourcePath (internal) + */ +static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, + awstring *szPathBuf, DWORD* pcchPathBuf ) +{ + MSIPACKAGE *package; + LPWSTR path; + UINT r; + + TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf ); + + 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 && (strlenW(path) > *pcchPathBuf)) + if (szPathBuf->str.w && !pcchPathBuf ) { - *pcchPathBuf = strlenW(path)+1; - rc = ERROR_MORE_DATA; + msiobj_release( &package->hdr ); + return ERROR_INVALID_PARAMETER; } - else if (path) - { - *pcchPathBuf = strlenW(path)+1; - strcpyW(szPathBuf,path); - TRACE("Returning Path %s\n",debugstr_w(path)); - rc = ERROR_SUCCESS; - } - HeapFree(GetProcessHeap(),0,path); - - return rc; -} - -/*********************************************************************** -* MsiGetSourcePathA (MSI.@) -*/ -UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, - LPSTR szPathBuf, DWORD* pcchPathBuf) -{ - LPWSTR szwFolder; - LPWSTR szwPathBuf; - UINT rc; - - TRACE("getting source %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf); - - if (!szFolder) - return ERROR_FUNCTION_FAILED; - if (hInstall == 0) - return ERROR_FUNCTION_FAILED; - - szwFolder = strdupAtoW(szFolder); - if (!szwFolder) - return ERROR_FUNCTION_FAILED; - - szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR)); - - rc = MsiGetSourcePathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf); - - WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf, - *pcchPathBuf, NULL, NULL ); - - HeapFree(GetProcessHeap(),0,szwFolder); - HeapFree(GetProcessHeap(),0,szwPathBuf); - - return rc; -} - -/*********************************************************************** -* MsiGetSourcePathW (MSI.@) -*/ -UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR - szPathBuf, DWORD* pcchPathBuf) -{ - LPWSTR path; - UINT rc = ERROR_FUNCTION_FAILED; - MSIPACKAGE *package; - - TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf); - - package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); - if( !package ) - return ERROR_INVALID_HANDLE; path = resolve_folder(package, szFolder, TRUE, FALSE, NULL); msiobj_release( &package->hdr ); - if (path && strlenW(path) > *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; - } - HeapFree(GetProcessHeap(),0,path); - - return rc; + 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.@) @@ -243,14 +312,14 @@ UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, 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; } @@ -295,7 +364,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 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) @@ -304,10 +373,10 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, * 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 { @@ -315,17 +384,17 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 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; } @@ -406,7 +475,7 @@ UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); - HeapFree(GetProcessHeap(),0,szwFeature); + msi_free(szwFeature); return rc; } @@ -478,7 +547,7 @@ UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature, rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction); - HeapFree( GetProcessHeap(), 0 , szwFeature); + msi_free( szwFeature); return rc; } @@ -534,7 +603,7 @@ UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, rc = MsiSetComponentStateW(hInstall, szwComponent, iState); - HeapFree(GetProcessHeap(), 0, szwComponent); + msi_free(szwComponent); return rc; } @@ -552,7 +621,7 @@ UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent, rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction); - HeapFree( GetProcessHeap(), 0 , szwComponent); + msi_free( szwComponent); return rc; } @@ -648,10 +717,10 @@ LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall) 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; } diff --git a/reactos/lib/msi/msi.c b/reactos/lib/msi/msi.c index 0d58d3c95c0..af1728dd81d 100644 --- a/reactos/lib/msi/msi.c +++ b/reactos/lib/msi/msi.c @@ -76,19 +76,19 @@ UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct) 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 ) @@ -108,7 +108,7 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct) } /* now alloc and fetch the path of the database to open */ - path = HeapAlloc( GetProcessHeap(), 0, count ); + path = msi_alloc( count ); if( !path ) goto end; @@ -120,16 +120,30 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct) 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) { @@ -188,8 +202,8 @@ UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine) r = MsiInstallProductW( szwPath, szwCommand ); end: - HeapFree( GetProcessHeap(), 0, szwPath ); - HeapFree( GetProcessHeap(), 0, szwCommand ); + msi_free( szwPath ); + msi_free( szwCommand ); return r; } @@ -198,42 +212,16 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine) { 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; } @@ -268,9 +256,8 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, 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]; @@ -297,7 +284,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, 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. @@ -306,42 +293,37 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, * 4, cleanupany runonce entry. */ - rc = MsiOpenProductW(szProduct,&handle); - if (rc != ERROR_SUCCESS) - goto end; + r = MSI_OpenProductW( szProduct, &package ); + if (r != ERROR_SUCCESS) + return r; - package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE); - if (!package) - { - rc = ERROR_INVALID_HANDLE; - goto end; - } - - 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 ); + msi_free(commandline); + +end: msiobj_release( &package->hdr ); - HeapFree(GetProcessHeap(),0,commandline); -end: - if (handle != -1) - MsiCloseHandle(handle); - - return rc; + return r; } UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel, @@ -368,8 +350,8 @@ 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; } @@ -390,7 +372,7 @@ UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, } r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState ); - HeapFree( GetProcessHeap(), 0, szwProduct ); + msi_free( szwProduct ); return r; } @@ -423,7 +405,7 @@ UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer) if( ERROR_SUCCESS == r ) WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL); - HeapFree( GetProcessHeap(), 0, szwComponent ); + msi_free( szwComponent ); return r; } @@ -490,7 +472,7 @@ UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, if( szBuffer ) { - szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) ); + szwBuffer = msi_alloc( (*pcchValueBuf) * sizeof(WCHAR) ); pcchwValueBuf = *pcchValueBuf; if( !szwBuffer ) goto end; @@ -500,13 +482,18 @@ UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, &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; } @@ -619,7 +606,7 @@ UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes) return ERROR_OUTOFMEMORY; } r = MsiEnableLogW( dwLogMode, szwLogFile, attributes ); - HeapFree( GetProcessHeap(), 0, szwLogFile ); + msi_free( szwLogFile ); return r; } @@ -654,7 +641,7 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct) return ERROR_OUTOFMEMORY; } r = MsiQueryProductStateW( szwProduct ); - HeapFree( GetProcessHeap(), 0, szwProduct ); + msi_free( szwProduct ); return r; } @@ -816,7 +803,7 @@ LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer, 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 ) { @@ -827,7 +814,7 @@ LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer, else r = 0; } - HeapFree(GetProcessHeap(), 0, bufW); + msi_free(bufW); return r; } @@ -943,7 +930,7 @@ UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage ) r = MsiVerifyPackageW( szPack ); - HeapFree( GetProcessHeap(), 0, szPack ); + msi_free( szPack ); return r; } @@ -980,14 +967,14 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent, 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 @@ -998,14 +985,14 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent, 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; @@ -1048,7 +1035,7 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent, goto end; sz += sizeof(WCHAR); - path = HeapAlloc( GetProcessHeap(), 0, sz ); + path = msi_alloc( sz ); if( !path ) goto end; @@ -1082,7 +1069,7 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent, } end: - HeapFree(GetProcessHeap(), 0, path ); + msi_free(path ); RegCloseKey(hkey); return rrc; } @@ -1108,15 +1095,15 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature) 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; } @@ -1167,14 +1154,14 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf, 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; } @@ -1190,9 +1177,9 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf, 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; } @@ -1222,7 +1209,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, if( !dwVerLen ) return GetLastError(); - lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen); + lpVer = msi_alloc(dwVerLen); if( !lpVer ) { ret = ERROR_OUTOFMEMORY; @@ -1263,7 +1250,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, } end: - HeapFree(GetProcessHeap(), 0, lpVer); + msi_free(lpVer); return ret; } @@ -1473,12 +1460,12 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent, 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; } @@ -1489,7 +1476,7 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent, else { RegCloseKey(hkey); - HeapFree(GetProcessHeap(),0,info); + msi_free(info); return ERROR_INDEX_ABSENT; } @@ -1507,9 +1494,9 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent, 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; @@ -1545,19 +1532,19 @@ UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent, 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; } @@ -1691,14 +1678,24 @@ UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct) 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_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) { WCHAR path[MAX_PATH]; @@ -1725,30 +1722,156 @@ UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget, 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; } diff --git a/reactos/lib/msi/msi.rc b/reactos/lib/msi/msi.rc index 4e48f957d33..f43ff3a84f1 100644 --- a/reactos/lib/msi/msi.rc +++ b/reactos/lib/msi/msi.rc @@ -1,36 +1,39 @@ -/* - * 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_De.rc" -#include "msi_En.rc" -#include "msi_Es.rc" -#include "msi_Fr.rc" -#include "msi_Nl.rc" -#include "msi_Pt.rc" -#include "msi_Ru.rc" +/* + * 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" diff --git a/reactos/lib/msi/msi.spec b/reactos/lib/msi/msi.spec index f3815037988..33f2db14641 100644 --- a/reactos/lib/msi/msi.spec +++ b/reactos/lib/msi/msi.spec @@ -4,10 +4,10 @@ 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) @@ -125,8 +125,8 @@ 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) @@ -173,8 +173,8 @@ 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 diff --git a/reactos/lib/msi/msi_Bg.rc b/reactos/lib/msi/msi_Bg.rc new file mode 100644 index 00000000000..8a0ead57e79 --- /dev/null +++ b/reactos/lib/msi/msi_Bg.rc @@ -0,0 +1,33 @@ +/* + * 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" +} diff --git a/reactos/lib/msi/msi_En.rc b/reactos/lib/msi/msi_En.rc index 854b7a8cc8f..f3330c88528 100644 --- a/reactos/lib/msi/msi_En.rc +++ b/reactos/lib/msi/msi_En.rc @@ -1,33 +1,33 @@ -/* - * 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" -} +/* + * 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" +} diff --git a/reactos/lib/msi/msi_Fi.rc b/reactos/lib/msi/msi_Fi.rc new file mode 100644 index 00000000000..5de0be8a72e --- /dev/null +++ b/reactos/lib/msi/msi_Fi.rc @@ -0,0 +1,33 @@ +/* + * 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" +} diff --git a/reactos/lib/msi/msi_No.rc b/reactos/lib/msi/msi_No.rc new file mode 100644 index 00000000000..fbed9fbeec6 --- /dev/null +++ b/reactos/lib/msi/msi_No.rc @@ -0,0 +1,33 @@ +/* + * Norwegian Bokmål resources for MSI + * + * Copyright 2005 Alexander N. Sørnes + * + * 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'." +} diff --git a/reactos/lib/msi/msi_Ru.rc b/reactos/lib/msi/msi_Ru.rc index ee90d92089a..b9f41d79ef8 100644 --- a/reactos/lib/msi/msi_Ru.rc +++ b/reactos/lib/msi/msi_Ru.rc @@ -1,34 +1,34 @@ -/* - * 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" -} +/* + * 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" +} diff --git a/reactos/lib/msi/msipriv.h b/reactos/lib/msi/msipriv.h index ce235fe4a76..9f4f644f17b 100644 --- a/reactos/lib/msi/msipriv.h +++ b/reactos/lib/msi/msipriv.h @@ -34,11 +34,12 @@ #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; @@ -57,8 +58,6 @@ struct tagMSIOBJECTHDR UINT type; LONG refcount; msihandledestructor destructor; - struct tagMSIOBJECTHDR *next; - struct tagMSIOBJECTHDR *prev; }; typedef struct tagMSIDATABASE @@ -67,7 +66,7 @@ typedef struct tagMSIDATABASE IStorage *storage; string_table *strings; LPCWSTR mode; - MSITABLE *first_table, *last_table; + struct list tables; } MSIDATABASE; typedef struct tagMSIVIEW MSIVIEW; @@ -188,26 +187,22 @@ typedef struct tagMSIPACKAGE 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; @@ -241,8 +236,6 @@ typedef struct tagMSIPREVIEW #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); @@ -250,6 +243,21 @@ DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0 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); @@ -259,16 +267,9 @@ extern void msiobj_addref(MSIOBJECTHDR *); 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 ); @@ -300,9 +301,10 @@ extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname, 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 *); @@ -379,6 +381,10 @@ extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL cr 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 ); @@ -411,28 +417,55 @@ extern DWORD gUIFilter; 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; } @@ -440,8 +473,9 @@ inline static LPWSTR strdupW( LPCWSTR src ) { 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; } diff --git a/reactos/lib/msi/msiquery.c b/reactos/lib/msi/msiquery.c index 3cade1d95f8..ed7d8ebfbe4 100644 --- a/reactos/lib/msi/msiquery.c +++ b/reactos/lib/msi/msiquery.c @@ -49,7 +49,7 @@ static void MSI_CloseView( MSIOBJECTHDR *arg ) LIST_FOR_EACH_SAFE( ptr, t, &query->mem ) { - HeapFree( GetProcessHeap(), 0, ptr ); + msi_free( ptr ); } } @@ -71,7 +71,7 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) if( r != ERROR_SUCCESS ) return r; x = lstrcmpW( name, col_name ); - HeapFree( GetProcessHeap(), 0, col_name ); + msi_free( col_name ); if( !x ) { *n = i; @@ -101,7 +101,7 @@ UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, r = MsiDatabaseOpenViewW( hdb, szwQuery, phView); - HeapFree( GetProcessHeap(), 0, szwQuery ); + msi_free( szwQuery ); return r; } @@ -139,62 +139,28 @@ UINT MSI_DatabaseOpenViewW(MSIDATABASE *db, return r; } -static UINT MSI_OpenQueryV( MSIDATABASE *db, MSIQUERY **view, - LPCWSTR fmt, va_list args ) -{ - LPWSTR szQuery; - LPCWSTR p; - UINT sz, rc; - va_list va; - - /* figure out how much space we need to allocate */ - va = args; - sz = lstrlenW(fmt) + 1; - p = fmt; - while (*p) - { - 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++; - } - - /* 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); + int size = 100, res; + LPWSTR query; + /* 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); return r; } @@ -217,7 +183,8 @@ UINT MSI_IterateRecords( MSIQUERY *view, DWORD *count, 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; @@ -240,11 +207,25 @@ MSIRECORD *MSI_QueryGetRecord( MSIDATABASE *db, LPCWSTR fmt, ... ) 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 ) { @@ -313,8 +294,7 @@ UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec) 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 ) @@ -335,7 +315,7 @@ UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec) sval = MSI_makestring( query->db, ival ); MSI_RecordSetStringW( rec, i, sval ); - HeapFree( GetProcessHeap(), 0, sval ); + msi_free( sval ); } else { @@ -468,6 +448,29 @@ out: 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; @@ -478,6 +481,12 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR 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; @@ -511,8 +520,11 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR 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 ); @@ -627,18 +639,64 @@ MSIDBERROR WINAPI MsiViewGetErrorA( MSIHANDLE handle, LPSTR szColumnNameBuffer, 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, @@ -785,7 +843,7 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, return ERROR_OUTOFMEMORY; } r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec ); - HeapFree( GetProcessHeap(), 0, szwTable ); + msi_free( szwTable ); return r; } diff --git a/reactos/lib/msi/order.c b/reactos/lib/msi/order.c index 2a03bab63b8..b17be99143d 100644 --- a/reactos/lib/msi/order.c +++ b/reactos/lib/msi/order.c @@ -160,7 +160,7 @@ static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 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; @@ -187,7 +187,7 @@ static UINT ORDER_close( struct tagMSIVIEW *view ) 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 ); @@ -240,11 +240,11 @@ static UINT ORDER_delete( struct tagMSIVIEW *view ) 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; } @@ -317,8 +317,7 @@ UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, 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; diff --git a/reactos/lib/msi/package.c b/reactos/lib/msi/package.c index 6ffd768b9aa..b37ce4de1c6 100644 --- a/reactos/lib/msi/package.c +++ b/reactos/lib/msi/package.c @@ -380,6 +380,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db ) 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; @@ -390,6 +391,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db ) 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 */ @@ -403,6 +406,34 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db ) 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; @@ -410,6 +441,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) 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); @@ -422,7 +454,14 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **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; } @@ -451,7 +490,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) 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; @@ -463,40 +502,19 @@ UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phP { 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); + 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); - - 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; } @@ -519,7 +537,7 @@ UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPa ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage ); - HeapFree( GetProcessHeap(), 0, szwPack ); + msi_free( szwPack ); return ret; } @@ -580,7 +598,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, 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++) @@ -593,8 +611,8 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, 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); @@ -607,7 +625,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, if (msg_field > 1) strcatW(message,space); - HeapFree(GetProcessHeap(),0,tmp); + msi_free(tmp); } TRACE("(%p %lx %lx %s)\n",gUIHandlerA, gUIFilter, log_type, @@ -616,7 +634,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, /* 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 ); @@ -640,9 +658,9 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, CloseHandle(log_file); } } - HeapFree( GetProcessHeap(), 0, msg ); + msi_free( msg ); - HeapFree(GetProcessHeap(),0,message); + msi_free( message); return ERROR_SUCCESS; } @@ -694,8 +712,8 @@ UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue) hr = MsiSetPropertyW( hInstall, szwName, szwValue); end: - HeapFree( GetProcessHeap(), 0, szwName ); - HeapFree( GetProcessHeap(), 0, szwValue ); + msi_free( szwName ); + msi_free( szwValue ); return hr; } @@ -739,19 +757,15 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) 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); + + MSI_ViewClose(view); + msiobj_release(&view->hdr); } - - rc = MSI_ViewExecute(view,row); - msiobj_release(&row->hdr); - MSI_ViewClose(view); - msiobj_release(&view->hdr); return rc; } @@ -789,11 +803,11 @@ static UINT MSI_GetPropertyRow(MSIPACKAGE *package, LPCWSTR szName, MSIRECORD ** 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); @@ -874,7 +888,7 @@ UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName, *pchValueBuf = 0; TRACE("property not found\n"); } - HeapFree( GetProcessHeap(), 0, szwName ); + msi_free( szwName ); return rc; } diff --git a/reactos/lib/msi/preview.c b/reactos/lib/msi/preview.c index 5c596fbc85a..4c7c62b6022 100644 --- a/reactos/lib/msi/preview.c +++ b/reactos/lib/msi/preview.c @@ -145,7 +145,7 @@ UINT WINAPI MsiPreviewDialogA( MSIHANDLE hPreview, LPCSTR szDialogName ) return ERROR_OUTOFMEMORY; } r = MsiPreviewDialogW( hPreview, strW ); - HeapFree( GetProcessHeap(), 0, strW ); + msi_free( strW ); return r; } diff --git a/reactos/lib/msi/record.c b/reactos/lib/msi/record.c index 8bdc3c4cf47..05f80967cc1 100644 --- a/reactos/lib/msi/record.c +++ b/reactos/lib/msi/record.c @@ -55,7 +55,7 @@ static void MSI_FreeField( MSIFIELD *field ) 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 ); @@ -654,7 +654,7 @@ UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR s return ERROR_OUTOFMEMORY; } ret = MsiRecordSetStreamW(hRecord, iField, wstr); - HeapFree(GetProcessHeap(),0,wstr); + msi_free(wstr); return ret; } diff --git a/reactos/lib/msi/registry.c b/reactos/lib/msi/registry.c index c96a766fcfa..b8c206a0d53 100644 --- a/reactos/lib/msi/registry.c +++ b/reactos/lib/msi/registry.c @@ -581,7 +581,7 @@ UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct, 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; } @@ -650,7 +650,7 @@ UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index, szParent, GUID_SIZE, NULL, NULL); } - HeapFree( GetProcessHeap(), 0, szwProduct); + msi_free( szwProduct); return r; } @@ -730,7 +730,7 @@ UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct) szProduct, GUID_SIZE, NULL, NULL); } - HeapFree( GetProcessHeap(), 0, szwComponent); + msi_free( szwComponent); return r; } @@ -780,8 +780,7 @@ UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex, szwComponent = strdupAtoW(szComponent); if (lpQualifierBuf) - lpwQualifierBuf = HeapAlloc(GetProcessHeap(),0, (*pcchQualifierBuf) * - sizeof(WCHAR)); + lpwQualifierBuf = msi_alloc( (*pcchQualifierBuf) * sizeof(WCHAR)); else lpwQualifierBuf = NULL; @@ -791,8 +790,7 @@ UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex, pcchwQualifierBuf = 0; if (lpApplicationDataBuf) - lpwApplicationDataBuf = HeapAlloc(GetProcessHeap(),0 , - (*pcchApplicationDataBuf) * sizeof(WCHAR)); + lpwApplicationDataBuf = msi_alloc( (*pcchApplicationDataBuf) * sizeof(WCHAR)); else lpwApplicationDataBuf = NULL; @@ -831,9 +829,9 @@ UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex, *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; } @@ -868,16 +866,16 @@ UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex, 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); } @@ -907,7 +905,7 @@ UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex, debugstr_w(lpApplicationDataBuf)); } - HeapFree(GetProcessHeap(),0,full_buffer); + msi_free(full_buffer); return rc; } @@ -971,6 +969,6 @@ UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved, WideCharToMultiByte( CP_ACP, 0, productW, GUID_SIZE, lpProductBuf, GUID_SIZE, NULL, NULL ); } - HeapFree(GetProcessHeap(), 0, szwUpgradeCode); + msi_free( szwUpgradeCode); return r; } diff --git a/reactos/lib/msi/select.c b/reactos/lib/msi/select.c index 0ab500f2f15..7345c1777fa 100644 --- a/reactos/lib/msi/select.c +++ b/reactos/lib/msi/select.c @@ -189,8 +189,9 @@ static UINT SELECT_delete( struct tagMSIVIEW *view ) if( sv->table ) sv->table->ops->delete( sv->table ); + sv->table = NULL; - HeapFree( GetProcessHeap(), 0, sv ); + msi_free( sv ); return ERROR_SUCCESS; } @@ -259,8 +260,7 @@ UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, 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; @@ -279,13 +279,10 @@ UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, 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; } diff --git a/reactos/lib/msi/source.c b/reactos/lib/msi/source.c index 136d492fa48..4f67e185f03 100644 --- a/reactos/lib/msi/source.c +++ b/reactos/lib/msi/source.c @@ -129,7 +129,7 @@ static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss) 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) @@ -141,7 +141,7 @@ static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss) else strcpyW(ss->szIndex,szIndex); - HeapFree(GetProcessHeap(),0,val); + msi_free(val); index ++; } } @@ -221,7 +221,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, 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,';'); @@ -240,7 +240,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, else rc = ERROR_SUCCESS; } - HeapFree(GetProcessHeap(),0,buffer); + msi_free(buffer); } } else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0) @@ -254,7 +254,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, 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) @@ -267,7 +267,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, szValue[0] = buffer[0]; rc = ERROR_SUCCESS; } - HeapFree(GetProcessHeap(),0,buffer); + msi_free(buffer); } } else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0) @@ -369,13 +369,13 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, 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) { @@ -444,7 +444,7 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, rc = OpenURLSubkey(sourcekey, &typekey, TRUE); else { - ERR("Unknown media type!\n"); + ERR("unknown media type: %08lx\n", dwOptions); RegCloseKey(sourcekey); return ERROR_FUNCTION_FAILED; } @@ -455,7 +455,7 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, 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 { @@ -467,7 +467,7 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, 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); @@ -547,11 +547,11 @@ UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid, 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); diff --git a/reactos/lib/msi/sql.tab.c b/reactos/lib/msi/sql.tab.c index 39dc0f0e955..f4643950f11 100644 --- a/reactos/lib/msi/sql.tab.c +++ b/reactos/lib/msi/sql.tab.c @@ -1,159 +1,360 @@ -/* 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" @@ -222,10 +423,23 @@ static struct expr * EXPR_sval( void *info, struct sql_str * ); 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; @@ -233,25 +447,146 @@ typedef union 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 + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 465 "sql.tab.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + 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 -#define YYFINAL 127 -#define YYFLAG -32768 -#define YYNTBASE 147 +/* 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 token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 400 ? yytranslate[x] : 177) +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 401 -/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ -static const short yytranslate[] = +#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, @@ -278,373 +613,284 @@ static const short yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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 + 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 -static const short yyprhs[] = +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char 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 + 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, 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 + 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 }; -#endif - -#if YYDEBUG -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const short yyrline[] = +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned 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 + 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) || defined YYERROR_VERBOSE - -/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ +#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[] = { - "$", "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 + "$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 -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const short yyr1[] = +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = { - 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 + 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 short yyr2[] = +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char 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 + 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[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[] = +/* 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, 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 + 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 }; -static const short yydefgoto[] = +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char 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 + -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 }; -static const short yypact[] = +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -111 +static const yysigned_char 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 + -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 }; -static const short yypgoto[] = +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char 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 + -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 }; - -#define YYLAST 124 - - -static const short yytable[] = +/* 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[] = { - 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 + 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[] = { - 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 + 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 }; -#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) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = { - short yyss; - YYSTYPE yyvs; -# if YYLSP_NEEDED - YYLTYPE yyls; -# endif + 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 }; -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAX (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) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - - #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif @@ -663,29 +909,35 @@ union yyalloc #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) @@ -693,41 +945,24 @@ 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 @@ -742,13 +977,93 @@ do { \ 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 @@ -761,15 +1076,17 @@ int yydebug; 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 + -#ifdef YYERROR_VERBOSE + +#if YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) @@ -819,78 +1136,126 @@ yystpcpy (yydest, yysrc) } # endif # endif -#endif + +#endif /* !YYERROR_VERBOSE */ + -#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; + } +} + + +/* 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 -#endif - -/* 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 +int yyparse (); #endif +#endif /* ! YYPARSE_PARAM */ -/* 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 (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL +yyparse (void) +#else +int +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; @@ -898,7 +1263,7 @@ yyparse (YYPARSE_PARAM_ARG) /* 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, @@ -908,7 +1273,7 @@ yyparse (YYPARSE_PARAM_ARG) 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; @@ -918,31 +1283,19 @@ yyparse (YYPARSE_PARAM_ARG) 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 + +#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")); @@ -959,9 +1312,7 @@ yyparse (YYPARSE_PARAM_ARG) yyssp = yyss; yyvsp = yyvs; -#if YYLSP_NEEDED - yylsp = yyls; -#endif + goto yysetstate; /*------------------------------------------------------------. @@ -976,7 +1327,7 @@ yyparse (YYPARSE_PARAM_ARG) 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; @@ -989,24 +1340,17 @@ yyparse (YYPARSE_PARAM_ARG) 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. */ + 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), - &yyls1, yysize * sizeof (*yylsp), + &yystacksize); - yyls = yyls1; -# else - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); -# endif + yyss = yyss1; yyvs = yyvs1; } @@ -1015,10 +1359,10 @@ yyparse (YYPARSE_PARAM_ARG) 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; { @@ -1029,10 +1373,8 @@ yyparse (YYPARSE_PARAM_ARG) 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); } @@ -1041,14 +1383,12 @@ yyparse (YYPARSE_PARAM_ARG) 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; } @@ -1056,7 +1396,6 @@ yyparse (YYPARSE_PARAM_ARG) goto yybackup; - /*-----------. | yybackup. | `-----------*/ @@ -1069,88 +1408,55 @@ 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. */ @@ -1181,49 +1487,28 @@ yyreduce: /* 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; @@ -1232,11 +1517,12 @@ case 7: 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; @@ -1244,11 +1530,12 @@ case 8: 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; @@ -1258,11 +1545,12 @@ case 9: 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; @@ -1272,11 +1560,12 @@ case 10: 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; @@ -1284,11 +1573,12 @@ case 11: 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; @@ -1296,20 +1586,22 @@ case 12: 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 ) @@ -1317,99 +1609,113 @@ case 14: 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; @@ -1419,67 +1725,86 @@ case 29: 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; @@ -1487,239 +1812,254 @@ case 39: 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" 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 @@ -1727,11 +2067,11 @@ case 68: 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; @@ -1744,145 +2084,151 @@ yyerrlab: 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) +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "Error: state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); } -#endif - -/*--------------. -| yyerrhandle. | -`--------------*/ -yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; @@ -1890,9 +2236,7 @@ yyerrhandle: YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif + yystate = yyn; goto yynewstate; @@ -1912,13 +2256,15 @@ yyabortlab: 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 @@ -1927,7 +2273,9 @@ yyreturn: #endif return yyresult; } -#line 604 "./sql.y" + + +#line 615 "./sql.y" static void *parser_alloc( void *info, unsigned int sz ) @@ -1935,7 +2283,7 @@ 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]; } @@ -1968,7 +2316,7 @@ int SQL_lex( void *SQL_lval, SQL_input *sql ) 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; @@ -1977,7 +2325,7 @@ int SQL_lex( void *SQL_lval, SQL_input *sql ) } 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; } @@ -2127,11 +2475,10 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, 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; } + diff --git a/reactos/lib/msi/sql.tab.h b/reactos/lib/msi/sql.tab.h index f49301be8b1..4726cbd15e3 100644 --- a/reactos/lib/msi/sql.tab.h +++ b/reactos/lib/msi/sql.tab.h @@ -1,9 +1,329 @@ -#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; @@ -11,153 +331,15 @@ typedef union 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 */ + + + diff --git a/reactos/lib/msi/sql.y b/reactos/lib/msi/sql.y index a311d6aa886..6669441c2b4 100644 --- a/reactos/lib/msi/sql.y +++ b/reactos/lib/msi/sql.y @@ -1,810 +1,819 @@ -%{ - -/* - * 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 -#include -#include - -#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 TK_ID -%token TK_INSERT TK_INSTEAD TK_INT -%token 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 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 table id -%type selcollist column column_and_type column_def table_def -%type column_assignment update_assign_list constlist -%type query from fromtable selectfrom unorderedsel -%type oneupdate onedelete oneselect onequery onecreate oneinsert -%type expr val column_val const_val -%type column_type data_type data_type_l data_count -%type 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; - } - ; - -column_type: - data_type_l - { - $$ = $1 | MSITYPE_VALID; - } - | data_type_l TK_LOCALIZABLE - { - FIXME("LOCALIZABLE ignored\n"); - $$ = $1 | MSITYPE_VALID; - } - ; - -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 - { - $$ = 0; - } - ; - -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; - - $$ = NULL; - DISTINCT_CreateView( sql->db, &$$, $3 ); - if( !$$ ) - YYABORT; - } - ; - -selectfrom: - selcollist from - { - SQL_input* sql = (SQL_input*) info; - - $$ = NULL; - if( $1 ) - SELECT_CreateView( sql->db, &$$, $2, $1 ); - else - $$ = $2; - - if( !$$ ) - YYABORT; - } - ; - -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 || !$$ ) - 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 = HeapAlloc( GetProcessHeap(), 0, 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; ilen; 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 ) - { - if( *sql.view ) - (*sql.view)->ops->delete( *sql.view ); - *sql.view = NULL; - return ERROR_BAD_QUERY_SYNTAX; - } - - return ERROR_SUCCESS; -} +%{ + +/* + * 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 +#include +#include + +#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 TK_ID +%token TK_INSERT TK_INSTEAD TK_INT +%token 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 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 table id +%type selcollist column column_and_type column_def table_def +%type column_assignment update_assign_list constlist +%type query from fromtable selectfrom unorderedsel +%type oneupdate onedelete oneselect onequery onecreate oneinsert +%type expr val column_val const_val +%type column_type data_type data_type_l data_count +%type 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; ilen; 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; +} diff --git a/reactos/lib/msi/string.c b/reactos/lib/msi/string.c index 62a73310e07..815d808188c 100644 --- a/reactos/lib/msi/string.c +++ b/reactos/lib/msi/string.c @@ -72,18 +72,17 @@ string_table *msi_init_stringtable( int entries, UINT codepage ) { 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( !st ) - { - HeapFree( GetProcessHeap(), 0, st ); - return NULL; - } if( entries < 1 ) entries = 1; + st->strings = msi_alloc_zero( sizeof (msistring) * entries ); + if( !st ) + { + msi_free( st ); + return NULL; + } st->maxcount = entries; st->freeslot = 1; st->codepage = codepage; @@ -98,10 +97,10 @@ VOID msi_destroy_stringtable( string_table *st ) for( i=0; imaxcount; 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 ) @@ -123,8 +122,7 @@ 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; @@ -177,7 +175,7 @@ int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT ref 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 ); @@ -226,7 +224,7 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT r 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__); @@ -387,13 +385,13 @@ UINT msi_string2idA( string_table *st, LPCSTR buffer, UINT *id ) 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; } diff --git a/reactos/lib/msi/suminfo.c b/reactos/lib/msi/suminfo.c index f7692a4c828..323da5c9e77 100644 --- a/reactos/lib/msi/suminfo.c +++ b/reactos/lib/msi/suminfo.c @@ -83,22 +83,6 @@ typedef struct { #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; @@ -113,7 +97,7 @@ static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y', 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; } @@ -225,7 +209,7 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz 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; @@ -291,7 +275,7 @@ static UINT load_summary_info( MSISUMMARYINFO *si, IStream *stm ) return ret; } - data = HeapAlloc( GetProcessHeap(), 0, section_hdr.cbSection); + data = msi_alloc( section_hdr.cbSection); if( !data ) return ret; @@ -305,7 +289,7 @@ static UINT load_summary_info( MSISUMMARYINFO *si, IStream *stm ) else ERR("failed to read properties %ld %ld\n", count, sz); - HeapFree( GetProcessHeap(), 0, data ); + msi_free( data ); return ret; } @@ -412,7 +396,7 @@ static UINT save_summary_info( MSISUMMARYINFO * si, IStream *stm ) 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 ); @@ -426,7 +410,7 @@ static UINT save_summary_info( MSISUMMARYINFO * si, IStream *stm ) 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; @@ -519,7 +503,7 @@ UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, pHandle); - HeapFree( GetProcessHeap(), 0, szwDatabase ); + msi_free( szwDatabase ); return ret; } @@ -546,6 +530,7 @@ static UINT get_prop( MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, { MSISUMMARYINFO *si; PROPVARIANT *prop; + UINT ret = ERROR_SUCCESS; TRACE("%ld %d %p %p %p %p %p\n", handle, uiProperty, puiDataType, piValue, pftValue, str, pcchValueBuf); @@ -578,6 +563,7 @@ static UINT get_prop( MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, { len = MultiByteToWideChar( CP_ACP, 0, prop->u.pszVal, -1, str->str.w, *pcchValueBuf ); + len--; } else { @@ -585,6 +571,8 @@ static UINT get_prop( MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, if( str->str.a ) lstrcpynA(str->str.a, prop->u.pszVal, *pcchValueBuf ); } + if (len >= *pcchValueBuf) + ret = ERROR_MORE_DATA; *pcchValueBuf = len; } break; @@ -599,7 +587,7 @@ static UINT get_prop( MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, break; } msiobj_release( &si->hdr ); - return ERROR_SUCCESS; + return ret; } UINT WINAPI MsiSummaryInfoGetPropertyA( @@ -690,14 +678,14 @@ static UINT set_prop( MSIHANDLE handle, UINT uiProperty, UINT uiDataType, { 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; diff --git a/reactos/lib/msi/table.c b/reactos/lib/msi/table.c index 89c2611fe51..b3b110ae989 100644 --- a/reactos/lib/msi/table.c +++ b/reactos/lib/msi/table.c @@ -1,7 +1,7 @@ /* * 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 @@ -41,9 +41,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); typedef struct tagMSICOLUMNINFO { - LPWSTR tablename; + LPCWSTR tablename; UINT number; - LPWSTR colname; + LPCWSTR colname; UINT type; UINT offset; } MSICOLUMNINFO; @@ -51,10 +51,8 @@ typedef struct tagMSICOLUMNINFO struct tagMSITABLE { USHORT **data; - UINT ref_count; UINT row_count; - struct tagMSITABLE *next; - struct tagMSITABLE *prev; + struct list entry; WCHAR name[1]; }; @@ -64,8 +62,9 @@ static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, 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; @@ -97,7 +96,7 @@ static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) if( !bTable ) count = lstrlenW( in )+2; - out = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) ); + out = msi_alloc( count*sizeof(WCHAR) ); p = out; if( bTable ) @@ -131,7 +130,7 @@ static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) *p++ = ch; } ERR("Failed to encode stream name (%s)\n",debugstr_w(in)); - HeapFree( GetProcessHeap(), 0, out ); + msi_free( out ); return NULL; } @@ -219,7 +218,7 @@ static UINT read_stream_data( IStorage *stg, LPCWSTR stname, 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); @@ -240,7 +239,7 @@ static UINT read_stream_data( IStorage *stg, LPCWSTR stname, } sz = stat.cbSize.QuadPart; - data = HeapAlloc( GetProcessHeap(), 0, sz ); + data = msi_alloc( sz ); if( !data ) { WARN("couldn't allocate memory r=%08lx!\n",r); @@ -251,7 +250,7 @@ static UINT read_stream_data( IStorage *stg, LPCWSTR stname, 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; } @@ -277,7 +276,7 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) 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); @@ -314,7 +313,7 @@ UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, } sz = stat.cbSize.QuadPart; - data = HeapAlloc( GetProcessHeap(), 0, sz ); + data = msi_alloc( sz ); if( !data ) { WARN("couldn't allocate memory r=%08lx!\n",r); @@ -325,7 +324,7 @@ UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, 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; } @@ -359,7 +358,7 @@ static UINT write_stream_data( IStorage *stg, LPCWSTR stname, 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); @@ -397,62 +396,70 @@ end: 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; irow_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; irow_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; jnext = 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 */ @@ -568,14 +528,14 @@ static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO 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; } @@ -585,36 +545,28 @@ static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO 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; - } + table = find_cached_table( db, name ); + if( table ) + return table; - r = read_table_from_storage( db, name, ptable ); - if( r != ERROR_SUCCESS ) - return r; + table = read_table_from_storage( db->storage, name, cols, num_cols ); + if( table ) + list_add_head( &db->tables, &table->entry ); - /* add the table to the list */ - add_table( db, *ptable ); - (*ptable)->ref_count++; - - 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 ) ); @@ -622,13 +574,15 @@ static UINT save_table( MSIDATABASE *db, MSITABLE *t ) 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; istorage, t->name, rawdata, rawsize ); - HeapFree( GetProcessHeap(), 0, rawdata ); +err: + msi_free_colinfo( cols, num_cols ); + msi_free( cols ); + msi_free( rawdata ); return r; } @@ -668,7 +625,7 @@ HRESULT init_string_table( IStorage *stg ) /* 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"); @@ -688,7 +645,7 @@ HRESULT init_string_table( IStorage *stg ) 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"); @@ -699,27 +656,22 @@ HRESULT init_string_table( IStorage *stg ) 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; @@ -728,7 +680,7 @@ UINT load_string_table( MSIDATABASE *db ) 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; @@ -753,7 +705,7 @@ UINT load_string_table( MSIDATABASE *db ) /* 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++; @@ -767,13 +719,11 @@ UINT load_string_table( MSIDATABASE *db ) 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 ) @@ -793,13 +743,13 @@ 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 ); @@ -821,7 +771,7 @@ static UINT save_string_table( MSIDATABASE *db ) } 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; @@ -851,8 +801,8 @@ static UINT save_string_table( MSIDATABASE *db ) ret = ERROR_SUCCESS; err: - HeapFree( GetProcessHeap(), 0, data ); - HeapFree( GetProcessHeap(), 0, pool ); + msi_free( data ); + msi_free( pool ); return ret; } @@ -866,53 +816,63 @@ static const WCHAR szColumn[] = { 'C','o','l','u','m','n',0 }; 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= *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; istrings, 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; } @@ -936,25 +896,23 @@ static UINT get_tablecolumns( MSIDATABASE *db, { 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; } @@ -972,7 +930,7 @@ static UINT get_tablecolumns( MSIDATABASE *db, 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 @@ -996,16 +954,12 @@ static UINT get_tablecolumns( MSIDATABASE *db, } *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; @@ -1021,8 +975,8 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ) 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; @@ -1034,8 +988,6 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ) if( table->data[ i ][ 0 ] == table_id ) break; - release_table( db, table ); - if (i!=count) return TRUE; @@ -1141,7 +1093,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt 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 ); @@ -1149,8 +1101,8 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt 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; } @@ -1203,18 +1155,18 @@ static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num ) 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; } @@ -1229,19 +1181,13 @@ static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num ) 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; } @@ -1255,7 +1201,6 @@ static UINT TABLE_close( struct tagMSIVIEW *view ) if( !tv->table ) return ERROR_FUNCTION_FAILED; - release_table( tv->db, tv->table ); tv->table = NULL; return ERROR_SUCCESS; @@ -1470,23 +1415,16 @@ static UINT TABLE_delete( struct tagMSIVIEW *view ) TRACE("%p\n", view ); - if( tv->table ) - release_table( tv->db, tv->table ); tv->table = NULL; if( tv->columns ) { - UINT i; - for( i=0; inum_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; } @@ -1510,7 +1448,7 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ) { MSITABLEVIEW *tv ; UINT r, sz, column_count; - MSICOLUMNINFO *columns, *last_col; + MSICOLUMNINFO *columns; TRACE("%p %s %p\n", db, debugstr_w(name), view ); @@ -1527,38 +1465,36 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **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 ); @@ -1580,7 +1516,7 @@ UINT MSI_CommitTables( MSIDATABASE *db ) 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 ) diff --git a/reactos/lib/msi/update.c b/reactos/lib/msi/update.c index 0af29e07b17..6a5791297a0 100644 --- a/reactos/lib/msi/update.c +++ b/reactos/lib/msi/update.c @@ -172,7 +172,7 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view ) if( wv ) wv->ops->delete( wv ); msiobj_release( &uv->db->hdr ); - HeapFree( GetProcessHeap(), 0, uv ); + msi_free( uv ); return ERROR_SUCCESS; } @@ -209,8 +209,7 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, r = WHERE_CreateView( db, &wv, tv, expr ); if( r != ERROR_SUCCESS ) { - if( sv ) - sv->ops->delete( tv ); + tv->ops->delete( tv ); return r; } @@ -218,12 +217,11 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, 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; diff --git a/reactos/lib/msi/upgrade.c b/reactos/lib/msi/upgrade.c index e96a8e4aadc..3851abb2a4c 100644 --- a/reactos/lib/msi/upgrade.c +++ b/reactos/lib/msi/upgrade.c @@ -68,7 +68,7 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, 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 @@ -82,7 +82,7 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, /*null*/ len++; - newprop = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR)); + newprop = msi_alloc( len*sizeof(WCHAR) ); if (prop) { @@ -96,8 +96,8 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, 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) diff --git a/reactos/lib/msi/version.rc b/reactos/lib/msi/version.rc index 85179ce15e2..d5164a4e08a 100644 --- a/reactos/lib/msi/version.rc +++ b/reactos/lib/msi/version.rc @@ -1,26 +1,26 @@ -/* - * 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" +/* + * 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" diff --git a/reactos/lib/msi/where.c b/reactos/lib/msi/where.c index 9bad7b54c8d..cf54e4a05af 100644 --- a/reactos/lib/msi/where.c +++ b/reactos/lib/msi/where.c @@ -242,7 +242,8 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 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; @@ -269,7 +270,7 @@ static UINT WHERE_close( struct tagMSIVIEW *view ) 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 ); @@ -328,13 +329,14 @@ static UINT WHERE_delete( struct tagMSIVIEW *view ) 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; } @@ -444,7 +446,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, 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 ) @@ -462,7 +464,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, return ERROR_FUNCTION_FAILED; } - wv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *wv ); + wv = msi_alloc_zero( sizeof *wv ); if( !wv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/w32api/include/msiquery.h b/reactos/w32api/include/msiquery.h index 14c6c249e28..ab70681cb69 100644 --- a/reactos/w32api/include/msiquery.h +++ b/reactos/w32api/include/msiquery.h @@ -252,6 +252,10 @@ UINT WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE, LPSTR); 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*);