CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

delphi可以编写VXD虚拟驱动程序吗?

楼主wen_zang(文臧)2001-09-01 14:49:06 在 Delphi / VCL组件开发及应用 提问

delphi可以编写VXD虚拟驱动程序吗?  
  如果能,该怎么写?  
  最好能给我一个小实例。。。。(详细一点) 问题点数:84、回复次数:45Top

1 楼wen_zang(文臧)回复于 2001-09-01 23:40:10 得分 0

  这么久了,都没人答。  
  提前一点点。。。。。。Top

2 楼summernightrain(夏夜雨)回复于 2001-09-01 23:47:14 得分 70

可以是可以,但是还是不太好,因为这方面的资料太少了,你会做不下去的。如果你以前没有用过C开发VXD的话,我建议你还是用C吧!!  
   
  转贴一篇文章。  
   
  用   Delphi   编写   VxD   设备驱动程序(转)(sundyl   转贴)  
   
       
  出处:http://www.chinaasp.com/columns/delphi/article1472.asp  
   
  正文:  
   
  用   Delphi   编写   VxD   设备驱动程序(转)  
   
  关键词:Delphi控件杂项  
   
  作者:Emil   Biserov(dinfo@mail.primorye.ru)(Russion)    
  英语翻译:Vitaly   Zayko(zayko@vitsoftware.com)    
  中文翻译改编:Riceball(teditor@mailroom.com)    
   
  前言    
      用   Delphi   3.0   编写   VxD   设备驱动程序,在Delphi   3   下编译通过,Delphi   2   下没有测试,Delphi   4   建立的   Object   文件   M$   Linker   5.12.8181   不能识别,这里使用的汇编器是M$的Macro   Assembler   ver.   6.11d   ,联结器是M$   Incremental   Linker   ver.   5.12.8181   ,它们来自   Windows   98DDK(http://www.microsoft.com/ddk/ddk98.htm)。    
   
  介绍    
      Windows   存在有两种类型的   VxD   设备驱动程序:    
          1、静态(Static)   VxD   ,装入操作系统并永久的存在于内存中;    
          2、动态(Dynamic)   VxD,当需要时才调入内存,用完后关闭VxD即可释放内存。    
      Inprise   Delphi   有能力建立任何一种类型的   VxD   设备驱动程序,下面我们将介绍如何建立动态   VxD。    
      当   Win32   应用程序打开一个   VxD   “虚拟”设备时,VWIN32   使用   LoadDevice   将   VxD   装入内存,并建立消息W32_DEVICEIOCONTROL   ,发向   VxD。    
      也就是说,VxD   至少应该响应以下两个系统信息和编写以下的一个函数:    
          SYS_DYNAMIC_DEVICE_INIT    
          SYS_DYNAMIC_DEVICE_EXIT    
          W32_DEVICEIOCONTROL   函数.    
      消息   SYS_DYNAMIC_DEVICE_INIT   在尝试装入   VxD   时发送到   VxD   ,消息   SYS_DYNAMIC_DEVICE_EXIT   在尝试动态交换时发送到   VxD   ,消息的处理者在成功处理后,应该在寄存器   AX   中返回   VXD_SUCCESS   标志。    
   
      W32_DEVICEIOCONTROL   的   dwService   参数有以下的值:    
          DIOC_OPEN   当   VxD   通过   CreateFile()   函数尝试打开操作时发送(在   SYS_DYNAMIC_DEVICE_INIT   消息后),如果成功返回   NO_ERROR   (0);      
          DIOC_CLOSEHANDLE   当   VxD   通过   CloseHandle()   函数尝试关闭操作时发送(在   SYS_DYNAMIC_DEVICE_EXIT   前)    
          所有其它的值   >   0   意味着不同的函数调用(由   dwIoControlCode   给出),当   VxD   被   DeviceIoControl   函数调用时。    
   
  启动模块(vxdmain.asm)    
  ...    
  extrn   SysDynamicDeviceInit   :PROC    
  extrn   SysDynamicDeviceExit   :PROC    
  extrn   W32DeviceIoControl     :PROC    
  ...    
                                                  PUBLIC     DELPHIIO_DDB    
                          Public     @@HandleFinally    
                          Public     @initialization    
  ...    
  Control_0         proc    
          cmp         eax,   SYS_DYNAMIC_DEVICE_INIT    
          jnz         short   chkSysDynExit    
          call         SysDynamicDeviceInit    
          cmp         eax,   1    
          retn          
  ;-------------    
   
  chkSysDynExit:    
          cmp         eax,   SYS_DYNAMIC_DEVICE_EXIT    
          jnz         short   chkDevIOCtl    
          call         SysDynamicDeviceExit    
          cmp         eax,   1    
          retn          
  ;-------------    
  chkDevIOCtl:    
          cmp         eax,   W32_DEVICEIOCONTROL    
          jnz         short   loc_ret    
          push         esi    
          push         edx    
          push         ebx    
          push         ecx    
          call         W32DeviceIoControl    
          cmp         eax,   1    
          retn          
  ;-------------    
  loc_ret:    
          clc          
          retn          
   
  Control_0         endp    
   
  @@HandleFinally:    
  @initialization:    
                          ret    
   
  _LTEXT     ends    
                                                  END    
   
      Delphi   会为单元的   initialization/finalization   建立代码调用外部过程   HandleFinaly   和   initialization   ,即使   initialization/finalization   在单元中不存在。因此我们在汇编的启动文件中建立空的外部过程入口。    
   
  主   Delphi   程序单元(vxdProcs.pas)      
  ...    
  procedure   ShellMessage(Handle,   Flags   :   integer;   const   Message,   Caption   :   PChar;      
      Callback,   ReferenceData   :   pointer);   stdcall;   assembler;    
  asm    
      mov         ebx,   Handle                 //   virtual   machine   handle    
      mov         eax,   Flags                 //   message   box   flags    
      mov         ecx,   Message                 //   address   of   message   text    
      mov         edi,   Caption                 //   address   of   caption   text    
      mov         esi,   Callback                 //   address   of   callback    
      mov         edx,   ReferenceData                 //   reference   data   for   callback    
   
      int         20H                         //   VxDCall    
      dd         170004h                         //   Shell_Message    
  end;    
   
  function   SysDynamicDeviceInit   :   INTEGER;    
  begin    
      ShellMessage(0,   $10,   Copyright,   'SysDynInit:   Hello   from   Delphi   VxD   !!!',   nil,   nil);    
      Result   :=   VXD_SUCCESS;    
  end;    
   
  function   SysDynamicDeviceExit   :   INTEGER;    
  begin    
      ShellMessage(0,   $10,   Copyright,   'SysDynDevExit:   Bye   from   Delphi   VxD   !!!',   nil,   nil);    
      Result   :=   VXD_SUCCESS;    
  end;    
   
  function   W32DeviceIoControl(dwService   :   INTEGER;    
                                                          dwDDB   :   INTEGER;    
                                                          hDevice   :   INTEGER;    
                                                          lpDIOCParms   :   pointer)   :   INTEGER;    
  begin    
      ShellMessage(0,   $10,   Copyright,   'W32DevIOCtl',   nil,   nil);    
   
      if   (dwService   =   DIOC_OPEN)   then    
      begin    
              Result   :=   NO_ERROR;    
      end    
      else   if   (dwService   =   DIOC_CLOSEHANDLE)   then    
      begin    
              Result   :=   VXD_SUCCESS;    
      end    
      else   if   (dwService   >   MAX_PASVXD_W32_API)   then    
      begin    
              Result   :=   ERROR_NOT_SUPPORTED;    
      end    
          else    
      begin    
              Result   :=   VXD_SUCCESS;      
      end;    
  end;    
  ...    
   
   
  [译者:好了,简单的   VxD   设备驱动程序编写完毕了。你可以将它当作一个写   VxD   设备驱动程序的模板。]    
   
  附一:Make.bat    
  D:\VISUAL~1\98DDK\BIN\Win98\ml   -coff   -DBLD_COFF   -DIS_32   -W2   -c   -Cx   -Zm   -DMASM6   vxdmain.asm    
  call   dcc3.bat   -J   vxdprocs.pas    
  D:\VISUAL~1\98DDK\BIN\link   /DEF:vxddef.def   /VXD   vxdmain.obj   vxdprocs   /OUT:delphiio.vxd    
   
  附二:    
  现在让我们来编写对该   VxD   的测试程序,两个按钮:一个打开   VxD;一个关闭   VxD。    
   
  const    
  VxDName   =   '\\.\DELPHIIO.VXD';    
   
  ...    
   
  function   TVxDTestForm.OpenVxDDriver:   boolean;    
  begin    
  HVxDHandle   :=   CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);    
  Result   :=   HVxDHandle   <>   INVALID_HANDLE_VALUE;    
  end;    
   
  procedure   TVxDTestForm.CloseVxDDriver;    
  begin    
  if   HVxDHandle   <>   INVALID_HANDLE_VALUE   then   begin    
      CloseHandle(HVxDHandle);    
      HVxDHandle   :=   INVALID_HANDLE_VALUE;    
  end;    
  end    
     
     
  Top

