這是為什么呢?熟悉Win32 API編程的人都知道,在用VB編程時(shí),我們可以用相應(yīng)的API函數(shù)來(lái)獲得有關(guān)系統(tǒng)的硬盤的信息,會(huì)不會(huì)是錯(cuò)在API的調(diào)用函數(shù)呢?想到這里我用自編的程序來(lái)查看PC Alert的有關(guān)文件,發(fā)現(xiàn)其調(diào)用了GetDiskFreeSpace函數(shù),問(wèn)題就出在這個(gè)函數(shù)上。下面是該函數(shù)的參數(shù)說(shuō)明:Byval lpRootPathName As String(為欲查看的分區(qū)的根路徑如C:\) ,lpSectorsPerCluster As Long(為一簇的扇區(qū)數(shù)), lpBytesPerSector As Long(為每一扇區(qū)的字節(jié)數(shù)), lpNumberOfFreeClusters As Long(當(dāng)前分區(qū)中未使用的簇?cái)?shù)), lpTotalNumberOfClusters As Long(總的簇?cái)?shù)) As Long。當(dāng)我們調(diào)用此函數(shù)時(shí),是以lpBytesPerSector×lpSectorsPerCluster×TotalNumberOfClusters來(lái)計(jì)算分區(qū)總的大小的,在VB中我用來(lái)查看自己的C盤時(shí)返回值分別為512 、64、 65526,因而計(jì)算出的C盤的大小只有2.05G。
以下是關(guān)于MSDN中的有關(guān)詳細(xì)說(shuō)明:對(duì)于大于的2G分區(qū),GetDiskFreeSpace函數(shù)可能(什么可能,是一定?。┓祷劐e(cuò)誤的值,此時(shí)函數(shù)會(huì)屏蔽存在lpNumberOfFreeClusters及l(fā)pTotalNumberOfClusters中的值,因此建議不要用該函數(shù)來(lái)獲得大于2G分區(qū)的信息。對(duì)于大于2G的分區(qū)應(yīng)當(dāng)使用GetDiskFreeSpaceEx函數(shù)(從Win95 OEM OSR2開(kāi)始),此函數(shù)可以返回分區(qū)的有關(guān)正確信息。
找到了問(wèn)題所在便可以對(duì)癥下藥了,即用GetDiskFreeSpaceEx函數(shù)代替GetDiskFreeSpace函數(shù)即可。以下是GetDiskFreeSpaceEx函數(shù)中所要傳遞增的參數(shù)
lpRootPathName String ,不包括卷名的磁盤根路徑名
lpFreeBytesAvailableToCaller LARGE_INTEGER,指定一個(gè)變量,用于容納調(diào)用者可用的字節(jié)數(shù)量
lpTotalNumberOfBytes LARGE_INTEGER ,指定一個(gè)變量,用于容納磁盤上的總字節(jié)數(shù)
lpTotalNumberOfFreeBytes LARGE_INTEGER,指定一個(gè)變量,用于容納磁盤上可用的字節(jié)數(shù)
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
我們可以看到LARGE_INTEGER是一個(gè)由兩個(gè)long型組成的一個(gè)類型,兩個(gè)long組成表示的都是無(wú)符號(hào)的數(shù),在轉(zhuǎn)換時(shí)應(yīng)當(dāng)定義一個(gè)single型的變量,使其等于highpart*(2^32-1) + lowpart,注意此處的兩個(gè)long型相當(dāng)于C/C++中的無(wú)符號(hào)型整數(shù)類型,因?yàn)樵赩B中不存在此種類型,故而在換算時(shí)要處理好轉(zhuǎn)換關(guān)系。我本人的做法是首先判斷l(xiāng)ong型變量的正負(fù),如是正直接相乘,如是負(fù)則用2^32-1減去該值再相乘(具體算法詳見(jiàn)下面的代碼)。
Option Explicit
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function GetDiskFreeSpace Lib "kernel32" Alias "GetDiskFreeSpaceA" (ByVal lpRootPathName As String, lpSectorsPerCluster As Long, lpBytesPerSector As Long, lpNumberOfFreeClusters As Long, lpTotalNumberOfClusters As Long) As Long
Private Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias "GetDiskFreeSpaceExA" _
(ByVal lpRootPathName As String, lpFreeBytesAvailableToCaller As LARGE_INTEGER, _
lpTotalNumberOfBytes As LARGE_INTEGER, lpTotalNumberOfFreeBytes _
As LARGE_INTEGER) As Long
Private Sub Command1_Click()
Dim lngSectors&
Dim lngTotalCluster&
Dim lngFreeCluster&
Dim lngPerCluster&
Dim lngperBytes&
Dim lngSize#
GetDiskFreeSpace "c:\", lngPerCluster, lngperBytes, lngFreeCluster, lngTotalCluster
MsgBox CStr(lngTotalCluster * lngperBytes * lngPerCluster)
Debug.Print lngTotalCluster, lngperBytes, lngPerCluster
End Sub
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function GetDiskFreeSpace Lib "kernel32" Alias "GetDiskFreeSpaceA" (ByVal lpRootPathName As String, lpSectorsPerCluster As Long, lpBytesPerSector As Long, lpNumberOfFreeClusters As Long, lpTotalNumberOfClusters As Long) As Long
Private Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias "GetDiskFreeSpaceExA" _
(ByVal lpRootPathName As String, lpFreeBytesAvailableToCaller As LARGE_INTEGER, _
lpTotalNumberOfBytes As LARGE_INTEGER, lpTotalNumberOfFreeBytes _
As LARGE_INTEGER) As Long
Private Sub Command1_Click()
注釋:用GetDiskFreeSpace得到錯(cuò)誤的容量
Dim lngSectors&
Dim lngTotalCluster&
Dim lngFreeCluster&
Dim lngPerCluster&
Dim lngperBytes&
Dim lngSize#
GetDiskFreeSpace "c:\", lngPerCluster, lngperBytes, lngFreeCluster, lngTotalCluster
MsgBox CStr(lngTotalCluster * lngperBytes * lngPerCluster)
End Sub
Private Sub cmdStart_Click()
注釋:用GetDiskFreeSpaceEx得到正確的容量
Dim lngFreeCaller As LARGE_INTEGER
Dim lngTotal As LARGE_INTEGER
Dim lngTotalFree As LARGE_INTEGER
Dim sngSize#
GetDiskFreeSpaceEx "c:\", lngFreeCaller, lngTotal, lngTotalFree
注釋:以下用來(lái)顯示出分區(qū)總?cè)萘?以G為單位)
MsgBox GetSize(lngTotal) / 2 ^ 30
End Sub
Private Function GetSize(lngSize As LARGE_INTEGER) As Single
注釋:用來(lái)從LARGE_INTEGER型變量中換算出實(shí)際的大小
With lngSize
If .highpart < 0 Then
GetSize = (2 ^ 32 - 1 - .highpart) * (2 ^ 32 - 1)
Else
GetSize = .highpart * (2 ^ 32 - 1)
End If
If .lowpart < 0 Then
GetSize = GetSize + (2 ^ 32 - 1 - .lowpart)
Else
GetSize = GetSize + .lowpart
End If
End With
End Function
Private Function GetSize(lngSize As LARGE_INTEGER) As Single
注釋:用來(lái)從LARGE_INTEGER型變量中換算出實(shí)際的大小
With lngSize
If .highpart < 0 Then
GetSize = (2 ^ 32 - 1 - .highpart) * (2 ^ 32 - 1)
Else
GetSize = .highpart * (2 ^ 32 - 1)
End If
If .lowpart < 0 Then
GetSize = GetSize + (2 ^ 32 - 1 - .lowpart)
Else
GetSize = GetSize + .lowpart
End If
End With
End Function
從LARGE_INTEGER的定義來(lái)看,應(yīng)用此函數(shù)理論上可得到2^64/2^30=2^34G的分區(qū)的大小,不知這輩子能否用上這么大的硬盤.