junyee 发表于 2026-1-20 22:17 原版的可执行文件还算是可以的。
reg2inf.zip
(3.59 KB, 下载次数: 0)
|
|
本帖最后由 junyee 于 2026-1-20 22:47 编辑 我拿 mingw 编译了下,同时参考了前楼兄弟的。 “IsReturn() 这个是怎么猜出来的。 总算编译成功了。但是执行失败,提示 not a reg file. 然后看了看代码,我的天,这代码,结构混乱,代码质量差。 这乱七八糟能工作就怪了。 可读性不佳,注释没有,甚至搞出 errorcode++ 这种不方便 排查的方法。 用 err_xxx 来替代 errmsg[] 会易懂得多。 作者还喜欢用 一块内存来装两段数据,节省是好,但是对于电脑程序来说,多一个内存碎片并不会太浪费。 ```如 WideCharToMultiByte(CP_ACP,0,(LPCWSTR)(lpfile+size),-1,lpfile,size,0,0); destBuffer=(stringBuffer=(temp=lpfile+size)+1)+size+1; ``` 又不是追求高效率高并发的场景。 改了半小时,目前进度 能成生 inf了。估 这个浏览器不支持 flash插件.如何传送上来啊。 |
| 围观学习 |
| 来看看,学习一下。 |
| // Reg2Inf.c - Registry to INF converter // Build: cl /O2 Reg2Inf.c user32.lib kernel32.lib #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // 常量定义 #define MAX_PATH_LENGTH 1024 #define BUFFER_SIZE 65536 // 全局变量 int errorcode = 0; char *errorprompts[] = { "This program generates .Inf file from a .Reg file. (by kajaa@eastday.com)\n" "Syntax:\tReg2Inf [switches] [<SourceFile.Reg> [DestFile.Inf]]\n" "\tswitches:\n" "\t\t-w\toutput WHOLE keyname instead of abbreviation\n" "\t\t-t\toutput in TINY mode, no comments\n", "Memory Allocation Error\n", "File cannot be opened\n", "Memory Allocation Error\n", "Not a REG File\n", "File cannot be created\n", "OK\n", }; // INF文件模板 #define INFHEADER \ "[Version]\r\n"\ "Signature=\"$CHICAGO$\"\r\n"\ "Provider=kajaa@eastday.com, 2002\r\n\r\n"\ "[DefaultInstall]\r\n"\ "; DelReg=$PZ_DelReg\r\n"\ "AddReg=$PZ_AddReg\r\n" #define INFCOMMENTS \ "; reg-root-string, [subkey], [value-name], [flags], [value]\r\n"\ ";DelReg=$PZ_DelReg\r\n"\ "; reg-root-string, subkey, [value-name]\r\n"\ ";Delfiles=$PZ_Delfiles\r\n"\ "; file-name[,,,flag]\r\n"\ ";Renfiles=$PZ_Renfiles\r\n"\ "; new-file-name,old-file-name\r\n"\ ";Copyfiles=$PZ_Copyfiles\r\n"\ "; destination-file-name[,source-file-name][,temporary-file-name][,flag]\r\n"\ ";UpdateInis=$PZ_UpdateInis\r\n"\ "; ini-file,ini-section,[old-ini-entry],[new-ini-entry],[flags]\r\n"\ "\r\n"\ "[DestinationDirs]\r\n"\ "; -01 or 0xffff The directory from which the INF was installed.\r\n"\ "; 01 SourceDrive:\\path.\r\n"\ "; 10 Windows directory.\r\n"\ "; 11 System directory. (%windir%\\system on Windows 95, %windir%\\system32 on Windows NT)\r\n"\ "; 12 Drivers directory.(%windir%\\system32\\drivers on Windows NT)\r\n"\ "; 17 INF file directory.\r\n"\ "; 18 Help directory.\r\n"\ "; 20 Fonts directory.\r\n"\ "; 21 Viewers directory.\r\n"\ "; 24 Applications directory.\r\n"\ "; 25 Shared directory.\r\n"\ "; 30 Root directory of the boot drive.\r\n"\ "; 50 %windir%\\system\r\n"\ "; 51 Spool directory.\r\n"\ "; 52 Spool drivers directory.\r\n"\ "; 53 User Profile directory.\r\n"\ "; 54 Path to ntldr or OSLOADER.EXE\r\n" #define INFBEGIN "\r\n[$PZ_DelReg]\r\n\r\n[$PZ_AddReg]\r\n" // 配置选项 int use_abb_key = 1; // 使用缩写键名 int use_tiny_mode = 0; // 是否使用简洁模式 // 辅助函数:不区分大小写的字符串比较 int strncmpi(const char *s1, const char *s2, size_t n) { while (n-- && *s1 && *s2) { if (tolower(*s1) != tolower(*s2)) return tolower(*s1) - tolower(*s2); s1++; s2++; } return 0; } // 辅助函数:检查是否是换行符 int IsReturn(const char *ptr) { return (ptr[0] == '\r' && ptr[1] == '\n'); } // 跳过空白字符和注释 char *skipwhitespace(char *buffer, int comment) { char *lp = buffer; while (*lp) { if (!comment) { switch (*lp) { case '\t': case ' ': break; case ';': comment = 1; break; default: if (IsReturn(lp)) { lp += 2; continue; } else { if (*lp != '\r' && *lp != '\n') return lp; break; } } lp++; } else { if (IsReturn(lp)) { lp += 2; comment = 0; continue; } else { if (*lp == '\r' || *lp == '\n') comment = 0; } lp++; } } return lp; } // 识别注册表根键 int whichroot(char *lp, char **root) { #define HKLM "HKEY_LOCAL_MACHINE" #define HKCU "HKEY_CURRENT_USER" #define HKU "HKEY_USERS" #define HKCR "HKEY_CLASSES_ROOT" #define HKLMSC "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes" if (strncmpi(lp, HKLMSC, strlen(HKLMSC)) == 0) { *root = "hkcr"; return strlen(HKLMSC); } if (strncmpi(lp, HKLM, strlen(HKLM)) == 0) { *root = "hklm"; return strlen(HKLM); } if (strncmpi(lp, HKCU, strlen(HKCU)) == 0) { *root = "hkcu"; return strlen(HKCU); } if (strncmpi(lp, HKU, strlen(HKU)) == 0) { *root = "hku"; return strlen(HKU); } if (strncmpi(lp, HKCR, strlen(HKCR)) == 0) { *root = "hkcr"; return strlen(HKCR); } return 0; } // 写入二进制数据 char *writebinary(char *src, char *dest, int hex) { if (hex) { // 处理十六进制字符串 while (*src && (IsReturn(src) == 0 || *(src - 1) == '\\')) { *dest++ = *src++; } } else { // 处理DWORD值 unsigned int value = 0; sscanf(src, "%x", &value); // 以小端格式写入(低字节在前) for (int i = 0; i < 4; i++) { unsigned char byte = (value >> (i * 8)) & 0xFF; if (i > 0) *dest++ = ','; char temp[4]; sprintf(temp, "%02x", byte); *dest++ = temp[0]; *dest++ = temp[1]; } } return dest; } // 生成字符串引用 char stringBuffer[BUFFER_SIZE]; char *stringEnd = stringBuffer; int stringNumber = 0; char *genstring(char *key) { char *se = stringEnd; // 生成唯一ID stringNumber++; se += sprintf(se, "STR%d_", stringNumber); // 处理键名,将反斜杠替换为下划线 char *temp = key; while (*temp) { if (*temp == '\\') { *se++ = '_'; } else { *se++ = *temp; } temp++; } // 记录字符串长度 int kl = se - stringEnd; // 添加字符串定义 *se++ = '='; *se++ = '"'; strcpy(se, key); se += strlen(key); *se++ = '"'; strcpy(se, "\r\n"); se += 2; // 返回字符串引用 char *result = stringEnd; stringEnd = se; return result; } // 生成INF值 int genvalues(char *buffer, char *destBuffer, int *skipbytes, char **curkeyname) { char *lp = buffer; char *dest = destBuffer; switch (*lp) { case '[': { // 处理键名 char *end = strchr(lp, ']'); if (end) { *skipbytes = (end - buffer) + 1; *end = '\0'; lp++; // 跳过'[' // 检查根键 char *root = NULL; int rootlen = whichroot(lp, &root); if (rootlen > 0) { // 生成新的键名 char *key = lp + rootlen; if (*key == '\\') key++; // 如果需要缩写,生成字符串引用 char *keyref = key; if (use_abb_key) { keyref = genstring(key); } // 保存当前键名 *curkeyname = strdup(lp); // 添加换行(如果不是第一行) if (dest > destBuffer && *(dest-2) != '\r' && *(dest-1) != '\n') { strcpy(dest, "\r\n"); dest += 2; } // 添加键注释 sprintf(dest, "; %s\r\n", lp); dest += strlen(dest); } } break; } case '@': case '"': { // 处理值 char *valueName = lp; char *valueEnd = NULL; if (*lp != '@') { // 带引号的值名 valueName++; valueEnd = strchr(valueName, '"'); if (valueEnd) { *valueEnd = '\0'; valueEnd++; // 跳过引号 } } else { // 默认值 valueName = ""; valueEnd = lp + 1; } if (valueEnd) { // 查找等号 char *equal = strchr(valueEnd, '='); if (equal) { *skipbytes = (equal - buffer) + 1; char *valueStart = equal + 1; // 确定值类型 int valueType = -1; // -1=未知, 0=字符串, 1=十六进制, 0x10001=DWORD char *valuePtr = valueStart; if (*valueStart == '"') { // 字符串值 valueType = 0; valuePtr++; // 跳过引号 } else if (strncmpi(valueStart, "dword:", 6) == 0) { // DWORD值 valueType = 0x10001; valuePtr += 6; } else if (strncmpi(valueStart, "hex:", 4) == 0) { // 十六进制值 valueType = 1; valuePtr += 4; } else if (strncmpi(valueStart, "hex(7):", 7) == 0) { // 多字符串值 valueType = 2; valuePtr += 7; } else if (strncmpi(valueStart, "hex(2):", 7) == 0) { // 可扩展字符串值 valueType = 3; valuePtr += 7; } if (valueType >= 0) { // 写入INF格式 if (valueType == 0) { // 字符串值 char *valueEnd = strchr(valuePtr, '"'); if (valueEnd) { *valueEnd = '\0'; // 转义引号 char escapedValue[MAX_PATH_LENGTH]; char *destPtr = escapedValue; char *srcPtr = valuePtr; while (*srcPtr) { if (*srcPtr == '%') { *destPtr++ = '%'; *destPtr++ = '%'; } else if (*srcPtr == '"') { *destPtr++ = '\\'; *destPtr++ = '"'; } else { *destPtr++ = *srcPtr; } srcPtr++; } *destPtr = '\0'; sprintf(dest, "hkcu,\"Software\\Test\",\"%s\",0,\"%s\"\r\n", valueName, escapedValue); } } else if (valueType == 0x10001) { // DWORD值 unsigned int dwordValue; sscanf(valuePtr, "%x", &dwordValue); sprintf(dest, "hkcu,\"Software\\Test\",\"%s\",0x10001,%08x\r\n", valueName, dwordValue); } else { // 十六进制值 sprintf(dest, "hkcu,\"Software\\Test\",\"%s\",%d,", valueName, valueType); dest += strlen(dest); dest = writebinary(valuePtr, dest, 1); strcpy(dest, "\r\n"); } dest += strlen(dest); } } } break; } } return dest - destBuffer; } // 写入INF头部 int writeheader(char *header, char *destBuffer, int from, const char *sectionName) { char *sp = header; char *dp = destBuffer + from; while (*sp) { // 替换占位符 if (strncmp(sp, "$PZ_", 4) == 0) { strcpy(dp, sectionName); dp += strlen(sectionName); sp += 4; } else { *dp++ = *sp++; } } return dp - destBuffer; } // 转换主函数 void convert(const char *srcfile, const char *destfile) { FILE *in = fopen(srcfile, "rb"); if (!in) { errorcode = 2; // 文件无法打开 return; } // 获取文件大小 fseek(in, 0, SEEK_END); long filesize = ftell(in); fseek(in, 0, SEEK_SET); // 读取文件内容 char *fileContent = (char*)malloc(filesize + 1); if (!fileContent) { fclose(in); errorcode = 1; // 内存分配错误 return; } fread(fileContent, 1, filesize, in); fileContent[filesize] = '\0'; fclose(in); // 检查是否是REG文件 char *fileStart = skipwhitespace(fileContent, 0); if (!strncmp(fileStart, "REGEDIT4", 8) || !strncmp(fileStart, "Windows Registry Editor Version", 31)) { // 创建输出文件 FILE *out = fopen(destfile, "w"); if (!out) { free(fileContent); errorcode = 5; // 文件无法创建 return; } // 准备输出缓冲区 char outputBuffer[BUFFER_SIZE]; int outputPos = 0; // 写入INF头部 outputPos = writeheader(INFHEADER, outputBuffer, outputPos, "DefaultInstall"); if (!use_tiny_mode) { outputPos = writeheader(INFCOMMENTS, outputBuffer, outputPos, ""); } // 开始转换 strcpy(outputBuffer + outputPos, INFBEGIN); outputPos += strlen(INFBEGIN); // 处理REG文件内容 char *curpos = fileStart; int skipbytes = 0; char *curkeyname = NULL; while (*curpos) { curpos = skipwhitespace(curpos + skipbytes, 1); if (!*curpos) break; int written = genvalues(curpos, outputBuffer + outputPos, &skipbytes, &curkeyname); outputPos += written; if (outputPos > BUFFER_SIZE - 1024) { // 缓冲区快满了,写入文件 fwrite(outputBuffer, 1, outputPos, out); outputPos = 0; } } // 写入剩余的缓冲区内容 if (outputPos > 0) { fwrite(outputBuffer, 1, outputPos, out); } // 添加字符串表 if (stringEnd > stringBuffer) { fprintf(out, "\r\n[Strings]\r\n"); fwrite(stringBuffer, 1, stringEnd - stringBuffer, out); } fclose(out); errorcode = 6; // OK printf("INF file generated successfully: %s\n", destfile); } else { errorcode = 4; // 不是REG文件 } free(fileContent); if (curkeyname) free(curkeyname); } // 处理文件扩展名 void extfn(const char *cmd, char *result) { const char *ext = strrchr(cmd, '.'); if (ext) { strncpy(result, cmd, ext - cmd); result[ext - cmd] = '\0'; } else { strcpy(result, cmd); } } // 主函数 int main(int argc, char *argv[]) { if (argc < 2) { printf("%s", errorprompts[0]); return 1; } // 解析命令行参数 char *srcfile = NULL; char *destfile = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-' || argv[i][0] == '/') { switch (tolower(argv[i][1])) { case 'w': use_abb_key = 0; break; case 't': use_tiny_mode = 1; break; } } else { if (!srcfile) { srcfile = argv[i]; } else if (!destfile) { destfile = argv[i]; } } } if (!srcfile) { printf("%s", errorprompts[0]); return 1; } // 处理源文件路径 char sourcePath[MAX_PATH_LENGTH]; if (srcfile[0] == '"' && srcfile[strlen(srcfile)-1] == '"') { // 去除引号 strncpy(sourcePath, srcfile + 1, strlen(srcfile) - 2); sourcePath[strlen(srcfile) - 2] = '\0'; } else { strcpy(sourcePath, srcfile); } // 生成目标文件名 char destPath[MAX_PATH_LENGTH]; if (destfile) { if (destfile[0] == '"' && destfile[strlen(destfile)-1] == '"') { strncpy(destPath, destfile + 1, strlen(destfile) - 2); destPath[strlen(destfile) - 2] = '\0'; } else { strcpy(destPath, destfile); } } else { extfn(sourcePath, destPath); strcat(destPath, ".inf"); } // 执行转换 convert(sourcePath, destPath); // 显示结果 printf("%s", errorprompts[errorcode]); return errorcode == 6 ? 0 : 1; } |
| 等热心人 |
| 不会,等高手 |
| 多谢大佬 |
| 不会弄这个 |
| 网页版非常好用 |
| 看看了 不会弄这个 |
|
本帖最后由 heihei1314 于 2026-1-20 13:18 编辑 代码丢给deepseek,让deepseek转为网页版的,直接网页打开转就行了 htt删ps://chat.deeps删eek.com/share/th5qjsgi2zu20t3rr1 |
| 参与人数 1 | 无忧币 +2 | 收起 理由 |
|---|---|---|
|
| + 2 | 很给力! |
|
本帖最后由 BestMiniPE 于 2026-1-20 21:19 编辑 一通乱改,和下面的网页版一样的效果了。可惜我不懂inf。可以用 i686-w64-mingw32-g++.exe Reg2Inf.cpp -o Reg2Inf -static -lpthread
|
| 参与人数 1 | 无忧币 +1 | 收起 理由 |
|---|---|---|
|
| + 1 | 赞一个! |
Powered by Discuz! X3.3
© 2001-2017 Comsenz Inc.