OVH Cloud OVH Cloud

QUERY_SERVICE_CONFIG : Comment récupérer les propriétés d'un service

7 réponses
Avatar
aprosper_fr
Depuis 2 semaines, je cherche désespérement de l'aide pour faire
tourner la fonction QUERY_SERVICE_CONFIGA de l'API ADVAPI32.DLL.

Mon programme plante systématiquement lors du 2ème appel de l'API. JE
suis presque certain qu'il s'agit d'un problème au niveau du format
des données dans la structure. J'ai consulté de très nombreux sites
sur le sujet, dont celui de microsoft, sans parvenir à trouver l'aide
adéquate. PLEASE HELP ME !

Ci-dessous, le code :
----------------
Déclaration globale de la strcuture :
----------------
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
----------------
----------------
code de la procédure
----------------
PROCEDURE ServiceQuery( ServiceName_ est une chaîne, vlc_Demarrage =
"", vle_Demarrage = 0 )
PRIVÉ
vlc_ServiceName est une chaîne = ServiceName_
QueryConfigService est QUERY_SERVICE_CONFIGA
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,
0, 0, &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,
&QueryConfigService, TailleBuffer,...
&TailleBufferNécessaire )
Erreur(ErreurInfo())

---------- etc...------------

A l'exécution, le programme s'arrête sur le 2ème appel et donc avant
'Erreur(ErreurInfo())'. Les seules infos sur le problème sont la
fenêtre standard de windev qui indique qu'il y a eu une erreur
fatale... sans beaucoup plus de précision !
Dans la structure, j'ai essayé avec des chaînes ASCIIZ mais seule la
donnée 'lpDisplayName' est indiqué avec une taille maxi de 256. Pour
les autres, la taille est variable !

Si c'est possible de faire tourner ça en C, ça doit l'être en Windev !

7 réponses

Avatar
Romain PETIT
Alain a présenté l'énoncé suivant :
Depuis 2 semaines, je cherche désespérement de l'aide pour faire
tourner la fonction QUERY_SERVICE_CONFIGA de l'API ADVAPI32.DLL.


[...]

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

Si c'est possible de faire tourner ça en C, ça doit l'être en Windev !



Ta structure n'est pas correcte pour l'API.
Il ne faut JAMAIS passer des chaines Windev (non ASCIIZ) dont on va
récupérer la valeur à une API.
De plus, les membres lp.. sont des pointeurs sur des chaines et non des
chaines...
Déclare des chaines ASCIIZ à 4096 (comme MS le fait dans leurs exemple
en C++)...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/querying_a_service_s_configuration.asp

A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)
Avatar
aprosper_fr
Romain PETIT wrote in message news:...
Alain a présenté l'énoncé suivant :
> Depuis 2 semaines, je cherche désespérement de l'aide pour faire
> tourner la fonction QUERY_SERVICE_CONFIGA de l'API ADVAPI32.DLL.
[...]

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

> Si c'est possible de faire tourner ça en C, ça doit l'être en Windev !

Ta structure n'est pas correcte pour l'API.
Il ne faut JAMAIS passer des chaines Windev (non ASCIIZ) dont on va
récupérer la valeur à une API.
De plus, les membres lp.. sont des pointeurs sur des chaines et non des
chaines...
Déclare des chaines ASCIIZ à 4096 (comme MS le fait dans leurs exemple
en C++)...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/querying_a_service_s_configuration.asp

A+




Merci pour ta réponse.

Cependant et si je ne me trompe pas, l'allocation de 4096 bytes est
effectuée dans cet exemple pour la structure complète et non pour les
chaînes.
Je suis d'accord sur le principe CHAINE/ASCIIZ mais comment déclarer
une longueur fixe pour des chaînes de longueur variable ?

Et enfin sur la fait que les membres lp... sont des pointeurs je suis
également d'accord. Mais comment déclarer dans une structure un
pointeur sur une chaîne (fixe ou variable) ?

