*============================================================================== * Method: GetVolumeInformation * Status: Public * Purpose: Returns information about the specified volume * Author: Doug Hennig, from code taken off MSDN * Copyright: (c) 2001-2002 Stonefield Systems Group Inc. * Last revision: 04/02/2002 * Parameters: tcVolume - the volume to get information for * taArray - an array to hold information about the volume: * * Column Information * ------ ----------- * 1 Volume name * 2 Volume serial number * 3 File system name (FAT, NTFS, etc.) * 4 .T. if the file system supports case-sensitive * filenames * 5 .T. if the file system preserves case of filenames * 6 .T. if the file system supports Unicode filenames * 7 .T. if the file system preserves and enforces ACLs * (NTFS only) * 8 .T. if the file system supports file-based * compression * 9 .T. if the volume is compressed * 10 maximum filename length * * Returns: .T. * Environment in: none * Environment out: none *============================================================================== lparameters tcVolume, ; taArray local lcVolume, ; lcVolumeName, ; lnVolumeNameLen, ; lnVolumeSerialNumber, ; lnMaxFileNameLen, ; lnFileSystemFlags, ; lcFileSystemName, ; lnFileSystemNameLen, ; lcFileInfo, ; lcFileName, ; laFiles[1], ; lnFiles, ; lnI, ; lcFile, ; lnHandle #define ccNULL chr(0) #define cnFS_CASE_SENSITIVE 0 #define cnFS_CASE_IS_PRESERVED 1 #define cnFS_UNICODE_STORED_ON_DISK 2 #define cnFS_PERSISTENT_ACLS 3 #define cnFS_FILE_COMPRESSION 4 #define cnFS_VOL_IS_COMPRESSED 15 * Declare the API function and constants. declare GetVolumeInformation in Win32API ; string lpRootPathName, string @lpVolumeNameBuffer, ; integer nVolumeNameSize, integer @lpVolumeSerialNumber, ; integer @lpMaximumComponentLength, integer @lpFileSystemFlags, ; string @lpFileSystemNameBuffer, integer nFileSystemNameSize * If the path wasn't specified, use the current drive. Otherwise, get the drive * for the specified path, handling UNC paths specially. do case case vartype(tcVolume) <> 'C' or empty(tcVolume) lcVolume = addbs(sys(5)) case left(tcVolume, 2) = '\\' lcVolume = addbs(tcVolume) lcVolume = left(lcVolume, at('\', lcVolume, 4)) case len(tcVolume) = 1 lcVolume = tcVolume + ':\' otherwise lcVolume = addbs(justdrive(tcVolume)) endcase if empty(lcVolume) lcVolume = addbs(sys(5)) endif empty(lcVolume) * Create the parameters for the API function, then call it. lcVolumeName = space(255) lnVolumeNameLen = len(lcVolumeName) lnVolumeSerialNumber = 0 lnMaxFileNameLen = 0 lnFileSystemFlags = 0 lcFileSystemName = space(255) lnFileSystemNameLen = len(lcFileSystemName) GetVolumeInformation(lcVolume, @lcVolumeName, lnVolumeNameLen, ; @lnVolumeSerialNumber, @lnMaxFileNameLen, @lnFileSystemFlags, ; @lcFileSystemName, lnFileSystemNameLen) * Put the information into the array. dimension taArray[10] taArray[ 1] = left(lcVolumeName, at(ccNULL, lcVolumeName) - 1) taArray[ 2] = lnVolumeSerialNumber taArray[ 3] = left(lcFileSystemName, at(ccNULL, lcFileSystemName) - 1) taArray[ 4] = bittest(lnFileSystemFlags, cnFS_CASE_SENSITIVE) taArray[ 5] = bittest(lnFileSystemFlags, cnFS_CASE_IS_PRESERVED) taArray[ 6] = bittest(lnFileSystemFlags, cnFS_UNICODE_STORED_ON_DISK) taArray[ 7] = bittest(lnFileSystemFlags, cnFS_PERSISTENT_ACLS) taArray[ 8] = bittest(lnFileSystemFlags, cnFS_FILE_COMPRESSION) taArray[ 9] = bittest(lnFileSystemFlags, cnFS_VOL_IS_COMPRESSED) taArray[10] = lnMaxFileNameLen * If the serial number is 0 (which happens with Win95/98 systems on remote * drives), open a file on the drive and get the file information for it. if lnVolumeSerialNumber = 0 declare GetFileInformationByHandle in Win32API ; integer lnHandle, string @lcFileInfo declare integer CreateFile in Win32API ; string @lcFileName, integer dwDesiredAccess, ; integer dwShareMode, integer lpSecurityAttributes, ; integer dwCreationDisposition, integer dwFlagsAndAttributes, ; integer hTemplateFile declare CloseHandle in Win32API ; integer lnHandle lcFileInfo = space(255) * If a file was specified for the volume name, use it. Otherwise, find some * file we can open. if file(tcVolume) lcFileName = tcVolume else lnFiles = adir(laFiles, lcVolume + '*.*') lcFileName = '' for lnI = 1 to lnFiles lcFile = lcVolume + laFiles[lnI, 1] lnHandle = fopen(lcFile) fclose(lnHandle) if lnHandle >= 0 lcFileName = lcFile exit endif lnHandle >= 0 next lnI endif file(tcVolume) if not empty(lcFileName) lnHandle = CreateFile(@lcFileName, 0, 0, 0, 3, 0, 0) if lnHandle >= 0 GetFileInformationByHandle(lnHandle, @lcFileInfo) CloseHandle(lnHandle) lnVolumeSerialNumber = This.Hex2Decimal(substr(lcFileInfo, 29, 4)) taArray[2] = lnVolumeSerialNumber endif lnHandle >= 0 endif not empty(lcFileName) endif lnVolumeSerialNumber = 0 return .T.