Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
API GetVolumeInformation
Message
 
 
À
19/04/2001 11:08:41
Information générale
Forum:
Visual FoxPro
Catégorie:
Fonctions Windows API
Divers
Thread ID:
00497258
Message ID:
00497429
Vues:
15
Doug,

I tried it and it gives an error about ccNull variable.

>Hi Fabian.
>
>>I'm trying to get a disk serial number using API GetVOlumeInformation.
>>It works fine when I get local drive's number (like c:\ or d:\ )
>>but it fails when I try to reach network drives (like \\server\c\ ).
>>I read in Microsoft FAQ that it is a bug of W95 and W98. They give a workaround example in c++ , but it was imposible for me to translate it to VFP because of the HANDLERS and the structured type it uses.
>
>Here's the code I use to do this. It's wrapped in a function that retrieves more than just the disk serial number, but you can alter this function as you see fit.
>
>Doug
>
*==============================================================================
>* Function:          GetVolumeInformation
>* Purpose:           Returns information about the specified volume
>* Author:            Doug Hennig, from code taken off MSDN
>* Copyright:         (c) 2001 Stonefield Systems Group Inc.
>* Last revision:     02/20/2001
>* 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
>
>* 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
>
>* 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 = Hex2Decimal(substr(lcFileInfo, 29, 4))
>            taArray[2] = lnVolumeSerialNumber
>        endif lnHandle >= 0
>    endif not empty(lcFileName)
>endif lnVolumeSerialNumber = 0
>return .T.
>
>*==============================================================================
>* Function:          Hex2Decimal
>* Purpose:           Converts a value in Intel format to a decimal value
>* Author:            Doug Hennig
>* Copyright:         (c) 1996 Stonefield Systems Group Inc.
>* Last Revision:     09/07/99
>* Parameters:        tcValue  - the value to convert
>*                    tlSigned - .T. if the value is signed
>* Returns:           the numeric value
>* Environment in:    none
>* Environment out:   none
>*==============================================================================
>
>lparameters tcValue, ;
>    tlSigned
>local lnDecimal, ;
>    lnLen, ;
>    lnI, ;
>    lnMSB, ;
>    lnMax
>lnDecimal = 0
>lnLen     = len(tcValue)
>for lnI = 1 to lnLen
>    lnDecimal = lnDecimal + asc(substr(tcValue, lnI, 1)) * 256 ^ (lnI - 1)
>next lnI
>if tlSigned
>    lnMSB = (lnLen * 8) - 1
>    if bittest(lnDecimal, lnMSB)
>        lnMax     = 2 ^ (lnMSB + 1)
>        lnDecimal = lnResult - lnMax
>    endif bittest(lnDecimal, lnMSB)
>endif tlSigned
>return lnDecimal
If it's not broken, fix it until it is.


My Blog
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform