2010hook 发表于 2019-1-31 11:30:28

Reg2Inf 源码改进,C#和正则式

本帖最后由 2010hook 于 2019-2-1 10:19 编辑

名称:Reg2Inf 0.46
作者:n7Epsilon
出处:https://ryanvm.net/forum/viewtopic.php?t=2169
下载:http://cid-704054d7328ec826.skydrive.live.com/self.aspx/.Public/Reg2Inf%5E_0.46.zip
本坛下载附件

此工具,可能是同类最好,但还不完善。
若使用“/RepVars”参数,会把 “C:\Program Files (x86)\Common Files” 转成 “%16422% (x86)\Common Files”,注册表的路径也这么转哦。文件夹层次也没根据“\”划分。
x86 对应的应该是 16426,而且应该优先处理最长的环境变量。

希望有能力者帮忙改进:
1、针对x64改进,dirids需要补充,见文末。要支持任意盘符转换。
2、 用于指定CopyFiles、RenFiles或DelFiles入口的缺省操作目录。
注册表的路径,转成%24%之类的话,安装时不能转成系统环境路径,%1%也不能得到当前路径,那就不应该这么处理。
注册表的路径数值,应该转成%CommonProgramFiles(x86)%或%%CommonProgramFiles(x86)%%这种形式。
3、关于Unicode字符转换,系统API依赖已安装的代码页,不一定完整,那就优先调用严格的iconv.dll吧。
4、既然能处理好inf,那么稍加改进也能转成cmd吧。

-1 Absolute path
1%~dp0%
00 Null LDID
01 Source Drive_Letter:\Path_Name(the directory from which the INF file was installed)
02 Temp Setup
03 Uninstall
04 Backup
10 Windows directory. %SystemRoot%.
11 System directory. %SystemRoot%\system32.
12 Drivers directory. %SystemRoot%\system32\drivers.
13 Driver package's Driver Store directory. For Windows 8.1 and later, specifies the path to the Driver Store directory where the driver package was imported.
   The optional subdirectory in the SourceDiskFiles section for a file must match the subdirectory in the DestinationDirs section for the entry that applies to this file.
   Don't use DelFiles on a file for which DestinationDirs includes dirid 13.
   Don't use CopyFiles to rename a file for which DestinationDirs includes dirid 13.
14 Control Panel
15 Printers
16 Workgroup
17 INF Directory [%windir%\INF]
18 Help directory [%windir%\HELP]
19 Administration
20 Fonts [%windir%\FONTS]
21 Viewers [%windir%\SYSTEM\VIEWERS]
22 VMM32 [%windir%\SYSTEM\VMM32]
23 Color directory [%windir%\SYSTEM\COLOR]
24 Root of drive containing the Windows files are installed directory. e.g., if dirid 10 is "C:\winnt", then dirid 24 is "C:\".
25 Shared directory
26 Guaranteed boot device for Windows (Winboot)
27 Machine [%windir%]
28 Host Winboot
30 Root directory of the boot disk, also known as "ARC system partition". (This might or might not be the same directory as the one represented by dirid 24.)
31 Root directory of the Host drive of a virtual boot drive
50 System directory. This is equivalent to %SystemRoot%\system.
51 Spool directory. (not used for installing printer drivers - see Printer Dirids)
53 User profile directory.
54 Directory where Ntldr.exe and Osloader.exe are located.
55 Print processors directory. (not used for installing printer drivers)

