VS2005控制台程序修改nb0文件

我们要实现的功能就是通过CMD传递进来的值来在nb0文件末尾增加版本信息,新建控制台程序,自动生成的main函数如下,默认的代码非常简单:

  1. int _tmain(int argc, _TCHAR * argv[])
  2. {
  3. return0;
  4. }

为了实现此功能,我们发现有两种实现的办法,差别在于使用TCHAR还是char,下面分别给出这两种方式的实现代码,这两种实现方式CMD端传递的参数都一样,如下:

图1

1.      采用TCHAR

(1)    main函数

  1. int _tmain(int argc, _TCHAR * argv[])
  2. {
  3. TCHAR*pImageVersion;
  4. TCHAR*pFileDir;
  5. TCHAR*pFileName;
  6.  
  7. pFileDir= argv[1];
  8. pFileName= argv[2];
  9. pImageVersion= argv[3];
  10.  
  11. PIMG_CHECK_VERSION pImg_check_version;
  12.  
  13. printf("argc= %d\r\n",argc);
  14.  
  15. for(inti = 0; i < argc; i++)
  16. {
  17. printf("argv[%d]:%s\r\n",i,argv[i]);
  18. }
  19.  
  20. wcscpy(pImg_check_version->ImageVersion,pImageVersion);
  21.  
  22. AddDataToNb0File(pFileDir,pFileName,pImg_check_version);
  23. return0;
  24. }