3 楼chechy(www.qdocuments.net)回复于 2001-09-01 23:48:16 得分 5

我从一些资料上看过,好像是能写。其实Delphi中也可以用汇编的。  
  理论上,Windows上的程序Delphi都能写。当然了Delphi的效率确实比VC稍差。  
  我对底层程序没有兴趣,所以,你别问我该怎么写,我不会。  
   
  另:提问题最好在工作日,工作时间提。那时人气比较旺。Top

4 楼WorldCreater(造化天尊)回复于 2001-09-01 23:50:08 得分 0

听听Top

5 楼wen_zang(文臧)回复于 2001-09-02 00:43:00 得分 0

...    
  extrn   SysDynamicDeviceInit   :PROC    
  extrn   SysDynamicDeviceExit   :PROC    
  extrn   W32DeviceIoControl     :PROC    
  ...    
                                                  PUBLIC     DELPHIIO_DDB    
                          Public     @@HandleFinally    
                          Public     @initialization    
  ...    
  Control_0         proc    
          cmp         eax,   SYS_DYNAMIC_DEVICE_INIT    
          jnz         short   chkSysDynExit    
          call         SysDynamicDeviceInit    
          cmp         eax,   1    
          retn          
  ;-------------    
   
  chkSysDynExit:    
          cmp         eax,   SYS_DYNAMIC_DEVICE_EXIT    
          jnz         short   chkDevIOCtl    
          call         SysDynamicDeviceExit    
          cmp         eax,   1    
          retn          
  ;-------------    
  chkDevIOCtl:    
          cmp         eax,   W32_DEVICEIOCONTROL    
          jnz         short   loc_ret    
          push         esi    
          push         edx    
          push         ebx    
          push         ecx    
          call         W32DeviceIoControl    
          cmp         eax,   1    
          retn          
  ;-------------    
  loc_ret:    
          clc          
          retn          
   
  Control_0         endp    
   
  @@HandleFinally:    
  @initialization:    
                          ret    
   
  _LTEXT     ends    
                                                  END    
  //***************************  
  前面的这一段是什么意思?省略号省略的是:"asm.......end;"   吗??  
  Top

