VS2005控制台程序修改nb0文件

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

int _tmain(int argc, _TCHAR * argv[])
{return0;
}

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

图1

1.      采用TCHAR

(1)    main函数

int _tmain(int argc, _TCHAR * argv[])
{TCHAR*pImageVersion;TCHAR*pFileDir;TCHAR*pFileName;pFileDir= argv[1];pFileName= argv[2];pImageVersion= argv[3];PIMG_CHECK_VERSION  pImg_check_version;printf("argc= %d\r\n",argc);for(inti = 0; i < argc; i++){printf("argv[%d]:%s\r\n",i,argv[i]);}wcscpy(pImg_check_version->ImageVersion,pImageVersion);AddDataToNb0File(pFileDir,pFileName,pImg_check_version);return0;
}

(2)    AddDataToNb0File

BOOL AddDataToNb0File(TCHAR *pFileDir,TCHAR *pFileName, PIMG_CHECK_VERSION pCheckVersion){BOOLret = FALSE;TCHARtFilePath[FILE_NAME_LEN];DWORDdwSize;memset((PBYTE)tFilePath,0,sizeof(tFilePath));wcscpy(tFilePath,pFileDir);wcscat(tFilePath,pFileName);HANDLEhfile = CreateFile(tFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if(hfile== INVALID_HANDLE_VALUE){printf("AddDataToNb0File()GetLastError=0x%x\r\n",GetLastError());gotoExit;}DWORDFileSize = GetFileSize (hfile, NULL) ;if(FileSize == 0xFFFFFFFF){gotoExit;}SetFilePointer(hfile,(FileSize- sizeof(IMG_CHECK_VERSION)),NULL,FILE_BEGIN);WriteFile(hfile,(PBYTE)pCheckVersion,sizeof(IMG_CHECK_VERSION),&dwSize,NULL);SetFilePointer(hfile,FileSize,NULL,FILE_BEGIN);SetEndOfFile(hfile);ret=  TRUE;Exit:if(hfile!= INVALID_HANDLE_VALUE){CloseHandle(hfile);}returnret;
}

(3)    IMG_CHECK_VERSION结构体的定义

typedef struct _IMG_CHECK_VERSION_
{TCHARImageVersion[VERSION_LEN];
}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函数

int main(int argc, char * argv[])
{char*pImageVersion;char*pFileDir;char*pFileName;pFileDir= argv[1];pFileName= argv[2];pImageVersion= argv[3];PIMG_CHECK_VERSION  pImg_check_version;printf("argc= %d\r\n",argc);for(inti = 0; i < argc; i++){printf("argv[%d]:%s\r\n",i,argv[i]);}strcpy(pImg_check_version->ImageVersion,pImageVersion);AddDataToNb0File(pFileDir,pFileName,pImg_check_version);return0;
}

(2)    AddDataToNb0File函数

BOOL AddDataToNb0File(char *pFileDir, char*pFileName, PIMG_CHECK_VERSION pCheckVersion)
{BOOLret = FALSE;chartFilePath[FILE_NAME_LEN];DWORDdwSize;memset((PBYTE)tFilePath,0,sizeof(tFilePath));strcpy(tFilePath,pFileDir);strcat(tFilePath,pFileName);DWORDdwFileDirNum = MultiByteToWideChar (CP_ACP, 0, tFilePath, -1, NULL, 0);wchar_t*pFileDirAndName = new wchar_t[dwFileDirNum];MultiByteToWideChar(CP_ACP, 0, tFilePath, -1, pFileDirAndName, dwFileDirNum);printf("filedir and name : %s,dwFileDirNum=%d \r\n",pFileDirAndName,dwFileDirNum);HANDLEhfile = CreateFile(pFileDirAndName, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);//HANDLEhfile = CreateFile((LPCTSTR)tFilePath, GENERIC_READ |GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if(hfile== INVALID_HANDLE_VALUE){printf("AddDataToNb0File()GetLastError=0x%x\r\n",GetLastError());gotoExit;}DWORDFileSize = GetFileSize (hfile, NULL) ;if(FileSize == 0xFFFFFFFF){gotoExit;}SetFilePointer(hfile,(FileSize- sizeof(IMG_CHECK_VERSION)),NULL,FILE_BEGIN);WriteFile(hfile,(PBYTE)pCheckVersion,sizeof(IMG_CHECK_VERSION),&dwSize,NULL);SetFilePointer(hfile,FileSize,NULL,FILE_BEGIN);SetEndOfFile(hfile);ret=  TRUE;Exit:if(hfile!= INVALID_HANDLE_VALUE){CloseHandle(hfile);}returnret;
}

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

(3)    IMG_CHECK_VERSION结构体

typedef struct _IMG_CHECK_VERSION_
{charImageVersion[VERSION_LEN];
}IMG_CHECK_VERSION,*PIMG_CHECK_VERSION;

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

图5

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

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

VS2005控制台程序修改nb0文件相关推荐

  1. DCMTK:命令行应用程序修改DICOM文件中的标签

    DCMTK:命令行应用程序修改DICOM文件中的标签 命令行应用程序修改DICOM文件中的标签 命令行应用程序修改DICOM文件中的标签 #include "dcmtk/config/osc ...

  2. K8S——关于K8S控制台的yaml文件编写(基于上一章多节点K8S部署)

    K8S--关于K8S控制台的yaml文件编写(基于上一章多节点K8S部署) 一.yaml文件编写流程 二.证书自签 一.yaml文件编写流程 rbac.yaml---->secret.yaml- ...

  3. 深入理解.bin文件和.nb0文件的结构

    .bin文件是一个描述性质的映像文件,它由文件头(head).镜像数据目的起始地址(ImageStart).镜像数据长度(ImageLength)和多条相对独立的记录(record)构成. 文件头(h ...

  4. Java知识积累——同时输出到控制台和指定文件,或直接输出到指定文件

    很多时候的实际需求都不允许我们只是把结果输出到console就可以了,那么怎么把程序运行结果输出到指定文件,以及怎么能同时让其输出到指定文件和console呢? 通过网上搜索过来人的文章,找到了如下解 ...

  5. vs2005生成安装部署文件的步骤

    vs2005生成安装部署文件的步骤 1 新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点击确定. 2 安装向导 关闭后打开安 ...

  6. 控制台运行python文件_spyder如何在控制台执行python文件,debug python程序

    spyder如何在控制台执行python文件,debug python程序 发布时间:2020-08-01 14:42:02 来源:亿速云 阅读:93 作者:小猪 这篇文章主要讲解了spyder如何在 ...

  7. python控制台输出到文件_Python print 立即打印内容到重定向的文件

    看到本文标题也许要奇怪了,Python 的 print 难道不是也上可以看到结果的吗?在 Python shell 下只要 >> print('Hello world!') Hello w ...

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

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

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

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

最新文章

  1. 个人银行账户管理程序
  2. mac 查看端口_如何重置mac上的系统管理控制器smc教程
  3. iOS数据存储简要笔记
  4. 使用php与mysql构建我们的网站
  5. 使用html2Canvas将页面转化为canvas图片,最后长按保存到本地,史上最全 html2canvas 使用 踏坑之旅,没有之一
  6. oracel 创建视图给某个用户
  7. centos6.8中zabbix3.0.X的部署
  8. 股票历史数据下载接口汇总(动态更新)
  9. Android Studio躲避小球小游戏(一界面布局)
  10. FlashBuilder 4.6 破解序列号和方法
  11. Linux C/C++内存映射
  12. 手推SVM(二)-核方法
  13. ceph存储 PG的状态机和peering过程
  14. java中void是什么意思_JAVA里VOID是什么意思
  15. 麦凯恩争取赢最后辩论而由弱转强
  16. Bugku CTF 眼见为实(MISC)
  17. 计算H时M分S秒以后是_消防考试必会计算题汇总!
  18. 基础语法值c++提高编程
  19. 【Simulink】Three-Phase V-I Measurement 使用方法
  20. 搭建私服环境及私服的使用-将第三方jar上传私服

热门文章

  1. mfc 饼图绘画_每周推荐|江南百景图放置类佛系游戏,慢慢玩才是乐趣
  2. c语言用两个栈构造队列伪码,数据结构习题线性表栈队列.doc
  3. java param add_Java中的Map paramMap
  4. Android Studio系列教程一:下载与安装
  5. html盒子移动动画代码,HTML5/Canvas 盒子追踪动画
  6. qt 定义一个长度的数组,Qt - 声明一个QLabel数组并将其添加到QTabWidget的选项卡
  7. 节能与新能源汽车技术路线图2.0_节能与新能源汽车技术路线图(2.0版)
  8. android修改系统设置权限_安卓保护隐私利器!完美解决软件「不给权限就不运行」的小工具...
  9. Eclipse搭建SpringCloud+SSM+Maven项目
  10. linux进程假死的原因_一次Spring Boot假死诊断