16384 %USERPROFILE%\Desktop
16386 %USERPROFILE%\Start Menu\Programs
16389 %USERPROFILE%\Documents
16390 %USERPROFILE%\Favorites
16391 %USERPROFILE%\Start Menu\Programs\Startup
16392 %USERPROFILE%\Recent
16393 %USERPROFILE%\SendTo
16395 %USERPROFILE%\Start Menu
16397 %USERPROFILE%\Music
16398 %USERPROFILE%\Videos
16400 %USERPROFILE%\Desktop
16403 %USERPROFILE%\NetHood
16405 %USERPROFILE%\Templates
16406 %ALLUSERSPROFILE%\Start Menu
16407 %ALLUSERSPROFILE%\Start Menu\Programs
16408 %ALLUSERSPROFILE%\Start Menu\Programs\Startup
16409 %ALLUSERSPROFILE%\Desktop
16410 %USERPROFILE%\Application Data
16411 %USERPROFILE%\PrintHood
16412 %USERPROFILE%\Local Settings\Application Data
16415 %ALLUSERSPROFILE%\Favorites
16416 %USERPROFILE%\Local Settings\Temporary Internet Files
16417 %USERPROFILE%\Cookies
16418 %USERPROFILE%\Local Settings\History
16419 %ALLUSERSPROFILE%\Application Data
16422 %ProgramFiles%
16423 %USERPROFILE%\Pictures
16425 %SystemRoot%\system32 (valid for Microsoft Win32 user-mode applications that are running under Windows on Windows (WOW64))
16426 Program Files (valid for Win32 user-mode applications that are running under WOW64)
16427 %ProgramFiles%\Common Files
16428 Program Files\Common (valid for Win32 user-mode applications that are running under WOW64)
16429 %ALLUSERSPROFILE%\Templates
16430 %ALLUSERSPROFILE%\Documents
16431 %ALLUSERSPROFILE%\Start Menu\Programs\Administrative Tools
16432 %USERPROFILE%\Start Menu\Programs\Administrative Tools
16437 %ALLUSERSPROFILE%\Documents\My Music
16438 %ALLUSERSPROFILE%\Documents\My Pictures
16439 %ALLUSERSPROFILE%\Documents\My Videos
16440 %SystemRoot%\Resources
16441 %SystemRoot%\Resources\0409
16443 %USERPROFILE%\Local Settings\Application Data\Microsoft\CD Burning

2010hook 发表于 2019-1-31 12:44:35

本帖最后由 2010hook 于 2019-1-31 12:50 编辑

原作者把工具名称、网址插入到每一节开头,有些繁琐,最好改成插入到文件头,一行即可。
还要把不必要的MyRegTweaks相关代码清除。

chishingchan 发表于 2019-1-31 14:40:04

楼主推介的这个需要依赖 NET!我也收藏有国内某人(忘记了)的 Reg2InfC 源码。
本想自己写一个,无奈没时间。

2010hook 发表于 2019-1-31 16:57:19

chishingchan 发表于 2019-1-31 14:40
楼主推介的这个需要依赖 NET!我也收藏有国内某人(忘记了)的 Reg2InfC 源码。
本想自己写一个,无奈没时 ...

Reg2InfC 源码,顺手也发一份吧。
依赖NET,总比VBS堪用啊,只要能转换正确,可以接受。
感觉一个exe就能转 Inf、cmd。要求细致严谨,希望你能突破!

hszgb 发表于 2019-1-31 17:23:32

一起都来分析一下,好东西

chishingchan 发表于 2019-1-31 17:32:02

真正找到的是这个!2002年的。
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <shlobj.h>
#include <richedit.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma hdrstop

#include "..\api\winapi.h"

int errorcode;
LPSTR errorprompts[]=
{
"This program generates .Inf file from a .Reg file. (by kajaa@eastday.com)\n"
"Syntax:\tReg2Inf [<SourceFile.Reg> ]\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",
};

const int RESBUFSIZE=65500;
int skipbytes, knlsize;
LPSTR ComBuf,srcfile,destfile,destBuffer;

LPSTR WINAPI skipwhitespace(LPSTR buffer,int comment)
{
LPSTR lp;
lp=buffer;
while (*lp)
        {
        if (!comment)
                {
                switch(*lp)
                        {
                        case 0x9:
                        case 0x20: break;
                        case ';': comment=1; break;
                        default:
                                if (IsReturn(lp)) ++lp;
                                else{
                                        if (*lp!='\r'&&*lp!='\n') return lp;
                                        break;
                                        }
                        }
                ++lp;
                }
        else{
                if (IsReturn(lp)) ++lp, comment=0; else{ if (*lp=='\r'||*lp=='\n') comment=0; }
                ++lp;
                }
        }
return lp;
}