6 楼wen_zang(文臧)回复于 2001-09-02 11:05:56 得分 0

  又过了一晚,提前一下吧。。。Top

7 楼newsoftman(虫虫)回复于 2001-09-02 11:40:52 得分 4

好像不行,微软不授权delphi,但delphi可通过底层实现Top

8 楼BigBen(江南草)回复于 2001-09-02 15:26:33 得分 0

?ye....  
  delphi能进ring0吗?Top

9 楼wen_zang(文臧)回复于 2001-09-02 15:37:30 得分 0

听说可以。。。。Top

10 楼qiandeng(千灯)回复于 2001-09-02 16:35:29 得分 0

最好有点汇编知识才学Top

11 楼wen_zang(文臧)回复于 2001-09-02 23:57:00 得分 0

大家能不能给点建设行的答复???Top

12 楼wen_zang(文臧)回复于 2001-09-03 12:24:17 得分 0

我手中已经端着汇编教程的书看了。迫在眉睫,我是没办法中的办法了。。。。(最后的希望!)  
  帮帮忙吧。。。。。Top

13 楼summernightrain(夏夜雨)回复于 2001-09-03 14:03:20 得分 0

用Vtoolsd啊!!你不会C语言吗?不用汇编也可以开发Vxd的啊!!  
   
  Vtoolsd中有很多好的例子!!Top

