2301_76247106 2023-07-16 15:43 采纳率: 5%
浏览 87
已结题

windows驱动写文件日志

在进行windows驱动开发时,调试使用debugview虽然可以,但是有时想看整个运行流程。就需要将日志进行写文件进行存储在txt中,看了下资料。发现如何控制写文件的大小和文件个数。假如txt最大10M,个数不得超过五个。同时还有个问题。如果驱动在执行unload后,下一次如何记录上一次写日志已写的大小。这样已写的文件又是重新记录的,无法记录上一次文件中已写的日志文件大小。如何实现

  • 写回答

15条回答 默认 最新

  • IT技术分享社区 数据库领域优质创作者 2023-07-17 00:25
    关注
    获得1.35元问题酬金

    本次记录上一次日志文件的id信息,然后就可以获取上一次日志的详细信息了。

    评论
  • Mr.小朱同学 2023-07-17 00:59
    关注
    获得1.20元问题酬金
    评论
  • lilzutian 2023-07-17 03:49
    关注

    在Windows驱动开发中,由于驱动程序的特殊性,需要采用一些特殊的方法来实现日志文件的写入、文件大小控制以及记录上一次写入位置等功能。下面我将为您提供一个基本的实现方案,用于控制写文件大小和文件个数,以及记录上一次写入位置。

    控制文件大小和文件个数:
    为了实现文件大小和个数的控制,您可以在驱动程序中维护一个全局变量或使用其他方法来跟踪当前文件大小和文件个数。当日志达到指定大小时,创建一个新的日志文件,并且在超过文件个数限制时,删除最旧的文件。以下是一个简化的示例:

    #define MAX_LOG_SIZE 10 * 1024 * 1024 // 10MB
    #define MAX_LOG_FILES 5
    
    // 全局变量用于跟踪当前日志文件的大小和个数
    ULONG currentLogSize = 0;
    ULONG currentLogFileIndex = 1;
    
    // 函数用于写入日志
    void WriteToLogFile(const char* logMessage, ULONG logSize) {
        if (currentLogSize + logSize > MAX_LOG_SIZE) {
            // 如果超过了最大文件大小,创建新的日志文件
            currentLogFileIndex++;
            currentLogSize = 0;
            // 关闭当前文件,打开新文件并写入日志
            // ...
        }
    
        // 将日志写入当前日志文件
        // ...
        currentLogSize += logSize;
    
        if (currentLogFileIndex > MAX_LOG_FILES) {
            // 如果超过了最大文件个数,删除最旧的日志文件
            // ...
        }
    }
    记录上一次写入位置:
    由于驱动的unload后再次加载时不会保留上一次的运行状态,无法直接记录上一次写入位置。为了实现这一功能,您可以在驱动的unload时,将当前的写入位置信息保存在注册表或其他非易失性存储中,然后在驱动加载时从注册表中读取上一次的写入位置信息。
    // 驱动unload时保存当前写入位置信息
    void SaveLogPositionToRegistry() {
        // 将 currentLogFileIndex 和 currentLogSize 保存在注册表中
        // ...
    }
    
    // 驱动加载时从注册表读取上一次的写入位置信息
    void LoadLogPositionFromRegistry() {
        // 从注册表中读取上一次的 currentLogFileIndex 和 currentLogSize
        // ...
    }
    在Windows驱动开发中,由于驱动程序的特殊性,需要采用一些特殊的方法来实现日志文件的写入、文件大小控制以及记录上一次写入位置等功能。下面我将为您提供一个基本的实现方案,用于控制写文件大小和文件个数,以及记录上一次写入位置。
    
    控制文件大小和文件个数:
    为了实现文件大小和个数的控制,您可以在驱动程序中维护一个全局变量或使用其他方法来跟踪当前文件大小和文件个数。当日志达到指定大小时,创建一个新的日志文件,并且在超过文件个数限制时,删除最旧的文件。以下是一个简化的示例:
    
    c
    Copy code
    #define MAX_LOG_SIZE 10 * 1024 * 1024 // 10MB
    #define MAX_LOG_FILES 5
    
    // 全局变量用于跟踪当前日志文件的大小和个数
    ULONG currentLogSize = 0;
    ULONG currentLogFileIndex = 1;
    
    // 函数用于写入日志
    void WriteToLogFile(const char* logMessage, ULONG logSize) {
        if (currentLogSize + logSize > MAX_LOG_SIZE) {
            // 如果超过了最大文件大小,创建新的日志文件
            currentLogFileIndex++;
            currentLogSize = 0;
            // 关闭当前文件,打开新文件并写入日志
            // ...
        }
    
        // 将日志写入当前日志文件
        // ...
        currentLogSize += logSize;
    
        if (currentLogFileIndex > MAX_LOG_FILES) {
            // 如果超过了最大文件个数,删除最旧的日志文件
            // ...
        }
    }
    记录上一次写入位置:
    由于驱动的unload后再次加载时不会保留上一次的运行状态,无法直接记录上一次写入位置。为了实现这一功能,您可以在驱动的unload时,将当前的写入位置信息保存在注册表或其他非易失性存储中,然后在驱动加载时从注册表中读取上一次的写入位置信息。
    
    c
    Copy code
    // 驱动unload时保存当前写入位置信息
    void SaveLogPositionToRegistry() {
        // 将 currentLogFileIndex 和 currentLogSize 保存在注册表中
        // ...
    }
    
    // 驱动加载时从注册表读取上一次的写入位置信息
    void LoadLogPositionFromRegistry() {
        // 从注册表中读取上一次的 currentLogFileIndex 和 currentLogSize
        // ...
    }
    在实际开发中可能需要考虑更多细节和异常情况的处理。同时,在驱动开发中,涉及文件操作和注册表访问等涉及系统资源的行为需要谨慎处理,以避免对系统稳定性产生负面影响。务必在进行驱动开发时仔细测试和验证您的代码。
    

    展开全部

    评论
  • 技术宅program 2023-07-17 05:44
    关注
    获得0.60元问题酬金
    评论
  • CSDN-Ada助手 CSDN-AI 官方账号 2023-07-17 17:53
    关注
    获得1.35元问题酬金
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 以下回答来自chatgpt:

      我将尝试回答你的问题。在Windows驱动中实现文件日志的大小和数量控制可以通过以下步骤实现:

      1. 首先,你需要在驱动中使用文件系统API打开和操作文件。你可以使用ZwCreateFile函数来创建或打开一个文件,使用ZwWriteFile函数向文件写入日志内容。

      ```c HANDLE fileHandle; UNICODE_STRING fileName; OBJECT_ATTRIBUTES objAttr; IO_STATUS_BLOCK ioStatus; LARGE_INTEGER fileSize; CHAR logData[1024]; // 用于存储日志内容

      RtlInitUnicodeString(&fileName, L"\??\C:\log.txt"); // 指定日志文件路径

      InitializeObjectAttributes(&objAttr, &fileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

      // 创建或打开日志文件 status = ZwCreateFile(&fileHandle, SYNCHRONIZE | FILE_WRITE_DATA, &objAttr, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); ```

      1. 在写入日志之前,你可以使用ZwQueryInformationFile函数获取日志文件的当前大小。如果文件大小已经超过限制,你可以先关闭当前文件,然后创建一个新的日志文件。你可以使用ZwSetInformationFile函数设置文件大小。

      ```c // 获取当前文件大小 ZwQueryInformationFile(fileHandle, &ioStatus, &fileSize, sizeof(fileSize), FileStandardInformation);

      // 如果文件大小已经超过了限制 if (fileSize.QuadPart > 10 * 1024 * 1024) { // 关闭当前文件 ZwClose(fileHandle);

         // 获取新文件名并创建新的日志文件
         // ...
      
         // 如果超过了文件数量限制,你可能需要删除最旧的一个日志文件
         // ...
      

      } ```

      1. 当驱动执行unload时,你可以保存当前日志文件的大小,以便在下次加载时继续记录。

      ```c // 保存当前日志文件的大小 ZwQueryInformationFile(fileHandle, &ioStatus, &fileSize, sizeof(fileSize), FileStandardInformation);

      // 保存文件大小到某个位置,比如驱动配置信息中 // ... ```

      需要注意的是,以上代码片段仅供参考,具体实现可能需要根据你的需求做适当调整。

      如果以上提示不能满足你的需求,我无法给出进一步的具体解决方案。请谅解。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

    展开全部

    评论
  • 「已注销」 2023-07-18 06:21
    关注

    实在不行你就写个exe文件开个进程专门用来读写文件,之后日志靠管道发过去。这很好理解吧

    评论
  • yy64ll826 2023-07-20 01:20
    关注
    获得0.60元问题酬金
    评论
    yy64ll826 2023-07-20 01:20

    C语言实现写入日志文件

    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #ifdef WIN32
    #include <windows.h>
    #else
    #include <unistd.h>        // linux下头文件
    #endif
     
    #define FILE_MAX_SIZE (1024*1024)
     
    /*
    获得当前时间字符串
    @param buffer [out]: 时间字符串
    @return 空
    */
    void get_local_time(char* buffer)
    {
        time_t rawtime; 
        struct tm* timeinfo;
     
        time(&rawtime); 
        timeinfo = localtime(&rawtime); 
        sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d", 
            (timeinfo->tm_year+1900), timeinfo->tm_mon, timeinfo->tm_mday,
            timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
    }
     
    /*
    获得文件大小
    @param filename [in]: 文件名
    @return 文件大小
    */
    long get_file_size(char* filename)
    {
        long length = 0;
        FILE *fp = NULL;
     
        fp = fopen(filename, "rb");
        if (fp != NULL)
        {
            fseek(fp, 0, SEEK_END);
            length = ftell(fp);
        }
     
        if (fp != NULL)
        {
            fclose(fp);
            fp = NULL;
        }
     
        return length;
    }
     
    /*
    写入日志文件
    @param filename [in]: 日志文件名
    @param max_size [in]: 日志文件大小限制
    @param buffer [in]: 日志内容
    @param buf_size [in]: 日志内容大小
    @return 空
    */
    void write_log_file(char* filename, long max_size, char* buffer, unsigned buf_size)
    {
        if (filename != NULL && buffer != NULL)
        {
            // 文件超过最大限制, 删除
            long length = get_file_size(filename);
     
            if (length > max_size)
            {
                unlink(filename); // 删除文件
            }
     
            // 写日志
            {
                FILE *fp;
                fp = fopen(filename, "at+");
                if (fp != NULL)
                {
                    char now[32];
                    memset(now, 0, sizeof(now));
                    get_local_time(now);
                    fwrite(now, strlen(now)+1, 1, fp);
                    fwrite(buffer, buf_size, 1, fp);
     
                    fclose(fp);
                    fp = NULL;
                }
            }
        }
    }
     
    int main(int argc, char** argv)
    {
        int i;
        for (i=0; i<10; ++i)
        {
            char buffer[32];
            memset(buffer, 0, sizeof(buffer));
            sprintf(buffer, "====> %d\n", i);
            write_log_file("log.txt", FILE_MAX_SIZE, buffer, strlen(buffer));
    #ifdef WIN32
            Sleep(100); // 毫秒
    #else
            sleep(1);    // 秒
    #endif
            
        }
        // system("pause");
        return 0;
    }
    

    回复
  • 阳光宅男xxb 2023-07-22 08:24
    关注
    获得1.05元问题酬金

    控制日志文件的大小和数量,可以通过以下步骤实现:
    创建一个日志文件类,负责写日志和管理日志文件。
    在类中定义一个成员变量,用于保存当前写入的日志文件大小(以字节为单位)。
    在类中定义一个成员变量,用于保存当前写入的日志文件的数量。
    在类中定义一个方法,用于写日志。在写日志之前,检查当前日志文件的大小是否已经达到最大限制,如果是,则创建新的日志文件。
    在类中定义一个方法,用于在驱动程序卸载时保存当前写入的日志文件大小。

    评论
  • 竹山全栈 2023-07-23 13:44
    关注
    获得0.45元问题酬金

    为了控制写入文件的大小和个数,可以实时检查并限制当前文件的大小,一旦达到最大值,关闭并创建一个新文件来继续写入日志。可以使用C/C++的文件操作函数来获取和控制文件大小。在驱动执行unload后,可以通过记录上一次写入日志的文件名和大小,然后在重新加载驱动时恢复记录位置,继续在原有文件中写入日志

    评论
  • 垄断的5心 2023-07-16 22:31
    关注
    获得0.75元问题酬金

    这个相当于在开发层面更改很多次了

    评论
  • 故事不长丨 2023-07-17 00:34
    关注

    引用GPT回答:在Windows驱动开发中,可以使用以下方法来控制写文件的大小和文件个数,并记录上一次写日志已写的大小:

    1. 控制文件大小:
      a. 在驱动中设置一个变量来跟踪当前写入日志文件的大小,将其初始化为0。
      b. 每次写入日志时,获取写入内容的大小,并将其添加到跟踪变量中。
      c. 在每次写入日志后,检查跟踪变量是否超过了预设的最大文件大小(比如10M)。
      d. 如果超过了最大文件大小,则关闭当前文件,创建一个新的日志文件开始写入,并重置跟踪变量为当前写入内容的大小。

    2. 控制文件个数:
      a. 在驱动中维护一个文件计数器,初始值为0。
      b. 每当创建一个新的日志文件时,将文件计数器递增1。
      c. 在每次文件创建后,检查文件计数器是否超过了预设的最大文件个数(比如五个)。
      d. 如果超过了最大文件个数,则删除最旧的一个日志文件,将文件计数器减少1。

    3. 记录上一次写日志的大小:
      a. 在驱动中使用一个全局变量来记录上一次写日志的大小。
      b. 在每次写入日志时,将当前写入内容的大小添加到全局变量中。
      c. 当驱动执行unload时,将全局变量的值存储到一个持久化位置,比如注册表中。
      d. 下次加载驱动时,检查持久化位置中是否存在上一次写日志的大小。
      e. 如果存在,则在创建新的日志文件后,将已记录的大小作为偏移量,继续写入文件。

    评论
  • 玥轩_521 2023-07-17 01:36
    关注

    要实现控制写文件的大小和文件个数,你可以在驱动中使用文件流来写入日志,并在写入时进行判断和处理。

    首先,你可以在驱动加载时创建一个文件,并将文件句柄保存在全局变量中。在写入日志时,可以使用ZwWriteFile函数将日志内容写入文件。在每次写入之前,你可以使用ZwQueryInformationFile函数查询文件的当前大小,如果超过了10M,则关闭当前文件句柄,创建新的日志文件。

    为了控制文件个数,你可以在每次创建新的日志文件时,将之前的日志文件重命名或删除。你可以使用ZwSetInformationFile函数来重命名或删除文件。

    关于记录上一次写日志已写的大小,你可以在驱动卸载时将文件的当前大小保存在注册表或其他持久化存储中。下次加载驱动时,你可以读取注册表中的值,并根据该值来判断是否需要创建新的日志文件。

    需要注意的是,驱动开发涉及到系统级的操作,需要谨慎处理,确保代码的正确性和稳定性。

    评论
  • Bert_2022 2023-07-17 02:37
    关注

    在Windows Server 2019上部署IIS和PHP环境并运行PHP项目时,遇到"Call to undefined function drupal_get_path()"错误是因为缺少Drupal核心函数的引用。这个错误通常发生在没有正确配置Drupal项目的情况下。

    要解决这个问题,您可以尝试以下几个步骤:

    确认Drupal核心文件位置:检查您的Drupal项目是否正确安装,并确保所有Drupal核心文件位于项目目录中。这些文件通常位于"core"文件夹下。

    配置IIS以处理PHP文件:确保IIS已正确配置以处理PHP文件。可以按照以下步骤进行配置:

    打开IIS管理器,选择您的站点。
    右键单击站点,并选择"Handler Mappings"(处理程序映射)。
    确保存在"PHP_via_FastCGI"或"FastCGIModule"处理程序映射。
    如果不存在,请单击"Add Module Mapping"(添加模块映射)并配置正确的处理程序映射。确保将请求发送到正确的PHP可执行文件路径。
    检查PHP版本和扩展:确保您正在使用与Drupal项目兼容的PHP版本,并且已加载所需的扩展。您可以在Drupal官方网站上查找Drupal版本与PHP版本的兼容性信息。

    配置Drupal项目:打开您的Drupal项目文件夹,并确保已经完成以下步骤:

    复制并重命名default.settings.php文件为settings.php。
    打开settings.php文件,并确保数据库连接等必要配置已正确设置。
    清除Drupal缓存,您可以通过运行以下命令来完成:php ./core/scripts/drupal cache:rebuild
    重启IIS服务:在完成上述步骤后,重启IIS服务以确保所有更改生效。

    如果您仍然遇到问题,请检查PHP错误日志和Drupal日志文件,以获取更多详细的错误信息,这将有助于确定问题的根本原因并进行进一步的调试和解决。

    请注意,运行Drupal项目时,确保您的服务器满足Drupal的系统要求,并使用推荐的版本和配置。

    评论
  • Java毕设王 2023-07-17 05:24
    关注

    你可以通过以下方法控制写入文件的大小和文件个数,并在unload后记录上一次写日志的大小:

    控制文件大小和个数:

    在写入日志文件之前,可以先检查当前日志文件的大小。如果已超过设定的大小阈值(例如10MB),则将当前文件重命名或关闭,并创建一个新的日志文件。
    为了控制文件个数,可以在每次创建新的日志文件时,检查日志文件的数量。如果已达到设定的文件个数限制(例如5个),则删除最旧的一个日志文件,为新的日志文件腾出空间。
    记录上一次写日志的大小:

    可以在驱动的全局变量中保存上一次写入的日志文件大小。在unload函数中,将当前文件的大小记录到全局变量中。
    下次加载驱动时,可以从全局变量中读取上一次写入的文件大小,并使用该大小作为偏移量来写入新的日志文件。
    需要注意的是,驱动开发中需要谨慎处理文件操作和全局变量的使用,确保线程安全和资源释放。另外,文件操作涉及到文件系统的访问权限,确保在驱动程序中具备足够的权限来执行文件操作。

    评论
  • 杨得江-君临天下wyj 2023-07-20 02:28
    关注

    对于开发人员来说,UMD 日志记录可以阐明目前很难看到的内存成本,例如内部碎片或快速丢弃图面的影响。 它使 Microsoft 能够更好地与提供性能问题分析跟踪的客户和合作伙伴合作。 具体而言,此功能有助于克服调查内存相关性能问题的常见阻碍点:应用程序使用的工作集太大,但你无法确定导致问题的 API 资源或调用。

    驱动程序必须通过实现 UMD ETW 接口来公开 Direct3D 资源和视频内存分配之间的关系。 除了日志记录事件外,驱动程序还必须能够在任何时间点报告资源和分配之间的所有现有映射。

    UMD 驱动程序分配日志记录 DDI
    用户模式驱动程序分配日志记录设备驱动程序接口 (DDI) 提供 Windows 事件跟踪 (ETW) 内核级跟踪工具的事件,这些跟踪工具显示哪些 API 资源与 Microsoft DirectX 图形内核子系统 (Dxgkrnl.sys) 中的内核分配相关联。

    可以使用 DDI 发现内部内存碎片或快速丢弃表面的影响,以便为 Microsoft 提供更好的跟踪信息,以帮助你识别性能问题,并帮助确定应用的资源或 API 调用何时导致它使用过大的一组工作内存。

    使用这些来自 Umdprovider.h 标头的函数、枚举和结构记录用户模式显示驱动程序中的事件:

    UMDEtwLogMapAllocation 函数
    UMDEtwLogUnmapAllocation 函数
    UMDEtwRegister 函数
    UMDEtwUnregister 函数
    UMDETW_ALLOCATION_SEMANTIC 枚举
    UMDETW_ALLOCATION_USAGE 结构
    另请参阅 Umdetw.h 标头。

    硬件认证要求
    有关硬件设备在实现此功能时必须满足的要求的信息,请参阅 Device.Graphics ڂ UMDLogging 上的相关 WHCK 文档。

    有关使用 Windows 8 添加的功能的回顾,请参阅 WDDM 1.2 功能。

    评论
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 7月23日
  • 创建了问题 7月16日
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部