Files
filehasher/io_ring_test.c
amir d4ba121b56 Implementation of IO Ring in Windows
Fixing the two compilation warnings.
2026-03-31 00:26:03 +01:00

148 lines
3.7 KiB
C

#pragma once
#include <ioringapi.h>
#include <ntioring_x.h>
// #include "ioringapi.c"
#include <winerror.h>
// Initialize I/O Ring
HIORING io_ring_init(void) {
// if (!io_ring_load_functions()) {
// printf("[I/O Ring] Failed to load functions\n");
// return NULL;
// }
IORING_CAPABILITIES caps;
ZeroMemory(&caps, sizeof(caps));
HRESULT hr = QueryIoRingCapabilities(&caps);
if (FAILED(hr)) {
printf("[I/O Ring] QueryIoRingCapabilities failed: 0x%08lx\n", hr);
return NULL;
}
// printf("[I/O Ring] MaxVersion=%d, MaxSubmission=%u, MaxCompletion=%u\n",
// (int)caps.MaxVersion, caps.MaxSubmissionQueueSize,
// caps.MaxCompletionQueueSize);
if (caps.MaxVersion < IORING_VERSION_1) {
printf("[I/O Ring] Version too old\n");
return NULL;
}
IORING_CREATE_FLAGS flags = {0};
HIORING ring = NULL;
// hr = CreateIoRing(IORING_VERSION_1, flags, 256, 512, &ring);
hr = CreateIoRing(caps.MaxVersion, flags, 256, 512, &ring);
if (FAILED(hr)) {
printf("[I/O Ring] CreateIoRing failed: 0x%08lx\n", hr);
return NULL;
}
// printf("[I/O Ring] Created successfully\n");
// Check if read operation is supported
// HRESULT io_ring_support = IsIoRingOpSupported(ring, IORING_OP_READ);
// if (io_ring_support == S_FALSE) {
// printf("[I/O Ring] Not supported, %ld /n", io_ring_support);
// }
// Get ring info
IORING_INFO info;
ZeroMemory(&info, sizeof(info));
GetIoRingInfo(ring, &info);
// printf("[I/O Ring] Submission: %u, Completion: %u\n",
// info.SubmissionQueueSize, info.CompletionQueueSize);
return ring;
}
void io_ring_cleanup(HIORING ring) {
if (ring) {
CloseIoRing(ring);
// printf("[I/O Ring] Closed\n");
}
}
// Read file using I/O Ring
int io_ring_read_file(HIORING ring, HANDLE hFile, void *buffer, DWORD size,
UINT64 offset) {
IORING_HANDLE_REF file_ref = IoRingHandleRefFromHandle(hFile);
IORING_BUFFER_REF buf_ref = IoRingBufferRefFromPointer(buffer);
HRESULT hr = BuildIoRingReadFile(ring, file_ref, buf_ref, size, offset,
(UINT_PTR)buffer, IOSQE_FLAGS_NONE);
if (FAILED(hr))
return -1;
UINT32 submitted = 0;
hr = SubmitIoRing(ring, 1, INFINITE, &submitted);
if (FAILED(hr) || submitted == 0)
return -1;
for (;;) {
IORING_CQE cqe;
hr = PopIoRingCompletion(ring, &cqe);
if (FAILED(hr))
continue;
if (cqe.UserData != (UINT_PTR)buffer)
continue;
if (FAILED(cqe.ResultCode))
return -1;
return (int)cqe.Information;
}
}
// Test function
void test_io_ring(void) {
printf("\n=== Testing I/O Ring ===\n");
HIORING ring = io_ring_init();
if (!ring) {
printf("I/O Ring not available\n");
return;
}
// Create test file
HANDLE hFile = CreateFileA("test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
char test_data[] =
"Hello, I/O Ring! This is a test of the Windows I/O Ring API.";
DWORD written;
WriteFile(hFile, test_data, sizeof(test_data), &written, NULL);
CloseHandle(hFile);
}
// Read using I/O Ring
hFile = CreateFileA("test.txt", GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
char buffer[512] = {0};
int bytes = io_ring_read_file(ring, hFile, buffer, sizeof(buffer), 0);
if (bytes > 0) {
printf("Read %d bytes: %s\n", bytes, buffer);
} else {
printf("Failed to read file\n");
}
CloseHandle(hFile);
} else {
printf("Failed to open test file\n");
}
// Cleanup
DeleteFileA("test.txt");
io_ring_cleanup(ring);
printf("=== Test complete ===\n\n");
}