14 楼wen_zang(文臧)回复于 2001-09-03 16:09:35 得分 0

我是用vtoolsd,而且写vxd的工具我都有了。VTOOLSD只产生框架,用什么来编译?vc++?ddk?编译都不成功。步骤不对吧。指个引吧。。。Top

15 楼wen_zang(文臧)回复于 2001-09-04 02:03:41 得分 0

:-(  
  我在盼望着答案。。。。Top

16 楼gezehua(键客)回复于 2001-09-04 04:44:50 得分 5

据我所知,微软禁止其他公司的产品直接写出VXD,就好像WPS要另存为DOC(word),在法律意义上是不容许的。Delphi好像要用什么东西Link一下才行,我也不记得时什么了,网上找找吧!Top

17 楼wen_zang(文臧)回复于 2001-09-04 09:44:49 得分 0

大家看看吧。gezehua(键客)的答案才是真正有建议性的答案!!!!!Top

18 楼Tense(何必)回复于 2001-09-04 12:23:40 得分 0

关注Top

19 楼sanjianxia(三剑侠)回复于 2001-09-04 12:40:08 得分 0

好像有点难!Top

20 楼summernightrain(夏夜雨)回复于 2001-09-04 16:24:29 得分 0

你先买一本书来看看或者上我告诉你的那个网站,上面有针对使用Vtoolsd的教学。  
   
  简单的说就是这样的,先用   VC建立一个简单工程,不是MFC的,   名字要和Vtoolsd生成的框架名称相同,例如:  
      Vtoolsd生成了以下  
      appytime.c  
      appytime.h  
      appytime.mak  
      三个文件,那么你就最好生成名字为appytime的工程。然后制定它的mak文件为appytime.mak。指定它编译生成的文件为appytime.vxd,这样你再把上面的三个文件考到工程文件的目录下,把这三个文件用Addfile(右击生成的工程项)加入到工程中,这样你就可以看到该工程的结构了,然后就可以加入自己的代码并且编译了。Top

21 楼wen_zang(文臧)回复于 2001-09-04 17:42:19 得分 0

为什么Vtoolsd只能装一次?卸了之后,重装就装不上了?Top

22 楼summernightrain(夏夜雨)回复于 2001-09-04 20:31:53 得分 0

听说你要锁键盘,为什么不能用程序呢?  
  用程序来封锁键盘,你可以连ctrl+alt+del都封锁啊!!所有的键都不能用,除了用鼠标结束你的程序之外,用什么来结束呢?如果你连鼠标也锁住不就行了!!  
   
  Vxd也是要加载的呀!!别人如果查到你那个Vxd,一样可以从注册表里把它去掉,再重启就就没有了,动态加载的VXD也是需要一个程序来调用的。    
   
  你是怎么协载的?Top

23 楼wen_zang(文臧)回复于 2001-09-04 21:39:03 得分 0

我另外有程序是禁止修改注册表的。这个程序是进驻‘explorer.exe’进程的。她是一个客户机监控程序,在任务栏有图标,有菜单,可用密码退出。进入windows时禁止ctrl+alt+del只是想确保我的这个程序的运行。我的程序运行后,就解开。你可以连ctrl+alt+del封锁吗?   Top

24 楼wen_zang(文臧)回复于 2001-09-04 21:42:49 得分 0

我的VXD打算静态加载。它的任务只是让人在进入windows时,用ctrl+alt+del妨碍我的主程序运行。。。。。。Top

25 楼summernightrain(夏夜雨)回复于 2001-09-05 12:02:24 得分 0

不用Ctrl+Alt+Del也可以结束你主程序,这样的工具一大堆,比如RunIt,只需要点鼠标就可以结束你的程序了。如果你只是想让别人在Ctrl+Alt+Dle弹出的任务列表中结束不掉你的程序,隐藏进程不就可以了。  
   
  屏蔽系统键:  
  var    
      tempint:Integer;  
  begin  
      SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,@tempint,0);  
  end;  
   
  恢复  
  var  
      tempint:Integer;  
  begin  
      SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,@tempint,0);  
  end;    
  Top

