|
API et services : HELP |
|
Stagiaire WDF
Inscrit: 12/01/2004 16:31
Post(s): 3
|
J'ai un truc bizarre avec l'API QueryServiceConfigA de ADVAPI32.DLL. D'après le site de microsoft, il faut faire un 1er appel pour avoir une erreur permettant d'obtenir la taille nécessaire du buffer de sortie, puis un 2ème appel pour remplir ce buffer. Mon 1er appel fonctionne mais j'ai systèmatiquement une erreur fatale lors du 2ème appel (cf code ci-dessous. QUERY_SERVICE_CONFIGA est une structure qui contiendra la config demandée) :
PROCEDURE ServiceQuery( ServiceName_ est une chaîne, vlc_Demarrage = "", vle_Demarrage = 0 ) PRIVÉ vlc_ServiceName est une chaîne = ServiceName_ ServiceConfig est un QUERY_SERVICE_CONFIGA vle_ServiceStatus est un entier vle_OK est un entier TailleBuffer est un entier = Null TailleBufferNécessaire est un entier = 0 Resultat est un entier
vlc_Demarrage = "Pas de service ou erreur"
// On ouvre le service vle_OK = :ServiceOpen( vlc_ServiceName )
// Ouverture OK SI vle_OK = 0 ALORS
// On lance une 1ère fois pour récupérer la taille du buffer Resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, &ServiceConfig, TailleBuffer, &TailleBufferNécessaire )
// On renseigne la taille pour le prochain appel TailleBuffer = TailleBufferNécessaire TailleBufferNécessaire = 0
// On récupère les informations de configuration Resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, &ServiceConfig, TailleBuffer, &TailleBufferNécessaire )
-------------------------- ------ Ca plante ci-dessus --------------------------
Contribution le : 08/06/2004 10:57
|
|
|
Re: API et services : HELP |
|
Inscrit: 19/11/2002 12:20
Post(s): 390
|
Il faudrait que tu récupères le: GetLastError() (ou bien ErreurInfo avec la constante tous les messages) pour voir si c'est un problème de typage ou autre chose...
Vu qu'il y a une structure, c'est assez délicat... Pourrais tu faire le Erreurinfo et également poster la tête de ta structure?
Contribution le : 09/06/2004 00:39
|
|
|
Re: API et services : HELP |
|
Anonyme
|
Je ne peux pas récupérer l'erreur puisqu'il y a erreur fatale au moment de l'exécution du 2ème appel de l'API.
Pour la structure, cf ci-dessous :
QUERY_SERVICE_CONFIGA est une structure dwServiceType est un entier dwStartType est un entier dwErrorControl est un entier lpBinaryPathName est une chaîne lpLoadOrderGroup est une chaîne dwTagId est un entier lpDependencies est une chaîne lpServiceStartName est une chaîne lpDisplayName est une chaîne; FIN
Un instant j'ai eu un espoir car je ne sais pas ce que vient faire le ; après le mot chaîne. Je l'ai enlevé mais j'ai toujours la même erreur. Je suis presque certain que c'est un problème de type de variable ou qq chose comme ça... mais quoi ?
Contribution le : 09/06/2004 09:18
|
|
|
Re: API et services : HELP |
|
Animateur WDF
Inscrit: 26/06/2002 16:24
De wdforge.org
Post(s): 2822
|
Dans les structures avec échange API, il me semble qu'il faille utiliser des chaines fixes sur 25<4,5>...
En effet les chaine WinDev sont la longueur variable... et présente alors des erreur d'adressage
Contribution le : 09/06/2004 17:42
|
|
|
QUERY_SERVICE_CONFIG |
|
Anonyme
|
L'aide de windev préconise d'utiliser des variables de type chaîne. De plus, la seule données dont je connais la taille maxi (256) est ldDisplayName. Les autres chaînes sont de taille variable.
J'ai trouvé de la doc sur internet mais avec des exemples en C que j'ai du mal à transcrire en Windev.
J'ai du mal à croire que personne n'a jamais cherché à récupérer les infos d'un service dans un programme Windev !
Contribution le : 10/06/2004 16:08
|
|
|
Re: QUERY_SERVICE_CONFIG |
|
Stagiaire WDF
Inscrit: 01/06/2004 17:15
Post(s): 21
|
Non... pourquoi faire ?
Contribution le : 10/06/2004 16:44
|
|
|
Re: QUERY_SERVICE_CONFIG |
|
Anonyme
|
Pour quoi faire ?
He bien quand un crée un service via une application Windev, il est intéressant de visualiser les caractéristiques de ce service... et pour ça, il faut utiliser la fonction QUERY_SERVICE_CONFIGA de l'API !
Contribution le : 11/06/2004 08:10
|
|
|
Re: QUERY_SERVICE_CONFIG LA SOLUTION |
|
Anonyme
|
Réponse ci-dessou :
> QUERY_SERVICE_CONFIGA est une structure > dwServiceType est un entier > dwStartType est un entier > dwErrorControl est un entier > lpBinaryPathName est un entier > lpLoadOrderGroup est un entier > dwTagId est un entier > lpDependencies est un entier > lpServiceStartName est un entier > lpDisplayName est un entier > FIN > > resultat est un entier > TailleBufferNecessaire est un entier > TailleBuffer est un entier > QueryConfigService est une QUERY_SERVICE_CONFIGA > > // Ouverture du service manager > vle_OK=:ServiceOpen(vlc_NomService,vlc_ComputerName) > SI vle_OK=0 ALORS > // On lance une 1ère fois pour récupérer la taille du buffer > resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, 0, 0, &TailleBufferNecessaire ) > > // On renseigne la taille pour le prochain appel > TailleBuffer = TailleBufferNecessaire > TailleBufferNecessaire = 0 > > // On recupere les informations de configuration dans un tableau d'octets > tTab est un tableau de TailleBuffer entiers sur 1 octet sans signe > > resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, &tTab, TailleBuffer, &TailleBufferNecessaire ) > > // on transfert ce tableau d'octets dans la structure de pointeurs > Transfert(&QueryConfigService,&tTab,Dimension(QueryConfigService)) > > // ici par excemple, on veut récupérer le nom affiché du service > szDisplayName est une chaine ASCIIZ sur 4096 > > // L'adresse de chaine sera le pointeur récupéré > Transfert(&szDisplayName,QueryConfigService:lpDisplayName,Dimension(szDisplayName)) > > FIN > // on ferme > :ServiceClose() >
Contribution le : 16/06/2004 08:03
|
|
|
Re: QUERY_SERVICE_CONFIG LA SOLUTION |
|
Stagiaire WDF
Inscrit: 10/04/2003 14:20
Post(s): 10
|
jai fait ya quelques temps un prog qui liste tous les services (et peripheriques) en WD5.5 et ressort la config du service faut surtout faire un OpenSCManagerA avant toute action sur les services voila le code brut de ma procedure pListe qui affiche la config et statut d'un service (code WD5.5) Citation : DisplayName est chaine asciiz sur 256 ServiceName est chaine asciiz sur 256 PathName est chaine asciiz sur 256 LoadGroup est chaine asciiz sur 256 UserName est chaine asciiz sur 256 cint=0 NumSC=appeldll32("advapi32","OpenSCManagerA",null,null,SC_MANAGER_ALL_ACCESS) Si NumSC>0 alors ServiceName=sname config est un QUERY_SERVICE_CONFIG dConfig est entier long sans signe=dimension(config) hMem,cdBuf,pbNeeded sont entier long sans signe hSvc=appeldll32("advapi32","OpenServiceA",NumSC,&ServiceName,SERVICE_ALL_ACCESS) si hsvc > 0 alors Status est SERVICE_STATUS si appeldll32("advapi32","QueryServiceStatus",hSvc,&Status) alors wtype est entier long sans signe=status:ServiceType si wtype>SERVICE_INTERACTIVE_PROCESS alors wtype-=SERVICE_INTERACTIVE_PROCESS cint=1 FIN Listesupprimetout("START") selon wType cas SERVICE_KERNEL_DRIVER Listeajoute("START",gStartDriver) Type=1 cas SERVICE_FILE_SYSTEM_DRIVER Listeajoute("START",gStartDriver) Type=2 cas SERVICE_WIN32_OWN_PROCESS Listeajoute("START",gStartService) cint..etat=actif busername..etat=actif Type=3 cas SERVICE_WIN32_SHARE_PROCESS Listeajoute("START",gStartService) cint..etat=actif Type=4 fin etat=status:CurrentState+1 controle=status:ControlsAccepted+1 scode..etat=grise selon status:Win32ExitCode cas 0 ecode=1 cas 1066 ecode=2 scode..etat=inactif cas 1077 ecode=3 autre cas ecode=4 fin scode=status:ServiceSpecificExitCode check=status:CheckPoint whint=status:WaitHint fin appeldll32("advapi32","QueryServiceConfigA",hSvc,null,null,&pbNeeded) hMem = AppelDLL32("kernel32", "GlobalAlloc", 0x40, pbNeeded) si hMem>0 alors cdBuf=pbNeeded si appeldll32("advapi32","QueryServiceConfigA",hSvC,hmem,cdBuf,&pbNeeded) alors AppelDLL32("kernel32", "RtlMoveMemory", &config, hMem, dConfig) wLg est entier long sans signe wLg=cdBuf-(config:pPathName-hmem) si wLg>256 alors wLg=256 AppelDLL32("kernel32", "RtlMoveMemory", &PathName, config:pPathName, wLg) bpath=PathName wLg=cdBuf-(config:pDisplayName-hmem) si wLg>256 alors wLg=256 AppelDLL32("kernel32", "RtlMoveMemory", &DisplayName, config:pDisplayName, wLg) dname=DisplayName wLg=cdBuf-(config:pGroup-hmem) si wLg>256 alors wLg=256 AppelDLL32("kernel32", "RtlMoveMemory", &LoadGroup, config:pGroup, wLg) lgroup=listecherche("LGROUP",LoadGroup) wLg=cdBuf-(config:pServiceStart-hmem) si wLg>256 alors wLg=256 AppelDLL32("kernel32", "RtlMoveMemory", &UserName, config:pServiceStart, wLg) busername=UserName wLg=config:pServiceStart-config:pDepend si wLg>256 alors wLg=256 TDepend est chaine fixe sur 32000 AppelDLL32("kernel32", "RtlMoveMemory", &TDepend, config:pDepend, wLg) wDepend est chaine Listesupprimetout("LDEPEND") boucle wDepend=TDepend[[1 a (position(TDepend,caract(0x0))-1)]] si wDepend<>"" alors ListeAjoute("LDEPEND",wDepend) FIN TDepend=TDepend[[(position(TDepend,caract(0x0))+1) a 32000]] si TDepend[[1]]=caract(0x0) alors sortir FIN tagid=config:TagID si Type>=3 alors // Services start=config:StartType-1 sinon start=config:StartType+1 fin errctrl=config:ErrorControl+1 demarre..etat=grisé arrete..etat=grisé si config:StartType<>4 alors // SERVICE_DISABLED selon etat cas 2 // Arrêté demarre..etat=actif cas 5 // Démarré arrete..etat=actif fin fin appeldll32("advapi32","CloseServiceHandle",hSvc) appeldll32("advapi32","CloseServiceHandle",NumSC) EnumDepend(sname) retour FIN AppelDLL32("kernel32", "GlobalFree", hMem) sinon erreur("Impossible d'allouer la mémoire...") fin appeldll32("advapi32","CloseServiceHandle",hSvc) sinon erreur("Impossible d'ouvrir le service...") FIN appeldll32("advapi32","CloseServiceHandle",NumSC) sinon Erreur("Impossible d'ouvrir le Service Control Manager") fin
Contribution le : 18/06/2004 19:00
|
|
|
Re: QUERY_SERVICE_CONFIG LA SOLUTION |
|
Anonyme
|
Merci à tous.
En fait, j'ai trouvé la solution sur un autre forum et ci-dessous le code. Je n'avais besoin que du type de démarrage mais la structure est chargée avec toute la config. Il est possible de remplacer le tranfert de blocs mémoire par la fonction Windev ChaîneRécupère : --------------- PROCEDURE ServiceQuery( ServiceName_ est une chaîne, vlc_Demarrage = 0, vle_Demarrage = 0 ) PRIVÉ vlc_ServiceName est une chaîne = ServiceName_ QueryConfigService est QUERY_SERVICE_CONFIGA TailleBuffer est un entier = Null TailleBufferNécessaire est un entier = 0 Resultat est un entier TableauAdresses est un tableau de 1 entiers sur 1 octet sans signe
// On ouvre le service Resultat = :ServiceOpen( vlc_ServiceName )
// Ouverture OK SI Resultat = 0 ALORS // On lance l'API une 1ère fois pour récupérer la taille du buffer // Ca sert à rien de tester le code résultat puisque l'API sera en erreur à cause de la // dimension du buffer Resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, 0, 0, &TailleBufferNécessaire )
// On renseigne la taille pour le prochain appel TailleBuffer = TailleBufferNécessaire TailleBufferNécessaire = 0 // On dimensionne la tableau en fonction de la taille du buffer Dimension( TableauAdresses, TailleBuffer ) // On recupere les informations de configuration dans le tableau d'octets Resultat = API( "ADVAPI32.DLL", "QueryServiceConfigA", :vle_Service, &TableauAdresses, TailleBuffer,... &TailleBufferNécessaire ) // Il y a eu un problème avec l'API SI Resultat = 0 ALORS // On stocke l'erreur Resultat = API("KERNEL32","GetLastError")
SINON
// Pas d'erreur Resultat = 0 // on transfert le tableau d'octets dans la structure de pointeurs TRANSFERT( &QueryConfigService, &TableauAdresses, Dimension(QueryConfigService) ) // Selon le type de démarrage, on renseigne la valeur que doit prendre la combo SELON QueryConfigService:dwStartType CAS ::SERVICE_AUTO_START : // Automatique // On stocke la valeur que doit prendre la combo vlc_Demarrage = 1 CAS ::SERVICE_DEMAND_START : // Manuel // On stocke la valeur que doit prendre la combo vlc_Demarrage = 2
CAS ::SERVICE_DISABLED : // Désactivé // On stocke la valeur que doit prendre la combo vlc_Demarrage = 3 FIN // On stocke la valeur du type de démarrage vle_Demarrage = QueryConfigService:dwStartType FIN FIN
// Problème avec un des appels d'API SI Resultat <> 0 ALORS vlc_Demarrage = :Service_Erreur_Info(Resultat) // :ServiceClose() FIN
// Fermeture du canal vers le gestionnaire de service et vers le service :ServiceClose()
RENVOYER Resultat ------------------
Contribution le : 22/06/2004 13:44
|
|
Vous ne pouvez pas débuter de nouveaux sujets.
Vous pouvez voir les sujets.
Vous ne pouvez pas répondre aux contributions.
Vous ne pouvez pas éditer vos contributions.
Vous ne pouvez pas effacez vos contributions.
Vous ne pouvez pas ajouter de nouveaux sondages.
Vous ne pouvez pas voter en sondage.
Vous ne pouvez pas attacher des fichiers à vos contributions.
Vous ne pouvez pas poster sans approbation.
|
Connexion
Menu
Chercher WDForge
Chercher Web
Partenaires
|