먼저 내가 바보라고 말하면 용서해주십시오. IT 엔지니어는 아니지만 전자 기술자입니다.하지만 더 많은 기술을 필요로하는 것에 할당되었습니다.SetFilePointer가 실패하지 않고 포인터도 이동하지 않습니다.
SD 카드에 물리적 섹터를 쓰고 읽어야합니다. C++로 완성했지만 주요 응용 프로그램은 C#으로 작성되었으므로 첫 번째 dll을 작성하는 것이 좋은 순간이라고 생각했습니다.
다음은 섹터 작성을 위해 C++에서 작동하는 코드입니다.
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);
}
그럼 DLL을 만들었습니다.
[DllImport("AccesoBajoNivel.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int EscribeBloqueFisico(char numeroDisco, byte[] buffer, long BytesQueEscribir, long posicion_inicio);
가 그럼이 함수를 호출 : :
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);
}
그런 다음 나는 C# 프로젝트에 수입 : 기능이있다
int ResultEscribir = EscribeBloqueFisico(numeroDiscoFisico, BufferEscritura, 512, SectorEscribir * 512);
항상 첫 번째 섹터에 기록을 상관없이 값 "posicion_inicio"(시작 오프셋, spanish 태그에 대해 미안합니다.) 그래서 api에서 쓰기 기능을 변경하여 dwPtr (Result of SetFilePointer)를 작성한 바이트 대신 반환했습니다. 이것은 항상 제로 인 것처럼 보이는데, 그것은 분명히 내가 원하는 것이 아닙니다. 그러나 첫 번째 함수가 작동하고 dll 호출이 왜 작동하지 않는지 알 수 없습니다.
어쩌면 처음 눈에 볼 수 있어야 뭔가이지만, 내가 말했듯이, 나는 작업 (읽기 DISK_GEOMETRY 또는 VOLUME_DISK_EXTENTS으로) ... 전자는 사람, 프로그램의 종류에 익숙하지
다른 기능을 오전, 어떤 물리적 드라이브가 주어진 논리 단위인지 결정하는 데 사용됩니다. 제가 말했듯이, 글쓰기와 읽기가 잘 작동한다는 것은 제가 항상 섹터 0을 가리키고 있다는 것입니다 ...
미리 감사드립니다. 또한, 내가 여기에 게시하는 것은 이번이 처음이다. 여러 번 읽음 (이 때문에 내가 여기서 물어보기로 했음)하지만 질문을 게시 할 때 실수를했다면 지적 해주십시오.
대단히 감사합니다. (C++에서 int로 선언하면 C++에서 길었던 것이므로) 문제가 해결되었습니다. 또한 관리되지 않는 코드 디버깅에 대한 힌트를 주셔서 감사합니다. 이제 의도 한대로 작동합니다. 이 언어로 전환 할 때 데이터 유형에주의를 기울여야한다고 생각합니다. 다시 한 번 감사드립니다! 제발 내 영어를 용서해주세요 :) 편집 : 그렇게하기 위해 평판이 필요하다고 생각되는 것처럼 대답을 투표 할 수 없습니다. – JeToMad
** Microsoft Visual C++ **의 'long'은 기술적으로 32 비트입니다. IIRC, Linux/G ++에서 C#처럼 자주 64 비트입니다. – MSalters