(2)    AddDataToNb0File

  1. BOOL AddDataToNb0File(TCHAR *pFileDir,TCHAR *pFileName, PIMG_CHECK_VERSION pCheckVersion)
  2. {
  3. BOOLret = FALSE;
  4. TCHARtFilePath[FILE_NAME_LEN];
  5. DWORDdwSize;
  6.  
  7. memset((PBYTE)tFilePath,0,sizeof(tFilePath));
  8. wcscpy(tFilePath,pFileDir);
  9. wcscat(tFilePath,pFileName);
  10.  
  11. HANDLEhfile = CreateFile(tFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  12. if(hfile== INVALID_HANDLE_VALUE)
  13. {
  14. printf("AddDataToNb0File()GetLastError=0x%x\r\n",GetLastError());
  15. gotoExit;
  16. }
  17.  
  18. DWORDFileSize = GetFileSize (hfile, NULL) ;
  19.  
  20. if(FileSize == 0xFFFFFFFF)
  21. {
  22. gotoExit;
  23. }
  24.  
  25. SetFilePointer(hfile,(FileSize- sizeof(IMG_CHECK_VERSION)),NULL,FILE_BEGIN);
  26. WriteFile(hfile,(PBYTE)pCheckVersion,sizeof(IMG_CHECK_VERSION),&dwSize,NULL);
  27. SetFilePointer(hfile,FileSize,NULL,FILE_BEGIN);
  28. SetEndOfFile(hfile);
  29.  
  30. ret= TRUE;
  31.  
  32. Exit:
  33. if(hfile!= INVALID_HANDLE_VALUE)
  34. {
  35. CloseHandle(hfile);
  36. }
  37. returnret;
  38. }

(3)    IMG_CHECK_VERSION结构体的定义

  1. typedef struct _IMG_CHECK_VERSION_
  2. {
  3. TCHARImageVersion[VERSION_LEN];
  4. }IMG_CHECK_VERSION,*PIMG_CHECK_VERSION;

见main函数的printf函数,我们的本意是输出传递进来参数的所有字符串内容的,但自己的输出却是:

图2

可见只输出对应参数的第一个字符,比如argv[2]是传递“stepldr.nb0”进来的,但只输出s,虽然我们想要的功能能够达到,但是调试起来如果想看这些信息比较不方便。

修改之前stepldr.nb0文件最后一段全部为0,我们用UltraEdit文件打开如下:

图3

修改之后如下:

图4

由图4可知stepldr.nb0从0x1ff8到0x1fff这8个字节的数据由之前的0x00改为0x31、0x00、0x32、0x00、0x33、0x00、0x34、0x00,这对应于图1中传递进来的1234,为什么1个字符会占用两个字节呢?是因为我们的IMG_CHECK_VERSION结构体成员ImageVersion类型是TCHAR(相当于wchar_t),是宽字符,也就是说一个字符占用2个字节。

2.      采用char

(1)    main函数

  1. int main(int argc, char * argv[])
  2. {
  3. char*pImageVersion;
  4. char*pFileDir;
  5. char*pFileName;
  6.  
  7. pFileDir= argv[1];
  8. pFileName= argv[2];
  9. pImageVersion= argv[3];
  10.  
  11. PIMG_CHECK_VERSION pImg_check_version;
  12.  
  13. printf("argc= %d\r\n",argc);
  14.  
  15. for(inti = 0; i < argc; i++)
  16. {
  17. printf("argv[%d]:%s\r\n",i,argv[i]);
  18. }
  19.  
  20. strcpy(pImg_check_version->ImageVersion,pImageVersion);
  21. AddDataToNb0File(pFileDir,pFileName,pImg_check_version);
  22.  
  23. return0;
  24. }

(2)    AddDataToNb0File函数

  1. BOOL AddDataToNb0File(char *pFileDir, char*pFileName, PIMG_CHECK_VERSION pCheckVersion)
  2. {
  3. BOOLret = FALSE;
  4. chartFilePath[FILE_NAME_LEN];
  5. DWORDdwSize;
  6.  
  7. memset((PBYTE)tFilePath,0,sizeof(tFilePath));
  8. strcpy(tFilePath,pFileDir);
  9. strcat(tFilePath,pFileName);
  10.  
  11. DWORDdwFileDirNum = MultiByteToWideChar (CP_ACP, 0, tFilePath, -1, NULL, 0);
  12. wchar_t*pFileDirAndName = new wchar_t[dwFileDirNum];
  13.  
  14. MultiByteToWideChar(CP_ACP, 0, tFilePath, -1, pFileDirAndName, dwFileDirNum);
  15.  
  16. printf("filedir and name : %s,dwFileDirNum=%d \r\n",pFileDirAndName,dwFileDirNum);
  17.  
  18. HANDLEhfile = CreateFile(pFileDirAndName, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  19. //HANDLEhfile = CreateFile((LPCTSTR)tFilePath, GENERIC_READ |GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  20. if(hfile== INVALID_HANDLE_VALUE)
  21. {
  22. printf("AddDataToNb0File()GetLastError=0x%x\r\n",GetLastError());
  23. gotoExit;
  24. }
  25.  
  26. DWORDFileSize = GetFileSize (hfile, NULL) ;
  27.  
  28. if(FileSize == 0xFFFFFFFF)
  29. {
  30. gotoExit;
  31. }
  32.  
  33. SetFilePointer(hfile,(FileSize- sizeof(IMG_CHECK_VERSION)),NULL,FILE_BEGIN);
  34. WriteFile(hfile,(PBYTE)pCheckVersion,sizeof(IMG_CHECK_VERSION),&dwSize,NULL);
  35. SetFilePointer(hfile,FileSize,NULL,FILE_BEGIN);
  36. SetEndOfFile(hfile);
  37.  
  38. ret= TRUE;
  39.  
  40. Exit:
  41. if(hfile!= INVALID_HANDLE_VALUE)
  42. {
  43. CloseHandle(hfile);
  44. }
  45. returnret;
  46. }

这里要注意的是CreateFile函数的第1个参数类型要求是LPCTSTR,如果我们直接采用(LPCTSTR)tFilePath强制类型转换,GetLastError()返回值是2(ERROR_FILE_NOT_FOUND),表示找不到文件,采用MultiByteToWideChar函数转换为宽字符后就OK了。

(3)    IMG_CHECK_VERSION结构体

  1. typedef struct _IMG_CHECK_VERSION_
  2. {
  3. charImageVersion[VERSION_LEN];
  4. }IMG_CHECK_VERSION,*PIMG_CHECK_VERSION;

采用这样的方式修改stepldr.nb0后,如下:

图5

可见char占用一个字节,综合比较具体是采用哪种,根据需要来选择。

遇到一个很奇怪的问题,我在A电脑上用VS2005创建的这个控制台程序,编译出来后在B电脑上运行是提示不能运行这个程序,然后我在B电脑上编译A电脑的这个工程,重新生成控制台程序就可以,然后我用B电脑上编译的在A电脑上也OK,目前不知道原因,先备注下。

VS2005控制台程序修改nb0文件的更多相关文章

  1. Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse

    Python第十天   print >> f,和fd.write()的区别    stdout的buffer  标准输入 标准输出  从控制台重定向到文件  标准错误   重定向 输出流和 ...

  2. 用VS2005编译生成Lua库文件和解释器

    TMD,本来很简单的东西,网上说的乱七八糟,说的也不明白,大家抄来抄去,估计都不自己实践的..花了半个下午研究了一下,总结一下. 1)下载lua工程文件,地址为http://www.lua.org/f ...

  3. ssm框架之配置日志系统打印到控制台与指定文件

    前提: 0:ssm框架已经搭建并且成功运行 1.maven环境配置成功 2.tomcat配置成功,并且配置本机的tomcat环境变量 内容: 0.导入所需要的jar包 <!-- 配置log4j日 ...

  4. Config文件的使用:通过程序修改Config文件

    对于config文件,一般情况下都是使用ConfigurationManager加载,然后通过读取相应节点的值来获取想要的数据,但是,有时候需要修改config文件的值,这时候就用到了OpenExeC ...

  5. 日志输出:控制台和log文件输出日志

    self_log.py 中 import os import logging import time # 如果日志文件夹不存在,则创建 log_dir = "log" # 日志存放 ...

  6. Visual studio C++ 之空控制台工程添加文件并解决头文件包含问题

    背景 之前都是用的MFC已搭好框架,今天想自己从零开始完成添加文件,编译,并解决文件包含问题,在此做个记录. 正文 首先创建一个Win32控制台应用程序,不要直接点击完成,而是点击下一步,然后选择空项 ...

  7. Java代码工具箱之控制台输出重定向_控制台输出到文件

    1. 情形:有时候控制台输出太多,在MyEclipse显示不全. 2. 说明:本代码只会重定向 system.out 的内容, error及其它不受代码影响.其它应该类似. //自定导入必要库 //然 ...

  8. asp.net core-5.控制台读取json文件

    1,创建控制台应用程序,应用using Microsoft.Extensions.Configuration; 2,新建一个app.json文件 然后修改app.json的属性 3,生成项目,可以看到 ...

  9. 使用 VS2005 通过按钮自动上传文件到Linux

    首先去官网下载 winscp,官网地址:http://winscp.net/eng/download.php 因为我这里是做自动上传工具,所以我只下载了精简版的:Portable executable ...

随机推荐

  1. docker 感性介绍

    Docker 允许开发者们将他们的应用打包放在云端的“容器”中,无需再修改就可以发布到任何流行的 Linux 机器上.由于采用沙盒机制,各应用之间没有任何接口,所以不用担心它们会相互干扰.也同样因为这 ...

  2. cocos2dx中的三种基本的数据类型

    cocos2dx中提供了三种基本的数据类型:CCString(字符串),CCArray(数组),CCDictionary(数据字典(哈希的功能)) 2.CCString的用法 class  CCStr ...

  3. android 开发:讯飞的离线命令识别器官方demo使用及demo下载

    场景:使用本地构建语法,离线识别命令词. 修改文件AsrDemo.java mLocalGrammar  修改为你自己的语法 mAsr.setParameter(SpeechConstant.GRAM ...

  4. SQL Server数据库文件存储目录转移

    USE master GO DECLARE @DBName sysname, ) DECLARE @DB table( name sysname, physical_name sysname) BEG ...

  5. IIS搭建本地服务器,花生壳实现外网通过域名访问网站

    配置服务器 作为一个青年,没有实力,做不出标图所示的服务器. 作为一个学生,买不起服务器 作为一个小孩,买不起域名 但别忘了 作为一个平民玩家,只要有耐心 装备迟早会做出来的 (注:感觉有钱与没钱还是 ...

  6. 高质量的javascript代码 -- 深入理解Javascript

    一. 编写高质量的javascript代码基本要点a) 可维护的代码(Writing Maintainable Code)i. 可读(注释)ii. 一致(看上去是同一个人写的)iii. 已记录b) 最 ...

  7. python 发邮件 utf-8

    import smtplib from operator import itemgetter, attrgetter from email.mime.text import MIMEText from ...

  8. 【POJ】【3537】Crosses and Crosses

    博弈论 相当于放了x的位置,左右4格都不能再放x了,谁无处可放就输. n<=2000 直接枚举后继状态,暴力求SG函数即可. 例: 0000000->x..0000 / .x..000 / ...

  9. mysql 。。。

    MySQL的相关概念介绍 MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格 ...

  10. Unity3d集成移动MM SDK 2.2的技术要点(坑爹的MM SDK)

    原地址:http://dong2008hong.blog.163.com/blog/static/4696882720140423517951/ U3D集成移动MM的SDK绝对是以坑爹为主的东西. 浪 ...