Chinaunix首页 | 论坛 | 博客
  • 博客访问: 790078
  • 博文数量: 156
  • 博客积分: 5320
  • 博客等级: 大校
  • 技术积分: 1605
  • 用 户 组: 普通用户
  • 注册时间: 2004-10-09 12:24
文章分类

全部博文(156)

文章存档

2010年(20)

2009年(46)

2008年(21)

2007年(21)

2006年(33)

2005年(10)

2004年(5)

分类: WINDOWS

2009-03-24 12:01:03

方法一:修改注册表  
   
  设计思路  
   
          一般情况下,当用户在控制面板中配置好ODBC数据源后,Windows系统便在注册表中加入了一些子键来存储用户的配置结果。当应用程序需要用到数据源时,Windows便会通知底层接口查阅注册表中该数据源的配置。如果用户删除了某个ODBC数据源,那么也会在注册表中有所反应。如果配置的数据源是用户数据源,   Windows系统便会修改注册表的HKEY_CURRENT_USERSOFTWAREODBCODBC.INI子键;如果配置的数据源是系统数据源,Windows系统便会修改注册表的HKEY_LOCAL_MACHINESOFTWAREODBCODBC.INI主键。因此,我们可以在应用程序中使用Windows   API中的注册表编辑函数来完成Windows所做的工作,这样就可以达到动态加载数据源的目的。  
   
  具体实现  
   
          对于不同类型的数据源,注册表的修改也各有不同,但基本上都要修改两个地方。一个是在   ODBC.INI子键下建立一个与数据源描述名同名的子键,并在该子键下建立与数据源配置相关的项;另一个是在ODBC.INIODBC   Data   Sources子键下建立一个新项以便告诉驱动程序管理器ODBC数据源的类型。下面以配置一个Microsoft   Access数据源为例给出实现此功能的函数的代码。  
   
  /*strSourceName是要创建的数据源名,strSourceDb是数据库存放路径,strDescription是数据源的描述字符串。*/  
   
  BOOL   CLoadOdbcDlg::LoadDbSource(CString   strSourceName,   CString   strSourceDb,   CString   strDescription)  
  {  
      //存放打开的注册表键  
      HKEY   hKey;  
      DWORD   dw;  
   
      //存放注册表API函数执行的返回值  
      LONG   lReturn;  
   
      //存放要打开的子键  
      CString   strSubKey;  
   
      //检测是否安装了MS   Access   ODBC   driver:odbcjt32.dll  
      //获得   Windows系统目录  
      char   sysDir[MAX_PATH];  
      char   drvName[]="\odbcjt32.dll";  
      ::GetSystemDirectory(sysDir,   MAX_PATH);  
      strcat(sysDir,drvName);  
      CFileFind   findFile;  
      if(!findFile.FindFile(sysDir))  
      {  
          AfxMessageBox("您的计算机系统中没有安装MS   Access的ODBC驱动程序odbcjt32.dll,您将无法加载该类数据源。"   ,MB_OK   |   MB_ICONSTOP);  
          return   false;  
      }  
   
      strSubKey="SOFTWARE\ODBC\ODBC.INI\"   +   strSourceName;  
      //创建   ODBC数据源在注册表中的子键  
      lReturn=::RegCreateKeyEx(HKEY_LOCAL_MACHINE,   (LPCTSTR)strSubKey,   0,   NULL,   REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dw);  
      if(lReturn   !=   ERROR_SUCCESS)  
          return   false;  
   
      //设置数据源的各项参数  
      CString   strDbq   =   strSourceDb;  
      CString   strDriver   =   sysDir;  
      DWORD   dwDriverId   =   25;  
      CString   strFil   =   "MS   Access;";  
      CString   strPwd   =   strSourceName;  
      DWORD   dwSafeTransactions   =   0;  
      CString   strUid   =   strSourceName;  
      ::RegSetValueEx(hKey,   "DBQ",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strDbq),   strDbq.GetLength());  
      ::RegSetValueEx(hKey,   "Description",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strDescription),   strDescription.GetLength());  
      ::RegSetValueEx(hKey,   "Driver",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strDriver),   strDriver.GetLength());  
      ::RegSetValueEx(hKey,   "DriverId",   0L,   REG_DWORD,   (CONST   BYTE*)(&dwDriverId),   sizeof(dw));  
      ::RegSetValueEx(hKey,   "FIL",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strFil),strFil   .GetLength   ());  
      ::RegSetValueEx(hKey,   "PWD",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strPwd),strPwd.GetLength   ());  
      ::RegSetValueEx(hKey,   "SafeTransactions",   0L,   REG_DWORD,   (CONST   BYTE*)(&dwSafeTransactions),   sizeof(dw));  
      ::RegSetValueEx(hKey,   "UID",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strUid),strUid.GetLength());  
      ::RegCloseKey(hKey);  
   
      //创建   ODBC数据源的Jet子键  
      strSubKey   +=   "\Engines\Jet";  
      lReturn   =   ::RegCreateKeyEx(HKEY_LOCAL_MACHINE,   (LPCTSTR)strSubKey,   0,   NULL,   REG_OPTION_NON_VOLATILE,   KEY_WRITE,   NULL,   &hKey,   &dw);  
      if(lReturn   !=   ERROR_SUCCESS)  
          return   false;  
   
      //设置该子键下的各项参数  
      CString   strImplict="";  
      CString   strUserCommit="Yes";  
      DWORD   dwPageTimeout=5;  
      DWORD   dwThreads=3;  
      DWORD   dwMaxBufferSize=2048;  
      ::RegSetValueEx(hKey,   "ImplicitCommitSync",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strImplict),   strImplict.GetLength()+1);  
      ::RegSetValueEx(hKey,   "MaxBufferSize",   0L,   REG_DWORD,   (CONST   BYTE*)(&dwMaxBufferSize),   sizeof(dw));  
      ::RegSetValueEx(hKey,   "PageTimeout",   0L,   REG_DWORD,   (CONST   BYTE*)(&dwPageTimeout),   sizeof(dw));  
      ::RegSetValueEx(hKey,   "Threads",   0L,   REG_DWORD,   (CONST   BYTE*)(&dwThreads),   sizeof(dw));  
      ::RegSetValueEx(hKey,   "UserCommitSync",   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strUserCommit),   strUserCommit.GetLength());  
      ::RegCloseKey(hKey);  
   
      //设置ODBC数据库引擎名称  
      lReturn=::RegOpenKeyEx(HKEY_LOCAL_MACHINE,   "SOFTWARE\ODBC\ODBC.INI\ODBC   Data   Sources",   0L,   KEY_WRITE,   &hKey);  
      if(lReturn   !=   ERROR_SUCCESS)  
          return   false;  
      CString   strDbType="Microsoft   Access   Driver   (*.mdb)";  
      ::RegSetValueEx(hKey,   strSourceName,   0L,   REG_SZ,   (CONST   BYTE*)((LPCTSTR)strDbType),   strDbType.GetLength());  
   
      return   true;  
  }  
   
  由于在动态加载中,一般只会改变数据库文件、数据源说明以及数据源描述,故上述函数可以实现应用中的大部分要求。如果应用中还需要作更多的改变,那么也可以通过改变函数参数的方式加以实现。对于需要动态加载多种类型数据源的情况,可以用具有不同参数的重载函数去实现。  
   
  方法二:利用DLL  
   
  设计思路  
   
          Windows系统子目录中的动态链接库Odbcinst.dll提供了一个可以动态地增加、修改和删除数据源的函数SQLConfigDataSource()。该函数的原型如下:  
   
          BOOL   SQLConfigDataSource(HWND   hwndParent,   WORD   fRequest,   LPCSTR   lpszDriver,   LPCSTR   lpszAttributes);  
   
  hwndParent参数是父窗口句柄。如果该值为NULL,将不会显示与父窗口有关的对话框。  
   
  fRequest参数可以设置为下面的数值之一:  
   
      ODBC_ADD_DSN:增加一个新的用户数据源;  
  ?ODBC_CONFIG_DSN:修改(配置)一个已经存在的用户数据源;  
  ?ODBC_REMOVE_DSN:删除一个已经存在的用户数据源;  
  ?ODBC_ADD_SYS_DSN:增加一个新的系统数据源;  
  ?ODBC_CONFIG_SYS_DSN:修改   (配置)一个已经存在的系统数据源;  
  ?ODBC_REMOVE_SYS_DSN:删除一个已经存在的系统数据源。  
   
      lpszDriver参数用于传递数据库引擎的名字,等同于方法一中strDbType变量。  
   
      lpszAttirbutes参数是关键字的值,即一连串的"keyname=value"字符串,每两个字符串之间用   ""隔开,如   DSN   =   Personnel   Data
 
 