26 楼wen_zang(文臧)回复于 2001-09-05 12:39:23 得分 0

第一:我的程序只针对一般的计算机使用者;他们是不可以安装其他东西的。所以,使用高级方法  
          (使用工具)可以不予考虑。。。  
   
  第二:你的方法完全不起作用;  
   
  原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完  
  全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还  
  没有执行到,就根本不起作用。  
   
  如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)  
  不知可行否?)。请多指教。。。。。Top

27 楼wen_zang(文臧)回复于 2001-09-05 12:42:40 得分 0

第一:我的程序只针对一般的计算机使用者;他们是不可以安装其他东西的。所以,使用高级方法  
          (使用工具)可以不予考虑。。。  
   
  第二:你的方法完全不起作用;  
   
  原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完  
  全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还  
  没有执行到,就根本不起作用。  
   
  如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)  
  不知可行否?)。请多指教。。。。。Top

28 楼summernightrain(夏夜雨)回复于 2001-09-05 13:16:05 得分 0

你好像还没有转过弯来,等会儿我给你做一个程序(不用VXD),看你怎样只用Ctrl+Alt+Del的方式结束它。把你的Email给我。Top

29 楼summernightrain(夏夜雨)回复于 2001-09-05 14:19:46 得分 0

我试了,你说的第二种情况是对的。你不能用“另外有程序是禁止修改注册表的。这个程序是进驻‘explorer.exe’进程的。她是一个客户机监控程序,在任务栏有图标,有菜单,可用密码退出。”这个程序来禁止系统键吗?Top

30 楼wen_zang(文臧)回复于 2001-09-05 15:22:30 得分 0

不是,是用来禁止打开regedit的,还有其他的功能,如服务请求。Top

31 楼wen_zang(文臧)回复于 2001-09-05 15:28:41 得分 0

已进入青色桌面(无图标),你就无断按ctrl+alt+del   ,   然后又取消,反复作,就一定能看到  
  你要关程序了。只要她是进程,就一定能被关掉。。。(用这种方法)Top

32 楼wen_zang(文臧)回复于 2001-09-05 15:39:09 得分 0

wen_zang@163.net      
  wenzang@china.comTop

33 楼bnwxf(有一种感觉叫从容)回复于 2001-09-05 17:26:10 得分 0

http://www.driverdevelop.com/Top

34 楼dephi(四眼田鸡)回复于 2001-09-05 17:49:51 得分 0

UP  
  Top

35 楼summernightrain(夏夜雨)回复于 2001-09-06 13:00:02 得分 0

你如果使用VXD并不好,有很多麻烦的地方,第一,你必须监视你的程序是否被调用,一旦被调用那么就必须封锁键盘,当你的程序完成隐藏后,要通知VXD,告诉他可以不再封锁键盘了。第二,你要处理用户的注销问题。因为他如果注销的话,那么你的程序就会重新启动。这时你的VXD要重复上述过程。注:VXD调用API函数比较麻烦。  
  Top

