Author |
Topic: Windows disk volume name and serial number? (Read 460 times) |
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
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.
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
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.
|
|
|
|
CirothUngol
New Member
member is offline

Odie, Odie, cha cha cha.

Gender: 
Posts: 44
|
 |
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.
|
|
Logged
|
LB Booster + LB Workshop + LB Builder = My Programs on Google Drive
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
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.
|
|
|
|
|