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

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -