Jak odczytać dane z karty SD która nie ma systemu plików? Potrzebuje uzyskać wskaźnik na początek karty i czytać bajt po bajcie.
Windows czy Linux?
Windows
Jakiś konkretny?
Zapewne trzeba będzie odwoływać się bezpośrednio do API systemu, więc ta informacja będzie przydatna.
Powiedzmy Windows XP
Potrzebuje uzyskać wskaźnik na początek karty
Jaki wskaźnik, LOL?
Co ty uważasz że dyski są mapowane do przestrzeni wirtualnej? :DDDD
Jak odczytać dane z karty SD która nie ma systemu plików?
Tak samo jak ta z systemem plików tylko używając API odpowiadającego za dostęp bez abstrakcji systemu plików. Powodzenia, zwłaszcza z przekonaniem że twoim celem jest 'wskaźnik'.
Nie potrzebuje koniecznie wskaźnika tylko dane w jakiejkolwiek postaci np. przepisane do tablicy.
Kod w C++. Najpierw pobiera uchwyt do woluminu, na którym zamontowana jest podana litera dysku. Otwiera go i pobiera identyfikator pierwszego dysku, na którym znajduje się wolumin. Po czym czyta z tego dysku pierwsze 1024 bajtów i z MBR pobiera typ pierwszej partycji.
#include <cstdio>
#include <Windows.h>
#include <tchar.h>
int main()
{
LPCTSTR mountPoint = TEXT("c:\\");
TCHAR volumeDevicePath[MAX_PATH] = { 0 };
GetVolumeNameForVolumeMountPoint(mountPoint, volumeDevicePath, ARRAYSIZE(volumeDevicePath));
size_t volumeDevicePathLength = _tcslen(volumeDevicePath);
volumeDevicePath[volumeDevicePathLength - 1] = '\0';
HANDLE volumeDeviceHandle = CreateFile(volumeDevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
VOLUME_DISK_EXTENTS extents;
DWORD returnedBytes;
DeviceIoControl(volumeDeviceHandle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extents, sizeof(extents), &returnedBytes, NULL);
DWORD diskNumber = extents.Extents[0].DiskNumber;
CloseHandle(volumeDeviceHandle);
TCHAR diskDevicePath[MAX_PATH] = { 0 };
_stprintf(diskDevicePath, TEXT("\\\\?\\PhysicalDrive%d"), diskNumber);
HANDLE diskDeviceHandle = CreateFile(diskDevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
SetFilePointer(diskDeviceHandle, 0, NULL, FILE_BEGIN);
BYTE buffer[1024];
DWORD bytesRead;
DWORD returnValue = ReadFile(diskDeviceHandle, buffer, 1024, &bytesRead, NULL);
BYTE partitionIdentifier = buffer[446 + 4];
CloseHandle(diskDeviceHandle);
if(partitionIdentifier == 0x07)
printf("pierwsza partycja na dysku to IFS, HPFS, NTFS albo exFat\n");
return 0;
}
Tutaj przetłumaczony na Pascala kod @Rev:
Uses Windows, SysUtils;
function GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint: LPCTSTR;
lpszVolumeName: LPCTSTR; cchBufferLength: DWORD): BOOL; stdcall; external 'kernel32';
Type TCharArray = Array[0..MAX_PATH] of TCHAR;
Function Length(A: TCHARArray): Integer;
Begin
For Result := 0 To MAX_PATH Do
if (A[Result] = #0) Then
Exit;
End;
Var I : Integer;
mountPoint : LPCTSTR;
volumeDevicePath : TCHARArray;
volumeDeviceHandle : HANDLE;
extents : Record
NumberOfDiskExtents: DWORD;
Extents : Array[0..0] of Record
DiskNumber : DWORD;
StartingOffset: Int64;
ExtentLength : Int64;
End;
End;
returnedBytes : DWORD;
diskNumber : DWORD;
diskDevicePath : TCHARArray;
diskDeviceHandle : HANDLE;
buffer : Array[0..1024] of Byte;
bytesRead : DWORD;
partitionIdentifier: Byte;
Begin
mountPoint := 'c:\';
For I := 0 To MAX_PATH Do
volumeDevicePath[I] := #0;
GetVolumeNameForVolumeMountPointA(mountPoint, volumeDevicePath, MAX_PATH);
if not (GetLastError in [0, 234]) Then
Begin
Writeln('GetVolumeNameForVolumeMountPointA :: GetLastError = ', GetLastError, ' (device not found?)');
Readln;
Halt;
End;
volumeDevicePath[Length(volumeDevicePath)-1] := #0;
volumeDeviceHandle := CreateFile(volumeDevicePath, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, 0);
if (GetLastError <> 0) Then
Begin
Writeln('CreateFile :: GetLastError = ', GetLastError);
Readln;
Halt;
End;
DeviceIoControl(volumeDeviceHandle, 5636096, nil, 0, @extents, sizeof(extents), returnedBytes, nil);
if (GetLastError <> 0) Then
Begin
Writeln('DeviceIoControl :: GetLastError = ', GetLastError);
Readln;
Halt;
End;
diskNumber := extents.Extents[0].DiskNumber;
CloseHandle(volumeDeviceHandle);
diskDevicePath := '\\?\PhysicalDrive'+IntToStr(diskNumber);
diskDeviceHandle := CreateFile(diskDevicePath, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, 0);
SetFilePointer(diskDeviceHandle, 0, nil, FILE_BEGIN);
ReadFile(diskDeviceHandle, buffer, 1024, bytesRead, nil);
partitionIdentifier := buffer[446+4];
CloseHandle(diskDeviceHandle);
Writeln('partitionIdentifier = 0x', IntToHex(partitionIdentifier, 2));
if (partitionIdentifier = $07) Then
Writeln('Pierwsza partycja na dysku to IFS, HPFS, NTFS albo exFat.');
Readln;
Halt;
End.
U mnie wyświetla komunikat, więc chyba działa poprawnie :]
Edit: w poprzedniej wersji było "trochę" bug'ów - poprawione.