• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1483
  • Last Modified:

queryserviceconfig question

Does anyone have a working code sample of how to use queryserviceconfig in delphi 4?
0
mantra246
Asked:
mantra246
  • 7
  • 5
1 Solution
 
BedouinDNCommented:
A bit quick and dirty but...

You will need to add WinSvc.pas into uses clause.
And also will need to do some error trapping (not to mention freeing the memory)

//-----------------------------------QueryServiceConfig------------------------------------------------------

procedure TForm1.QuerySvcConfig(Service: String);
var
schm,
schs: SC_Handle;
ss: TServiceStatus;
dwChkP: DWord;
sConfig: PQueryServiceConfigA;
sNeeded: Cardinal;
begin
schm := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
        if (schm > 0) then
        begin
        schs := OpenService(schm, PChar(Service), SERVICE_QUERY_CONFIG);
                if (schs > 0) then
                begin
                //Call the QueryServiceConfig function to get the required buffer size
                        if QueryServiceConfig(schs,sConfig,0,sNeeded) <> TRUE then
                        begin
                                if GetLastError = ERROR_INSUFFICIENT_BUFFER then
                                begin
                                //Get the memory required by using the Bytes needed var
                                GetMem(sConfig,sNeeded);
                                        if QueryServiceConfig(schs,sConfig,sNeeded,sNeeded) <> TRUE then
                                        begin
                                        MessageDlg(SysErrorMessage(GetLastError),mtError,[MBOK],0);
                                        end
                                        else
                                        begin
                                        //Play with Config Info here
                                        end;
                                end;
                        end;
                CloseServiceHandle(schs);
                end;
        CloseServiceHandle(schm);
        end;
end;

//----------------------------------------------------------------
0
 
mantra246Author Commented:
Thanks BedouinDN but i get the error of "Type of actual and formal var parameters must be identical" on both:

if QueryServiceConfig(schs,sConfig,0,sNeeded) <> TRUE

and

if QueryServiceConfig(schs,sConfig,sNeeded,sNeeded) <> TRUE

It seems to be with the sConfig section.

Any idea why and what to do to fix it?

If it can be fixed and it works then it looks like the points are yours - along with a grade A for your help.

0
 
BedouinDNCommented:
This compiles OK in D6, maybe D4 is looking for a pointer rather than declaring as PQueryServiceConfigA.

Also might be looking for lpServiceConfig instead of PQueryServiceConfigA as this is what MSDN says, so if the below code does not work, try declaring sConfig as lpServiceConfig rather than pointer and remove the reference to PQueryServiceConfigA.
Sorry, I don't have D4 to test with so please let me know how you go..

procedure TForm1.QuerySvcConfig(Service: String);
var
schm,
schs: SC_Handle;
sConfig: Pointer;
pConfig: PQueryServiceConfigA;
sNeeded: Cardinal;
begin
sConfig := nil;
schm := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
        if (schm > 0) then
        begin
        schs := OpenService(schm, PChar(Service), SERVICE_QUERY_CONFIG);
                if (schs > 0) then
                begin
                //Call the QueryServiceConfig function to get the required buffer size
                        if QueryServiceConfig(schs,sConfig,0,sNeeded) <> TRUE then
                        begin
                                if GetLastError = ERROR_INSUFFICIENT_BUFFER then
                                begin
                                //Get the memory required by using the Bytes needed var
                                GetMem(sConfig,sNeeded);
                                        if QueryServiceConfig(schs,sConfig,sNeeded,sNeeded) <> TRUE then
                                        begin
                                        MessageDlg(SysErrorMessage(GetLastError),mtError,[MBOK],0);
                                        end
                                        else
                                        begin
                                        //Play with Config Info here
                                        pConfig := PQueryServiceConfigA(sConfig);
                                        ShowMessage(pConfig.lpDisplayName);
                                        end;
                                end;
                        end;
                CloseServiceHandle(schs);
                end;
        CloseServiceHandle(schm);
        end;
end;
0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
mantra246Author Commented:
Still the same error messages trying the new code.  I'm not sure about 'declaring sConfig as lpServiceConfig rather than pointer ' as it causes an "undeclared identifier" error when i change sConfig: Pointer; to sConfig: lpServiceConfig ;
0
 
mantra246Author Commented:
In your first code you posted, if i change sConfig: PQueryServiceConfigA; to sConfig: TQueryServiceConfig; the error "Type of actual and formal var parameters must be identical" messages stop - but it gives the error "incompatible types" at the GetMem(sConfig,sNeeded); line.
0
 
BedouinDNCommented:
How is the QueryServiceConfig function declared for you?
I.E. What exactly is the function asking for?

The original error ("Type of actual and formal var parameters must be identical") means that the code is passing an incorrect variable type to the function.

Bedouin..
0
 
mantra246Author Commented:
This is from the winsvc.pas file:

{$EXTERNALSYM QueryServiceConfigA}
function QueryServiceConfigA(hService: SC_HANDLE;
  var lpServiceConfig: TQueryServiceConfigA; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;
{$EXTERNALSYM QueryServiceConfigW}
function QueryServiceConfigW(hService: SC_HANDLE;
  var lpServiceConfig: TQueryServiceConfigW; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;
{$EXTERNALSYM QueryServiceConfig}
function QueryServiceConfig(hService: SC_HANDLE;
  var lpServiceConfig: TQueryServiceConfig; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;
0
 
mantra246Author Commented:
also

//
// 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;
0
 
BedouinDNCommented:
Unfortunately I have a different declaration of the function.
From WinSvc:
function QueryServiceConfig(hService: SC_HANDLE;
  lpServiceConfig: PQueryServiceConfig; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;

I would advise downloading the latest Win32 API conversion from Marcel van Brakel's site or the Project Jedi website.
This has a translation of the WinSvc.pas file that compiles without error for me and has the same declaration as my WinSvc.pas.

Marcel's site: http://members.chello.nl/m.vanbrakel2

If you unzip the zip file and add the folder to your Library path in Tools->Environment Options->Library, then add JwaWinSvc to your uses clause instead of WinSvc the original code should work OK. (hopefully) :-)



0
 
mantra246Author Commented:
It's ok - i used your code and played with it a while and it now seems to work fine - although i will have to test it out more and insert some error checking.  It was missing the ^ from sConfig with sConfig set up as a type and a pointer to it.

I shall give you the points though since you were very kind in trying to help and did provide code that i will use.  So i shall be adding some more points for the extra help you gave and making it a grade A.

Thanks for all the help.
0
 
BedouinDNCommented:
Well thankyou for that, but please do not feel obliged to add points or anything like that. You should really only give what you believe the help is worth.

At any rate, I hope this all works out OK for you

Cheers.
Bedouin..
0
 
mantra246Author Commented:
I am adding extra points to say thank you for going the extra mile on this one with me - it is the only way i can show that i appreciate the work you did on my behalf.   It may only be points but the principle is that what you did was appreciated and should be recognized as such.

Again, thank you for all your help on this one.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now