代码一篇,暂时没发现bug:
1 // vm_mgr.cpp : Defines the exported functions for the DLL application. 2 // 3 4 #include "stdafx.h" 5 6 #include7 #include 8 #include 9 #include 10 #include "../common/assist.h" 11 #include"../error_no/error_no.h" 12 #include "../Log/log.h" 13 #include "vm_mgr.h" 14 15 #define VM_ADDR_GEN(addr, index) (assert(index < 16), (((index & 0xfULL) << 60) | addr)) 16 #define VM_START_ADDR 0x100000000ULL 17 #define VM_WINDOW_SIZE (64 * 1024 * 1024UL) 18 #define VM_ALIGN_SIZE (64 * 1024) 19 20 struct vm_window { 21 void *p; 22 vm_ptr_t start; 23 unsigned long size; 24 }; 25 26 struct vm_item { 27 int addr_index; 28 HANDLE mutext; 29 HANDLE hMap; 30 vm_ptr_t vm_start_ptr; 31 unsigned long long vm_size; 32 struct vm_window window; 33 TCHAR file_path[MAX_PATH]; 34 }; 35 36 struct { 37 std::vector tbl; 38 } vm; 39 40 static int find_empty_index() 41 { 42 int addr_index; 43 int i; 44 45 for (addr_index = 0; ; addr_index++) { 46 for (i = 0; i < vm.tbl.size(); i++) { 47 if (vm.tbl.at(i).addr_index == addr_index) 48 break; 49 } 50 assert(addr_index <= 16); 51 if (i >= vm.tbl.size()) 52 return addr_index; 53 } 54 } 55 56 vm_ptr_t vm_alloc(unsigned long long size) 57 { 58 TCHAR tmp_path[MAX_PATH]; 59 TCHAR tmp_file_path[MAX_PATH]; 60 int err; 61 struct vm_item vm_item; 62 63 GetTempPath(ARRAY_SIZE(tmp_path), tmp_path); 64 GetTempFileName(tmp_path, _T("DediProg"), 0, tmp_file_path); 65 66 HANDLE hFile = CreateFile( 67 tmp_file_path, 68 GENERIC_READ | GENERIC_WRITE, 69 FILE_SHARE_READ | FILE_SHARE_WRITE, 70 NULL, 71 OPEN_ALWAYS, 72 FILE_FLAG_SEQUENTIAL_SCAN, 73 NULL 74 ); 75 if (hFile == NULL) { 76 return NULL; 77 } 78 79 vm_item.hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, size >> 32, size & 0xffffffff, NULL); 80 if (vm_item.hMap == NULL) { 81 err = GetLastError(); 82 return -E_ALLOC_MEMORY_FAIL; 83 } 84 vm_item.vm_start_ptr = (vm_ptr_t)MapViewOfFile( 85 vm_item.hMap, 86 FILE_MAP_ALL_ACCESS, 87 0 >> 32, 88 0 & 0xffffffff, 89 min(size, VM_WINDOW_SIZE) 90 ); 91 92 vm_item.addr_index = find_empty_index(); 93 vm_item.vm_start_ptr = VM_ADDR_GEN(vm_item.vm_start_ptr, vm_item.addr_index); 94 95 assert(vm_item.vm_start_ptr < ((-1) >> 4)); 96 97 CloseHandle(hFile); 98 hFile = NULL; 99 vm_item.vm_size = size;100 vm_item.window.size = (unsigned long)min(VM_WINDOW_SIZE, size);101 vm_item.window.start = vm_item.vm_start_ptr;102 vm_item.window.p = (unsigned char *)vm_item.vm_start_ptr;103 vm_item.mutext = CreateMutex(NULL, FALSE, NULL);104 _tcsncpy(vm_item.file_path, tmp_file_path, ARRAY_SIZE(vm_item.file_path));105 vm.tbl.push_back(vm_item);106 107 return vm_item.vm_start_ptr;108 }109 110 static __inline int in_region(vm_ptr_t ptr, unsigned long long size)111 {112 //static int dbg = 0;113 int i;114 115 for (i = 0; i < (int)vm.tbl.size(); i++) {116 if ((ptr + size) <= (vm.tbl.at(i).vm_start_ptr + vm.tbl.at(i).vm_size) && (ptr >= vm.tbl.at(i).vm_start_ptr))117 return i;118 //if (ptr + size > vm.tbl.at(i).vm_start_ptr + vm.tbl.at(i).vm_size)119 // i = 'DEAD';120 //if (ptr < vm.tbl.at(i).vm_start_ptr)121 // i = 'INVA';122 }123 124 LOG_BEGIN {125 log_add("----------------------------------------------");126 log_add("| Virtual Memory layout |");127 log_add("|--------------------------------------------|");128 for (i = 0; i < (int)vm.tbl.size(); i++)129 log_add("|window.start_addr:%llx | window.size:%llx |", vm.tbl.at(i).window.start, vm.tbl.at(i).window.size);130 log_add("|--------------------------------------------|");131 log_add("|user.ptr:%llx | user.size:%llx |", ptr, size);132 log_add("----------------------------------------------");133 } LOG_END;134 //dbg++;135 assert(!"Invalid Memory");136 return -1;137 }138 139 static __inline unsigned char *scroll_window(int vm_index, vm_ptr_t ptr, unsigned long size)140 {141 unsigned char *p;142 vm_ptr_t win_start;143 unsigned long win_size;144 unsigned long long file_offset;145 unsigned long long tmp_offset;146 147 148 win_start = vm.tbl.at(vm_index).window.start;149 win_size = vm.tbl.at(vm_index).window.size;150 151 152 UnmapViewOfFile(vm.tbl.at(vm_index).window.p);153 154 win_size = (unsigned long)min(VM_WINDOW_SIZE, size);155 156 assert(ptr >= vm.tbl.at(vm_index).vm_start_ptr);157 file_offset = ptr - vm.tbl.at(vm_index).vm_start_ptr;158 159 tmp_offset = file_offset / VM_ALIGN_SIZE * VM_ALIGN_SIZE;160 tmp_offset = file_offset - tmp_offset;161 162 file_offset = file_offset / VM_ALIGN_SIZE * VM_ALIGN_SIZE;163 164 size += (unsigned long)tmp_offset;165 166 p = (unsigned char *)MapViewOfFile(167 vm.tbl.at(vm_index).hMap,168 FILE_MAP_ALL_ACCESS,169 file_offset >> 32,170 file_offset & 0xffffffff,171 size172 );173 174 if (p) {175 vm.tbl.at(vm_index).window.start = ptr;176 vm.tbl.at(vm_index).window.size = size;177 vm.tbl.at(vm_index).window.p = p;178 179 return p + tmp_offset;180 }181 182 return NULL;183 }184 185 int vm_write(vm_ptr_t pointer, const unsigned char *buff, unsigned long long size)186 {187 int ret;188 unsigned char *p;189 unsigned long len;190 int index = in_region(pointer, size);191 192 ret = 0;193 194 if (index == -1) {195 ret = -1;196 goto end;197 }198 WaitForSingleObject(vm.tbl.at(index).mutext, 20000); /* timeout 10s */199 while (size) {200 len = (unsigned long)min(size, VM_WINDOW_SIZE);201 p = scroll_window(index, pointer, len);202 if (!p) {203 ret = -1;204 goto end;205 }206 207 memcpy(p, buff, len);208 209 pointer += len;210 buff += len;211 size -= len;212 }213 end:214 ReleaseMutex(vm.tbl.at(index).mutext);215 return ret;216 }217 218 219 int vm_read(unsigned char *buff, vm_ptr_t ptr, unsigned long long size)220 {221 unsigned char *p;222 unsigned long len;223 int index;224 225 assert(buff);226 227 index = in_region(ptr, size);228 229 if (index == -1)230 return -E_ALLOC_MEMORY_FAIL;231 232 while (size) {233 len = (unsigned long)min(size, VM_WINDOW_SIZE);234 p = scroll_window(index, ptr, len);235 if (!p)236 return -1;237 238 memcpy(buff, p, len);239 240 ptr += len;241 buff += len;242 size -= len;243 }244 245 return 0;246 }247 248 int vm_free(vm_ptr_t ptr)249 {250 int i;251 252 LOG_BEGIN {253 log_add("----------------------------------------------");254 log_add("| Virtual Memory layout |");255 log_add("|--------------------------------------------|");256 for (i = 0; i < (int)vm.tbl.size(); i++)257 log_add("|window.start_addr:%llx | window.size:%llx |", vm.tbl.at(i).window.start, vm.tbl.at(i).window.size);258 log_add("----------------------------------------------");259 } LOG_END;260 261 for (i = 0; i < (int)vm.tbl.size(); i++) {262 if (vm.tbl.at(i).vm_start_ptr == ptr) {263 assert(vm.tbl.at(i).hMap);264 265 UnmapViewOfFile(vm.tbl.at(i).window.p);266 CloseHandle(vm.tbl.at(i).hMap);267 268 DeleteFile(vm.tbl.at(i).file_path);269 270 vm.tbl.erase(vm.tbl.begin() + i);271 return 0;272 }273 }274 275 assert(!"Invalid pointer");276 277 return 0;278 }