问题描述
我有2个程序,一个程序使用Windows API获取所有进程信息,并将它们存储在这样的结构向量中:@H_404_1@
struct Info{
int pid,ppid;
char exeName[256];
}
当我用数据填充结构时,我将back_pushing结构保留在向量中。
现在,我尝试使用memcpy()
来存储映射文件中的数据,但是在第二个程序中无法正确读取它。您能帮我弄清楚如何正确读取数据吗?@H_404_1@
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <Tlhelp32.h>
#include <vector>
struct InfoProces {
DWORD pid;
DWORD ppid;
char exeName[256];
};
int main(){
HANDLE hProcesses;
PROCESSENTRY32 pe32;
hProcesses = Createtoolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcesses == INVALID_HANDLE_VALUE)
{
printf("Createtoolhelp32Snapshot Failed. err = %d",GetLastError());
return -1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcesses,&pe32)) {
printf("Process32First Failed. err = %d",GetLastError());
CloseHandle(hProcesses);
return -1;
}
HANDLE hdata = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,1024 * 1024,"data");
if (hdata == NULL) {
printf("Can't create a file mapping. err = %d",GetLastError());
return -1;
}
unsigned char* pdata = (unsigned char*)MapViewOfFile(hdata,FILE_MAP_WRITE,0);
if (pdata == NULL) {
printf("cant get pointer to mapping file. err = %d",GetLastError());
return -1;
}
do {
InfoProces pi;
pi.pid = pe32.th32ProcessID;
pi.ppid = pe32.th32ParentProcessID;
strcpy(pi.exeName,pe32.szExeFile);
} while (Process32Next(hProcesses,&pe32));
getchar();
CloseHandle(hProcesses);
return 0;
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <vector>
#include <stdio.h>
struct InfoProces {
DWORD pid;
DWORD ppid;
char exeName[256];
};
int main()
{
HANDLE hdata = OpenFileMapping(FILE_MAP_ALL_ACCESS,false,"data");
unsigned char* pdata = (unsigned char*)MapViewOfFile(hdata,FILE_MAP_READ,0);
if (pdata == NULL) {
printf("cant get pointer to mapped file. err = %d",GetLastError());
return -1;
}
std::vector<InfoProces>processes;
memcpy(&processes,pdata,sizeof(data));
for (std::vector<InfoProces>::iterator i = processes.begin(); i < processes.end(); i++)
printf("Process[%d](parinte[%d]): %s\n",i->pid,i->ppid,i->exeName);
return 0;
}
解决方法
正如评论所指出的那样,您已经获得了映射视图的起始地址(pdata
),您只能使用pdata
进行内存共享,而不能使用该进程的任何堆栈地址。
尝试将InfoProces
的内存复制到程序1中的pdata
:
memcpy(pdata,&pi,sizeof(InfoProces));
此外,在程序2中,您未设置矢量的大小,应将&processes
替换为processes.data()
。您还需要知道在程序1中添加的数组的大小:
std::vector<InfoProces> processes;
processes.resize(count);
memcpy(processes.data(),pdata,sizeof(InfoProces)*count);
以下代码对我有用。
程序1 :(记录InfoProces
的计数并将其保存在pdata
开头的DWORD中)
...
unsigned char* pdata = (unsigned char*)MapViewOfFile(hdata,FILE_MAP_WRITE,0);
if (pdata == NULL) {
printf("cant get pointer to mapping file. err = %d",GetLastError());
return -1;
}
unsigned char* begin = pdata;
//offset a size of DWORD;
DWORD count = 0;
pdata += sizeof(DWORD);
do {
InfoProces pi;
pi.pid = pe32.th32ProcessID;
pi.ppid = pe32.th32ParentProcessID;
strcpy(pi.exeName,pe32.szExeFile);
memcpy(pdata,sizeof(InfoProces));
pdata += sizeof(InfoProces);
count++;
} while (Process32Next(hProcesses,&pe32));
memcpy(begin,&count,sizeof(DWORD));
getchar();
UnmapViewOfFile(begin);
CloseHandle(hdata);
CloseHandle(hProcesses);
...
程序2:
...
unsigned char* pdata = (unsigned char*)MapViewOfFile(hdata,FILE_MAP_READ,0);
if (pdata == NULL) {
printf("cant get pointer to mapped file. err = %d",GetLastError());
return -1;
}
unsigned char* begin = pdata;
DWORD count = 0;
memcpy(&count,sizeof(DWORD));
pdata += sizeof(DWORD);
std::vector<InfoProces> processes;
processes.resize(count);
memcpy(processes.data(),sizeof(InfoProces)*count);
for (std::vector<InfoProces>::iterator i = processes.begin(); i < processes.end(); i++)
printf("Process[%d](parinte[%d]): %s\n",i->pid,i->ppid,i->exeName);
UnmapViewOfFile(begin);
CloseHandle(hdata);
...
最后,不要忘记关闭句柄并取消映射地址。