SetFilePointer nie zawodzi, ale również nie przesuwa wskaźnika

Po pierwsze, proszę mi wybaczyć, jeśli powiem coś głupiego, nie jestem facetem z branży IT, ale inżynierem elektroniką, ale zostałem przydzielony do czegoś, co wymaga więcej umiejętności niż ja.

Muszę pisać i odczytywać sektory fizyczne na karcie SD. Osiągnąłem to w C ++, ale główna aplikacja napisana jest w C #, więc pomyślałem, że to dobry moment na napisanie mojego pierwszego dll.

Oto kod działający w c ++ do pisania sektora.

private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {
HANDLE hFile   = INVALID_HANDLE_VALUE;
    BOOL fSuccess  = FALSE;


    DWORD dwBytesWritten = 0; 

    unsigned char  chBuffer[SIZE]; 

    long SectorActual = 39;
    long PosicionInicio = SectorActual * 512;

        for (int i=0; i<SIZE; i++) // Garbage values to be written
        {
            chBuffer[i]= i % 16;
            if((i/16)%2==0)
            {
                chBuffer[i]= 15 - chBuffer[i];
            }
        }
        hFile = CreateFileA("\\\\.\\PhysicalDrive5",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

        if (hFile == INVALID_HANDLE_VALUE) 
        { 
            textBox1->Text += "Could not open file (error " + GetLastError() + ") \r\n";
            return; 
        }

        DWORD dwPtr = SetFilePointer( hFile, 
                                PosicionInicio, 
                                NULL, 
                                FILE_BEGIN ); 

        if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
        { 
            textBox1->Text += "Error moving pointer (error " + GetLastError() + ") \r\n";
            return;     // Deal with failure 
        } // End of error handler 

        fSuccess = WriteFile(hFile, chBuffer, TAMANYO_SECTOR, &dwBytesWritten, NULL); 
        if (!fSuccess) 
        {
            textBox1->Text += "WriteFile failed\r\n";
        }
        else
        {
            textBox1->Text += "WriteFile wrote " + dwBytesWritten.ToString() + " bytes\r\n";
        }

        CloseHandle(hFile);
    }

Potem stworzyłem DLL. Funkcja jest taka:

 int AccesoBajoNivel::EscribeBloqueFisico(char numeroDisco, unsigned char * buffer, long      BytesQueEscribir, long posicion_inicio)
{
    HANDLE hFile   = INVALID_HANDLE_VALUE;
            BOOL fSuccess  = FALSE;
    DWORD dwBytesWritten = 0; 

    char ArrayDeChars[] = "\\\\.\\PhysicalDrive5";
            ArrayDeChars[17] = numeroDisco;
    LPCSTR pathAlDisco = ArrayDeChars;

    hFile = CreateFileA(pathAlDisco,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    if (hFile == INVALID_HANDLE_VALUE) 
    { 
        //printf("Could not open file (error %d)\n", GetLastError());
        CloseHandle(hFile);
        return -1; 
    }

    DWORD dwPtr = SetFilePointer( hFile, 
                            posicion_inicio, 
                            NULL, 
                            FILE_BEGIN ); 

    if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
    { 
        CloseHandle(hFile);
        return -2;     // Deal with failure 
    } // End of error handler 

    fSuccess = WriteFile(hFile, buffer, BytesQueEscribir, &dwBytesWritten, NULL); 
    if (!fSuccess) 
    {
        CloseHandle(hFile);
        return -3;
    }
    else
    {
        CloseHandle(hFile);
        //return dwBytesWritten;
        return dwPtr;
    }

    CloseHandle(hFile);
}

Następnie zaimportowałem projekt C #:

[DllImport("AccesoBajoNivel.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int EscribeBloqueFisico(char numeroDisco, byte[] buffer, long BytesQueEscribir, long posicion_inicio);

Następnie wywołuję funkcję:

int ResultEscribir = EscribeBloqueFisico(numeroDiscoFisico, BufferEscritura, 512, SectorEscribir * 512);

Zawsze zapisuje do pierwszego sektora, bez względu na wartość „posicion_inicio” (Jest to przesunięcie początkowe, przepraszam za hiszpańskie znaczniki). Dlatego zmieniłem funkcję zapisu w api, aby zwracała dwPtr (Result of SetFilePointer) zamiast zapisanych bajtów . Zawsze wydaje się to być zero, co oczywiście nie jest tym, czego chcę. Ale nie mogę zrozumieć, dlaczego pierwsza funkcja działa, a dll nie.

Może jest to coś, co powinno być widoczne na pierwszy rzut oka, ale jak powiedziałem, jestem facetem od elektroniki, nie przyzwyczajonym do tego rodzaju programowania ...

Działają inne funkcje (takie jak czytanie DISK_GEOMETRY lub VOLUME_DISK_EXTENTS), których używam do określenia, który dysk fizyczny jest daną jednostką logiczną. Jak mówię, również pisanie i czytanie działają dobrze, po prostu zawsze wskazuję na sektor zero ...

Z góry dziękuję. Również po raz pierwszy publikuję tutaj. Czytałem wiele razy (dlatego zdecydowałem się zapytać tutaj), ale jeśli popełniłem jakiś błąd podczas publikowania pytania, proszę to zaznaczyć.

questionAnswers(1)

yourAnswerToTheQuestion