【问题标题】:Kernel Mode: How read a txt file line by line? [closed]内核模式:如何逐行读取 txt 文件? [关闭]
【发布时间】:2017-10-12 21:13:42
【问题描述】:

我需要读取 txt 文件的每一行并将这一行作为参数传递给方法。

我找到了这个例子:

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);
    }

Reference

但这会读取文件的所有内容,而不是逐行读取。

关于如何做到这一点的一些想法?

【问题讨论】:

  • 这是你研究的一个例子。你为这个问题做了什么尝试?
  • @Mani,上面这个例子逐行读取一个txt文件?当然不是,对吧?那怎么办呢?一些代码示例等?
  • 这是一个非常简单的编程问题,将缓冲区的内容解析为单独的行。在寻求帮助之前,您至少应该尝试自己解决。
  • 如果您遇到了不小的问题,但是tiny 问题,您的代码不应该在内核模式下运行。除此之外,如果您确实在使用 C++,请使用 <iostream> 库。你可能不是,所以你需要更新你的标签。
  • 无法从文件中只读取一行。在用户模式和内核模式中都是如此。您可以做的是从文件中读取一大块数据,然后将其解析为单独的行。但在这种情况下,您需要自己完成,因为内核中没有运行时库可以为您完成。 (好吧,there is a runtime library,但它没有那种功能。)您是否考虑过让您的驱动程序成为用户模式而不是内核模式?

标签: c++ winapi driver kernel-mode


【解决方案1】:

读取所有文件以缓冲或将其映射为部分。比执行下一个代码:

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;
}

c/c++上实现findRN

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.xml 中执行此操作。例如 x64:

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 代码上相同,只是将寄存器名称中的 r 更改为 e

地图文件:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    相关资源
    最近更新 更多