IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Récupérer le type de démarrage d'un service


Sujet :

API, COM et SDKs Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 49
    Points : 36
    Points
    36
    Par défaut Récupérer le type de démarrage d'un service
    Salut,
    J'essaye de récupere le type de démarrage d'un service.
    Voila mon code :
    WinSvc.pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    //
    // Query Service Configuration Structure
    //
      PQueryServiceConfigA = ^TQueryServiceConfigA;
      PQueryServiceConfigW = ^TQueryServiceConfigW;
      PQueryServiceConfig = PQueryServiceConfigA;
      {$EXTERNALSYM _QUERY_SERVICE_CONFIGA}
       _QUERY_SERVICE_CONFIGA = record
        dwServiceType: DWORD;
        dwStartType: DWORD;
        dwErrorControl: DWORD;
        lpBinaryPathName: PAnsiChar;
        lpLoadOrderGroup: PAnsiChar;
        dwTagId: DWORD;
        lpDependencies: PAnsiChar;
        lpServiceStartName: PAnsiChar;
        lpDisplayName: PAnsiChar;
      end;
      {$EXTERNALSYM _QUERY_SERVICE_CONFIGW}
       _QUERY_SERVICE_CONFIGW = record
        dwServiceType: DWORD;
        dwStartType: DWORD;
        dwErrorControl: DWORD;
        lpBinaryPathName: PWideChar;
        lpLoadOrderGroup: PWideChar;
        dwTagId: DWORD;
        lpDependencies: PWideChar;
        lpServiceStartName: PWideChar;
        lpDisplayName: PWideChar;
      end;
      {$EXTERNALSYM _QUERY_SERVICE_CONFIG}
      _QUERY_SERVICE_CONFIG = _QUERY_SERVICE_CONFIGA;
      {$EXTERNALSYM QUERY_SERVICE_CONFIGA}
      QUERY_SERVICE_CONFIGA = _QUERY_SERVICE_CONFIGA;
      {$EXTERNALSYM QUERY_SERVICE_CONFIGW}
      QUERY_SERVICE_CONFIGW = _QUERY_SERVICE_CONFIGW;
      {$EXTERNALSYM QUERY_SERVICE_CONFIG}
      QUERY_SERVICE_CONFIG = QUERY_SERVICE_CONFIGA;
      TQueryServiceConfigA = _QUERY_SERVICE_CONFIGA;
      TQueryServiceConfigW = _QUERY_SERVICE_CONFIGW;
      TQueryServiceConfig = TQueryServiceConfigA;
    Ma fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    // retourne le type de démarrage du service
    function ServiceGetStartType( sMachineName, sServiceName : string) : DWord;
    var
     schm   : SC_Handle;
     schs   : SC_Handle;
     qsc    : TQueryServiceConfig;
     dwNeededBytes : DWord;
    begin
      // initialisation
      Result := 0;
      schs := 0;
     
      // se connecte au service control manager
      schm := OpenSCManager( PChar(sMachineName), Nil, SC_MANAGER_CONNECT);
     
      try
        // si la connection a réussie
        if schm > 0 then
        begin
          // ouvre un handle sur le service en question afin de recuperer sa config
          schs := OpenService( schm, PChar(sServiceName), SERVICE_QUERY_CONFIG);
     
          // si la connection au service a réussie
          if schs > 0 then
          begin
            // recupere le type de démarrage du service
            dwNeededBytes := 0;
            if QueryServiceConfig( schs, @qsc, sizeof(qsc), dwNeededBytes) then
            begin
              Result := qsc.dwStartType;
            end
            else
            begin
              // si échec, envoie une exception
              case GetLastError of
                ERROR_ACCESS_DENIED : Raise Exception.Create('ERROR_ACCESS_DENIED');
                ERROR_INSUFFICIENT_BUFFER : Raise Exception.Create('ERROR_INSUFFICIENT_BUFFER : ' + IntToStr(dwNeededBytes));
                ERROR_INVALID_HANDLE : Raise Exception.Create('ERROR_INVALID_HANDLE');
              else
                Raise Exception.Create( Format(rsUnableToGetServiceStartType, [sServiceName]));
              end;
            end;
          end
          else
          begin
            // envoie une exception
            Raise Exception.Create( Format(rsUnableToOpenService, [sServiceName]));
          end;
        end
        else
        begin
          // envoie une exception
          if sMachineName = '' then
          begin
            Raise Exception.Create( Format(rsUnableToConnectToSCM, [rsLocalMachine]));
          end
          else
          begin
            Raise Exception.Create( Format(rsUnableToConnectToSCM, [sMachineName]));
          end;
        end;
      finally
        if schs > 0 then
        begin
          // ferme le handle du service
          CloseServiceHandle(schs);
        end;
     
        if schm > 0 then
        begin
          // ferme le handle du control manager
          CloseServiceHandle(schm);
        end;
      end;
    end;
    Je tombe systématiquement en exception avec l'erreur ERROR_INSUFFICIENT_BUFFER
    la valeur de dwNeededBytes est 200.
    Est-ce que quelq'un a une idée pour résoudre ce problème?
    Merci.

  2. #2
    Membre habitué Avatar de gord's
    Inscrit en
    Avril 2003
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 115
    Points : 127
    Points
    127
    Par défaut
    c'est un mécanisme classique des API windows popur des fonctions qui retournent un buffer de taille variable.
    sur ERROR_INSUFFICIENT_BUFFER, il faut que tu réalloue ton buffer avec la taille neededSize, et que tu rappelles la fonction
    La prochaine révolution informatique : les machines qui font ce qu'on veut, au lieu de faire ce qu'on leur demande...
    Grand Vizir du Grand Gourou - Trois-quart aile gauche du TRFC et intendant de 3ème mi-temps - Papy fait de la résistance

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 49
    Points : 36
    Points
    36
    Par défaut
    Salut,
    OK, je comprend le principe mais quel est la syntaxe en delphi pour réallouer le bouffer avec la bonne taille?
    Merci.

  4. #4
    Membre habitué Avatar de gord's
    Inscrit en
    Avril 2003
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 115
    Points : 127
    Points
    127
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    pqsc    : *TQueryServiceConfig; 
     
    //pour le 1er tour : 
    getmem ( pqsc, sizeof(TQueryServiceConfig) );
    QueryServiceConfig( schs, pqsc, sizeof(TQueryServiceConfig), dwNeededBytes)
     
    //pour le 2ème tour : 
    freemem(pqsc);
    getmem ( pqsc, dwNeededBytes);
    QueryServiceConfig( schs, pqsc, dwNeededBytes, dwNeededBytes)
    La prochaine révolution informatique : les machines qui font ce qu'on veut, au lieu de faire ce qu'on leur demande...
    Grand Vizir du Grand Gourou - Trois-quart aile gauche du TRFC et intendant de 3ème mi-temps - Papy fait de la résistance

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 49
    Points : 36
    Points
    36
    Par défaut
    OK, merci gord's tu m'a bien aidé.
    Voila ma fonction au final pour ceux que ca interesse.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
     
    // retourne le type de démarrage du service
    function ServiceGetStartType( sMachineName, sServiceName : string) : DWord;
    var
     schm   : SC_Handle;
     schs, schs2   : SC_Handle;
     qsc   : PQueryServiceConfigA;
     dwNeededBytes : DWord;
    begin
      // initialisation
      Result := 0;
      schs := 0;
     
      // se connecte au service control manager
      schm := OpenSCManager( PChar(sMachineName), Nil, SC_MANAGER_CONNECT);
     
      try
        // si la connection a réussie
        if schm > 0 then
        begin
          // ouvre un handle sur le service en question afin de recuperer sa config
          schs := OpenService( schm, PChar(sServiceName), SERVICE_QUERY_CONFIG);
     
          // si la connection au service a réussie
          if schs > 0 then
          begin
            // initialisation de la taille du buffer
            dwNeededBytes := 0;
     
            // allocation de la mémoire par défaut
            GetMem( qsc, sizeof(PQueryServiceConfigA));
     
            // sauvegarde le handle du service parce que si il y a une erreur,
            // la valeur initiale est perdue
            schs2 := schs;
     
            // tente de récupérer le type de démarrage du service
            if QueryServiceConfig( schs, qsc, sizeof(PQueryServiceConfigA), dwNeededBytes) then
            begin
              // si réussi, retoune la valeur du type de démarrage
              Result := qsc.dwStartType;
            end
            else
            begin
              // si il y a eu une erreur de type buffer insuffisant
              if GetLastError = ERROR_INSUFFICIENT_BUFFER then
              begin
                // Libere la mémoire précédamant allouée
                FreeMem( qsc);
     
                // réalloue la mémoire necessaire
                GetMem( qsc, dwNeededBytes);
     
                // re-tente de récupérer le type de démarrage
                if QueryServiceConfig( schs2, qsc, dwNeededBytes, dwNeededBytes) then
                begin
                  // si réussi, retoune la valeur du type de démarrage
                  Result := qsc.dwStartType;
                end
                else
                begin
                  // si il y a eu ecore une erreur,
                  // crée une exception pour qu'elle soit traitée dans la fonction
                  // appellante
                  case GetLastError of
                    ERROR_ACCESS_DENIED : Raise Exception.Create('ERROR_ACCESS_DENIED');
                    ERROR_INSUFFICIENT_BUFFER : Raise Exception.Create('ERROR_INSUFFICIENT_BUFFER : ' + IntToStr(dwNeededBytes));
                    ERROR_INVALID_HANDLE : Raise Exception.Create('ERROR_INVALID_HANDLE');
                  else
                    Raise Exception.Create( Format(rsUnableToGetServiceStartType, [sServiceName]));
                  end;
                end;
              end
              else
              begin
                // envoie une exception
                Raise Exception.Create( Format(rsUnableToGetServiceStartType, [sServiceName]));
              end;
            end;
          end
          else
          begin
            // envoie une exception
            Raise Exception.Create( Format(rsUnableToOpenService, [sServiceName]));
          end;
        end
        else
        begin
          // envoie une exception
          if sMachineName = '' then
          begin
            Raise Exception.Create( Format(rsUnableToConnectToSCM, [rsLocalMachine]));
          end
          else
          begin
            Raise Exception.Create( Format(rsUnableToConnectToSCM, [sMachineName]));
          end;
        end;
      finally
        if schs > 0 then
        begin
          // ferme le handle du service
          CloseServiceHandle(schs);
        end;
     
        if schm > 0 then
        begin
          // ferme le handle du control manager
          CloseServiceHandle(schm);
        end;
      end;
    end;
    Merci.
    @+.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 09/11/2018, 17h09
  2. [Vb.NET] Changer le type de démarrage d'un service Windows
    Par Aspic dans le forum Windows Forms
    Réponses: 9
    Dernier message: 22/08/2009, 10h29
  3. pb de démarrage de JRun Service Manager
    Par lalyly dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 18/10/2005, 15h11
  4. Récupérer le type et la taille d'une colonne
    Par Progs dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 23/09/2005, 17h27
  5. Planifier le démarrage d'un service Window
    Par tscoops dans le forum Windows XP
    Réponses: 2
    Dernier message: 29/03/2005, 14h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo