I am trying to get the correct file size of entire directories, however the results I am getting don't make any sense.
Here is a stripped down copy of my code.
$MAIN
AUTODEFINE "off"
DEF run, cd, i, j, k:INT
DEF handle[30]:UINT
DEF dSize[30]:UINT64
DEF dir[260]:ISTRING
TYPE filetime
	DEF qwtime:UINT64
ENDTYPE
TYPE WIN32_FIND_DATA
	DEF dwFileAttributes AS INT
	DEF ftCreationTime AS FILETIME
	DEF ftLastAccessTime AS FILETIME
	DEF ftLastWriteTime AS FILETIME
	DEF nFileSizeHigh AS UINT
	DEF nFileSizeLow AS UINT
	DEF dwReserved0 AS INT
	DEF dwReserved1 AS INT
	DEF cFileName[MAX_PATH] AS ISTRING
	DEF cAlternate[14] AS ISTRING
ENDTYPE
FOR i = 0 TO 29
	handle[i] = 0
	dsize[i] = 0
NEXT i
OPENCONSOLE
dir = "C:\\Users\\BillH\\Movies\\VIDEO_TS\\"
cd = 0
GetFiles(dir)
PRINT "Press Enter to End"
INPUT k
CLOSECONSOLE
END
SUB GetFiles(path:STRING)
DEF dir, attrib:INT
DEF filename = "":STRING
DEF tSize = 0, Size = 0:UINT64
dir = FINDOPEN(path + "*.*")
IF (dir)
	DO
		filename = FINDNEXT(dir,attrib)
		IF len(filename)
			IF (attrib & @file_directory)
				IF (filename = ".") OR (filename = "..")
					filename = "x"
				ELSE
					cd++
					dsize[cd] = 0
					GetFiles(path + filename + "\\")
				ENDIF
			ELSE
'				Size = *<WIN32_FIND_DATA>dir.nFileSizeLow + 256q * *<WIN32_FIND_DATA>dir.nFileSizeHigh
				Size = ((*<WIN32_FIND_DATA>dir.nFileSizeHigh << 32) | *<WIN32_FIND_DATA>dir.nFileSizeLow)
				PRINT filename," ",USING("%q###,###,###,###,###",Size)
				tSize += Size
			ENDIF
		ENDIF
	UNTIL filename = ""
	FINDCLOSE dir
ENDIF
dsize[cd] += tSize
PRINT path," ",USING("%q###,###,###,###,###",dsize[cd])," ",cd
cd--
dsize[cd] += tSize
RETURN
ENDSUBThe results this prints is:
QuoteVIDEO_TS.BUP            8,192
VIDEO_TS.IFO           73,728
VTS_01_0.BUP           73,728
VTS_01_0.IFO      1,072,801,792
VTS_01_1.VOB      1,072,875,520
VTS_01_2.VOB       214,685,696
VTS_01_3.VOB       214,685,696
C:\Users\BillH\Movies\VIDEO_TS\      2,575,204,352 0
Press Enter to End
But when I do a standard DIR from DOS Window, I get:
QuoteDirectory of C:\Users\BillH\Movies\VIDEO_TS
12/23/2010  05:35 PM    <DIR>          .
12/23/2010  05:35 PM    <DIR>          ..
12/23/2010  05:35 PM             8,192 VIDEO_TS.BUP
12/23/2010  05:35 PM             8,192 VIDEO_TS.IFO
12/23/2010  05:35 PM            73,728 VTS_01_0.BUP
12/23/2010  05:35 PM            73,728 VTS_01_0.IFO
12/23/2010  05:24 PM     1,072,801,792 VTS_01_1.VOB
12/23/2010  05:34 PM     1,072,875,520 VTS_01_2.VOB
12/23/2010  05:35 PM       214,685,696 VTS_01_3.VOB
               7 File(s)  2,360,526,848 bytes
The File sizes do not match.  Maybe some one else could take a look at what I am doing and maybe see what I messed up.
Thanks,
Bill
			
				Hi billhsln, the problem lies at the alignment of your filetime structure. It can't be defined as int64 here, because int64 in structures will be automatically aligned to 8 byte boundary. You can replace int64 with two integers, or force 4 byte alignment in the finddata structure:TYPE WIN32_FIND_DATA,4Or just include windowssdk.inc :)
			
			
			
				Changed:
TYPE filetime
   DEF dwLowDateTime:INT
   DEF dwHighDateTime:INT
ENDTYPE
first and then after that did not fix the problem, then tried:
TYPE WIN32_FIND_DATA,4
still returns the same bad results.
Thanks,
Bill
			
			
			
				Got it, it seems to be invalid use of my previous "trick":
SUB GetFiles(path:STRING)
	DEF dir:INT
	DEF tSize = 0, Size = 0:UINT64
	dir = FINDOPEN(path + "*.*")
	while (dir)
		IF (*<WIN32_FIND_DATA>dir.dwFileAttributes & @FILE_DIRECTORY)
			IF (*<WIN32_FIND_DATA>dir.cFileName = ".") OR (*<WIN32_FIND_DATA>dir.cFileName = "..")
				'filename = "x"
			ELSE
				cd++
				dSize[cd] = 0
				GetFiles(path + *<WIN32_FIND_DATA>dir.cFileName + "\\")
			ENDIF
		ELSE
			Size = *<WIN32_FIND_DATA>dir.nFileSizeLow + (4294967296q * *<WIN32_FIND_DATA>dir.nFileSizeHigh)
			PRINT *<WIN32_FIND_DATA>dir.cFileName," ",USING("%q###,###,###,###,###",Size)
			tSize += Size
		ENDIF
		istring temp[MAX_PATH] = FINDNEXT(dir)
		if (!*<WIN32_FIND_DATA>dir.cFileName[0])
			FINDCLOSE(dir)
			dir = 0
		endif
	ENDWHILE
	dSize[cd] += tSize
	PRINT path," ",USING("%q###,###,###,###,###",dSize[cd])," ",cd
	cd--
	dSize[cd] += tSize
	RETURN
ENDSUB
			
			
			
				The file size is not exactly 100% of the problem.
Both VIDEO_TS.BUP  and VIDEO_TS.IFO should be  8,192, which is the correct size for both.
My problem is that the file size does not match the file.
Bill
			
			
			
				The construction of your loop was wrong, because FINDOPEN actually returns initialized WIN32_FIND_DATA for the first file, and after you entered do-while loop and called FINDNEXT, the file name returned from FINDNEXT did not matched the properties in WIN32_FIND_DATA, which was already initialized for the next file. If you want to cast dir variable to WIN32_FIND_DATA, you must follow the rules from my example code, and ignore the string and attributes from FINDNEXT. FINDOPEN calls FindFirstFile, copies file name and its attributes to a buffer, so they can be returned in the next call to FINDNEXT. FINDNEXT calls FindNextFile, returns the previously saved file nams and attributes, then copies new file name to buffer.
dir = FINDOPEN
  dir = WIN32_FIND_DATA with first file.
name = FINDNEXT
  name = first file.
  dir = WIN32_FIND_DATA with the second file.
			
			
			
				Bill,
I substituted Sapero's GetFiles routine above for yours and it works like it is suppose to.
LarryMc
			
			
			
				Thanks, Sapero and Larry.  I am now using Sapero's code and it working perfectly.  Seems it is a correct understanding of how the FINDOPEN/FINDNEXT works.  Thanks for all your help.
Will upload the final product, when I get it done.
I know there is a Utility (DirSize 32), which does exactly what I am trying to do, but I want to learn how to use TreeView controls.
Thanks again,
Bill