| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | #include "master.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-13 00:57:24 -04:00
										 |  |  | F_STRING *get_error_message(void) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	DWORD id = GetLastError(); | 
					
						
							|  |  |  | 	F_CHAR *msg = error_message(id); | 
					
						
							|  |  |  | 	F_STRING *string = from_u16_string(msg); | 
					
						
							|  |  |  | 	LocalFree(msg); | 
					
						
							|  |  |  | 	return string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* You must LocalFree() the return value! */ | 
					
						
							|  |  |  | F_CHAR *error_message(DWORD id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_CHAR *buffer; | 
					
						
							|  |  |  | 	int index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DWORD ret = FormatMessage( | 
					
						
							|  |  |  | 		FORMAT_MESSAGE_ALLOCATE_BUFFER | | 
					
						
							|  |  |  | 		FORMAT_MESSAGE_FROM_SYSTEM, | 
					
						
							|  |  |  | 		NULL, | 
					
						
							|  |  |  | 		id, | 
					
						
							|  |  |  | 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 
					
						
							|  |  |  | 		(LPTSTR)(void *) &buffer, | 
					
						
							|  |  |  | 		0, NULL); | 
					
						
							|  |  |  | 	if(ret == 0) | 
					
						
							|  |  |  | 		return error_message(GetLastError()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* strip whitespace from end */ | 
					
						
							|  |  |  | 	index = wcslen(buffer) - 1; | 
					
						
							|  |  |  | 	while(index >= 0 && isspace(buffer[index])) | 
					
						
							|  |  |  | 		buffer[index--] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return buffer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HMODULE hFactorDll; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-13 00:57:24 -04:00
										 |  |  | void init_ffi(void) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	hFactorDll = GetModuleHandle(FACTOR_DLL); | 
					
						
							|  |  |  | 	if(!hFactorDll) | 
					
						
							|  |  |  | 		fatal_error("GetModuleHandle(\"" FACTOR_DLL_NAME "\") failed", 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | void ffi_dlopen(F_DLL *dll) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | 	dll->dll = LoadLibraryEx(alien_offset(dll->path), NULL, 0); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void *ffi_dlsym(F_DLL *dll, F_SYMBOL *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ffi_dlclose(F_DLL *dll) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	FreeLibrary((HMODULE)dll->dll); | 
					
						
							|  |  |  | 	dll->dll = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* You must free() this yourself. */ | 
					
						
							|  |  |  | const F_CHAR *default_image_path(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_CHAR full_path[MAX_UNICODE_PATH]; | 
					
						
							|  |  |  | 	F_CHAR *ptr; | 
					
						
							|  |  |  | 	F_CHAR path_temp[MAX_UNICODE_PATH]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) | 
					
						
							|  |  |  | 		fatal_error("GetModuleFileName() failed", 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if((ptr = wcsrchr(full_path, '.'))) | 
					
						
							|  |  |  | 		*ptr = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	snwprintf(path_temp, sizeof(path_temp)-1, L"%s.image", full_path);  | 
					
						
							|  |  |  | 	path_temp[sizeof(path_temp) - 1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return safe_strdup(path_temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* You must free() this yourself. */ | 
					
						
							|  |  |  | const F_CHAR *vm_executable_path(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_CHAR full_path[MAX_UNICODE_PATH]; | 
					
						
							|  |  |  | 	if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) | 
					
						
							|  |  |  | 		fatal_error("GetModuleFileName() failed", 0); | 
					
						
							|  |  |  | 	return safe_strdup(full_path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | void find_file_stat(F_CHAR *path) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | 	// FindFirstFile is the only call that can stat c:\pagefile.sys
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	WIN32_FIND_DATA st; | 
					
						
							|  |  |  | 	HANDLE h; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | 	if(INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st))) | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | 		dpush(F); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		FindClose(h); | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | 		dpush(T); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | DEFINE_PRIMITIVE(existsp) | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | { | 
					
						
							|  |  |  | 	BY_HANDLE_FILE_INFORMATION bhfi; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	F_CHAR *path = unbox_u16_string(); | 
					
						
							|  |  |  | 	//wprintf(L"path = %s\n", path);
 | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | 	HANDLE h = CreateFileW(path, | 
					
						
							|  |  |  | 			GENERIC_READ, | 
					
						
							|  |  |  | 			FILE_SHARE_READ, | 
					
						
							|  |  |  | 			NULL, | 
					
						
							|  |  |  | 			OPEN_EXISTING, | 
					
						
							|  |  |  | 			FILE_FLAG_BACKUP_SEMANTICS, | 
					
						
							|  |  |  | 			NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | 	if(h == INVALID_HANDLE_VALUE) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | 		// FindFirstFile is the only call that can stat c:\pagefile.sys
 | 
					
						
							|  |  |  | 		WIN32_FIND_DATA st; | 
					
						
							|  |  |  | 		HANDLE h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st))) | 
					
						
							|  |  |  | 			dpush(F); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			FindClose(h); | 
					
						
							|  |  |  | 			dpush(T); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:19 -04:00
										 |  |  | 	box_boolean(GetFileInformationByHandle(h, &bhfi)); | 
					
						
							| 
									
										
										
										
											2007-12-06 03:18:56 -05:00
										 |  |  | 	CloseHandle(h); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | DEFINE_PRIMITIVE(read_dir) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	HANDLE dir; | 
					
						
							|  |  |  | 	WIN32_FIND_DATA find_data; | 
					
						
							|  |  |  | 	F_CHAR *path = unbox_u16_string(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GROWABLE_ARRAY(result); | 
					
						
							| 
									
										
										
										
											2007-12-26 01:45:16 -05:00
										 |  |  | 	REGISTER_ROOT(result); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(INVALID_HANDLE_VALUE != (dir = FindFirstFile(path, &find_data))) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		do | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			CELL name = tag_object(from_u16_string(find_data.cFileName)); | 
					
						
							|  |  |  | 			CELL dirp = tag_boolean(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); | 
					
						
							|  |  |  | 			CELL pair = allot_array_2(name,dirp); | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 			GROWABLE_ARRAY_ADD(result,pair); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		while (FindNextFile(dir, &find_data)); | 
					
						
							| 
									
										
										
										
											2008-02-27 15:59:15 -05:00
										 |  |  | 		FindClose(dir); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-26 01:45:16 -05:00
										 |  |  | 	UNREGISTER_ROOT(result); | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 	GROWABLE_ARRAY_TRIM(result); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-26 01:45:16 -05:00
										 |  |  | 	dpush(result); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | F_SEGMENT *alloc_segment(CELL size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *mem; | 
					
						
							|  |  |  | 	DWORD ignore; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if((mem = (char *)VirtualAlloc(NULL, getpagesize() * 2 + size, | 
					
						
							|  |  |  | 		MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0) | 
					
						
							| 
									
										
										
										
											2008-07-25 23:05:36 -04:00
										 |  |  | 		out_of_memory(); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore)) | 
					
						
							|  |  |  | 		fatal_error("Cannot allocate low guard page", (CELL)mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!VirtualProtect(mem + size + getpagesize(), | 
					
						
							|  |  |  | 		getpagesize(), PAGE_NOACCESS, &ignore)) | 
					
						
							|  |  |  | 		fatal_error("Cannot allocate high guard page", (CELL)mem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	F_SEGMENT *block = safe_malloc(sizeof(F_SEGMENT)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	block->start = (CELL)mem + getpagesize(); | 
					
						
							|  |  |  | 	block->size = size; | 
					
						
							|  |  |  | 	block->end = block->start + size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return block; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dealloc_segment(F_SEGMENT *block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SYSTEM_INFO si; | 
					
						
							|  |  |  | 	GetSystemInfo(&si); | 
					
						
							|  |  |  | 	if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE)) | 
					
						
							|  |  |  | 		fatal_error("dealloc_segment failed",0); | 
					
						
							|  |  |  | 	free(block); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | long getpagesize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static long g_pagesize = 0; | 
					
						
							|  |  |  | 	if (! g_pagesize) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		SYSTEM_INFO system_info; | 
					
						
							|  |  |  | 		GetSystemInfo (&system_info); | 
					
						
							|  |  |  | 		g_pagesize = system_info.dwPageSize; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return g_pagesize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sleep_millis(DWORD msec) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-11-12 23:18:29 -05:00
										 |  |  | 	Sleep(msec); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-03-06 21:44:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-09 17:57:21 -04:00
										 |  |  | DEFINE_PRIMITIVE(os_env) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_CHAR *key = unbox_u16_string(); | 
					
						
							| 
									
										
										
										
											2008-04-11 22:37:18 -04:00
										 |  |  | 	F_CHAR *value = safe_malloc(MAX_UNICODE_PATH * 2); | 
					
						
							| 
									
										
										
										
											2008-04-09 17:57:21 -04:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2008-04-11 22:37:18 -04:00
										 |  |  | 	ret = GetEnvironmentVariable(key, value, MAX_UNICODE_PATH * 2); | 
					
						
							| 
									
										
										
										
											2008-04-09 17:57:21 -04:00
										 |  |  | 	if(ret == 0) | 
					
						
							|  |  |  | 		dpush(F); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		dpush(tag_object(from_u16_string(value))); | 
					
						
							|  |  |  | 	free(value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-09 00:35:28 -04:00
										 |  |  | DEFINE_PRIMITIVE(set_os_env) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-04-09 01:33:29 -04:00
										 |  |  | 	F_CHAR *key = unbox_u16_string(); | 
					
						
							| 
									
										
										
										
											2008-04-09 00:35:28 -04:00
										 |  |  | 	REGISTER_C_STRING(key); | 
					
						
							| 
									
										
										
										
											2008-04-09 01:33:29 -04:00
										 |  |  | 	F_CHAR *value = unbox_u16_string(); | 
					
						
							| 
									
										
										
										
											2008-04-09 00:35:28 -04:00
										 |  |  | 	UNREGISTER_C_STRING(key); | 
					
						
							| 
									
										
										
										
											2008-04-09 17:57:21 -04:00
										 |  |  | 	if(!SetEnvironmentVariable(key, value)) | 
					
						
							|  |  |  | 		general_error(ERROR_IO, tag_object(get_error_message()), F, NULL); | 
					
						
							| 
									
										
										
										
											2008-04-09 00:35:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(unset_os_env) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-04-09 17:57:21 -04:00
										 |  |  | 	if(!SetEnvironmentVariable(unbox_u16_string(), NULL) | 
					
						
							|  |  |  | 		&& GetLastError() != ERROR_ENVVAR_NOT_FOUND) | 
					
						
							|  |  |  | 		general_error(ERROR_IO, tag_object(get_error_message()), F, NULL); | 
					
						
							| 
									
										
										
										
											2008-04-09 00:35:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-07 00:31:53 -04:00
										 |  |  | DEFINE_PRIMITIVE(set_os_envs) | 
					
						
							| 
									
										
										
										
											2008-03-06 21:44:52 -05:00
										 |  |  | { | 
					
						
							|  |  |  | 	not_implemented_error(); | 
					
						
							|  |  |  | } |