[代码] 判断部分文件类型的实现

代码判断部分文件类型的实现

支持chm,doc,docx,lnk,pe等文件

bool IsSpecialFile(const wchar_t* w_file_path) {
    //chm
    //lnk
    //url
    //doc xls xlsx docm
    //docx ppsx pptx

    bool ret = false;
    if (w_file_path == nullptr || wcslen(w_file_path) <= 0) {
        return ret;
    }

    #define DOC_PREFIX "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00"
    #define DOCX_PREFIX "\x50\x4B\x03\x04\x14\x00\x06\x00\x08\x00"
    #define LNK_PREFIX "\x01\x14\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"
    #define CHM_PREFIX "\x49\x54\x53"
    #define PE_PREFIX "MZ"

    FILE* fp = nullptr;
    fp = _wfsopen(w_file_path, L"rb", _SH_DENYNO);
    if (fp == nullptr)
    {
        return ret;
    }


    fseek(fp, 0, SEEK_END);
    size_t len = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    if (len >= 32) {
        len = 32;
    }

    uint8_t buffer[32] = { 0 };

    len = fread(buffer, 1, len, fp);
    fclose(fp);

    size_t size = sizeof(DOC_PREFIX);
    size_t size1 = sizeof(DOCX_PREFIX);
    size_t size2 = sizeof(LNK_PREFIX);
    size_t size3 = sizeof(CHM_PREFIX);
    if (memcmp(buffer, DOC_PREFIX, sizeof(DOC_PREFIX) - 1) == 0) {
        ret = true;
    }
    else if (memcmp(buffer, DOCX_PREFIX, sizeof(DOCX_PREFIX) - 1) == 0) {
        ret = true;
    }
    else if (memcmp(buffer, CHM_PREFIX, sizeof(CHM_PREFIX) - 1) == 0) {
        ret = true;
    }
    else if (memcmp(&buffer[4], LNK_PREFIX, sizeof(LNK_PREFIX) - 1) == 0) {
        ret = true;
    }
    else if (memcmp(buffer, PE_PREFIX, sizeof(PE_PREFIX) - 1) == 0) {
        ret = true;
    }

    return ret;
}

CreateFile的实现

HANDLE hFile = INVALID_HANDLE_VALUE;
    uint8_t buffer[32] = { 0 };
    DWORD bytesRead = 0;
    do {
        hFile = CreateFileW(w_file_path, GENERIC_READ,
                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        if (hFile == INVALID_HANDLE_VALUE) {
            break;
        }
        if (!ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) {
            break;
        }
    } while (tt_get_bool(false));
    if (hFile == INVALID_HANDLE_VALUE) {
        return ret;
    }
    CloseHandle(hFile);
    if (bytesRead == 0) {
        return ret;
    }

类似的文件判断可参考: 利用文件头标志判断文件类型

编写文件相关代码要考虑的因素

1.文件是否需要打开,是否有记得关闭

2.文件是否可能被其他程序占用

3.是否要读取文件,文件是否回过大,导致内存暴增,从而程序崩溃。

4.文件路径是否支持多语言路径,多语言就需要注意使用unicode编码

5.共享文件权限设置(共享读/写/删除)

编写文件遍历要考虑的因素

  1. 文件是否是link,link可能会导致遍历死循环,导致oom
  2. 文件遍历是否限制层级,会递归遍历很有可能过深,导致oom
  3. 文件路径正则匹配时,主要文件路径使用的正斜杠\还是反斜杠/,不同的方式正则都需要支持

点赞

本文标签: C++

版权声明:本博客所有文章除特别声明外,本文皆为《shiver blog》原创,转载请保留文章出处。

本文链接:[代码] 判断部分文件类型的实现 - https://www.binary-monster.top/article/53

  1. 把这个实现一遍:<https://mimesniff.spec.whatwg.org/> 🤪。

    1. 二进制怪兽

      你是说实现解析PE的代码吗,一直没时间写,哈哈 确实要手动写一遍

    2. 二进制怪兽

      噢噢噢 我搞错 以为是PE的解析 蟹蟹 我有空看看

1

发表评论

电子邮件地址不会被公开。 必填项已用*标注