Steward
分享是一種喜悅、更是一種幸福
驅動程式 - Windows Driver Model (WDM) - 解決StampInf.exe無法修改"Z:\"底下的INF檔案問題
main.cpp
#include <windows.h>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
namespace fs = std::filesystem;
static const wchar_t* TEMP_DIR = L"c:\\stampinf_temp";
int wmain(int argc, wchar_t* argv[])
{
if (argc < 2) {
std::wcerr << L"Usage: stampinf.exe [arguments]\n";
return 1;
}
fs::path wrapperPath = fs::absolute(argv[0]);
fs::path realStampinf = wrapperPath.parent_path() / L"_stampinf.exe";
if (!fs::exists(realStampinf)) {
std::wcerr << L"ERROR: Real stampinf.exe not found:\n" << L" " << realStampinf << L"\n";
return 1;
}
int fIndex = -1;
fs::path originalFile;
for (int i = 1; i < argc; ++i) {
if (_wcsicmp(argv[i], L"-f") == 0) {
if (i + 1 >= argc) {
std::wcerr << L"ERROR: -f requires a filename.\n";
return 1;
}
fIndex = i;
originalFile = argv[i + 1];
break;
}
}
if (fIndex == -1) {
std::wcerr << L"ERROR: -f parameter not found.\n";
return 1;
}
if (!fs::exists(originalFile)) {
std::wcerr << L"ERROR: File does not exist:\n" << L" " << originalFile << L"\n";
return 1;
}
fs::path tempDir = TEMP_DIR;
std::error_code ec;
fs::create_directories(tempDir, ec);
if (ec) {
std::wcerr << L"ERROR: Cannot create temporary directory:\n" << L" " << tempDir << L"\n";
return 1;
}
fs::path tempFile = tempDir / originalFile.filename();
std::wcout << L"Copying:\n" << L" " << originalFile << L"\n" << L"to:\n" << L" " << tempFile << L"\n";
fs::copy_file(originalFile, tempFile, fs::copy_options::overwrite_existing, ec);
if (ec) {
std::wcerr << L"ERROR: Failed to copy file: " << ec.message().c_str() << L"\n";
return 1;
}
std::wstring commandLine;
auto appendArg = [&](const std::wstring& arg)
{
if (!commandLine.empty()) {
commandLine += L" ";
}
commandLine += L"\"";
size_t backslashes = 0;
for (wchar_t c : arg) {
if (c == L'\\') {
++backslashes;
}
else if (c == L'"') {
commandLine.append(backslashes * 2 + 1, L'\\');
commandLine += L'"';
backslashes = 0;
}
else {
if (backslashes) {
commandLine.append(backslashes, L'\\');
}
backslashes = 0;
commandLine += c;
}
}
if (backslashes) {
commandLine.append(backslashes * 2, L'\\');
}
commandLine += L"\"";
};
for (int i = 1; i < argc; ++i) {
appendArg(argv[i]);
if (i == fIndex) {
++i;
appendArg(tempFile.wstring());
}
}
std::wcout << L"\nExecuting:\n";
std::wcout << L"\"" << realStampinf << L"\" " << commandLine << L"\n\n";
std::wstring fullCommand = L"\"" + std::wstring(realStampinf) + L"\" " + commandLine;
STARTUPINFOW si = {};
PROCESS_INFORMATION pi = {};
si.cb = sizeof(si);
std::vector<wchar_t> cmdBuffer(
fullCommand.begin(),
fullCommand.end()
);
cmdBuffer.push_back(L'\0');
BOOL result = CreateProcessW(
nullptr,
cmdBuffer.data(),
nullptr,
nullptr,
FALSE,
0,
nullptr,
nullptr,
&si,
&pi
);
if (!result) {
DWORD error = GetLastError();
std::wcerr << L"ERROR: CreateProcess failed. Error = " << error << L"\n";
fs::copy_file(tempFile, originalFile, fs::copy_options::overwrite_existing, ec);
fs::remove(tempFile, ec);
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD exitCode = 1;
GetExitCodeProcess(pi.hProcess, &exitCode);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
std::wcout << L"\nCopying modified file back:\n" << L" " << tempFile << L"\n" << L"to:\n" << L" " << originalFile << L"\n";
fs::copy_file(tempFile, originalFile, fs::copy_options::overwrite_existing, ec);
if (ec) {
std::wcerr << L"ERROR: Failed to copy file back: " << ec.message().c_str() << L"\n";
fs::remove(tempFile, ec);
return 1;
}
fs::remove(tempFile, ec);
std::wcout << L"\nstampinf.exe exit code: " << exitCode << L"\n";
return static_cast<int>(exitCode);
}
編譯
$ x86_64-w64-mingw32-g++ -std=c++17 -O2 -s -municode -static -o stampinf.exe main.cpp
P.S. 將原本stampinf.exe改成_stampinf.exe後, 再把編譯後的stampinf.exe複製進去即可