36 楼wen_zang(文臧)回复于 2001-09-06 21:11:49 得分 0

TO   summernightrain(夏夜雨)  
  这也是没办法中的办法,只能从根本上去解决问题,只有vxd不属于进程。难作,也是必须要作的,不可回避。我是知道,这个是不可回避的。我问这么多只有两个目的,那就是  
  第一:除了vxd外,有没有第二种方法。  
  第二:如不得已而用vxd的话,有没有作vxd得捷径,因为我对vc++不熟,既学vc++,又学vxd,达到目的的周期太长。如果,delphi能作,就勉强用一用。起码不用重新去学一门语言。  
   
  当然,如果能得到你的建议(或帮助)最好。  
   
  在此,我谢谢你的建议。。。。。。。。Top

37 楼()回复于 2001-09-06 21:16:42 得分 0

是不是可以到VC版拉个人来讲讲解一下?Top

38 楼summernightrain(夏夜雨)回复于 2001-09-07 10:24:47 得分 0

回答:  
      1,可否考虑用钩子来处理,写一个Explorer要调用的钩子,然后再这个Dll中调用你要启动的程序,然后进行封锁键盘。  
      2,如果要学VXD的话,只开发键盘方面的,基本可以不需要C++,会C就可以了。VC++你只需要学习如何用它来编译你的   C版本的VXD就可以了。不知道你看了Vtoolsd的例子没有,它里面有两部分的例子分别是C和C++的(当然不是一样的)。我以前用它来做的硬盘隐藏就是用C编的。关于什么时候该用C什么时候该用C++,我可以说在开发VXD的时候大部分情况都是你想用什么就用什么!Top

39 楼Tense(何必)回复于 2001-09-07 15:45:45 得分 0

To:summernightrain(夏夜雨)   
  你的东东太多,我也一下糊涂了。  
  用Dephi做Vxd的也看过一些,差不多很烦。调用也麻烦。  
  Top

40 楼wen_zang(文臧)回复于 2001-09-07 17:53:21 得分 0

To:summernightrain(夏夜雨)   
  "Explorer要调用的钩子",这句话的意思不就是用Explorer来调用自己的dll吗?怎么用Explorer来调用自己的dll?Explorer能调用吗?我真有点不可思议。怎么做?你能给我讲一讲。Top

41 楼wen_zang(文臧)回复于 2001-09-07 17:59:06 得分 0

我在继续加分,欢迎大家进来踊跃发言,各抒己见。一起探讨一下。。。。。。。  
  如果不够分,我会另开几个帖子,大家来拿。但不希望灌水。。。。。。。。Top

42 楼JScript()回复于 2001-09-07 23:59:57 得分 0

.Top

43 楼wen_zang(文臧)回复于 2001-09-08 14:00:09 得分 0

大家都怎么啦?为什么都不说话。。。。。:-(Top

44 楼Focus(西门大灌人)回复于 2001-09-08 14:07:38 得分 0

GZTop

45 楼wen_zang(文臧)回复于 2001-09-08 19:49:53 得分 0

我非常沮丧的结束了这张贴子。整整一个星期了,我的目的未能达到。看来是,靠天靠地不如靠自己。。。。。。。。。。。。     Top

相关问题

  • 如何用Delphi编写VxD设备驱动程序?尝试中。。。
  • 我们讨论一下Delphi编写驱动程序的问题。
  • 关于VB驱动编写
  • 驱动程序的编写
  • 怎么用VC编写驱动程序?
  • 如何编写手写板驱动
  • 哪有编写VXD的书?
  • 用DELPHI 编写WEB ISAPI
  • 用delphi编写一个“foxmail”……
  • 怎样编写‘ISA’卡的驱动程序

关键词

  • c++
  • vc++
  • win32
  • delphi
  • 驱动
  • 函数
  • 键盘
  • vxd
  • 程序
  • w32

得分解答快速导航

  • 帖主:wen_zang
  • summernightrain
  • chechy
  • newsoftman
  • gezehua

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo