EFI_STATUS get_pci_device(IN EFI_DEVICE_PATH *p, OUT EFI_PCI_IO **p_pciio)
{
	EFI_STATUS ret;
	EFI_HANDLE pci_handle;
	EFI_DEVICE_PATH *tmp_path = p;

	ret = locate_device_path(&PciIoProtocol, &tmp_path, &pci_handle);
	if (EFI_ERROR(ret)) {
		efi_perror(ret, L"Failed to locate handle for EFI_PCI_IO_PROTOCOL");
		return ret;
	}

	ret = handle_protocol(pci_handle, &PciIoProtocol, (void**)p_pciio);
	if (EFI_ERROR(ret)) {
		efi_perror(ret, L"Failed to open PciIoProtocol");
		return ret;
	}

	return EFI_SUCCESS;
}
EFI_STATUS get_esp_fs(EFI_FILE_IO_INTERFACE **esp_fs)
{
    EFI_STATUS ret = EFI_SUCCESS;
    EFI_GUID SimpleFileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
    EFI_HANDLE esp_handle = NULL;
    EFI_FILE_IO_INTERFACE *esp;

    ret = gpt_get_partition_handle(BOOTLOADER_PART, LOGICAL_UNIT_USER,
                                   &esp_handle);
    if (EFI_ERROR(ret)) {
        efi_perror(ret, L"Failed to get ESP partition");
        return ret;
    }

    ret = handle_protocol(esp_handle, &SimpleFileSystemProtocol,
                          (void **)&esp);
    if (EFI_ERROR(ret)) {
        efi_perror(ret, L"HandleProtocol for ESP partition failed");
        return ret;
    }
    *esp_fs = esp;

    return ret;
}
示例#3
0
文件: entry.c 项目: drscaon/efilinux
/**
 * efi_main - The entry point for the OS loader image.
 * @image: firmware-allocated handle that identifies the image
 * @sys_table: EFI system table
 */
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table)
{
	WCHAR *error_buf;
	EFI_STATUS err;
	EFI_LOADED_IMAGE *info;
	CHAR16 *name, *options;
	UINT32 options_size;
	char *cmdline;

	InitializeLib(image, _table);
	sys_table = _table;
	boot = sys_table->BootServices;
	runtime = sys_table->RuntimeServices;

	if (CheckCrc(sys_table->Hdr.HeaderSize, &sys_table->Hdr) != TRUE)
		return EFI_LOAD_ERROR;

	Print(banner, EFILINUX_VERSION_MAJOR, EFILINUX_VERSION_MINOR);

	err = fs_init();
	if (err != EFI_SUCCESS)
		goto failed;

	err = handle_protocol(image, &LoadedImageProtocol, (void **)&info);
	if (err != EFI_SUCCESS)
		goto fs_deinit;

	if (!read_config_file(info, &options, &options_size)) {
		int i;

		options = info->LoadOptions;
		options_size = info->LoadOptionsSize;

		/*
		 * Skip the first word, that's probably our name. Stop
		 * when we hit a word delimiter (' ') or the start of an
		 * efilinux argument ('-').
		 */
		i = 0;
		while (i < options_size) {
			if (options[i] == ' ' || options[i] == '-')
				break;
			i++;
		}

		options = &options[i];
		options_size -= i;
	}

	if (options && options_size != 0) {
		err = parse_args(options, options_size, &name, &cmdline);

		/* We print the usage message in case of invalid args */
		if (err == EFI_INVALID_PARAMETER) {
			fs_exit();
			return EFI_SUCCESS;
		}

		if (err != EFI_SUCCESS)
			goto fs_deinit;
	}

	err = load_image(image, name, cmdline);
	if (err != EFI_SUCCESS)
		goto free_args;

	return EFI_SUCCESS;

free_args:
	free(cmdline);
	free(name);
fs_deinit:
	fs_exit();
failed:
	/*
	 * We need to be careful not to trash 'err' here. If we fail
	 * to allocate enough memory to hold the error string fallback
	 * to returning 'err'.
	 */
	if (allocate_pool(EfiLoaderData, ERROR_STRING_LENGTH,
			  (void **)&error_buf) != EFI_SUCCESS) {
		Print(L"Couldn't allocate pages for error string\n");
		return err;
	}

	StatusToString(error_buf, err);
	Print(L": %s\n", error_buf);
	return exit(image, err, ERROR_STRING_LENGTH, error_buf);
}
示例#4
0
int _stdcall
WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
		char *lpszCmdLine, int nCmdShow) {
	wchar_t errbuf[512];
	wchar_t pidgin_dir[MAX_PATH];
	wchar_t *pidgin_dir_start = NULL;
	wchar_t exe_name[MAX_PATH];
	HMODULE hmod;
	wchar_t *wtmp;
	int pidgin_argc;
	char **pidgin_argv; /* This is in utf-8 */
	int i, j, k;
	BOOL debug = FALSE, help = FALSE, version = FALSE, multiple = FALSE, success;
	LPWSTR *szArglist;
	LPWSTR cmdLine;

	/* If debug or help or version flag used, create console for output */
	for (i = 1; i < __argc; i++) {
		if (strlen(__argv[i]) > 1 && __argv[i][0] == '-') {
			/* check if we're looking at -- or - option */
			if (__argv[i][1] == '-') {
				if (strstr(__argv[i], "--debug") == __argv[i])
					debug = TRUE;
				else if (strstr(__argv[i], "--help") == __argv[i])
					help = TRUE;
				else if (strstr(__argv[i], "--version") == __argv[i])
					version = TRUE;
				else if (strstr(__argv[i], "--multiple") == __argv[i])
					multiple = TRUE;
			} else {
				if (strchr(__argv[i], 'd'))
					debug = TRUE;
				else if (strchr(__argv[i], 'h'))
					help = TRUE;
				else if (strchr(__argv[i], 'v'))
					version = TRUE;
				else if (strchr(__argv[i], 'm'))
					multiple = TRUE;
			}
		}
	}

	if (debug || help || version) {
		/* If stdout hasn't been redirected to a file, alloc a console
		 *  (_istty() doesn't work for stuff using the GUI subsystem) */
		if (_fileno(stdout) == -1 || _fileno(stdout) == -2) {
			LPFNATTACHCONSOLE MyAttachConsole = NULL;
			if ((hmod = GetModuleHandleW(L"kernel32.dll"))) {
				MyAttachConsole =
					(LPFNATTACHCONSOLE)
					GetProcAddress(hmod, "AttachConsole");
			}
			if ((MyAttachConsole && MyAttachConsole(ATTACH_PARENT_PROCESS))
					|| AllocConsole()) {
				freopen("CONOUT$", "w", stdout);
				freopen("CONOUT$", "w", stderr);
			}
		}
	}

	cmdLine = GetCommandLineW();

	/* If this is a protocol handler invocation, deal with it accordingly */
	if ((wtmp = wcsstr(cmdLine, PROTO_HANDLER_SWITCH)) != NULL) {
		handle_protocol(wtmp);
		return 0;
	}

	/* Load exception handler if we have it */
	if (GetModuleFileNameW(NULL, pidgin_dir, MAX_PATH) != 0) {

		/* primitive dirname() */
		pidgin_dir_start = wcsrchr(pidgin_dir, L'\\');

		if (pidgin_dir_start) {
			HMODULE hmod;
			pidgin_dir_start[0] = L'\0';

			/* tmp++ will now point to the executable file name */
			wcscpy(exe_name, pidgin_dir_start + 1);

			wcscat(pidgin_dir, L"\\exchndl.dll");
			if ((hmod = LoadLibraryW(pidgin_dir))) {
				FARPROC proc;
				/* exchndl.dll is built without UNICODE */
				char debug_dir[MAX_PATH];
				printf("Loaded exchndl.dll\n");
				/* Temporarily override exchndl.dll's logfile
				 * to something sane (Pidgin will override it
				 * again when it initializes) */
				proc = GetProcAddress(hmod, "SetLogFile");
				if (proc) {
					if (GetTempPathA(sizeof(debug_dir) * sizeof(char), debug_dir) != 0) {
						strcat(debug_dir, "pidgin.RPT");
						printf(" Setting exchndl.dll LogFile to %s\n",
							debug_dir);
						(proc)(debug_dir);
					}
				}
				proc = GetProcAddress(hmod, "SetDebugInfoDir");
				if (proc) {
					char *pidgin_dir_ansi = NULL;
					/* Restore pidgin_dir to point to where the executable is */
					pidgin_dir_start[0] = L'\0';
					i = WideCharToMultiByte(CP_ACP, 0, pidgin_dir,
						-1, NULL, 0, NULL, NULL);
					if (i != 0) {
						pidgin_dir_ansi = malloc(i * sizeof(char));
						i = WideCharToMultiByte(CP_ACP, 0, pidgin_dir,
							-1, pidgin_dir_ansi, i, NULL, NULL);
						if (i == 0) {
							free(pidgin_dir_ansi);
							pidgin_dir_ansi = NULL;
						}
					}
					if (pidgin_dir_ansi != NULL) {
						_snprintf(debug_dir, sizeof(debug_dir) / sizeof(char),
							"%s\\pidgin-%s-dbgsym",
							pidgin_dir_ansi,  VERSION);
						debug_dir[sizeof(debug_dir) / sizeof(char) - 1] = '\0';
						printf(" Setting exchndl.dll DebugInfoDir to %s\n",
							debug_dir);
						(proc)(debug_dir);
						free(pidgin_dir_ansi);
					}
				}

			}

			/* Restore pidgin_dir to point to where the executable is */
			pidgin_dir_start[0] = L'\0';
		}
	} else {
		DWORD dw = GetLastError();
		const wchar_t *err_msg = get_win32_error_message(dw);
		_snwprintf(errbuf, 512,
			L"Error getting module filename.\nError: (%u) %s",
			(UINT) dw, err_msg);
		wprintf(L"%s\n", errbuf);
		MessageBoxW(NULL, errbuf, NULL, MB_OK | MB_TOPMOST);
		pidgin_dir[0] = L'\0';
	}

	/* Determine if we're running in portable mode */
	if (wcsstr(cmdLine, L"--portable-mode")
			|| (exe_name != NULL && wcsstr(exe_name, L"-portable.exe"))) {
		printf("Running in PORTABLE mode.\n");
		portable_mode = TRUE;
	}

	if (portable_mode)
		portable_mode_dll_prep(pidgin_dir);
	else if (!getenv("PIDGIN_NO_DLL_CHECK"))
		dll_prep(pidgin_dir);

	winpidgin_set_locale();

	winpidgin_add_stuff_to_path();

	/* If help, version or multiple flag used, do not check Mutex */
	if (!help && !version)
		if (!winpidgin_set_running(getenv("PIDGIN_MULTI_INST") == NULL && !multiple))
			return 0;

	/* Now we are ready for Pidgin .. */
	wcscat(pidgin_dir, L"\\pidgin.dll");
	if ((hmod = LoadLibraryW(pidgin_dir)))
		pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main");

	/* Restore pidgin_dir to point to where the executable is */
	if (pidgin_dir_start)
		pidgin_dir_start[0] = L'\0';

	if (!pidgin_main) {
		DWORD dw = GetLastError();
		BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
		const wchar_t *err_msg = get_win32_error_message(dw);

		_snwprintf(errbuf, 512, L"Error loading pidgin.dll.\nError: (%u) %s%s%s",
			(UINT) dw, err_msg,
			mod_not_found ? L"\n" : L"",
			mod_not_found ? L"This probably means that GTK+ can't be found." : L"");
		wprintf(L"%s\n", errbuf);
		MessageBoxW(NULL, errbuf, L"Error", MB_OK | MB_TOPMOST);

		return 0;
	}

	/* Convert argv to utf-8*/
	szArglist = CommandLineToArgvW(cmdLine, &j);
	pidgin_argc = j;
	pidgin_argv = malloc(pidgin_argc* sizeof(char*));
	k = 0;
	for (i = 0; i < j; i++) {
		success = FALSE;
		/* Remove the --portable-mode arg from the args passed to pidgin so it doesn't choke */
		if (wcsstr(szArglist[i], L"--portable-mode") == NULL) {
			int len = WideCharToMultiByte(CP_UTF8, 0, szArglist[i],
				-1, NULL, 0, NULL, NULL);
			if (len != 0) {
				char *arg = malloc(len * sizeof(char));
				len = WideCharToMultiByte(CP_UTF8, 0, szArglist[i],
					-1, arg, len, NULL, NULL);
				if (len != 0) {
					pidgin_argv[k++] = arg;
					success = TRUE;
				}
			}
			if (!success)
				wprintf(L"Error converting argument '%s' to UTF-8\n",
					szArglist[i]);
		}
		if (!success)
			pidgin_argc--;
	}
	LocalFree(szArglist);


	return pidgin_main(hInstance, pidgin_argc, pidgin_argv);
}
示例#5
0
int _stdcall
WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
		char *lpszCmdLine, int nCmdShow) {
	char errbuf[512];
	char pidgin_dir[MAX_PATH];
	char exe_name[MAX_PATH];
	HMODULE hmod;
	char *tmp;
	int pidgin_argc = __argc;
	char **pidgin_argv = __argv;
	int i;
	BOOL debug = FALSE, help = FALSE, version = FALSE, multiple = FALSE;

	/* If debug or help or version flag used, create console for output */
	for (i = 1; i < __argc; i++) {
		if (strstr(__argv[i], "-d") || strstr(__argv[i], "--debug"))
			debug = TRUE;
		else if (strstr(__argv[i], "-h") || strstr(__argv[i], "--help"))
			help = TRUE;
		else if (strstr(__argv[i], "-v") || strstr(__argv[i], "--version"))
			version = TRUE;
		else if (strstr(__argv[i], "-m") || strstr(__argv[i], "--multiple"))
			multiple = TRUE;
	}

	if (debug || help || version) {
		/* If stdout hasn't been redirected to a file, alloc a console
		 *  (_istty() doesn't work for stuff using the GUI subsystem) */
		if (_fileno(stdout) == -1 || _fileno(stdout) == -2) {
			LPFNATTACHCONSOLE MyAttachConsole = NULL;
			if ((hmod = GetModuleHandle("kernel32.dll"))) {
				MyAttachConsole =
					(LPFNATTACHCONSOLE)
					GetProcAddress(hmod, "AttachConsole");
			}
			if ((MyAttachConsole && MyAttachConsole(ATTACH_PARENT_PROCESS))
					|| AllocConsole()) {
				freopen("CONOUT$", "w", stdout);
				freopen("CONOUT$", "w", stderr);
			}
		}
	}

	/* If this is a protocol handler invocation, deal with it accordingly */
	if ((tmp = strstr(lpszCmdLine, PROTO_HANDLER_SWITCH)) != NULL) {
		handle_protocol(tmp);
		return 0;
	}

	/* Load exception handler if we have it */
	if (GetModuleFileName(NULL, pidgin_dir, MAX_PATH) != 0) {
		char *prev = NULL;
		tmp = pidgin_dir;

		/* primitive dirname() */
		while ((tmp = strchr(tmp, '\\'))) {
			prev = tmp;
			tmp++;
		}

		if (prev) {
			prev[0] = '\0';

			/* prev++ will now point to the executable file name */
			strcpy(exe_name, prev + 1);

			strcat(pidgin_dir, "\\exchndl.dll");
			if (LoadLibrary(pidgin_dir))
				printf("Loaded exchndl.dll\n");

			prev[0] = '\0';
		}
	} else {
		DWORD dw = GetLastError();
		const char *err_msg = get_win32_error_message(dw);
		_snprintf(errbuf, 512,
			"Error getting module filename.\nError: (%u) %s",
			(UINT) dw, err_msg);
		printf("%s\n", errbuf);
		MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST);
		pidgin_dir[0] = '\0';
	}

	/* Determine if we're running in portable mode */
	if (strstr(lpszCmdLine, "--portable-mode")
			|| (exe_name != NULL && strstr(exe_name, "-portable.exe"))) {
		int i = 0, c = 0;

		printf("Running in PORTABLE mode.\n");
		portable_mode = TRUE;

		/* Remove the --portable-mode arg from the args passed to pidgin so it doesn't choke */
		pidgin_argv = malloc(sizeof(char*) * pidgin_argc);
		for (; i < __argc; i++) {
			if (strstr(__argv[i], "--portable-mode") == NULL) {
				pidgin_argv[c] = __argv[i];
				c++;
			} else
				pidgin_argc--;
		}
	}

	if (portable_mode)
		portable_mode_dll_prep(pidgin_dir);
	else if (!getenv("PIDGIN_NO_DLL_CHECK"))
		dll_prep();

	winpidgin_set_locale();

	winpidgin_add_stuff_to_path();

	/* If help, version or multiple flag used, do not check Mutex */
	if (!help && !version)
		if (!winpidgin_set_running(getenv("PIDGIN_MULTI_INST") == NULL && !multiple))
			return 0;

	/* Now we are ready for Pidgin .. */
	if ((hmod = LoadLibrary("pidgin.dll")))
		pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main");

	if (!pidgin_main) {
		DWORD dw = GetLastError();
		BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
		const char *err_msg = get_win32_error_message(dw);

		_snprintf(errbuf, 512, "Error loading pidgin.dll.\nError: (%u) %s%s%s",
			(UINT) dw, err_msg,
			mod_not_found ? "\n" : "",
			mod_not_found ? "This probably means that GTK+ can't be found." : "");
		printf("%s\n", errbuf);
		MessageBox(NULL, errbuf, TEXT("Error"), MB_OK | MB_TOPMOST);

		return 0;
	}

	return pidgin_main(hInstance, pidgin_argc, pidgin_argv);
}
示例#6
0
/**
 * efi_main - The entry point for the OS loader image.
 * @image: firmware-allocated handle that identifies the image
 * @sys_table: EFI system table
 */
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table)
{
	WCHAR *error_buf;
	EFI_STATUS err;
	EFI_LOADED_IMAGE *info;
	CHAR16 *name = NULL;
	CHAR16 *options;
	BOOLEAN options_from_conf_file = FALSE;
	UINT32 options_size;
	CHAR8 *cmdline = NULL;
	struct bootimg_hooks hooks;

	main_image_handle = image;
	InitializeLib(image, _table);
	sys_table = _table;
	boot = sys_table->BootServices;
	runtime = sys_table->RuntimeServices;

	if (CheckCrc(ST->Hdr.HeaderSize, &ST->Hdr) != TRUE)
		return EFI_LOAD_ERROR;

	log_init();

	info(banner, EFILINUX_VERSION_MAJOR, EFILINUX_VERSION_MINOR,
		EFILINUX_BUILD_STRING, EFILINUX_VERSION_STRING,
		EFILINUX_VERSION_DATE);

	store_osloader_version(EFILINUX_BUILD_STRING);

	err = fs_init();
	if (err != EFI_SUCCESS)
		error(L"fs_init failed, DnX mode ?\n");

	err = handle_protocol(image, &LoadedImageProtocol, (void **)&info);
	if (err != EFI_SUCCESS)
		goto fs_deinit;

	efilinux_image_base = info->ImageBase;
	efilinux_image = info->DeviceHandle;

	if (!read_config_file(info, &options, &options_size)) {
		int i;

		options = info->LoadOptions;
		options_size = info->LoadOptionsSize;

		/* Skip the first word, that's our name. */
		for (i = 0; i < options_size && options[i] != ' '; i++)
			;
		options = &options[i];
		options_size -= i;
	} else
		options_from_conf_file = TRUE;

	err = init_platform_functions();
	if (EFI_ERROR(err)) {
		error(L"Failed to initialize platform: %r\n", err);
		goto fs_deinit;
	}

	CHAR16 type = '\0';
	if (options && options_size != 0) {
		err = parse_args(options, options_size, &type, &name, &cmdline);

		if (options_from_conf_file)
			free(options);

		/* We print the usage message in case of invalid args */
		if (err == EFI_INVALID_PARAMETER) {
			fs_exit();
			return EFI_SUCCESS;
		}

		if (err != EFI_SUCCESS)
			goto fs_deinit;
	}

	hooks.before_exit = loader_ops.hook_before_exit;
	hooks.before_jump = loader_ops.hook_before_jump;
	hooks.watchdog = tco_start_watchdog;

	debug(L"shell cmdline=%a\n", cmdline);
	switch(type) {
	case 'f':
		if (!name) {
			error(L"No file name specified or name is empty\n");
			goto free_args;
		}
		info(L"Starting file %s\n", name);
		err = android_image_start_file(info->DeviceHandle, name, cmdline, &hooks);
		break;
	case 't': {
		enum targets target;
		if ((err = name_to_target(name, &target)) != EFI_SUCCESS) {
			error(L"Unknown target name %s\n", name);
			goto free_args;
		}
		info(L"Starting target %s\n", name);
		loader_ops.load_target(target, cmdline);
		break;
	}
	case 'p': {
		EFI_GUID part_guid;
		if ((err = name_to_guid(name, &part_guid)) != EFI_SUCCESS) {
			error(L"Unknown target name %s\n", name);
			goto free_args;
		}
		info(L"Starting partition %s\n", name);
		err = android_image_start_partition(&part_guid, cmdline, &hooks);
		break;
	}
	case 'c': {
		int i;
		for (i = 0 ; i < sizeof(commands) / sizeof(*commands); i++)
			if (!StrCmp(commands[i].name, name))
				commands[i].func();
		err = EFI_SUCCESS;
	}
		break;
	case 'a':
	{
		CHAR16 *endptr;
		VOID * addr = (VOID *)strtoul16(name, &endptr, 0);
		if ((name[0] == '\0' || *endptr != '\0')) {
			error(L"Failed to convert %s into address\n", name);
			goto free_args;
		}
		debug(L"Loading android image at 0x%x\n", addr);
		err = android_image_start_buffer(addr, cmdline, &hooks);
		break;
	}
	default:
		debug(L"type=0x%x, starting bootlogic\n", type);
		err = start_boot_logic(cmdline);
		if (EFI_ERROR(err)) {
			error(L"Boot logic failed: %r\n", err);
			goto free_args;
		}
	}

free_args:
	if (cmdline)
		free(cmdline);
	if (name)
		free(name);
fs_deinit:
	fs_exit();
	/*
	 * We need to be careful not to trash 'err' here. If we fail
	 * to allocate enough memory to hold the error string fallback
	 * to returning 'err'.
	 */

	error_buf = AllocatePool(ERROR_STRING_LENGTH);
	if (!error_buf) {
		error(L"Couldn't allocate pages for error string\n");
		return EFI_OUT_OF_RESOURCES;
	}

	StatusToString(error_buf, err);
	error(L": %s\n", error_buf);

	loader_ops.hook_before_exit();

	return exit(image, err, ERROR_STRING_LENGTH, error_buf);
}