#define INFHEADER \
"\r\nSignature=\"$CHICAGO$\"\r\nProvider=kajaa@eastday.com, 2002\r\n\r\n"\
"\r\n"\
"; DelReg=$PZ_DelReg\r\n"\
"AddReg=$PZ_AddReg\r\n"

#define INFCOMMENTS \
"; reg-root-string, , , , \r\n"\
";DelReg=$PZ_DelReg\r\n"\
"; reg-root-string, subkey, \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,,,\r\n"\
"\r\n"\
"\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]"


LPSTR curkeyname,root,key;
int WINAPI whichroot(LPSTR lp)
{
#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, sizeof(HKLMSC)-1)==0)
        {
        root="hkcr";
        return sizeof(HKLMSC);
        }
if (strncmpi(lp, HKLM, sizeof(HKLM)-1)==0)
        {
        root="hklm";
        return sizeof(HKLM);
        }
if (strncmpi(lp, HKCU, sizeof(HKCU)-1)==0)
        {
        root="hkcu";
        return sizeof(HKCU);
        }
if (strncmpi(lp, HKU, sizeof(HKU)-1)==0)
        {
        root="hku";
        return sizeof(HKU);
        }
if (strncmpi(lp, HKCR, sizeof(HKCR)-1)==0)
        {
        root="hkcr";
        return sizeof(HKCR);
        }
return 0;
}

LPSTR writebinary(LPSTR src,LPSTR dest,int hex)
{
if (hex)
        {
//        V2LP(dest)=0x090a0d5c,dest+=4;
        while (*src&&(IsReturn(src)==0||*(src-1)=='\\')) *dest++=*src++;
        }
else{
        short *ch;
        ch=((short *)src)+3;
        V2SP(dest)=*ch--; *(dest+2)=','; dest+=3;
        V2SP(dest)=*ch--; *(dest+2)=','; dest+=3;
        V2SP(dest)=*ch--; *(dest+2)=','; dest+=3;
        V2SP(dest)=*ch; dest+=2;
        }
return dest;
}

int use_abb_key=1,use_tiny_mode; LPSTR stringBuffer,stringEnd;
LPSTR WINAPI genstring(LPSTR key)
{
static int number;
int kl;
LPSTR se,temp;
if (use_abb_key==0) return key;
se=stringEnd;
se+=sprintf(se,"%s%d_",ComBuf,++number);
temp=key;
while (*temp)
        {
        if ((*temp&'\x80')!=0)
                {
                se+=sprintf(se,"%d",++number);
                ++temp;
                }
        else *se++=*temp++;
        while (*temp&&*temp!='\\') ++temp;
        if (*temp) ++temp;
        }
kl=(temp=se)-stringEnd;
*temp++='='; *temp++='\"';
lstrcpy(temp,key); while (*temp) ++temp;
*temp++='\"'; V2SP(temp)=0x0a0d;
se=(temp+=2);
*temp++='%';
lstrcpyn(temp,stringEnd,kl+1);
V2SP(temp+=kl)=0x25;
return stringEnd=se;
}

