【玩转.Net MF – 05】加载文件系统中的Pe文件

简介:

在远程文件查看器里,我们可以很方便地访问设备的文件,但是有一点,双击其中的pe文件并不能直接执行,下面我们将为.Net MF添加这个功能。

默认情况下,.Net MF的用户程序是放在Flash中的BLOCKTYPE_DEPLOYMENT区(参见《Flash远程读写》),只能通过VS2008进行部署。TinyCLR启动后,直接从Flash的BLOCKTYPE_DEPLOYMENT区的加载应用程序,由于这样的设计,所以在Flash上仅能存放一个用户程序。

.Net MF已经支持了文件系统,并且我们实现了远程文件查看器,理论上只要空间足够,我们能放若干个用户程序,这样问题就来了,我们能否任意执行文件系统中的pe文件?

.Net MF系统中的可执行文件或模块,其扩展名并不是exe或dll,统一为pe,唯一不同是,可执行的pe文件中含有启动入口标识。pe文件是exe和dll经过MetaDataProcessor.exe文件再加工而来。

实现思路其实很简单:第一、分别把不同的用户程序,放到不同目录中去;第二、在根目录建立一个config.ini纯文本文件,里面有一条记录:Startup=\xxx,标识启动项;第三、修改TinyCLR代码,让其从config.ini中的指定目录处加载用户程序。

 TinyCLR中的Code修改如下(CLRStartup.cpp文件),枚举指定目录中的pe文件,并加载之。


 
 
  1.  HRESULT LoadDeploymentAssemblies()  
  2.  
  3.  {  
  4.  
  5.      TINYCLR_HEADER();  
  6.  
  7.    
  8.  
  9.      WCHAR current_file[256];  
  10.  
  11.        WCHAR temp_path[256];  
  12.  
  13.      UINT32 findHandle=NULL;   
  14.  
  15.        FileSystemVolume* volume = NULL;  
  16.  
  17.      STREAM_DRIVER_INTERFACE*  streamDriver=volume->m_streamDriver;  
  18.  
  19.        HRESULT ret;  
  20.  
  21.    
  22.  
  23.      volume = FileSystemVolumeList::GetFirstVolume();  
  24.  
  25.        if(volume ==NULL)  
  26.  
  27.        {  
  28.  
  29.             TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  30.  
  31.        }  
  32.  
  33.        streamDriver=volume->m_streamDriver;  
  34.  
  35.          if(streamDriver==NULL)  
  36.  
  37.        {  
  38.  
  39.             TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  40.  
  41.        }  
  42.  
  43.      //--  
  44.  
  45.      UINT32 rHandle = NULL;    
  46.  
  47.       if(streamDriver->Open(&volume->m_volumeId, L"\\config.ini", &rHandle) == S_OK && rHandle != NULL)  
  48.  
  49.        {             
  50.  
  51.               INT64 FileSize;  
  52.  
  53.               int bytesread=0;  
  54.  
  55.             streamDriver->GetLength(rHandle,&FileSize);  
  56.  
  57.                 if(FileSize>510 || FileSize<20)  
  58.  
  59.                 {  
  60.  
  61.                      streamDriver->Close(rHandle);   
  62.  
  63.                 if(FileSize == 0)  debug_printf("Can't find config.ini!\r\n");  
  64.  
  65.                      else debug_printf("Load Application failed(2)!\r\n");  
  66.  
  67.                   TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  68.  
  69.                 }             
  70.  
  71.          if(streamDriver->Read(rHandle, (BYTE *)temp_path,(INT32)FileSize ,&bytesread) != S_OK && bytesread!=(UINT32)FileSize)  
  72.  
  73.              {  
  74.  
  75.                     streamDriver->Close(rHandle);    
  76.  
  77.                  debug_printf("Load Application failed(3)!\r\n");  
  78.  
  79.                  TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  80.  
  81.              }  
  82.  
  83.              streamDriver->Close(rHandle);             
  84.  
  85.    
  86.  
  87.              if(temp_path[0]!=0xFEFF || temp_path[8]!=0x3D)  
  88.  
  89.              {  
  90.  
  91.                  TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  92.  
  93.              }  
  94.  
  95.              memcpy(current_file, &temp_path[9],FileSize-9*2 );  
  96.  
  97.              temp_path[FileSize/2-9] = 0;  
  98.  
  99.              for(int i=FileSize/2-10;i>0; i--)  
  100.  
  101.              {  
  102.  
  103.                   if(current_file[i]==0x0D ||current_file[i]==0x0A) current_file[i] = 0;  
  104.  
  105.              }  
  106.  
  107.       }  
  108.  
  109.         else 
  110.  
  111.       {  
  112.  
  113.             TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);  
  114.  
  115.         }  
  116.  
  117.         //--  
  118.  
  119.         ret = volume->FindOpen(current_file,&findHandle);  
  120.  
  121.       if(findHandle==NULL || ret != S_OK)  
  122.  
  123.   {  
  124.  
  125.            TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);      
  126.  
  127.       }    
  128.  
  129.     //--  
  130.  
  131.     FS_FILEINFO findData;  
  132.  
  133.     int pathsize=wcslen(current_file);  
  134.  
  135.       current_file[pathsize++]='\\';  
  136.  
  137.        
  138.  
  139.     findData.FileName=(UINT16 *)&current_file[pathsize];  
  140.  
  141.     findData.FileNameSize = 200;  
  142.  
  143.       memset(findData.FileName,0,(findData.FileNameSize+1)*2);  
  144.  
  145.                
  146.  
  147.       BOOL found=FALSE;   
  148.  
  149.       ret = volume->FindNext(findHandle,&findData,&found);  
  150.  
  151.       while( ret==S_OK && found)  
  152.  
  153.       {        TINYCLR_CHECK_HRESULT(ContiguousBlockAssemblies(volume,current_file));            
  154.  
  155.            memset(temp_path,0,findData.FileNameSize+1);  
  156.  
  157.             ret = volume->FindNext(findHandle,&findData,&found);   
  158.  
  159.       }   
  160.  
  161.     //--  
  162.  
  163.     volume->FindClose(findHandle);       
  164.  
  165.       TINYCLR_NOCLEANUP();             
  166.  
  167. }  
  168.  

