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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
_________________
R&B
Contact, CV.
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer


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
Créer un fichier PDF de la contribution Imprimer



 Haut   Précédent   Suivant




Enregistrer votre réponse
CompteNom   Mot de passe   Authentification
Message:


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.

[Recherche avancée]


Connexion
Menu
Chercher WDForge
Chercher Web
Partenaires
Visualiser tous les Partenaires...
WinDev, WebDev, WinDev Mobile et HyperFile sont des marques déposées par PCSoft. |  Voter |  Legal |  Contact |   XOOPS 2.0.13.2