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; }
/** * 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); }
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); }
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); }
/** * 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); }