int WINAPI genvalues(LPSTR buffer,int size)
{
LPSTR lp,dest;
skipbytes=0, lp=buffer, dest=destBuffer+size;
switch(*lp)
        {
        case '[':
                while (*lp&&*lp!=']') ++lp; skipbytes=lp-buffer+1; ++buffer;
                if (*lp)
                        {
                        *lp=0, lp=buffer;
                        if (curkeyname==0||lstrcmpi(lp,curkeyname))
                                {
                                int len;
                                if ((len=whichroot(buffer))!=0)
                                        {
                                        if (V2SP(dest-4)!=0x0a0d)
                                                V2SP(dest)=0x0a0d, dest+=2;
                                        key=genstring((curkeyname=buffer)+len);
                                        }
                                }
                        }
                break;
        case '@':
        case '\"':
                if (*lp!='@')
                        {
                        ++lp;
                        while (*lp&&*lp!='\"') ++lp;
                        ++buffer;
                        }
                *lp++=0, skipbytes=lp-buffer+1;
                if (*lp)
                        {
                        while (*lp&&*lp!='=') ++lp;
                        if (*lp)
                                {
                                ++lp;
                                if (*lp=='\"') size=0, ++lp;
                                else{
                                        if (strncmpi(lp,"dword:",6)==0) size=0x10001, lp+=6;
                                        else{
                                                if (strncmpi(lp,"hex:",4)==0) size=1, lp+=4;
                                                else size=-1;
                                                }
                                        }
                                if (size>=0)
                                        {
                                        dest+=sprintf(dest,"%s,\"%s\",",root,key);//\"%s\",%d,
                                        if (*buffer) dest+=sprintf(dest,"\"%s\",", buffer); else *(dest++)=',';
                                        if (size) dest+=sprintf(dest,"%d,",size); else *(dest++)=',';
                                        if (size==0)
                                                {
                                                *dest++='\"';
                                                while (*lp)
                                                        {
                                                        if (V2SP(lp)==0x5c5c)
                                                                ++lp;
                                                        else{
                                                                if (V2SP(lp)==0x225c)
                                                                        *dest++='\"', lp++;
                                                                else{
                                                                        if (*lp=='%') *dest++='%';
                                                                        else{
                                                                                if (*lp=='\"') break;
                                                                                }
                                                                        }
                                                                }
                                                        *dest++=*lp++;
                                                        }
                                                *dest++='\"';
                                                }
                                        else dest=writebinary(lp, dest, size==1);
                                        V2SP(dest)=0x0a0d, dest+=2;
                                        }
                                }
                        }
                break;
        }
return dest-destBuffer;
}

int WINAPI writeheader(LPSTR header,int from)
{
int size;
LPSTR sp,dp;
size=knlsize, sp=header, dp=destBuffer+from;
while (*sp)
        {
        if (V2LP(sp)==0x5a502424)
                {
                lstrcpy(dp,ComBuf);
                dp+=size, sp+=4;
                }
        else *dp++=*sp++;
        }
return dp-destBuffer;
}

void WINAPI convert(void)
{
DWORD size;
LPSTR lpfile,temp;
HANDLE hfile;
if ((hfile=ezCreateFile(srcfile,0))!=INVALID_HANDLE_VALUE)
        {
        ++errorcode;
        if ((lpfile=(LPSTR)GlobalAlloc(GPTR,(size=GetFileSize(hfile,0))*5+4+sizeof(INFHEADER)))!=0)
                {
                ++errorcode;
                if (ReadFile(hfile,lpfile+size,size,&size,0)==0) size=0;
                }
        CloseHandle(hfile);
        if (size)
                {
                if (V2SP(lpfile+size)==(short)0xfeff)
                        WideCharToMultiByte(CP_ACP,0,(LPCWSTR)(lpfile+size),-1,lpfile,size,0,0);
                else
                        CopyMemory(lpfile,lpfile+size,size);
                destBuffer=(stringBuffer=(temp=lpfile+size)+1)+size+1; *temp=0;
                stringEnd=stringBuffer+sprintf(stringBuffer,"\r\n\r\n");
                #define REGID_UNICODE "Windows Registry Editor Version 5.00"
                if        (
                        strncmpi(temp=skipwhitespace(lpfile,0),"REGEDIT4",sizeof("REGEDIT4")-1)==0
                        ||
                        strncmpi(temp+1,"REGEDIT4",sizeof("REGEDIT4")-1)==0
                        ||
                        strncmpi(temp,REGID_UNICODE,sizeof(REGID_UNICODE)-1)==0
                        ||
                        strncmpi(temp+1,REGID_UNICODE,sizeof(REGID_UNICODE)-1)==0
                        )
                        {
                        ++errorcode;
                        if ((hfile=ezCreateFile(destfile,1))!=INVALID_HANDLE_VALUE)
                                {
                                ++errorcode;
                                size=writeheader(INFHEADER,0);
                                if (use_tiny_mode==0) size=writeheader(INFCOMMENTS,size);
                                size=writeheader(INFBEGIN,size);
                                while (*(temp=skipwhitespace(temp+skipbytes,1))!=0)
                                        size=genvalues(temp,size);
                                lstrcpy(destBuffer+size,stringBuffer);
                                WriteFile(hfile,destBuffer,size+(stringEnd-stringBuffer),&size,0);
                                CloseHandle(hfile);
                                printf("%s Generated ", destfile);
                                }
                        }
                }
        }
}

