Solved

Error code 87

Posted on 2004-08-29
13
1,565 Views
Last Modified: 2008-01-09
Hi,

I've a program that needs to run on both WinXP and Win2k systems. However, it seems not to run on a Win2k system, as it generates a System Error Code 87 (ERROR_INVALID_PARAMETER). As i only have Delphi installed on a WinXP system, i cannot debug the program on the Win2k system.

The program doesn't directly use many lowlevel WinAPI procedures. It uses the RunningProcessesList from JCL and it reads and writes some values from the registry.

I really have no clue why it won't run on Win2k. My experience was that most API calls where supported by both WinXP and Win2k. Do you have some list with API calls that aren't supported by Win2k? Maybe i'll then find the causer of my problems.

Also a list with procedures that might trigger such a very undescriptive error message would be welcome...

Thanks in advance for any help!
Evarest
0
Comment
Question by:Evarest
13 Comments
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11931465
It might be easier to just use WMI to get an overview of all running processes. But okay...

For a list of procedures and the platform requirements, visit http://msdn.microsoft.com/library/ for the MSDN library. Here's there are complete overviews of the Windows API, the valid parameters and on which platforms it runs. But the MSDN site is huge...

Now, about retrieving a list of all running processes, you could just use WMI. Do do so, you first need to import the C:\WINNT\system32\wbem\wbemdisp.tlb type library which will handle the process retrieval. Basically, all you'd need then is this code:

uses
  SysUtils,
  Windows,
  ActiveX,
  Classes,
  WbemScripting_TLB in 'WbemScripting_TLB.pas'; // This one was created by the import.

function ADsEnumerateNext( pEnumVariant: IEnumVARIANT; cElements: ULONG; var pvar: OleVARIANT; var pcElementsFetched: ULONG ): HRESULT; safecall; external 'activeds.dll'; // Delphi doesn't know this function.

procedure DumpProcesses( const List: TStrings ); // Fills list with executable names.
var
  Enum: IEnumVARIANT;
  varArr: OleVariant;
  lNumElements: ULong;
  Process: SWBemObject;
begin
  Enum := CoSWbemLocator.Create.ConnectServer( '', 'root\cimv2', '', '', '', '', 0, nil ).ExecQuery( 'Select * from Win32_Process', 'WQL', wbemFlagBidirectional, nil )._NewEnum as IEnumVariant;
  while ( Succeeded( ADsEnumerateNext( Enum, 1, varArr, lNumElements ) ) ) and ( lNumElements > 0 ) do begin
    Process := IUnknown( varArr ) as SWBemObject;
    List.Add( VarToStr( Process.Properties_.Item( 'ExecutablePath', 0 ).Get_Value ) );
  end;
  Process := nil;
  Enum := nil;
end;

Or do something else with the process information in the Process object above. There's lots of useful information inside it.

About the Windows API, my experience is that you really have to be very careful since even the smallest service pack might disable your nice procedures. Fortunately, those things won't happen very often.
0
 
LVL 4

Author Comment

by:Evarest
ID: 11931566
Dear WorkShop_Alex,

as in the other post about WMI, i'd rather not use it (memoryleaks and slow). My app now does exactly what it should do, and oddly, it seems not to be the RunningProcessesList procedure which is causing all this trouble. My users are telling me that whatever they do, they get this code 87 error...

As i'm not calling WinAPI directly from anywhere in my code except the RunningProcessesList, I cannot say what's the problem.

As you pointed out, MSDN is not exactly the best place to go searching for an answer. And it's quite impossible for me to send my users an app with on every line of code a messagebox so i know where my app finally goes wrong :-)

I thought that maybe an expert had had a similar problem (code 87 but quite difficult to point the source). However, as it seems, it's not going to be the case...

Thanks anyway,
Evarest
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 11931861
you don't have to show a message box in every spot you want to find out what's going on... what you do is use a .log file instead, the user keeps going and finds the errors, and you send all the information, every exception, every error to the log file, if you're good enough with exceptions and error trapping, your .log file should tell exactly where the problem is
0
 
LVL 4

Author Comment

by:Evarest
ID: 11932093
"if you're good enough with exceptions and error trapping, your .log file should tell exactly where the problem is"

That's true: the only problem is that it only returns the very descriptive error message:

System Error.  Code: 87.Falscher Parameter.

And this is not really something that can help me any further...
0
 
LVL 4

Author Comment

by:Evarest
ID: 11932205
Quite a nice note: this error message occured after a program uptime of 220 milliseconds :-)

It seems that the problem is located somewhere in the beginning of my code. Also, it seems that not all systems running Win2k have these problems...

It's getting worse and worse...

Evarest
0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 90 total points
ID: 11934853
Okay, a wild guess... Are you using the registry to access some information? Especially writing to a key in the local machine area? Then the problem could be that those users don't have enough access rights. Check if your application runs for administrators but not for regular users... ;-)

Your error message is a bit too generic to solve just like this. You should try to see if you can determine the exact location of where the bug occuts, e.g. by including an unique tag at every place where you show/write a log message.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 4

Author Comment

by:Evarest
ID: 11935616
I've sent a debug version of the program to my users. I hope they will run it and send the debug file to me.

