Мне нужно прочитать каждую строку в текстовом файле и передать эту строку в качестве параметра в метод.
Я нашел этот пример:
LARGE_INTEGER byteOffset;
ntstatus = ZwCreateFile(&handle,
GENERIC_READ,
&objAttr, &ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);
if(NT_SUCCESS(ntstatus)) {
byteOffset.LowPart = byteOffset.HighPart = 0;
ntstatus = ZwReadFile(handle, NULL, NULL, NULL, &ioStatusBlock,
buffer, BUFFER_SIZE, &byteOffset, NULL);
if(NT_SUCCESS(ntstatus)) {
buffer[BUFFER_SIZE-1] = '\0';
DbgPrint("%s\n", buffer);
}
ZwClose(handle);
}
но это читать все содержимое файла, а не построчно.
Некоторые идеи о том, как это сделать?
прочитать весь файл в буфер или отобразить его как раздел. чем выполнить следующий код:
extern "C" PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz);
void processLine(SIZE_T len, PCSTR line)
{
DbgPrint("%.*s\n", len, line);
}
NTSTATUS process(PCSTR buf, SIZE_T cb)
{
PCSTR end = buf + cb, line = buf;
while (buf = findRN(end - line, line))
{
processLine(buf - line, line);
line = buf + 2;
}
if (line != end)
{
processLine(end - line, line);
}
return 0;
}
реализация findRN
на C / C ++
PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz)
{
if (cb < 2)
{
return 0;
}
cb--;
do
{
if (*sz++ == '\r')
{
if (*sz == '\n')
{
return sz - 1;
}
}
} while (--cb);
return 0;
}
если вам нужна / нужна сверхбыстрая максимально эффективная реализация, сделайте это в asm. например х64:
findRN proc
cmp rcx,1
ja @@0
xor rax,rax
ret
@@0:
mov ax,0a0dh
xchg rdi,rdx
dec rcx
@@1:
repne scasb
jne @@2
cmp [rdi],ah
jne @@1
@@2:
sete al
dec rdi
movzx rax,al
neg rax
and rax,rdi
xchg rdi,rdx
ret
findRN endp
на коде x86 то же самое, только изменение р в е в именах регистров
файл карты:
NTSTATUS process(POBJECT_ATTRIBUTES poa)
{
HANDLE hFile, hSection = 0;
IO_STATUS_BLOCK iosb;
NTSTATUS status = NtOpenFile(&hFile, FILE_GENERIC_READ, poa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
if (0 <= status)
{
FILE_STANDARD_INFORMATION fsi;
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
{
if (fsi.EndOfFile.HighPart)
{
status = STATUS_FILE_TOO_LARGE;
}
else if (!fsi.EndOfFile.LowPart)
{
status = STATUS_MAPPED_FILE_SIZE_ZERO;
}
else
{
status = NtCreateSection(&hSection, SECTION_MAP_READ, 0, 0, PAGE_READONLY, SEC_COMMIT, hFile);
}
}
NtClose(hFile);
if (0 <= status)
{
PVOID BaseAddress = 0;
SIZE_T ViewSize = 0;
status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0,
0, 0, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
NtClose(hSection);
if (0 <= status)
{
status = process((PCSTR)BaseAddress, fsi.EndOfFile.LowPart);
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
}
}
return status;
}
Других решений пока нет …