In this code I don't understand how the records IngLower and IngUpper of the LargeInt type are populated. For instance, if I add udtFreeBytesAvail to the watch list and set a breakpoint at the 16th line the records of udtFreeBytesAvail become populated, I know it's because of the parameters of the API function GetDiskFreeSpaceEx, but I don't understand why both records become populated, and not just one for example. And also why both records have different values. I appreciate your help, and sorry if my problem is not well described as I'm new to programming.
Public Type LargeInt
lngLower As Long
lngUpper As Long
End Type
Public Declare Function GetDiskFreeSpaceEx Lib "kernel32.dll" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName As String, lpFreeBytesAvailableToCaller As LargeInt, lpTotalNumberOfBytes As LargeInt, lpTotalNumberofFreeBytes As LargeInt) As Long
Public Function FreeDiskSpace(ByVal sDriveLetter As String) As Double
Dim udtFreeBytesAvail As LargeInt, udtTtlBytes As LargeInt
Dim udtTTlFree As LargeInt
Dim dblFreeSpace As Double
If GetDiskFreeSpaceEx(sDriveLetter, udtFreeBytesAvail, udtTtlBytes, udtTTlFree) Then
If udtFreeBytesAvail.lngLower < 0 Then
dblFreeSpace = udtFreeBytesAvail.lngUpper * 2 ^ 32 + udtFreeBytesAvail.lngLower + 4294967296#
Else
dblFreeSpace = udtFreeBytesAvail.lngUpper * 2 ^ 32 + udtFreeBytesAvail.lngLower
End If
End If
FreeDiskSpace = dblFreeSpace
End Function
Other already explained it, but as you still seem to struggle to understand why it works, let me try and clarify this:
The UDT "keeps" its members (the 2 Long integers in this case) in a consecutive memory location, the 1st byte of lngUpper directly follows the last byte of lngLower, occupying in total 8 bytes (=64 bits) consecutive memory. The API GetDiskFreeSpaceEx writes 64 consecutive bits at the start of the variables provided to it as lpFreeBytesAvailableToCaller etc. Hence it "fills out" both 32 bit Long variables of the UDT.