远程文件查看器中的代码稍加修改,就能支持双击运行。在双击事件里,一是修改config.ini文件中的运行目录,二是重启TinyCLR,让其加载指定目录中的程序。由于相关代码比较简单,这里就不贴了。

下面来演示一下最终成果。

1、              新建两个.Net MF测试程序,分别命名为Test1、Test2,相关代码如下:


 
 
  1. public static void Main()  
  2.  
  3. {  
  4.  
  5. Debug.Print("123456789");  
  6.  
  7. }  
  8.  
  9. public static void Main()  
  10.  
  11. {  
  12.  
  13. Debug.Print("abcdefghijklmn!!!");  
  14.  
  15. }  
  16.  

编译后的pe文件分别为:Test1.pe,Test2.pe

2、              新建config.ini文件(这步可以省略)

3、              通过远程文件查看器,新建两个目录,Test1和Test2,分别拷入Test1.pe和Test2.pe文件。

 

 

4、              分别双击Test1.pe和Test2.pe文件,查看运行结果。


 

 

 






本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/321213,如需转载请自行联系原作者

相关文章
|
Windows
.Net Micro Framework研究—模拟器直接运行MF程序
既然VS2005能启动运行,我想我们也可以,唯一不同的是模拟器加载的参数不同而已
761 0
.Net Micro Framework研究—用MF编写俄罗斯方块
现在对MF充满了激情,所以从零做起(没有参考任何现成代码,只不过还是依照我早期的思路编写而成),花费我大半天的时间才编写完毕(在编写过程中,还发现MF对二维数组支持不大好,我后面会提到)
430 0
.Net Micro Framework研究—让MF支持鼠标
MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了
537 0
|
机器人
.Net Micro Framework研究—用MF控制机器人
机器人研究一直是我很早以前的梦想,没有想到在深入研究.Net Micro Framework同时能和机器人搭上了联系。
620 0
.Net Micro Framework研究—让MF支持英文输入法
目前字符串不仅无法转换为数字,并且没有字符插入功能,所以这个函数也必须自己来实现,此外输入焦点光标也需要自己绘制,好了,先不说难处了,先看看最终成果。
795 0
.Net Micro Framework研究—MF驱动继电器
年前张欣有一个比较好的想法,想用Digi的MF板驱动一个小型继电器,这样就可以用MF直接控制家中的小功率220V的电器了
636 0
|
安全
.Net MF V4.0开源前的代码整理
已经有好长一段时间没有更新博客了,一是去美国总部和台湾出差用了不少时间,二是做.Net MF代码整理又花了近一个月的时间。不过令人欣慰的是,目前.Net MF V4.0的相关代码整理已经告一段落,就等着下一步的开源了
721 0
|
Linux C++ C#
【.Net Micro Framework PortingKit – 15】移植总结兼MF未来发展
我坚信.Net Micro Framework在未来嵌入式发展中,一定会占有一席之地(更何况现在已经开源了,并且采用更为彻底的Apache 2.0 license)。希望更多的人参与其中,把.Net Micro Framework移植到更多嵌入式平台上去,使它成为真正名副其实的“框架”。
963 0
|
内存技术
【玩转.Net MF – 01】Flash远程读写
目前在PC远程访问设备Flash,也就是部署TinyCLR和下载应用程序
640 0
|
内存技术
【玩转.Net MF – 02】让PC成为MF的鼠标键盘
通过扩展我以前为.Net MF开发的WinForm库(参见我以前的文章《开源System.Windows.Forms库,让.Net Micro Framework界面开发和上位机一样简单》),增加一个输入代理层,就可以实现虚拟鼠标和键盘输入。
695 0