1 创建REG文件
  我们就以创建一个可以解除注册表禁用限制的REG文件restore.reg为例来介绍一下具体过程。 

  打开记事本,在记事本文件中输入以下内容: 

  REGEDIT4 

  空一行 

  [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System] 

  "DisableRegistryTools"=dword :  

  00000000 

  保存此文件,在打开的“另存为”对话框中选择好保存路径,再单击“保存类型”中的下拉箭头选择“所有文件”(一定要选择此步,不然保存后的文件会自动加上TXT的扩展名),然后在“文件名”中输入“restore.reg”后按“保存”按钮(如图1)。以后你就可以通过双击这个restore.reg来直接解除禁用注册表的限制。 

  对REG文件进行修改 

  我们在利用REG文件对注册表进行操作时,要操作的对象有两种:一种是对主键进行操作,一种是对主键下的键值项目进行操作。对主键的操作有添加、删除两种,而对键值项目的操作则分为添加、修改和删除三种。下面我们就一个一个来实现。 

  1、对主键的操作 

  (1)添加主键 

  要想利用REG文件在注册表中添加一个主键是非常方便的,只需要在文件体部分直接以“[ ]”的形式写上要添加的主键路径即可。 

  例如:在HKEY_LOCAL_MACHINE\Software主键下添加一个名称为“123456”的主键,内容如下: 

  REGEDIT4 

  空一行 

  [HKEY_LOCAL_MACHINE\Software\123456] 



  (2)删除主键 

  要用REG文件在注册表中删除一个主键,在文件体部分“[ ]”括起来的主键路径前面加上一个“-”符号即可,删除主键操作将会一并删除该主键下的所有子键及其键值项目,所以这是个比较危险的命令,使用要十分注意。例如要删除我们刚才添加的那个主键,内容如下: 

  REGEDIT4 

  空一行 

  [-HKEY_LOCAL_MACHINE\Software\123456] 

  2、对键值项目的操作 

  (1)添加键值项目 

  添加键值项目的操作如同注册表编辑器中的“新建”命令,一般来说,键值的数据类型分为三种:字符串值、二进制值和DWORD值。在REG文件中我们也要设置添加的键值项目的数据类型,如果要添加字符串值,则“=”号后边要用英文的双引号引住数据;如果添加的为DWORD类型值,“=”号后边的格式为“dword:数据”;如果添加的为二进制值,“=”号后边则为“hex:数据”。要设置默认值的键值数据时,“=”号前边的键值名称应为“@”符号,并且没有双引号。 

  例如我们要在“HKEY_LOCAL_MACHINE\Software\123456”主键下设置默认键值为“654321”,并分别添加“姓名”键值项目(字符串值)、“年龄”键值项目(二进制值)、“婚否”键值项目(DWORD值)。相应的REG文件内容如下: 

  REGEDIT4 

  空一行 

  [HKEY_LOCAL_MACHINE\Software\12356] 

  @="654321" 

  "姓名"="徐海斌" 

  "年龄"=hex:23 

  "婚否"=dword:00000000 

  在添加键值项目时,如果该键值所在的主键路径不存在的话,在添加键值项目的同时会自动新建该主键。另外在添加字符串值的键值项目时还有一点值得注意的地方,当这个字符串值是包括文件路径的字符串值时,路径分隔符应用“\\”双斜杠表示,以示和注册表中的主键路径分隔符区别开来。例如我们要在注册中“HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ 

  Run”主键下的启动组中添加位于“C:\PROGRAM FILES\BOOBSOFT\屏幕保护控制器”目录下的一个应用程序“屏幕保护控制器.exe”的启动键值项目,REG文件内容如下: 

  REGEDIT4 

  空一行 

  [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] 
 

