Jak odczytać dysk (kartę SD) bez systemu plików.

0

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.

0

Windows czy Linux?

0

Windows

0

Jakiś konkretny?
Zapewne trzeba będzie odwoływać się bezpośrednio do API systemu, więc ta informacja będzie przydatna.

0

Powiedzmy Windows XP

1

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'.

0

Nie potrzebuje koniecznie wskaźnika tylko dane w jakiejkolwiek postaci np. przepisane do tablicy.

2

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;
}
2

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1