I'm using the registry LOCAL_MACHINE, but i've encapsuled that into a try...except block. That should be OK then...
0
 
LVL 4

Author Comment

by:Evarest
ID: 11936776
Workshop_Alex,

i think you struck gold: the problem seems to lay in the access restrictions posed upon limited accounts. Stupid me, but it never crossed my mind that the user with the problems could be working on a company PC, which of course only has limited rights.

I think I've solved most problems with the Registry, but i still have the following problem:

I need to get the complete path of a process by its PID. You can do this by calling

OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);

and extracting some info, but this is ONLY possible in administration accounts (thus full rights). PROCESS_QUERY_INFORMATION will give you an error in limited accounts.

Is it possible to get the full path of a process by its PID?

Thanks in advance!
Evarest
0
 
LVL 45

Expert Comment

by:aikimark
ID: 11937532
1. Take a look at your Win2K maintenance level.  Some WinXP API calls were retrofitted into Win2K with one of the service packs.

2. Is your program running as a service?

3. Have you done an installation on the Win2K machine or just copied the executable?  There may be some dependent DLLs you are missing.

4. For debugging purposes, you consider Codesite (from Raize Software).
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11939929
Evarest, it was a lucky guess but hey, I remembered that I did have similar problems once which were related to the registry being write-protected in some areas.

And yes, limited accounts are as the name implies, limited. To get around such problems you need to create a work-around solution. In one of the projects that I've worked on we solved these issues by creating a system service that would be running under an administrator account, thus having full access. By communicating with this service we could give normal users access to things that normally only administrators could do. Later we changed the model from a service to COM+ applications, that were set to run on a server with administration rights but this was because we changed to a multi-tier solution.

I'm not sure if there's an easy way for a limited user to override the security in some way. It would actually be a breach of security if this was possible because technically this could mean the limited user might also disable or close certain processes. (E.g. the antivirus or firewall software.)

I know you dislike WMI because of the memory leaks but still, it bypasses these security issues if I'm not mistaken. I've chosen for WMI in many situations just because of time limits. If you have a deadline in 5 days, you just can't spend 4 days trying to find some alternative solution, then do the rest in one day... If your project has a time-limit too, considering using WMI for now so your users will have a working version. That should buy you some time to improve things for the next version.
0
 
LVL 4

Author Comment

by:Evarest
ID: 11940391
Dear WorkShop_Alex,

yesterday i managed to create a more stable version of the program by limiting access to the registry and setting the OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID); between try...excepts.

The OpenProcess will now only give problems in an WinNT4 environment, but that's then a pitty for them... The problem is that there i can only use EnumProcesses to get information about the running processes. With the PIDs I'm able to extract the paths, however, the  PROCESS_QUERY_INFORMATION will fail in a limited account, resulting in no paths for me.

In WinXP, this problem can be prevented by using also the filename (not the entire path), which i get from the ProcessEntry32 of CreateToolhelp32Snapshot. Using this filename, i can scan for files with the same name and returnt their paths.

Actually, there's only a problem with getting PROCESS_QUERY_INFORMATION from files residing in the C:\Windows or C:\Windows\System32 folders... The rest doesn't pose any problems...

Sadly, WMI still isn't an option, as the monitoring program needs to be running indefinately, and i cannot afford any memoryleaks (have had some in the past, and that wasn't the nicest experience to have...)

Wrt Codesite which Aikimark suggested: as i'm only a poor student :-) I can't really afford such a tool...

Evarest
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11941176
It might be a good idea to just write a test application that uses WMI in a tight loop and see how much memory it will waste if you keep it running for a day. If it continuously keeps leaking memory it's not usable. But if it's stops wasting memory after a while, it can be used. Some components are just reserving memory for any further calls, cashing data if need be. WMI is probably doing something similar too.
As an alternative, you might create a small process that just gets the information you wants and writes it in a temporary file. All you have to do then is call the process and read the file afterwards. The lost memory will be reclaimed when this small process ends.

Running indefinitely on Windows systems is a bit rare since there are quite a few parts of Windows that will sooner or later bring down the system. I did write a scheduler application once which was supposed to run indefinitely. This too needed to run indefinitely but it was leaking a bit of memory too. However, the amount of memory loss after a week was still not enough (about 5 MB) to be very troublesome. Thus, as I say, find out how much memory you will be losing and check if this is an acceptable amount.
Or use a little trick and let your application restart itself every N days, thus the process is cleared and with it all lost memory. ;-)

I know, these are just work-arounds. But limited user accounts will never be able to use PID's just because of security reasons. But there's an alternative by creating a system service application. These can be executed by a specific user account, which should be the administrator. All you need then is a way to communicate with the service, telling the service to provide you whatever you need to know. The server will be running under administrator privileges, thus it will be able to read whatever you need to read. And services aren't too hard to code...
0
 
LVL 4

Author Comment

by:Evarest
ID: 11943002
[quote]But there's an alternative by creating a system service application. These can be executed by a specific user account, which should be the administrator. All you need then is a way to communicate with the service, telling the service to provide you whatever you need to know. The server will be running under administrator privileges, thus it will be able to read whatever you need to read. And services aren't too hard to code...[/quote]

For the project i'm working on, this isn't really of use. However it might come in handy lateron, in another project. Thanks for the idea!

Evarest
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now