2 创建REG文件

  "scr"="C:\\PROGRAM ILES\\BOOBSOFT\\屏幕保护控制器\\屏幕保护控制器.exe" 

  (2)修改键值项目 

  其实修改和添加很类似,对于已经存在的键值项目,我们要修改其数据时,只需要将正确的数据赋予对应的键值项目即可,新的数据会自动覆盖错误的旧数据,例如,当某些恶意网页修改了你的IE标题栏文字,在标题栏中总是显示那个网站的广告文字,很讨厌,我们知道修改IE标题栏文字是通过“HKEY_CURRENT_USER\Software\ 


  Microsoft\Internet Explorer\Main”主键下的“Window Title”(如图2)键值的数据进行设置的,那么我们就可以通过REG文件改回默认的IE标题栏文字。 

  REGEDIT4 

  空一行 

  [HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main] 

  "Window Title"="" 

  (3)删除键值项目 

  用REG文件删除键值项目也是很方便的,和删除主键相类似,也是通过“=”号实现的,不过这次不是加在前面,而是把“-”符号放在键值项目的等号后面。例如一些恶意网页在修改IE标题栏等设置的同时,还修改了开始菜单相关的键值项目数据,使得开始菜单中的“运行”、“查找”、“关闭”等命令都不见了,导入下面的这个REG文件删除相应的键值项目后就可以找回开始菜单中的这些命令了。 

  REGEDIT4 

  空一行 

  [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policie*\**plorer]  

  "NoRun"=-(解除“运行”命令) 

  "NoClose"=-(找回“关闭系统”命令) 

  "NoFind"=-(找回“查找”命令) 

  下一次我们将来实现REG文件的关联,看看REG文件是如何将其中的数据导入到注册表中的。 

  上一次我们认识了REG文件,知道了如何创建REG文件和通过REG文件进行添加、修改、删除操作,这一次我们来看一看REG文件是如何将其中的数据导入到注册表中的。 

  导入信息 


  当我们双击REG文件时,系统会首先提示“确实要把XXX.REG内的信息添加到注册表吗?”的询问对话框(如图1),单击“是”按钮,系统就会按照REG文件中所描述的操作对注册表进行修改,完成以后并会给出提示“XXX.REG中的信息已经成功输入注册表”,把REG文件中的信息导入注册表的操作称为“合并”。 


  修改默认值 

  在REG文件上单击鼠标右键,有三个命令是关于REG文件的:合并、Print、编辑,以粗体显示的就是“合并”操作,这也是默认的打开方式,也就是双击时执行的操作。如果你不想让双击REG文件时执行“合并”的操作,你可以更改它的默认打开方式为“编辑”。打开资源管理器,单击“查看”菜单中的“文件夹选项”命令,在打开的对话框中单击“文件类型”标签,然后在“已注册的文件类型”列表中找到并选中“注册表项目”(如图2),从下面的“打开方式”我们也可以看出:原来REG文件默认的“合并”操作关联的是注册表编辑器Regedit呀! 接下来点击“编辑”按钮,打开“编辑文件类型”对话框,然后选择“操作”列表中的“编辑”,再点击“设为默认值”按钮即可(如图3),以后双击REG文件时就会用记事本来打开进行编辑。 


  在这里笔者顺便告诉大家一个独门绝技,如果你希望REG文件在导入时没有任何提示,你可以在图4所示的对话框中选中“合并”,然后单击“编辑”按钮,在弹出对话框的命令行中输入“regedit.exe /s "%1"”即可,这是使用了注册表编辑器Regedit的一个被称为安静导入模式的隐藏参数“/S”,在导入REG文件时如果加上“/S”参数,系统就不会再弹出任何提示对话框而直接导入了。 


  解除禁用 

  有时在某些电脑中设置了禁用注册表编辑器后,为了防止一些电脑高手使用REG文件(看完了这篇文章你也可以成为高手了^_^)来解除对注册表编辑器的限制,会让REG文件的默认打开程序设置为其他无关程序,当然这时可以通过修改“文件夹选项”中的相关设置改回来,但还有一种更绝的办法可以使REG文件不能用系统默认的方式打开。 


  运行注册表编辑器,将“HKEY_CLASSES_ROOT\.reg”下的默认值改为“txtfile”,这时REG文件的打开方式都指向了TXT文本文件。这样更改后不知道的人即使修改“文件夹类型”中的“注册表项目”设置也无法改回来,当然这时系统也已经禁用了注册表编辑器,你是无法通过注册表编辑器修改了。但经过笔者的研究发现还有一种方法可以破解这种禁用REG文件。我们可以在编辑好的REG文件上按住“Shift”键的同时单击鼠标右键,这时系统会让你重新选择打开方式,从中选取用注册表编辑器Regedit打开就可以将REG文件导入注册表了。
阅读(6339) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~