We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Return values from WinAPI call

Diver
Diver asked
on
Medium Priority
293 Views
Last Modified: 2010-04-04
This procedure returns false if no diskette is found in drive A, otherwise it returns true. When it returns true I want to retrieve the serial number in the 'result' variable. How could this be done?


procedure GetInfo ;export;
  var
     dwTemp1, dwTemp2 : LongInt;
     Result : DWord;
  begin
     GetVolumeInformation (
        PChar('A:\'),
        Nil,
        0,
        @Result,
        dwTemp1,
        dwTemp2,
        Nil,
        0);
  end;

  exports
     GetInfo;

Comment
Watch Question

Commented:
Hi Diver,

Getting the serial number of a disk.

                         Question:

                         How do I retrieve the serial number of a disk?

                         Answer:

                         You can use the Windows API function GetVolumeInformation()

                         procedure TForm1.Button1Click(Sender: TObject);
                         var
                           VolumeSerialNumber : DWORD;
                           MaximumComponentLength : DWORD;
                           FileSystemFlags : DWORD;
                           SerialNumber : string;
                         begin
                           GetVolumeInformation('C:\',
                                                nil,
                                                0,
                                                @VolumeSerialNumber,
                                                MaximumComponentLength,
                                                FileSystemFlags,
                                                nil,
                                                0);
                           SerialNumber := IntToHex(HiWord(VolumeSerialNumber), 4) +
                                           '-' +
                                           IntToHex(LoWord(VolumeSerialNumber), 4);
                           Memo1.Lines.Add(SerialNumber);
                         end;
(From Borlands developer support)

Regards, ZiF.

Author

Commented:
Yes, I know how to retrieve it. But how can it be returned from a function in a dll? I want to return both the value of the GetVolumeInformation function as the serial number in the 4th parameter. That's what I was asking for.

Commented:
function GetInfo(VAR SerialNumber: DWORD): Boolean;
var
  dwTemp1, dwTemp2 : LongInt;
begin
  Result := GetVolumeInformation (
            'A:\', Nil, 0,
            @SerialNumber,
            dwTemp1, dwTemp2, Nil, 0);
end;

Author

Commented:
Vladika, I don't think you tested your code. When inserting a disk I get an acces violation error at address...

OK, it looks like it is not that easy... hmm, let me raise the points... hope I get the right answer this time.

I want to use Win API calls like GetVolumeInfo and GetComputerName in functions in a DLL.
So, the result of this function has to be exported.
But, I also want to export the value of certain parameters, like the name of the GetComputerName call and the serial number of the GetVolumeInfo call.

Please provide me with the correct code for BOTH calls. A brief explanation of what exactly is happening would be welcome too. This is new stuff to me and I want to learn something from you.

I hope I made myself clear.
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Commented:
If something is incomprehensible, ask questions

Author

Commented:
Hello, Vladika. This works fine now. Excellent work! Sorry for my nervous reaction yesterday; suppose I was doing to much things at a time. Can I still ask you a few questions? I'll raise the points to 120 to compensate for your effort. BTW, are you Russian or is this just a good sounding nickname :-) ?

How come that the serial number is returned in the 'result' variable and not the boolean output of the GetVolumeInformation itself?

Why has CompName to be defined as an array of char? Can't it be returned as a string?

The GetVolumeInformation function now only reads drive A (hard coded). How would this function be written if the drive letter is an input variable coming from a textbox on a form? (the function is always called from the dll, so the drive letter has to be passed from the form to the dll).

Hope this is a bit clear. Anyway, thanks for helping me that much.

Commented:
Hello, Diver.

Yes, I am Russian. I think you guessed by my bad English :)

> How come that the serial number is returned in the 'result' variable and not the boolean
> output of the GetVolumeInformation itself?
> How would this function be written if the drive letter is an input variable coming
> from a textbox on a form?

Here is example
................
function GetInfo2(Drive: PChar): DWORD; stdcall;
var
  dwTemp1, dwTemp2 : LongInt;
begin
  if not GetVolumeInformation(Drive, nil, 0, @Result,
    dwTemp1, dwTemp2, nil, 0) then Result := 0;  // '0' indicates error
end;
................
exports
  GetInfo2 index 3;
................

In the program
...........
function GetInfo2(Drive: PChar): DWORD; stdcall; external 'mylib.dll';
...........
procedure TForm1.Button3Click(Sender: TObject);
var SN: Integer;
    S: string;
begin
  SN := GetInfo2(PChar(Edit1.Text));
  if SN <> 0 then // no error
  begin
    S := 'Serial Number: ' +
      IntToHex(HiWord(SN), 4) + '-' + IntToHex(LoWord(SN), 4);
    Application.MessageBox(PChar(S), '', 0)
  end else
    RaiseLastWin32Error;
end;


> Why has CompName to be defined as an array of char?
array of char is equvalent PChar
You must pass in GetComputerName buffer which
should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters
So, TCompName is
1) PChar
2) have enough size to contain MAX_COMPUTERNAME_LENGTH + 1 characters

> Can't it be returned as a string?
I don't try such thing.
I think the problems appears with using this dll in not Delphi.
Use PChar instead of string.

Author

Commented:
Vladika, it was not your English, but your name that made me think you're Russian. BTW, your English is not bad at all (mine is not perfect either, because it's not my native language).
Thanks for answering all my question. Thanks also for the code: this works fine too.
I just want to ask you one more favor (and I'm raising the points again - in fact I'm planning to double them :-) - if you can answer me). I have a homemade C++ dll that reads and writes to sectors on a disk, and sets a volume id. What follows are the declarations in the header file.
Can this dll be called from my dll? Can you do that in Delphi code?

Functions:
----------
ReadFloppySectors(drive, sector, num, buffer)
WriteFloppySectors(drive, sector, num, buffer)
SetVolumeId(drive, id)

Arguments:
----------
drive      - Floppy drive number (0 = "A:", 1 = "B:")
sector      - First sector number
num      - Number of sectors
buffer      - Address of allocated buffer
                    Buffer size must be a multiple of sector size (usually 512 bytes)
id      - A 32-bit hex representation

Commented:
Hi, Diver

> Can this dll be called from my dll? Can you do that in Delphi code?
Yes, yes.

But information is not enough.
Before write dll I must know
1) parameters types
2) calling convention
3) procedure import name or index
4) your dll name

You can send me dll and header file by email
demon@dezcom.mephi.ru

Or write here missing information

Author

Commented:
Thanks, Dmitri. You've done an excellent job!
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.