У меня есть это решение. < /p>
mnwe - (минимальный пример неработающего) < /h4>
Chatgpt дал мне следующее тестовое приложение: < /p>
Код: Выделить всё
#include
#include
#define DEVICE_PATH "\\\\.\\MemoryGraveyard"
#define BUFF_SIZE 1024
__declspec(align(512)) BYTE readBuffer[BUFF_SIZE];
void readWithOverlapped(HANDLE device, DWORD offset, DWORD length) {
OVERLAPPED overlapped = { 0 };
overlapped.Offset = offset;
overlapped.OffsetHigh = 0;
DWORD bytesRead = 0;
printf("[INFO] Reading with OVERLAPPED (offset: %u, length: %u)\n", offset, length);
BOOL success = ReadFile(
device,
readBuffer,
length,
&bytesRead,
&overlapped);
if (!success) {
DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
// Wait for the async I/O to complete
if (GetOverlappedResult(device, &overlapped, &bytesRead, TRUE)) {
printf("[OK] Read %lu bytes: '%.*s'\n", bytesRead, bytesRead, readBuffer);
}
else {
printf("[ERROR] GetOverlappedResult failed: %lu\n", GetLastError());
}
}
else {
printf("[ERROR] ReadFile (OVERLAPPED) failed: %lu\n", err);
}
}
else {
printf("[OK] Read %lu bytes: '%.*s'\n", bytesRead, bytesRead, readBuffer);
}
}
void readWithSetFilePointer(HANDLE device, DWORD offset, DWORD length) {
LARGE_INTEGER li;
li.QuadPart = offset;
DWORD bytesRead = 0;
printf("[INFO] Reading with SetFilePointerEx (offset: %u, length: %u)\n", offset, length);
if (!SetFilePointerEx(device, li, NULL, FILE_BEGIN)) {
printf("[ERROR] SetFilePointerEx failed: %lu\n", GetLastError());
return;
}
BOOL success = ReadFile(
device,
readBuffer,
length,
&bytesRead,
NULL);
if (!success) {
printf("[ERROR] ReadFile failed: %lu\n", GetLastError());
return;
}
printf("[OK] Read %lu bytes: '%.*s'\n", bytesRead, bytesRead, readBuffer);
}
int main() {
HANDLE device = CreateFileA(
DEVICE_PATH,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // needed for OVERLAPPED I/O
NULL);
if (device == INVALID_HANDLE_VALUE) {
printf("[ERROR] Failed to open device: %lu\n", GetLastError());
return 1;
}
printf("[INFO] Device opened successfully.\n");
// Example usage
readWithOverlapped(device, 0, 16);
readWithSetFilePointer(device, 32, 16);
CloseHandle(device);
return 0;
}
< /code>
Излишне говорить, что я получаю: < /p>
[INFO] Device opened successfully.
[INFO] Reading with OVERLAPPED (offset: 0, length: 16)
[ERROR] ReadFile (OVERLAPPED) failed: 87
[INFO] Reading with SetFilePointerEx (offset: 32, length: 16)
[ERROR] SetFilePointerEx failed: 1
< /code>
код моего драйвера: < /p>
#include
/*
This device driver is not supposed to synchronize access to the graveyard buffer.
Also, it is not supposed to initialize the graveyard.
*/
#define BUFF_SIZE 1024
static char graveyard[BUFF_SIZE];
// Marks the Irp as completed and returns an error status for bad parameters:
static NTSTATUS badParamsReturn(PIRP Irp) {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
// Marks the Irp as completed and returns a normal status with transferred bytes:
static NTSTATUS normalReturn(PIRP Irp,
ULONG transferred = 0) {
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = transferred;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// Checks if the parameters are valid:
static bool badParams(PVOID userBuffer,
ULONGLONG offsetBytes,
ULONG lengthBytes) {
if (userBuffer == nullptr || lengthBytes == 0) return true;
// The size of the graveyard buffer:
ULONGLONG graveyardSize = sizeof(graveyard);
if (offsetBytes >= graveyardSize) {
return true;
}
return lengthBytes > graveyardSize - offsetBytes;
}
// Read handler:
static void serveReadRequest(PVOID userBuffer,
ULONGLONG offset,
ULONG length) {
RtlCopyMemory(userBuffer,
&graveyard[(size_t) offset],
length);
}
// Write handler:
static void serveWriteRequest(PVOID userBuffer,
ULONGLONG offset,
ULONG length) {
RtlCopyMemory(&graveyard[(size_t) offset],
userBuffer,
length);
}
// The read handler for the driver:
NTSTATUS MyRead(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
auto stack = IoGetCurrentIrpStackLocation(Irp);
auto length = stack->Parameters.Read.Length;
auto offset = stack->Parameters.Read.ByteOffset.QuadPart;
DbgPrint("MyRead: offset %llu, length %lu\n",
offset,
length);
PVOID userBuffer = Irp->AssociatedIrp.SystemBuffer;
if (badParams(userBuffer, offset, length)) {
return badParamsReturn(Irp);
}
serveReadRequest(userBuffer,
offset,
length);
return normalReturn(Irp,
length);
}
// The write handler for the driver:
NTSTATUS MyWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
auto stack = IoGetCurrentIrpStackLocation(Irp);
auto length = stack->Parameters.Write.Length;
auto offset = stack->Parameters.Write.ByteOffset.QuadPart;
DbgPrint("MyWrite: offset %llu, length %lu\n",
offset,
length);
PVOID userBuffer = Irp->AssociatedIrp.SystemBuffer;
if (badParams(userBuffer, offset, length)) {
return badParamsReturn(Irp);
}
serveWriteRequest(userBuffer,
offset,
length);
return normalReturn(Irp,
length);
}
NTSTATUS MyCreateClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
return normalReturn(Irp);
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) {
UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING(L"\\??\\MemoryGraveyard");
IoDeleteSymbolicLink(&symbolicLink);
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("MemoryGraveyard driver unloaded.\n");
}
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\MemoryGraveyard");
UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING(L"\\??\\MemoryGraveyard");
PDEVICE_OBJECT DeviceObject = nullptr;
NTSTATUS status = IoCreateDevice(
DriverObject,
0,
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(status)) return status;
//DriverObject->Flags |= DO_BUFFERED_IO;
status = IoCreateSymbolicLink(&symbolicLink, &deviceName);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(DeviceObject);
return status;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = MyRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = MyWrite;
DriverObject->DriverUnload = DriverUnload;
DbgPrint("MemoryGraveyard driver loaded.\n");
return STATUS_SUCCESS;
}
Итак, я полагаю, что ошибка находится в длине /
Код: Выделить всё
offsetПодробнее здесь: https://stackoverflow.com/questions/796 ... error-code