LB Booster
« Windows disk volume name and serial number? »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 03:49am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Windows disk volume name and serial number?  (Read 453 times)
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Windows disk volume name and serial number?
« Reply #10 on: Jul 12th, 2017, 08:39am »

on Jul 11th, 2017, 11:33pm, CirothUngol wrote:
* numerical input can be variables or constants
* numerical output is always in the form of a STRUCT
* string input must be in the form of a variable with no null terminator
* string output must be in the form of a variable with a null terminator

That's pretty close, yes. There's not generally any harm in adding a NUL terminator to an 'input' string, but it is unnecessary (one is added automatically by LB/LBB). According to the LB docs it is essential to add a NUL to an 'output' string, but in practice that requirement was relaxed along the line. However I still prefer to do it because it's what the docs say.

Quote:
Is string output ever in the form of a STRUCT?

It can be, yes - it's your choice. Here's an example of exactly that:

Code:
    struct temp, path as char[260]
    calldll #kernel32, "GetTempPathA", _MAX_PATH as long, temp as struct, ret as long
    print temp.path.struct 

In some ways I think this is actually nicer than the more common form, using a NUL-terminated string. For example it eliminates the need to truncate the output using LEFT$().

Quote:
Yet when long is substituted in the CALLDLL it seems to work fine.

You should not be surprised. A long can contain any integer value between -2147483648 and +2147483647. A ulong can contain any integer value between 0 and +4294967295. Therefore if the value concerned is in the range 0 to +2147483647 it makes not the slightest difference whether you use a long or ulong. Very commonly values will be in this range.

Quote:
I'm quite certain that those devilish details would matter at some point, but when might that be?

When the value concerned is negative you should use a long and when it is greater than +2147483647 you should use a ulong. However, having said that, LBB will automatically substitute the correct parameter type in a CALLDLL statement if it notices that you have made a mistake (that may not necessarily be true of LB 4).

Of course if you are using long or ulong in a STRUCT, which doesn't necessarily have anything to do with CALLDLL or the Windows API (despite what you may read elsewhere, structs are really useful in all sorts of other circumstances) then it may well matter which you use.

Richard.
« Last Edit: Jul 12th, 2017, 08:44am by Richard Russell » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Windows disk volume name and serial number?
« Reply #11 on: Jul 13th, 2017, 09:43am »

on Jul 12th, 2017, 08:39am, Richard Russell wrote:
In some ways I think this is actually nicer than the more common form

I'm rapidly convincing myself of this. Returning string values in STRUCTs is more consistent with the way numeric values are returned, it does not require the returned string to be truncated using LEFT$, and it's (arguably) easier to understand.

Here is Rod's program adapted accordingly:

Code:
    RootPathName$ = "C:\"
    struct VolumeNameBuffer, vnb as char[261]
    VolumeNameSize = len(VolumeNameBuffer.struct)
    struct FileSystemNameBuffer, fsnb as char[261]
    FileSystemNameSize = len(FileSystemNameBuffer.struct)
    struct VolumeSerialNumber, vsn as ulong
    struct MaximumComponentLength, mcl as ulong
    struct FileSystemFlags, fsf as ulong

    calldll #kernel32, "GetVolumeInformationA",_
        RootPathName$ as ptr,_
        VolumeNameBuffer as struct,_
        VolumeNameSize as long,_
        VolumeSerialNumber as struct,_
        MaximumComponentLength as struct,_
        FileSystemFlags as struct,_
        FileSystemNameBuffer as struct,_
        FileSystemNameSize as long,_
        Result as long

    print "Call result ";Result
    print "VolumeName ";VolumeNameBuffer.vnb.struct
    print "Serial Number ";dechex$(VolumeSerialNumber.vsn.struct)
    print "Component length ";MaximumComponentLength.mcl.struct
    print "System Flags ";dechex$(FileSystemFlags.fsf.struct)
    print "File System Name ";FileSystemNameBuffer.fsnb.struct

    end 

Richard.
« Last Edit: Jul 13th, 2017, 09:46am by Richard Russell » User IP Logged

CirothUngol
New Member
Image


member is offline

Avatar

Odie, Odie, cha cha cha.


PM

Gender: Male
Posts: 44
xx Re: Windows disk volume name and serial number?
« Reply #12 on: Jul 14th, 2017, 12:41am »

Thanks again for the replies. I like the idea of using STRUCT for all output from API/DLLs, as it implies consistency and the code looks cleaner. I may never have known it to be an option had you not said, since char as a type doesn't seem to be mentioned anywhere in the LB 4.5 docs (I see that it's mentioned in LBB docs under STRUCT).

My only concern is that one seems unable to use a variable in the STRUCT definition for char members (eg. char[_MAX_PATH]), forcing the use of a constant instead (eg. char[260]). I receive a 'missing ] in struct' error unless I use a constant value. Is this avoidable? It's really the only reason I'm hesitant to use it instead of the more cumbersome string-buffer-with-added-null/left$-characters-before-the-null combo. Also, does the constant value include the null (259+null), or is the length actually 261 (260+null)?

...and as for the relative paths issue, I discovered that even though FILES gives no drive:\path info if none is provided (ie. if path$ is empty then x$(0,2) and x$(0,3) are empty), it will handle the relative stuff just fine if you provide it with a fully qualified path. So, I was able to correct the issue with the following 3 lines of Code:
' resolve relative paths
IF path$ = "" THEN path$ = StartupDir$
IF INSTR(path$,"\") =  1 THEN path$ = LEFT$(StartupDir$,2); path$
IF INSTR(path$,":") <> 2 THEN path$ = StartupDir$; "\"; path$ 
Then when you feed path$ into FILES all relativity is automatically resolved. Seems to work like a charm.
User IP Logged

LB Booster + LB Workshop + LB Builder = My Programs on Google Drive
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Windows disk volume name and serial number?
« Reply #13 on: Jul 14th, 2017, 1:30pm »

on Jul 14th, 2017, 12:41am, CirothUngol wrote:
Is this avoidable? It's really the only reason I'm hesitant to use it

It's understandable that the buffer size cannot be a variable (it's declaring a static buffer rather than a dynamic object such as a string) but it would have been desirable for a Windows Constant to be accepted as well as a literal number. For whatever reason - you'd have to ask Carl why - only the latter is accepted in practice.

So it's not currently avoidable (LBB could in principle be adapted to accept a Windows Constant, as a language extension, but it won't at present). However I don't share your hesitancy; a constant is a constant so having to enter the numeric value rather than its symbolic form doesn't concern me other than from a readability standpoint.

If you want to avoid a mistake being made you could always do this:

Code:
    struct temp, path as char[260]
    if len(temp.struct) <> _MAX_PATH then print "Incorrect constant" : end 

Richard.
« Last Edit: Jul 14th, 2017, 2:45pm by Richard Russell » User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls