Inno Setup Windows DLL function call with pointer to structure -
i trying set service's failure actions using inno setup's pascal scripting language. receive classic "access violation @ address..." error. seems impossible because language don't have support pointers. ideas? here code snippet:
type tscaction = record atype1 : longword; delay1 : longword; atype2 : longword; delay2 : longword; atype3 : longword; delay3 : longword; end; type tservicefailureactionsa = record dwresetperiod : dword; prebootmsg : string; pcommand : string; cactions : dword; saactions : tscaction; end; function changeserviceconfig2(hservice: longword; dwinfolevel: longword; lpinfo: tservicefailureactionsa): bool; external 'changeserviceconfig2a@advapi32.dll stdcall'; procedure simplechangeserviceconfig(aservice: string); var scmhandle: longword; servicehandle: longword; sfactions: tservicefailureactionsa; sactions: tscaction; begin try scmhandle := openscmanager('', '', sc_manager_all_access); if scmhandle = 0 raiseexception('simplechangeserviceconfig@openscmanager: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); try servicehandle := openservice(scmhandle, aservice, service_all_access); if servicehandle = 0 raiseexception('simplechangeserviceconfig@openservice: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); try sactions.atype1 := sc_action_restart; sactions.delay1 := 60000; // first.ndelay: in milliseconds, mmc displayed in minutes sactions.atype2 := sc_action_restart; sactions.delay2 := 60000; sactions.atype3 := sc_action_restart; sactions.delay3 := 60000; sfactions.dwresetperiod := 1; // in seconds, mmc displayes in days //sfactions.prebootmsg := null; // reboot message unchanged //sfactions.pcommand := null; // command line unchanged sfactions.cactions := 3; // first, second , subsequent failures sfactions.saactions := sactions; if not changeserviceconfig2( servicehandle, // handle service service_config_failure_actions, // change: description sfactions) // new description raiseexception('simplechangeserviceconfig@changeserviceconfig2: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); if servicehandle <> 0 closeservicehandle(servicehandle); end; if scmhandle <> 0 closeservicehandle(scmhandle); end; except showexceptionmessage; end; end;
you have 2 problems in script. deanna suggested have use var
keyword in declaration of lpinfo
parameter.
also need change tscaction
type array 2 elements.
here script can include in inno setup script.
const service_config_delayed_auto_start_info = 3; //the lpinfo parameter pointer service_delayed_auto_start_info structure. //windows server 2003 , windows xp: value not supported. service_config_description = 1; //the lpinfo parameter pointer service_description structure. service_config_failure_actions = 2; //the lpinfo parameter pointer service_failure_actions structure. //if service controller handles sc_action_reboot action, caller must have // se_shutdown_name privilege. more information, see running special privileges. service_config_failure_actions_flag = 4; //the lpinfo parameter pointer service_failure_actions_flag structure. //windows server 2003 , windows xp: value not supported. service_config_preferred_node = 9; //the lpinfo parameter pointer service_preferred_node_info structure. //windows server 2008, windows vista, windows server 2003, , windows xp: value not supported. service_config_preshutdown_info = 7; //the lpinfo parameter pointer service_preshutdown_info structure. //windows server 2003 , windows xp: value not supported. service_config_required_privileges_info = 6; //the lpinfo parameter pointer service_required_privileges_info structure. //windows server 2003 , windows xp: value not supported. service_config_service_sid_info = 5; //the lpinfo parameter pointer service_sid_info structure. service_config_trigger_info = 8; //the lpinfo parameter pointer service_trigger_info structure. //this value not supported ansi version of changeserviceconfig2. //windows server 2008, windows vista, windows server 2003, , windows xp: value not supported until windows server 2008 r2. sc_action_none = 0; // no action. sc_action_reboot = 2; // reboot computer. sc_action_restart = 1; // restart service. sc_action_run_command = 3; // run command. type tscaction = record atype1 : longword; delay1 : longword; end; type tservicefailureactionsa = record dwresetperiod : dword; prebootmsg : string; pcommand : string; cactions : dword; saactions : array of tscaction; end; function changeserviceconfig2( hservice: longword; dwinfolevel: longword; var lpinfo: tservicefailureactionsa): bool; external 'changeserviceconfig2a@advapi32.dll stdcall'; procedure simplechangeserviceconfig(aservice: string); var scmhandle: longword; servicehandle: longword; sfactions: tservicefailureactionsa; sactions: array of tscaction; begin setarraylength(sactions ,3); try scmhandle := openscmanager('', '', sc_manager_all_access); if scmhandle = 0 raiseexception('simplechangeserviceconfig@openscmanager: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); try servicehandle := openservice(scmhandle, aservice, service_all_access); if servicehandle = 0 raiseexception('simplechangeserviceconfig@openservice: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); try sactions[0].atype1 := sc_action_restart; sactions[0].delay1 := 60000; // first.ndelay: in milliseconds, mmc displayed in minutes sactions[1].atype1 := sc_action_restart; sactions[1].delay1 := 60000; sactions[2].atype1 := sc_action_none; sactions[2].delay1 := 60000; sfactions.dwresetperiod := 1; // in seconds, mmc displayes in days //sfactions.prebootmsg := null; // reboot message unchanged //sfactions.pcommand := null; // command line unchanged sfactions.cactions := 3; // first, second , subsequent failures sfactions.saactions := sactions; if not changeserviceconfig2( servicehandle, // handle service service_config_failure_actions, // change: description sfactions) // new description raiseexception('simplechangeserviceconfig@changeserviceconfig2: ' + aservice + ' ' + syserrormessage(dllgetlasterror)); if servicehandle <> 0 closeservicehandle(servicehandle); end; if scmhandle <> 0 closeservicehandle(scmhandle); end; except showexceptionmessage; end; end;
Comments
Post a Comment