#include <windows.h>
#include <iostream>
#include <stdexcept>

// 函数：检查文件是否为DLL文件
bool isDllFile(const char* filePath) {
    // 打开文件，使用 CreateFileA 以支持窄字符串
    HANDLE file = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("无法打开文件");
    }

    // 创建文件映射
    HANDLE fileMapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (fileMapping == NULL) {
        CloseHandle(file);
        throw std::runtime_error("无法创建文件映射");
    }

    // 映射文件到内存
    LPVOID fileBase = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
    if (fileBase == NULL) {
        CloseHandle(fileMapping);
        CloseHandle(file);
        throw std::runtime_error("无法映射文件");
    }

    // 获取DOS头（IMAGE_DOS_HEADER）
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBase;
    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
        // 不合法的PE文件
        UnmapViewOfFile(fileBase);
        CloseHandle(fileMapping);
        CloseHandle(file);
        throw std::runtime_error("文件不是有效的PE文件");
    }

    // 获取NT头（IMAGE_NT_HEADERS）
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)fileBase + dosHeader->e_lfanew);
    if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
        // 不合法的PE文件
        UnmapViewOfFile(fileBase);
        CloseHandle(fileMapping);
        CloseHandle(file);
        throw std::runtime_error("文件不是有效的PE文件");
    }

    // 检查标志位（Flags）中的 IMAGE_FILE_DLL 位
    bool isDll = (ntHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0;

    // 释放资源
    UnmapViewOfFile(fileBase);
    CloseHandle(fileMapping);
    CloseHandle(file);

    return isDll;
}

int main() {
    const char* filePath = "C:\\Users\\19266\\Desktop\\.vscode\\ok.exe";  // 使用窄字符串

    try {
        if (isDllFile(filePath)) {
            std::cout << "该文件是DLL文件。" << std::endl;
        } else {
            std::cout << "该文件不是DLL文件。" << std::endl;
        }
    } catch (const std::runtime_error& e) {
        std::cerr << "错误：" << e.what() << std::endl;
    }

    return 0;
}