J'ai tenté de créer des chaînes en dehors de la structure et de mettre
uniquement des entiers dans la structure, puis d'initialiser les
entiers avec les adresses des chaînes...mais ça n'a rien donné.
Avatar
farplus
Bonjour,


Alain a présenté l'énoncé suivant :
Romain PETIT wrote in message news

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







Je suis d'accord sur le principe CHAINE/ASCIIZ mais comment déclarer
une longueur fixe pour des chaînes de longueur variable ?



n'en ait pas cure car le système remplit les chaînes avec le délimiteur

fait des chaines ASCIIZ assez longues pour éviter le débordement.
Essaie, ça devrait marcher:

QUERY_SERVICE_CONFIGA est une structure
dwServiceType est un entier
dwStartType est un entier
dwErrorControl est un entie
lpBinaryPathName est une chaîne ASCIIZ sur 4096
lpLoadOrderGroup est une chaîne ASCIIZ sur 4096
dwTagId est un entier
lpDependencies est une chaîne ASCIIZ sur 4096
lpServiceStartName est une chaîne ASCIIZ sur 4096
lpDisplayName est une chaîne ASCIIZ sur 4096
FIN


tiens nous au courant.

--
Ceci est une signature automatique de MesNews.
Site : http://mesnews.no-ip.com
Avatar
Romain PETIT
farplus a émis l'idée suivante :

Essaie, ça devrait marcher:


[...]
lpDisplayName est une chaîne ASCIIZ sur 4096
tiens nous au courant.



Non, ça ne peut pas marcher !
lpDisplayName est un pointeur !
C'est un entier qui correspond à une adresse mémoire
correspondant à une chaine (ASCIIZ).

Voici ce qu'il faut faire :

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()


A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)
Avatar
aprosper_fr
CA MARCHE !!!

Merci à tous et en particulier à Romain qui a trouvé la solution !

J'avais bien essayé le transfert de blocs mémoires mais sans pouvoir
aller jusqu'au bout de la démarche.

Ca fait plaisir de voir que sur ce forum il y a de vrais experts et
une vraie solidarité.
J'ai posté dans d'autres forums qui sont visiblement beaucoup moins
pro et beaucoup moins actifs.

Un GRAND merci à tous ! Alain


Romain PETIT wrote in message news:...
farplus a émis l'idée suivante :

> Essaie, ça devrait marcher:
[...]
> lpDisplayName est une chaîne ASCIIZ sur 4096
> tiens nous au courant.

Non, ça ne peut pas marcher !
lpDisplayName est un pointeur !
C'est un entier qui correspond à une adresse mémoire
correspondant à une chaine (ASCIIZ).

Voici ce qu'il faut faire :

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()


A+


Avatar
Romain PETIT
Alain a utilisé son clavier pour écrire :

Ca fait plaisir de voir que sur ce forum il y a de vrais experts et
une vraie solidarité.
J'ai posté dans d'autres forums qui sont visiblement beaucoup moins
pro et beaucoup moins actifs.



Ca dépend : si par "activité" tu entends volume ou nombre de messages,
alors fcdaw est moins "actif" que certains forums privés...
Par contre les réponses ici ne sont pas censurées, les discussions sont
plus libres et les solutions souvent plus pertinentes...

A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)
Avatar
Romain PETIT
Romain PETIT a exposé le 12/06/2004 :
// 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))



Tiens, en passsant je viens de (re)découvrir ChaineRecupère() qui
remplace le bidule ci-dessus :

sChaine est une chaîne
sChaine = ChaîneRécupère(QueryConfigService:lpBinaryPathName,
crAdresseASCIIZ)+RC+...
ChaîneRécupère(QueryConfigService:lpLoadOrderGroup,
crAdresseASCIIZ)+RC+...
ChaîneRécupère(QueryConfigService:lpDependencies,
crAdresseASCIIZ)+RC+...
ChaîneRécupère(QueryConfigService:lpServiceStartName,
crAdresseASCIIZ)+RC+...
ChaîneRécupère(QueryConfigService:lpDisplayName, crAdresseASCIIZ)

Info(sChaine)

A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)