void WINAPI extfn(LPSTR cmd)
{
int i;
LPSTR fp;
if (*(fp=cmd)=='\"') { ++fp,++cmd; while (*fp!='\"') ++fp; *fp=0; }
GetFullPathName(cmd,MAX_PATH,ComBuf,&fp);
*((ComBuf=fp)-1)=0;
i=0; while (*fp) ++fp,++i;
while (i&&*fp!='.') --fp,--i;
if (i) *fp=0;
knlsize=i;
}

void main(int argc,char *argv[])
{
if (argc>=2)
        {
        int i; LPSTR tmp,fn1,fn2;
        for (fn1=fn2=0,i=1; i<argc; i++)
                {
                if (*(tmp=argv)=='-'||*tmp=='/')
                        {
                        switch(*(tmp+1))
                                {
                                case 'w':
                                case 'W':
                                        use_abb_key=0;
                                        break;
                                case 't':
                                case 'T':
                                        use_tiny_mode=1;
                                        break;
                                }
                        }
                else{
                        if (fn1) fn2=tmp; else fn1=tmp;
                        }
                }
        if (fn1==0) fn1=argv; ++errorcode;
        if ((ComBuf=(LPSTR)GlobalAlloc(GPTR,3*MAX_PATH))!=0)
                {
                ++errorcode;
                destfile=(srcfile=ComBuf+MAX_PATH)+MAX_PATH;
                extfn(fn1);
                lstrcpy(srcfile,fn1); if (fn2) lstrcpy(destfile,fn2); else lstrcat(lstrcpy(destfile,srcfile),".inf");
                convert();
                }
        }
printf(errorprompts);
}

2010hook 发表于 2019-1-31 17:58:36

本帖最后由 2010hook 于 2019-1-31 20:00 编辑

chishingchan 发表于 2019-1-31 17:32
真正找到的是这个!2002年的。

“不能转换x64带有(x86)的路径”,我误会了,reg里面就是这样,没转换。
你能趁春节假期稍微完善一下吗?工作量应该不大吧?
输出“Provider=*”替换成“AdvancedINF=2.5”更好。

2010hook 发表于 2019-1-31 19:26:39

本帖最后由 2010hook 于 2019-1-31 20:10 编辑

嘿嘿,我用Hex编辑器修改了一下:
1、“Provider=***”改成“AdvancedINF=2.5”,支持一些高级特性。
2、主键名称,由小写改为大写。

这个48K工具,最大遗憾还是输出编码并非Unicode。

附件提供源码和cmd:

chishingchan 发表于 2019-2-1 12:04:13

2010hook 发表于 2019-1-31 19:26
嘿嘿,我用Hex编辑器修改了一下:
1、“Provider=***”改成“AdvancedINF=2.5”,支持一些高级特性。
2、 ...

可以整合到上下文菜单(右键菜单)

AdvancedINF=2.5, "您需要一个新版本的 ADVPACK.DLL 文件"
Signature="$CHICAGO$"


AddReg=添加注册表
CopyFiles=复制文件


复制文件=11

[复制文件]
Reg2Inf.exe

[添加注册表]
HKCR,"regfile\shell\转换为(.&INF)\command",,0x20000,"Reg2Inf.exe -w ""%%1"""
页: [1]
查看完整版本: Reg2Inf 源码改进,C#和正则式