Bestimmung der Partitionsgröße schlägt fehl
-
Ich versuch unter Vista die Größe der einzelnen Laufwerke zu ermitteln. Mein Compiler ist VS2005. Vista läuft mit UAC und meine Anwendung wird mit Administratorrechten gestartet (Rechte-Maustaste: "Als Administrator ausführen"). Der Aufruf "DeviceIoControl" schlägt fehl und als Errorcode wird "5" zurückgegeben, was bedeutet "Access is denied.". Kann mir jemand weiterhelfen und mir sagen was ich falsch mache? Eine alternative Methode um die Partitionsgröße zu bestimmen wäre auch ok, aber das Problem hätte ich der Vollständigkeit halber schon gerne gelöst.
boolean GetDiskSize(char driveletter, LONGLONG *disksize){ char driveBuffer[16]; HANDLE hDevice; DWORD BytesReturned; GET_LENGTH_INFORMATION sizeInfo; sprintf(driveBuffer, "\\\\.\\%c:", driveletter); hDevice = CreateFile(driveBuffer, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE){ OUTPUT(va("Error CreateFile: %i", GetLastError())); return FALSE; } if(DeviceIoControl(hDevice, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &sizeInfo, sizeof(sizeInfo), &BytesReturned, 0) == 0){ OUTPUT(va("Error DeviceIoControl: %i", GetLastError())); CloseHandle(hDevice); return FALSE; } CloseHandle(hDevice); OUTPUT(va("Disksize: %I64d", sizeInfo.Length.QuadPart)); *disksize = sizeInfo.Length.QuadPart; return TRUE; }
-
Warum so umständlich? Wie wäre es mit GetDiskFreeSpaceEx?
-
_Luckie schrieb:
Warum so umständlich? Wie wäre es mit GetDiskFreeSpaceEx?
weil die MSDN folgendes zu der Funktion "GetDiskFreeSpaceEx" sagt:
lpTotalNumberOfBytes [out] A pointer to a variable that receives the total number of bytes on a disk that are available to the user who is associated with the calling thread. This parameter can be NULL. Windows Me/98/95: This parameter cannot be NULL. If per-user quotas are being used, this value may be less than the total number of bytes on a disk. To determine the total number of bytes on a disk or volume, use IOCTL_DISK_GET_LENGTH_INFO.
-
Wenn ich den CreateFile Aufruf wiel folgt ändere, funktioniert dein Code vom Prinzip her bei mir:
hDevice = CreateFile( TEXT("\\\\.\\HarddiskVolume1") , GENERIC_READ , FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY , NULL);Edit:
Im Prinzip heißt:#include <windows.h> boolean GetDiskSize( TCHAR *driveletter, LONGLONG *disksize){ HANDLE hDevice; DWORD BytesReturned; GET_LENGTH_INFORMATION sizeInfo; TCHAR cDosDeviceBuff[MAX_PATH] ; TCHAR cDevicePath[MAX_PATH] ; QueryDosDevice( driveletter , cDosDeviceBuff , MAX_PATH - 1 ); wsprintf( cDevicePath , _T( "\\\\.\\%s" ) , &cDosDeviceBuff[8] ) ; _tprintf( _T("%s = %s\n") , driveletter , cDevicePath ); hDevice = CreateFile( cDevicePath , GENERIC_READ , FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY , NULL) ; if (hDevice == INVALID_HANDLE_VALUE){ _tprintf( _T("InvalidHandle Error:%d\n") , GetLastError() ) ; return FALSE; } if(!DeviceIoControl(hDevice, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &sizeInfo, sizeof(sizeInfo), &BytesReturned, 0)){ _tprintf( _T("ERROR %d\n") ,GetLastError() ); CloseHandle(hDevice); return FALSE; } CloseHandle(hDevice); *disksize = sizeInfo.Length.QuadPart; return TRUE; } int _tmain(int argc, _TCHAR* argv[]) { LONGLONG disksize ; TCHAR letter[] = _T("D:") ; GetDiskSize( letter , &disksize ); _tprintf( _T( "%lld\n" ) , disksize ); return 0; }
-
theHorst schrieb:
Wenn ich den CreateFile Aufruf wiel folgt ändere, funktioniert dein Code vom Prinzip her bei mir:
hDevice = CreateFile( TEXT("\\\\.\\HarddiskVolume1") , GENERIC_READ , FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY , NULL);Danke für den Hinweis, mit diesem Aufruf und Administratorrechten klappt es jetzt für alle Laufwerke ausser für meine alte 1,44MB Floppy. "DeviceIoControl" gibt mir da den Errorcode "1" (Incorrect function) zurück.
Hat jemand eine Erklärung warum das nicht funktioniert? (Diskette ist im Laufwerk und der Schreibschutz ist draussen)
-
-
Die Einschränkung von GetDiskFreeSpaceEx gilt doch nur für Windows 9x oder verstehe ich da die Hilfe falsch? Und Windows 9x würde ich so wie so nicht mehr unterstützen und die Einschränkung hinnehmen.