// From smartmontools os_win32.cpp void GetWindowsVersion(void) { OSVERSIONINFOEXA vi, vi2; const char* w = 0; const char* w64 = "32 bit"; char* vptr; size_t vlen; unsigned major, minor; ULONGLONG major_equal, minor_equal; BOOL ws; nWindowsVersion = WINDOWS_UNDEFINED; safe_strcpy(WindowsVersionStr, sizeof(WindowsVersionStr), "Windows Undefined"); memset(&vi, 0, sizeof(vi)); vi.dwOSVersionInfoSize = sizeof(vi); if (!GetVersionExA((OSVERSIONINFOA *)&vi)) { memset(&vi, 0, sizeof(vi)); vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); if (!GetVersionExA((OSVERSIONINFOA *)&vi)) return; } if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) { if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) { // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); for (major = vi.dwMajorVersion; major <= 9; major++) { memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major; if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal)) continue; if (vi.dwMajorVersion < major) { vi.dwMajorVersion = major; vi.dwMinorVersion = 0; } minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); for (minor = vi.dwMinorVersion; minor <= 9; minor++) { memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMinorVersion = minor; if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal)) continue; vi.dwMinorVersion = minor; break; } break; } } if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) { ws = (vi.wProductType <= VER_NT_WORKSTATION); nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion; switch (nWindowsVersion) { case 0x50: w = "2000"; break; case 0x51: w = "XP"; break; case 0x52: w = (!GetSystemMetrics(89)?"2003":"2003_R2"); break; case 0x60: w = (ws?"Vista":"2008"); break; case 0x61: w = (ws?"7":"2008_R2"); break; case 0x62: w = (ws?"8":"2012"); break; case 0x63: w = (ws?"8.1":"2012_R2"); break; case 0x64: w = (ws?"8.2":"2012_R3"); break; default: if (nWindowsVersion < 0x50) nWindowsVersion = WINDOWS_UNSUPPORTED; else w = "9 or later"; break; } } } if (is_x64()) w64 = "64-bit"; vptr = &WindowsVersionStr[sizeof("Windows ") - 1]; vlen = sizeof(WindowsVersionStr) - sizeof("Windows ") - 1; if (!w) safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId==VER_PLATFORM_WIN32_NT?"NT":"??"), (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64); else if (vi.wServicePackMinor) safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64); else if (vi.wServicePackMajor) safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64); else safe_sprintf(vptr, vlen, "%s %s", w, w64); }
// Returns 0 on success, nonzero on error static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) { HANDLE file_handle = NULL; DWORD buf_size, wr_size; BOOL s, is_syslinux_cfg, is_old_vesamenu; int i_length, r = 1; char psz_fullpath[1024], *psz_basename; const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)]; unsigned char buf[ISO_BLOCKSIZE]; CdioListNode_t* p_entnode; iso9660_stat_t *p_statbuf; CdioList_t* p_entlist; size_t i, nul_pos; lsn_t lsn; int64_t i_file_length; if ((p_iso == NULL) || (psz_path == NULL)) return 1; i_length = safe_sprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path); if (i_length < 0) return 1; psz_basename = &psz_fullpath[i_length]; p_entlist = iso9660_ifs_readdir(p_iso, psz_path); if (!p_entlist) { uprintf("Could not access directory %s\n", psz_path); return 1; } _CDIO_LIST_FOREACH(p_entnode, p_entlist) { if (FormatStatus) goto out; p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode); /* Eliminate . and .. entries */ if ( (strcmp(p_statbuf->filename, ".") == 0) || (strcmp(p_statbuf->filename, "..") == 0) ) continue; iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level); if (p_statbuf->type == _STAT_DIR) { if (!scan_only) _mkdirU(psz_fullpath); if (iso_extract_files(p_iso, psz_iso_name)) goto out; } else { i_file_length = p_statbuf->size; if (check_iso_props(psz_path, &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) { continue; } // Replace slashes with backslashes and append the size to the path for UI display nul_pos = safe_strlen(psz_fullpath); for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '/') psz_fullpath[i] = '\\'; safe_strcpy(&psz_fullpath[nul_pos], 24, size_to_hr(i_file_length)); uprintf("Extracting: %s\n", psz_fullpath); SetWindowTextU(hISOFileName, psz_fullpath); // ISO9660 cannot handle backslashes for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '\\') psz_fullpath[i] = '/'; psz_fullpath[nul_pos] = 0; if (is_old_vesamenu && use_own_vesamenu) { if (CopyFileA("vesamenu.c32", psz_fullpath, FALSE)) { uprintf(" Replaced with local version\n"); continue; } uprintf(" Could not replace file: %s\n", WindowsErrorString()); } file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) { uprintf(" Unable to create file: %s\n", WindowsErrorString()); goto out; } for (i = 0; i_file_length > 0; i++) { if (FormatStatus) goto out; memset(buf, 0, ISO_BLOCKSIZE); lsn = p_statbuf->lsn + (lsn_t)i; if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { uprintf(" Error reading ISO9660 file %s at LSN %lu\n", psz_iso_name, (long unsigned int)lsn); goto out; } buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE); ISO_BLOCKING(s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL)); if ((!s) || (buf_size != wr_size)) { uprintf(" Error writing file: %s\n", WindowsErrorString()); goto out; } i_file_length -= ISO_BLOCKSIZE; if (nb_blocks++ % PROGRESS_THRESHOLD == 0) { SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks); } } ISO_BLOCKING(safe_closehandle(file_handle)); if (is_syslinux_cfg) { if (replace_in_token_data(psz_fullpath, "append", iso_report.label, iso_report.usb_label, TRUE) != NULL) uprintf("Patched %s: '%s' -> '%s'\n", psz_fullpath, iso_report.label, iso_report.usb_label); } } } r = 0; out: ISO_BLOCKING(safe_closehandle(file_handle)); _cdio_list_free(p_entlist, true); return r; }
/* * Open a drive or volume with optional write and lock access * Returns INVALID_HANDLE_VALUE (/!\ which is DIFFERENT from NULL /!\) on failure. * This call is quite risky (left unchecked, inadvertently passing 0 as index would * return a handle to C:, which we might then proceed to unknowingly repartition!), * so we apply the following mitigation factors: * - Valid indexes must belong to a specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX] * - When opening for write access, we lock the volume. If that fails, which would * typically be the case on C:\ or any other drive in use, we report failure * - We report the full path of any drive that was successfully opened for write acces */ HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) { BOOL r; DWORD size; HANDLE hDrive = INVALID_HANDLE_VALUE; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; UINT drive_type; char drives[26*4]; /* "D:\", "E:\", etc. */ char *drive = drives; char logical_drive[] = "\\\\.\\#:"; char physical_drive[24]; if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { uprintf("WARNING: Bad index value. Please check the code!\n"); } DriveIndex -= DRIVE_INDEX_MIN; // If no drive letter is requested, open a physical drive if (DriveLetter == NULL) { safe_sprintf(physical_drive, sizeof(physical_drive), "\\\\.\\PHYSICALDRIVE%d", DriveIndex); hDrive = CreateFileA(physical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Could not open drive %s: %s\n", physical_drive, WindowsErrorString()); goto out; } if (bWriteAccess) { uprintf("Caution: Opened %s drive for write access\n", physical_drive); } } else { *DriveLetter = ' '; size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } hDrive = INVALID_HANDLE_VALUE; for ( ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ drive_type = GetDriveTypeA(drive); // NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default // Using Alt-F in Rufus does enable listing, but this mode is unsupported. if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED))) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &size, NULL); if ((!r) || (size <= 0)) { uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { break; } safe_closehandle(hDrive); } if (hDrive == INVALID_HANDLE_VALUE) { goto out; } if (bWriteAccess) { uprintf("Caution: Opened %s drive for write access\n", logical_drive); } *DriveLetter = *drive?*drive:' '; } if ((bLockDrive) && (!DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL))) { uprintf("Could not get exclusive access to %s %s\n", logical_drive, WindowsErrorString()); safe_closehandle(hDrive); goto out; } out: return hDrive; }
/* * FormatMessage does not handle internet errors * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385465.aspx */ const char* WinInetErrorString(void) { static char error_string[256]; DWORD size = sizeof(error_string); error_code = HRESULT_CODE(GetLastError()); if ((error_code < INTERNET_ERROR_BASE) || (error_code > INTERNET_ERROR_LAST)) return WindowsErrorString(); // TODO: These should be localized on an ad-hoc basis switch(error_code) { case ERROR_INTERNET_OUT_OF_HANDLES: return "No more handles could be generated at this time."; case ERROR_INTERNET_TIMEOUT: return "The request has timed out."; case ERROR_INTERNET_INTERNAL_ERROR: return "An internal error has occurred."; case ERROR_INTERNET_INVALID_URL: return "The URL is invalid."; case ERROR_INTERNET_UNRECOGNIZED_SCHEME: return "The URL scheme could not be recognized or is not supported."; case ERROR_INTERNET_NAME_NOT_RESOLVED: return "The server name could not be resolved."; case ERROR_INTERNET_PROTOCOL_NOT_FOUND: return "The requested protocol could not be located."; case ERROR_INTERNET_INVALID_OPTION: return "A request specified an invalid option value."; case ERROR_INTERNET_BAD_OPTION_LENGTH: return "The length of an option supplied is incorrect for the type of option specified."; case ERROR_INTERNET_OPTION_NOT_SETTABLE: return "The request option cannot be set, only queried."; case ERROR_INTERNET_SHUTDOWN: return "The Win32 Internet function support is being shut down or unloaded."; case ERROR_INTERNET_INCORRECT_USER_NAME: return "The request to connect and log on to an FTP server could not be completed because the supplied user name is incorrect."; case ERROR_INTERNET_INCORRECT_PASSWORD: return "The request to connect and log on to an FTP server could not be completed because the supplied password is incorrect."; case ERROR_INTERNET_LOGIN_FAILURE: return "The request to connect to and log on to an FTP server failed."; case ERROR_INTERNET_INVALID_OPERATION: return "The requested operation is invalid."; case ERROR_INTERNET_OPERATION_CANCELLED: return "The operation was cancelled, usually because the handle on which the request was operating was closed before the operation completed."; case ERROR_INTERNET_INCORRECT_HANDLE_TYPE: return "The type of handle supplied is incorrect for this operation."; case ERROR_INTERNET_INCORRECT_HANDLE_STATE: return "The requested operation cannot be carried out because the handle supplied is not in the correct state."; case ERROR_INTERNET_NOT_PROXY_REQUEST: return "The request cannot be made via a proxy."; case ERROR_INTERNET_REGISTRY_VALUE_NOT_FOUND: return "A required registry value could not be located."; case ERROR_INTERNET_BAD_REGISTRY_PARAMETER: return "A required registry value was located but is an incorrect type or has an invalid value."; case ERROR_INTERNET_NO_DIRECT_ACCESS: return "Direct network access cannot be made at this time."; case ERROR_INTERNET_NO_CONTEXT: return "An asynchronous request could not be made because a zero context value was supplied."; case ERROR_INTERNET_NO_CALLBACK: return "An asynchronous request could not be made because a callback function has not been set."; case ERROR_INTERNET_REQUEST_PENDING: return "The required operation could not be completed because one or more requests are pending."; case ERROR_INTERNET_INCORRECT_FORMAT: return "The format of the request is invalid."; case ERROR_INTERNET_ITEM_NOT_FOUND: return "The requested item could not be located."; case ERROR_INTERNET_CANNOT_CONNECT: return "The attempt to connect to the server failed."; case ERROR_INTERNET_CONNECTION_ABORTED: return "The connection with the server has been terminated."; case ERROR_INTERNET_CONNECTION_RESET: return "The connection with the server has been reset."; case ERROR_INTERNET_FORCE_RETRY: return "Calls for the Win32 Internet function to redo the request."; case ERROR_INTERNET_INVALID_PROXY_REQUEST: return "The request to the proxy was invalid."; case ERROR_INTERNET_HANDLE_EXISTS: return "The request failed because the handle already exists."; case ERROR_INTERNET_SEC_CERT_DATE_INVALID: return "SSL certificate date that was received from the server is bad. The certificate is expired."; case ERROR_INTERNET_SEC_CERT_CN_INVALID: return "SSL certificate common name (host name field) is incorrect."; case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR: return "The application is moving from a non-SSL to an SSL connection because of a redirect."; case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR: return "The application is moving from an SSL to an non-SSL connection because of a redirect."; case ERROR_INTERNET_MIXED_SECURITY: return "Some of the content being viewed may have come from unsecured servers."; case ERROR_INTERNET_CHG_POST_IS_NON_SECURE: return "The application is posting and attempting to change multiple lines of text on a server that is not secure."; case ERROR_INTERNET_POST_IS_NON_SECURE: return "The application is posting data to a server that is not secure."; case ERROR_FTP_TRANSFER_IN_PROGRESS: return "The requested operation cannot be made on the FTP session handle because an operation is already in progress."; case ERROR_FTP_DROPPED: return "The FTP operation was not completed because the session was aborted."; case ERROR_GOPHER_PROTOCOL_ERROR: case ERROR_GOPHER_NOT_FILE: case ERROR_GOPHER_DATA_ERROR: case ERROR_GOPHER_END_OF_DATA: case ERROR_GOPHER_INVALID_LOCATOR: case ERROR_GOPHER_INCORRECT_LOCATOR_TYPE: case ERROR_GOPHER_NOT_GOPHER_PLUS: case ERROR_GOPHER_ATTRIBUTE_NOT_FOUND: case ERROR_GOPHER_UNKNOWN_LOCATOR: return "Gopher? Really??? What is this, 1994?"; case ERROR_HTTP_HEADER_NOT_FOUND: return "The requested header could not be located."; case ERROR_HTTP_DOWNLEVEL_SERVER: return "The server did not return any headers."; case ERROR_HTTP_INVALID_SERVER_RESPONSE: return "The server response could not be parsed."; case ERROR_HTTP_INVALID_HEADER: return "The supplied header is invalid."; case ERROR_HTTP_INVALID_QUERY_REQUEST: return "The request made to HttpQueryInfo is invalid."; case ERROR_HTTP_HEADER_ALREADY_EXISTS: return "The header could not be added because it already exists."; case ERROR_HTTP_REDIRECT_FAILED: return "The redirection failed because either the scheme changed or all attempts made to redirect failed."; case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: return "Client Authentication certificate needed"; case ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT: return "Bad auto proxy script."; case ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT: return "Unable to download script."; case ERROR_INTERNET_NOT_INITIALIZED: return "Internet has not be initialized."; case ERROR_INTERNET_UNABLE_TO_CACHE_FILE: return "Unable to cache the file."; case ERROR_INTERNET_TCPIP_NOT_INSTALLED: return "TPC/IP not installed."; case ERROR_INTERNET_DISCONNECTED: return "Internet is disconnected."; case ERROR_INTERNET_SERVER_UNREACHABLE: return "Server could not be reached."; case ERROR_INTERNET_PROXY_SERVER_UNREACHABLE: return "Proxy server could not be reached."; case ERROR_INTERNET_FAILED_DUETOSECURITYCHECK: return "A security check prevented internet connection."; case ERROR_INTERNET_NEED_MSN_SSPI_PKG: return "This connection requires an MSN Security Support Provider Interface package."; case ERROR_INTERNET_LOGIN_FAILURE_DISPLAY_ENTITY_BODY: return "Please ask Microsoft about that one!"; case ERROR_INTERNET_EXTENDED_ERROR: InternetGetLastResponseInfoA(&error_code, error_string, &size); return error_string; default: safe_sprintf(error_string, sizeof(error_string), "Unknown internet error 0x%08X", error_code); return error_string; } }
BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan) { size_t i, size; int j; uint16_t sl_version; FILE* fd; int r = 1; iso9660_t* p_iso = NULL; udf_t* p_udf = NULL; udf_dirent_t* p_udf_root; char *tmp, *buf, *ext; char path[MAX_PATH], path2[16]; const char* basedir[] = { "i386", "minint" }; const char* tmp_sif = ".\\txtsetup.sif~"; iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL; char* spacing = " "; if ((!enable_iso) || (src_iso == NULL) || (dest_dir == NULL)) return FALSE; scan_only = scan; if (!scan_only) spacing = ""; cdio_log_set_handler(log_handler); psz_extract_dir = dest_dir; // Change progress style to marquee for scanning if (scan_only) { uprintf("ISO analysis:"); SendMessage(hMainDialog, UM_PROGRESS_INIT, PBS_MARQUEE, 0); total_blocks = 0; memset(&img_report, 0, sizeof(img_report)); has_ldlinux_c32 = FALSE; // String array of all isolinux/syslinux locations StrArrayCreate(&config_path, 8); StrArrayCreate(&isolinux_path, 8); PrintInfo(0, MSG_202); } else { uprintf("Extracting files...\n"); IGNORE_RETVAL(_chdirU(app_dir)); PrintInfo(0, MSG_231); if (total_blocks == 0) { uprintf("Error: ISO has not been properly scanned.\n"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN); goto out; } nb_blocks = 0; iso_blocking_status = 0; } // First try to open as UDF - fallback to ISO if it failed p_udf = udf_open(src_iso); if (p_udf == NULL) goto try_iso; uprintf("%sImage is an UDF image", spacing); p_udf_root = udf_get_root(p_udf, true, 0); if (p_udf_root == NULL) { uprintf("%sCould not locate UDF root directory", spacing); goto out; } if (scan_only) { if (udf_get_logical_volume_id(p_udf, img_report.label, sizeof(img_report.label)) <= 0) img_report.label[0] = 0; } r = udf_extract_files(p_udf, p_udf_root, ""); goto out; try_iso: // Perform our first scan with Joliet disabled (if Rock Ridge is enabled), so that we can find if // there exists a Rock Ridge file with a name > 64 chars or if there are symlinks. If that is the // case then we also disable Joliet during the extract phase. if ((!enable_joliet) || (enable_rockridge && (scan_only || img_report.has_long_filename || img_report.has_symlinks))) { iso_extension_mask &= ~ISO_EXTENSION_JOLIET; } if (!enable_rockridge) { iso_extension_mask &= ~ISO_EXTENSION_ROCK_RIDGE; } p_iso = iso9660_open_ext(src_iso, iso_extension_mask); if (p_iso == NULL) { uprintf("%s'%s' doesn't look like an ISO image", spacing, src_iso); r = 1; goto out; } uprintf("%sImage is an ISO9660 image", spacing); i_joliet_level = iso9660_ifs_get_joliet_level(p_iso); if (scan_only) { if (iso9660_ifs_get_volume_id(p_iso, &tmp)) { safe_strcpy(img_report.label, sizeof(img_report.label), tmp); safe_free(tmp); } else img_report.label[0] = 0; } else { if (iso_extension_mask & (ISO_EXTENSION_JOLIET|ISO_EXTENSION_ROCK_RIDGE)) uprintf("%sThis image will be extracted using %s extensions (if present)", spacing, (iso_extension_mask & ISO_EXTENSION_JOLIET)?"Joliet":"Rock Ridge"); else uprintf("%sThis image will not be extracted using any ISO extensions", spacing); } r = iso_extract_files(p_iso, ""); out: iso_blocking_status = -1; if (scan_only) { // Remove trailing spaces from the label for (j=(int)safe_strlen(img_report.label)-1; ((j>=0)&&(isspaceU(img_report.label[j]))); j--) img_report.label[j] = 0; // We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here img_report.projected_size = total_blocks * ISO_BLOCKSIZE; // We will link the existing isolinux.cfg from a syslinux.cfg we create // If multiple config files exist, choose the one with the shortest path // (so that a '/syslinux.cfg' is preferred over a '/isolinux/isolinux.cfg') if (!IsStrArrayEmpty(config_path)) { // Set the img_report.cfg_path string to maximum length, so that we don't have to // do a special case for StrArray entry 0. memset(img_report.cfg_path, '_', sizeof(img_report.cfg_path)-1); img_report.cfg_path[sizeof(img_report.cfg_path)-1] = 0; for (i=0; i<config_path.Index; i++) { // OpenSuse based Live image have a /syslinux.cfg that doesn't work, so we enforce // the use of the one in '/boot/[i386|x86_64]/loader/isolinux.cfg' if present. // Note that, because the openSuse live script are not designed to handle anything but // an ISO9660 filesystem for the live device, this still won't allow for proper boot. // See https://github.com/openSUSE/kiwi/issues/354 if ( (_stricmp(config_path.String[i], "/boot/i386/loader/isolinux.cfg") == 0) || (_stricmp(config_path.String[i], "/boot/x86_64/loader/isolinux.cfg") == 0)) { safe_strcpy(img_report.cfg_path, sizeof(img_report.cfg_path), config_path.String[i]); img_report.needs_syslinux_overwrite = TRUE; break; } // Tails uses an '/EFI/BOOT/isolinux.cfg' along with a '/isolinux/isolinux.cfg' // which are the exact same length. However, only the /isolinux one will work, // so for now, at equal length, always pick the latest. // We may have to revisit this and prefer a path that contains '/isolinux' if // this hack is not enough for other images. if (safe_strlen(img_report.cfg_path) >= safe_strlen(config_path.String[i])) safe_strcpy(img_report.cfg_path, sizeof(img_report.cfg_path), config_path.String[i]); } uprintf(" Will use '%s' for Syslinux", img_report.cfg_path); // Extract all of the isolinux.bin files we found to identify their versions for (i=0; i<isolinux_path.Index; i++) { size = (size_t)ExtractISOFile(src_iso, isolinux_path.String[i], dot_isolinux_bin, FILE_ATTRIBUTE_NORMAL); if (size == 0) { uprintf(" Could not access %s", isolinux_path.String[i]); } else { buf = (char*)calloc(size, 1); if (buf == NULL) break; fd = fopen(dot_isolinux_bin, "rb"); if (fd == NULL) { free(buf); continue; } fread(buf, 1, size, fd); fclose(fd); sl_version = GetSyslinuxVersion(buf, size, &ext); if (img_report.sl_version == 0) { safe_strcpy(img_report.sl_version_ext, sizeof(img_report.sl_version_ext), ext); img_report.sl_version = sl_version; j = (int)i; } else if ((img_report.sl_version != sl_version) || (safe_strcmp(img_report.sl_version_ext, ext) != 0)) { uprintf(" Found conflicting %s versions:\n '%s' (%d.%02d%s) vs '%s' (%d.%02d%s)", isolinux_bin, isolinux_path.String[j], SL_MAJOR(img_report.sl_version), SL_MINOR(img_report.sl_version), img_report.sl_version_ext, isolinux_path.String[i], SL_MAJOR(sl_version), SL_MINOR(sl_version), ext); } free(buf); _unlink(dot_isolinux_bin); } } if (img_report.sl_version != 0) { static_sprintf(img_report.sl_version_str, "%d.%02d", SL_MAJOR(img_report.sl_version), SL_MINOR(img_report.sl_version)); uprintf(" Detected Syslinux version: %s%s (from '%s')", img_report.sl_version_str, img_report.sl_version_ext, isolinux_path.String[j]); if ( (has_ldlinux_c32 && (SL_MAJOR(img_report.sl_version) < 5)) || (!has_ldlinux_c32 && (SL_MAJOR(img_report.sl_version) >= 5)) ) uprintf(" Warning: Conflict between Isolinux version and the presence of ldlinux.c32..."); } else { // Couldn't find a version from isolinux.bin. Force set to the versions we embed img_report.sl_version = embedded_sl_version[has_ldlinux_c32?1:0]; static_sprintf(img_report.sl_version_str, "%d.%02d", SL_MAJOR(img_report.sl_version), SL_MINOR(img_report.sl_version)); uprintf(" Warning: Could not detect Isolinux version - Forcing to %s (embedded)", img_report.sl_version_str); } } if (IS_WINPE(img_report.winpe)) { // In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif // during scan, to see if /minint was provided for OsLoadOptions, as it decides // whether we should use 0x80 or 0x81 as the disk ID in the MBR safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", basedir[((img_report.winpe&WINPE_I386) == WINPE_I386)?0:1]); ExtractISOFile(src_iso, path, tmp_sif, FILE_ATTRIBUTE_NORMAL); tmp = get_token_data_file("OsLoadOptions", tmp_sif); if (tmp != NULL) { for (i=0; i<strlen(tmp); i++) tmp[i] = (char)tolower(tmp[i]); uprintf(" Checking txtsetup.sif:\n OsLoadOptions = %s", tmp); img_report.uses_minint = (strstr(tmp, "/minint") != NULL); } _unlink(tmp_sif); safe_free(tmp); } if (HAS_INSTALL_WIM(img_report)) { img_report.install_wim_version = GetInstallWimVersion(src_iso); } if (img_report.has_grub2) { // In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version img_report.grub2_version[0] = 0; if ((GetTempPathU(sizeof(path), path) != 0) && (GetTempFileNameU(path, APPLICATION_NAME, 0, path) != 0)) { size = (size_t)ExtractISOFile(src_iso, "boot/grub/i386-pc/normal.mod", path, FILE_ATTRIBUTE_NORMAL); buf = (char*)calloc(size, 1); fd = fopen(path, "rb"); if ((size == 0) || (buf == NULL) || (fd == NULL)) { uprintf(" Could not read Grub version from 'boot/grub/i386-pc/normal.mod'"); } else { fread(buf, 1, size, fd); fclose(fd); GetGrubVersion(buf, size); } free(buf); _unlink(path); } if (img_report.grub2_version[0] != 0) uprintf(" Detected Grub version: %s", img_report.grub2_version); else { uprintf(" Could not detect Grub version"); img_report.has_grub2 = FALSE; } } StrArrayDestroy(&config_path); StrArrayDestroy(&isolinux_path); SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); } else if (HAS_SYSLINUX(img_report)) { safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir); // Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg fd = fopen(path, "r"); if (fd != NULL && img_report.needs_syslinux_overwrite) { fclose(fd); fd = NULL; safe_sprintf(path2, sizeof(path2), "%s\\syslinux.org", dest_dir); uprintf("Renaming: %s ⇨ %s", path, path2); IGNORE_RETVAL(rename(path, path2)); } if (fd == NULL) { fd = fopen(path, "w"); // No "/syslinux.cfg" => create a new one if (fd == NULL) { uprintf("Unable to create %s - booting from USB will not work", path); r = 1; } else { fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", img_report.cfg_path); for (i=safe_strlen(img_report.cfg_path); (i>0)&&(img_report.cfg_path[i]!='/'); i--); if (i>0) { img_report.cfg_path[i] = 0; fprintf(fd, " APPEND %s/\n", img_report.cfg_path); img_report.cfg_path[i] = '/'; } uprintf("Created: %s", path); } } if (fd != NULL) fclose(fd); } if (p_iso != NULL) iso9660_close(p_iso); if (p_udf != NULL) udf_close(p_udf); if ((r != 0) && (FormatStatus == 0)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT)); return (r == 0); }
BOOL CALLBACK dialog_proc_2(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam) { static device_context_t *device = NULL; static HWND hToolTip; char tmp[MAX_TEXT_LENGTH]; int val; switch (message) { case WM_INITDIALOG: SendMessage(dialog,WM_SETICON,ICON_SMALL, (LPARAM)mIcon); SendMessage(dialog,WM_SETICON,ICON_BIG, (LPARAM)mIcon); device = (device_context_t *)lParam; if (device) { wdi_is_driver_supported(WDI_LIBUSB0, &device->driver_info); //g_hwndTrackingTT = CreateTrackingToolTip(dialog,TEXT(" ")); hToolTip = create_tooltip(dialog, g_hInst, 300, tooltips_dlg2); memset(tmp, 0, sizeof(tmp)); safe_sprintf(tmp,sizeof(tmp) - 1, "0x%04X", device->wdi->vid); SetWindowText(GetDlgItem(dialog, ID_TEXT_VID), tmp); memset(tmp, 0, sizeof(tmp)); safe_sprintf(tmp,sizeof(tmp) - 1, "0x%04X", device->wdi->pid); SetWindowText(GetDlgItem(dialog, ID_TEXT_PID), tmp); memset(tmp, 0, sizeof(tmp)); if (device->wdi->is_composite) safe_sprintf(tmp,sizeof(tmp) - 1, "0x%02X", device->wdi->mi); SetWindowText(GetDlgItem(dialog, ID_TEXT_MI), tmp); SetWindowTextU(GetDlgItem(dialog, ID_TEXT_MANUFACTURER), device->manufacturer); SetWindowTextU(GetDlgItem(dialog, ID_TEXT_DEV_NAME), device->description); } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_BUTTON_NEXT: //memset(device, 0, sizeof(*device)); device->wdi->is_composite=false; GetWindowTextU(GetDlgItem(dialog, ID_TEXT_MANUFACTURER), device->manufacturer, sizeof(tmp)); GetWindowTextU(GetDlgItem(dialog, ID_TEXT_DEV_NAME), device->description, sizeof(tmp)); GetWindowText(GetDlgItem(dialog, ID_TEXT_VID), tmp, sizeof(tmp)); if(sscanf(tmp, "0x%04x", &val) == 1) device->wdi->vid = (WORD)val; GetWindowText(GetDlgItem(dialog, ID_TEXT_PID), tmp, sizeof(tmp)); if(sscanf(tmp, "0x%04x", &val) == 1) device->wdi->pid = (WORD)val; GetWindowText(GetDlgItem(dialog, ID_TEXT_MI), tmp, sizeof(tmp)); if (sscanf(tmp, "0x%02x", &val) == 1) { device->wdi->mi = (BYTE)val; device->wdi->is_composite=true; } if (save_file(dialog, device)) EndDialog(dialog, ID_DIALOG_3); return TRUE ; case ID_BUTTON_BACK: EndDialog(dialog, ID_DIALOG_1); return TRUE ; case ID_BUTTON_CANCEL: case IDCANCEL: EndDialog(dialog, 0); return TRUE ; } } return FALSE; }
int es_interface(int s, const void *data, size_t size) { int idx = 0 , retval = 0; char input_buf[RECV_BUF_SIZE+1]; // Copy the data into 'input_buf' memset( input_buf , 0 , RECV_BUF_SIZE+1 ); strncpy( input_buf , data , size ); char *commands[NTELNETCOMMANDS] = { "esinit" , "esread" , "esdone" , "esdisable" , "mwr" , "mrd" , "debug" , \ "dbgeyescan" , "initclk" , "readclk" , "printupod" , "iicr" , "iicw" , "printtemp" , "globalinit" }; if( !strncmp( input_buf , "h" , 1 ) || !strncmp( input_buf , "H" , 1 ) ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "commands :" ); for( idx = 0 ; idx < NTELNETCOMMANDS ; idx++ ) { safe_sprintf( input_buf , "%s %s" , input_buf , commands[idx] ); } safe_sprintf( input_buf , "%s\r\n" , input_buf ); return safe_send(s, input_buf); } char * temp_str , ** pEnd = NULL; typedef enum { ESINIT = 0 , ESREAD = 1 , ESDONE = 2 , ESDISABLE = 3 , MWR = 4 , MRD = 5 , DEBUG = 6 , \ DBGEYESCAN = 7 , INITCLK = 8 , READCLK = 9 , PRINTUPOD = 10 , IICR = 11 , IICW = 12 , PRINTTEMP = 13 , GLOBALINIT = 14 } command_type_t; command_type_t command_type = MWR; char tokens[NTELNETTOKENS][20] = {}; for( idx = 0 ; idx < NTELNETTOKENS ; idx++ ) { memset( tokens[idx] , 0 , 20 ); } // tokenize (strtok) the input and store in tokens[] temp_str = strtok( input_buf , " " ); int number_tokens = 0; while( temp_str != NULL ) { strncpy( tokens[number_tokens] , temp_str , strlen( temp_str ) ); ++number_tokens; temp_str = strtok( NULL , " {},\r\n"); } // identify the command for( idx = 0 ; idx < NTELNETCOMMANDS ; ++idx ) { if( !strncmp( commands[idx] , tokens[0] , strlen(commands[idx]) ) ) command_type = idx; } if( command_type == ESINIT ) { if( number_tokens == 2 ) { if( !strncmp( "run" , tokens[1] , 3 ) ) { global_run_eye_scan(); return safe_send( s , "1\r\n" ); } } if( number_tokens != 8 ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "Syntax: esinit <lane> <max_prescale> <horz_step> <data_width> <vert_step> <lpm_mode> <rate>\r\n"); return safe_send( s , input_buf ); } int curr_lane = strtoul( tokens[1] , pEnd , 0); xaxi_eyescan_enable_channel(curr_lane); eyescan_lock(); eye_scan * curr_eyescan = get_eye_scan_lane( curr_lane ); if( curr_eyescan == NULL ) { return safe_send( s , "error, no lane found\r\n" ); } curr_eyescan->pixel_count = 0; curr_eyescan->state = WAIT_STATE; curr_eyescan->p_upload_rdy = 0; // Read values in curr_eyescan->max_prescale = strtoul( tokens[2] , pEnd , 0); curr_eyescan->horz_step_size = strtoul( tokens[3] , pEnd , 0); curr_eyescan->data_width = strtoul( tokens[4] , pEnd , 0); curr_eyescan->vert_step_size = strtoul( tokens[5] , pEnd , 0); curr_eyescan->lpm_mode = strtoul( tokens[6] , pEnd , 0); curr_eyescan->max_horz_offset = strtoul( tokens[7] , pEnd , 0); // same as rate? //retval = configure_eye_scan( curr_eyescan , curr_lane ); curr_eyescan->enable = TRUE; // enable the lane curr_eyescan->initialized = FALSE; // need to reinitialize lane eyescan_unlock(); return 0; } if( command_type == ESREAD ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); if( number_tokens != 3 && number_tokens != 2 ) { safe_sprintf( input_buf , "Syntax: esread <lane> <pixel>\r\n"); return safe_send( s , input_buf ); } if( !strncmp( "all" , tokens[1] , 3 ) ) { if( !global_upload_ready() ) return 0; int curr_lane = 0; for( curr_lane = 0 ; curr_lane < MAX_NUMBER_OF_LANES ; curr_lane++ ) { eye_scan * curr_eyescan = get_eye_scan_lane( curr_lane ); if( curr_eyescan == NULL || curr_eyescan->enable == FALSE || curr_eyescan->p_upload_rdy == FALSE ) continue; for( idx = 0 ; idx < curr_eyescan->pixel_count ; idx++ ) { eye_scan_pixel * current_pixel = ( curr_eyescan->pixels + idx ); safe_sprintf( input_buf , "%s%d %d %d %d: %d %d %d %d %ld\r\n" , input_buf, curr_lane , idx , \ current_pixel->h_offset , current_pixel->v_offset , \ current_pixel->error_count , current_pixel->sample_count , \ current_pixel->prescale & 0x001F , current_pixel->ut_sign , current_pixel->center_error ); if( strlen(input_buf) > 1900 ) { retval = safe_send(s, input_buf); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); } } } if( strlen(input_buf) > 0 ) { retval = safe_send(s, input_buf); } return retval; } int curr_lane = strtoul( tokens[1] , pEnd , 0 ); eye_scan * curr_eyescan = get_eye_scan_lane( curr_lane ); if( curr_eyescan == NULL ) { return safe_send( s , "error, no lane found\r\n" ); } if( number_tokens == 2 ) { safe_sprintf( input_buf , "%d\r\n" , curr_eyescan->pixel_count ); retval = safe_send(s, input_buf); return retval; } else { int curr_pixel = strtoul( tokens[2] , pEnd , 0 ); int begin_pixel = curr_pixel; int end_pixel = curr_pixel + 1; if( curr_pixel == curr_eyescan->pixel_count ) { begin_pixel = 0; end_pixel = curr_eyescan->pixel_count; } else if( curr_pixel > curr_eyescan->pixel_count ) { return 0; } for( idx = begin_pixel ; idx <= end_pixel ; idx++ ) { eye_scan_pixel * current_pixel = ( curr_eyescan->pixels + idx ); safe_sprintf( input_buf , "%s%d %d %d %d: %d %d %d %d %ld\r\n" , input_buf, curr_lane , idx , \ current_pixel->h_offset , current_pixel->v_offset , \ current_pixel->error_count , current_pixel->sample_count , \ current_pixel->prescale & 0x001F , current_pixel->ut_sign , current_pixel->center_error ); if( strlen(input_buf) > 1900 ) { retval = safe_send(s, input_buf); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); } } if( strlen(input_buf) > 0 ) { retval = safe_send(s, input_buf); } return retval; } } if( command_type == ESDONE ) { if( number_tokens != 2 ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "Syntax: esdone <lane> \r\n"); return safe_send( s , input_buf ); } if( !strncmp( "all" , tokens[1] , 3 ) ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "%d\r\n" , global_upload_ready() ); return safe_send(s, input_buf); } int curr_lane = strtoul( tokens[1] , pEnd , 0); int is_ready = FALSE; eye_scan * curr_eyescan = get_eye_scan_lane( curr_lane ); if( curr_eyescan == NULL ) { return safe_send( s , "error, no lane found\r\n" ); } is_ready = curr_eyescan->p_upload_rdy; memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "%d: %d\r\n" , curr_lane , is_ready ); return safe_send(s, input_buf); } if( command_type == ESDISABLE ) { if( number_tokens != 2 ) { memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "Syntax: esdisable <lane> \r\n"); return safe_send( s , input_buf ); } if( !strncmp( "all" , tokens[1] , 3 ) ) { global_stop_eye_scan(); global_upload_unrdy(); return 0; } // Disable the eyescan int curr_lane = strtoul( tokens[1] , pEnd , 0); eye_scan * curr_eyescan = get_eye_scan_lane( curr_lane ); curr_eyescan->enable = FALSE; // Turn off the GTX for this channel xaxi_eyescan_disable_channel(curr_lane); return 0; } typedef enum { N=-1 , W = 0 , H = 1 , B = 2 } wtype_t; wtype_t wtype = N; char *wtypes[3] = { "w" , "h" , "b" }; uint wtype_sizes[3] = { 8 , 4 , 2 }; if( command_type == MWR || command_type == MRD ) { for( idx = 0 ; idx < 3 ; idx++ ){ if( !strncmp( wtypes[idx] , tokens[number_tokens-1] , 1 ) ) wtype = idx; } } u16_t number_of_words = 1; if( command_type == MRD ) { if( number_tokens == 2 ) number_of_words = 0; else if( number_tokens > 2 ) { if( wtype == N ) { number_of_words = strtoul( tokens[number_tokens-1] , pEnd , 0 ); } else { number_of_words = strtoul( tokens[number_tokens-2] , pEnd , 0 ); } } } else if( command_type == MWR ) { if( number_tokens == 3 ) number_of_words = 1; else if( number_tokens > 3 ) { if( wtype == N ) { number_of_words = strtoul( tokens[number_tokens-1] , pEnd , 0 ); } else { number_of_words = strtoul( tokens[number_tokens-2] , pEnd , 0 ); } } } if( command_type == MRD && number_tokens == 2 ) number_of_words = 1; u32_t address = 0; u32_t addresses[NTELNETTOKENS] = {0}; u32_t values[NTELNETTOKENS] = {0}; if( command_type == MWR || command_type == MRD ) { if( number_tokens > 1 ) { address = strtoul( tokens[1] , pEnd , 0 ); } } if( command_type == MWR ) { for( idx = 0 ; idx < number_of_words ; idx++ ) { values[idx] = strtoul( tokens[idx+2] , pEnd , 0 ); if( wtype == N || wtype == W ) { /* WORD, u32_t */ u32_t * tval = NULL; tval = ( (u32_t*)address + idx ); *tval = (u32_t)values[idx]; } else if( wtype == H ) { /* HALF, u16_t */ u16_t * tval = NULL; tval = ( (u16_t*)address + idx ); *tval = (u16_t)values[idx]; } else if( wtype == B ) { /* BYTE, u8_t */ u8_t * tval = NULL; tval = ( (u8_t*)address + idx ); *tval = (u8_t)values[idx]; } } } if( command_type == MRD ) { for( idx = 0 ; idx < number_of_words ; idx++ ) { if( wtype == N || wtype == W ) { /* WORD, u32_t */ u32_t * tval = NULL; tval = ( (u32_t*)address + idx ); addresses[idx] = (u32_t)tval; values[idx] = *tval; } else if( wtype == H ) { /* HALF, u16_t */ u16_t * tval = NULL; tval = ( (u16_t*)address + idx ); addresses[idx] = (u32_t)tval; values[idx] = *tval; } else if( wtype == B ) { /* BYTE, u8_t */ u8_t * tval = NULL; tval = ( (u8_t*)address + idx ); addresses[idx] = (u32_t)tval; values[idx] = *tval; } } return retval; } if( command_type == MRD ) { char format_string[20]; memset( format_string , 0 , 20 ); if( wtype >= 0 ) sprintf( format_string , "%%p: 0x%%0%dlx\r\n" , wtype_sizes[wtype] ); else sprintf( format_string , "%%p: 0x%%0%dlx\r\n" , wtype_sizes[0] ); for( idx = 0 ; idx < number_of_words ; idx++ ) { memset( input_buf , 0 , RECV_BUF_SIZE+1); safe_sprintf( input_buf , format_string , addresses[idx] , values[idx] ); retval = safe_send(s, input_buf); } return retval; } if( command_type == DEBUG ) { srand( time(NULL) ); safe_sprintf( input_buf , "echo mrd %p 4 b | nc 192.168.1.99 7\r\n" , u8_test_array ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mwr %p {0x%02x 0x%02x 0x%02x 0x%02x} 4 b | nc 192.168.1.99 7\r\n" , u8_test_array , (u8_t)rand() , (u8_t)rand() , (u8_t)rand() , (u8_t)rand() ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mrd %p 4 b | nc 192.168.1.99 7\r\n" , u8_test_array ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mrd %p 4 h | nc 192.168.1.99 7\r\n" , u16_test_array ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mwr %p {0x%04x 0x%04x 0x%04x 0x%04x} 4 h | nc 192.168.1.99 7\r\n" , u16_test_array , (u16_t)rand() , (u16_t)rand() , (u16_t)rand() , (u16_t)rand() ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mrd %p 4 h | nc 192.168.1.99 7\r\n" , u16_test_array ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mrd %p 4 w | nc 192.168.1.99 7\r\n" , u32_test_array ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mwr %p {0x%08lx 0x%08lx 0x%08lx 0x%08lx} 4 w | nc 192.168.1.99 7\r\n" , u32_test_array , (u32_t)rand() , (u32_t)rand() , (u32_t)rand() , (u32_t)rand() ); retval = safe_send(s, input_buf); safe_sprintf( input_buf , "echo mrd %p 4 w | nc 192.168.1.99 7\r\n" , u32_test_array ); retval = safe_send(s, input_buf); return retval; } if( command_type == DBGEYESCAN ) { int curr_lane = -1; memset( input_buf , 0 , RECV_BUF_SIZE+1 ); if( number_tokens == 2 ) { curr_lane = strtoul( tokens[1] , pEnd , 0 ); } eyescan_debugging( curr_lane , input_buf ); if( curr_lane == -1 ) { retval = safe_send( s , input_buf ); return retval; } u32 drp_addresses[146] = { \ 0x000, 0x00D, 0x00E, 0x00F, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x018, 0x019, 0x01A, 0x01B, 0x01C, 0x01D, 0x01E, 0x01F, 0x020, \ 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, 0x028, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E, 0x02F, 0x030, 0x031, 0x032, 0x033, \ 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x03F, 0x040, 0x041, 0x044, 0x045, 0x046, 0x047, 0x048, \ 0x049, 0x04A, 0x04B, 0x04C, 0x04D, 0x04E, 0x04F, 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, 0x059, 0x05B, 0x05C, 0x05D, \ 0x05E, 0x05F, 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x068, 0x069, 0x06A, 0x06B, 0x06F, 0x070, 0x071, 0x074, 0x075, 0x076, \ 0x077, 0x078, 0x079, 0x07A, 0x07C, 0x07D, 0x07F, 0x082, 0x083, 0x086, 0x087, 0x088, 0x08C, 0x091, 0x092, 0x097, 0x098, 0x099, 0x09A, \ 0x09B, 0x09C, 0x09D, 0x09F, 0x0A0, 0x0A1, 0x0A2, 0x0A3, 0x0A4, 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB, 0x0AC ,\ 0x14F, 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, 0x159, 0x15A, 0x15B , 0x15C, 0x15D \ }; for( idx = 0 ; idx < 146 ; idx++ ) { eyescan_debug_addr( curr_lane , drp_addresses[idx] , input_buf ); if( strlen(input_buf) > 1900 ) { retval = safe_send( s , input_buf ); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); } } if( strlen(input_buf) > 0 ) { retval = safe_send( s , input_buf ); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); } return retval; } if( command_type == INITCLK ) { #ifdef IS_OTC_BOARD SetClockDevID(0); retval = 0; if( number_tokens == 1 ) { retval = InitClockRegisters(); return retval; } else if( number_tokens == 2 ) { char * freqs[4] = { "125.000 MHz" , "148.778 MHz" , "200.395 MHz" , "299.000 MHz" }; u16 regvals[4][21] = { { 0x01b9, 0x24c4, 0x74fa, 0x04fa, 0x306f, 0x0023, 0x0003, 0x0023, 0x0003, 0x00c3, 0x0030, 0x0000, 0x00c3, 0x0030, 0x0000, 0x00c3, 0x0030, 0x0000, 0x00c3, 0x0030, 0x0000 } , { 0x01b9, 0x11e9, 0x5c3c, 0x04f0, 0x306f, 0x0023, 0x0004, 0x0023, 0x0004, 0x00c3, 0x0040, 0x0000, 0x00c3, 0x0040, 0x0000, 0x00c3, 0x0040, 0x0000, 0x00c3, 0x0040, 0x0000 } , { 0x01b9, 0x000c, 0x003b, 0x04f5, 0x306f, 0x0023, 0x0002, 0x0023, 0x0002, 0x00c3, 0x0020, 0x0000, 0x00c3, 0x0020, 0x0000, 0x00c3, 0x0020, 0x0000, 0x00c3, 0x0020, 0x0000 } , { 0x01b1, 0x21f5, 0xc846, 0x04f5, 0x306f, 0x0023, 0x0001, 0x0023, 0x0001, 0x00c3, 0x0010, 0x0000, 0x00c3, 0x0010, 0x0000, 0x00c3, 0x0010, 0x0000, 0x00c3, 0x0010, 0x0000 } }; int fidx = strtoul( tokens[1] , pEnd , 0); if( fidx >= 0 && fidx < 4 ) { u16 regval[21]; for( idx = 0 ; idx<21 ; idx++ ) { regval[idx] = regvals[fidx][idx]; } memset( input_buf , 0 , RECV_BUF_SIZE+1 ); safe_sprintf( input_buf , "Using clock frequency of %s\n" , freqs[fidx] ); retval = safe_send( s , input_buf ); retval = InitClockRegisters( regval ); return retval; } else { safe_printf( "Can't init clock\n"); return 0; } } else if( number_tokens == 22 ) { u16 regval[21]; for( idx = 1 ; idx<22 ; idx++ ) { regval[idx-1] = strtoul( tokens[idx] , pEnd , 0); } retval = InitClockRegisters( regval ); return retval; } else { safe_printf( "Can't init clock\n"); return 0; } #endif return retval; } if( command_type == READCLK ) { #ifdef IS_OTC_BOARD u16 *cfgdata = GetClockConfig(); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); for( idx = 0 ; idx < 21 ; idx++ ) { safe_sprintf( input_buf , "%s %04d " , input_buf , idx ); } safe_sprintf( input_buf , "%s\r\n" , input_buf ); retval = safe_send(s, input_buf); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); for( idx = 0 ; idx < 21 ; idx++ ) { safe_sprintf( input_buf , "%s0x%04x " , input_buf , cfgdata[idx] ); } safe_sprintf( input_buf , "%s\r\n" , input_buf ); retval = safe_send(s, input_buf); free(cfgdata); #endif return retval; } if( command_type == PRINTUPOD ) { #ifdef IS_OTC_BOARD u8_t i2c_addresses[8]; for( idx=0 ; idx<8; idx++ ) i2c_addresses[idx] = idx; for( idx=1 ; idx < number_tokens ; idx++ ) i2c_addresses[idx-1] = strtoul( tokens[idx] , pEnd , 0 ); for( idx=0;idx<8;idx++ ) { if( number_tokens > 1 && idx>=(number_tokens-1) ) continue; u8_t i2c_addr = i2c_addresses[idx]; if( i2c_addr < 8 ) { i2c_addr = upod_address(i2c_addr); } SetUPodI2CAddress( i2c_addr ); uPodMonitorData *mondata = GetUPodStatus(); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); char * temp_format_string = "Addr %p , status 0x%02x , temp %d.%03dC , 3.3V %duV , 2.5V %duV\n"; safe_sprintf( input_buf , temp_format_string , i2c_addr , mondata->status, \ mondata->tempWhole, mondata->tempFrac, \ 100*mondata->v33, 100*mondata->v25); free(mondata); retval = safe_send(s, input_buf); } #endif return retval; } if( command_type == IICR ) { #ifdef IS_OTC_BOARD int devid = 0; u8_t i2c_addr; u8_t regaddr; u8_t * data; u16_t nbytes = 1; devid = strtoul( tokens[1] , pEnd , 0 ); i2c_addr = strtoul( tokens[2] , pEnd , 0 ); regaddr = strtoul( tokens[3] , pEnd , 0 ); if( number_tokens == 5 ) nbytes = strtoul( tokens[4] , pEnd , 0 ); data = malloc( sizeof(u8_t) * nbytes ); /* Set the register address */ retval = IICMasterWrite(devid,i2c_addr,1,®addr); if( retval != XST_SUCCESS ) return retval; /* and do the read */ retval = IICMasterRead(devid,i2c_addr,nbytes,data); memset( input_buf , 0 , RECV_BUF_SIZE+1 ); for( idx = 0 ; idx < nbytes ; idx++ ) { safe_sprintf( input_buf , "%s 0x%02x" , input_buf , data[idx] ); } safe_sprintf( input_buf , "%s\r\n" , input_buf ); retval = safe_send(s, input_buf); free(data); #endif return retval; } if( command_type == IICW ) { #ifdef IS_OTC_BOARD int devid = 0; u8_t i2c_addr; u8_t regaddr; u8_t * buffer; u16_t nbytes = ( number_tokens - 4 ); devid = strtoul( tokens[1] , pEnd , 0 ); i2c_addr = strtoul( tokens[2] , pEnd , 0 ); regaddr = strtoul( tokens[3] , pEnd , 0 ); buffer = malloc( sizeof(u8_t) * ( nbytes + 1 ) ); buffer[0] = regaddr; for( idx = 4 ; idx < number_tokens ; idx++ ) { buffer[idx-3] = strtoul( tokens[idx] , pEnd , 0 ); } retval = IICMasterWrite(devid,i2c_addr,nbytes+1,buffer); free(buffer); #endif return retval; } if( command_type == PRINTTEMP ) { // We now update this in monitor, don't bother doing it twice... /* now write the web page data in two steps. FIrst the Xilinx temp/voltages */ char *pagefmt = "uptime %d , temp %0.1fC , intv %0.1fV , auxv %0.1fV , bramv %0.1fV\r\n"; safe_sprintf(input_buf,pagefmt,procStatus.uptime,procStatus.v7temp,procStatus.v7vCCINT,procStatus.v7vCCAUX,procStatus.v7vBRAM); int n=strlen(input_buf); int w; if ((w = safe_send(s, input_buf)) < 0 ) { safe_printf("error writing web page data (part 1) to socket\r\n"); safe_printf("attempted to lwip_write %d bytes, actual bytes written = %d\r\n", n, w); return -2; } return w; } if( command_type == GLOBALINIT ) { global_reset_eye_scan(); } return retval; }
void VertexDeclarationGL::init(bvertex_format fmt) { bformat = fmt; int i = 0; int offset = 0; Element *dest = elements; if (fmt & VERTEX_POSITION) { strcpy(dest->name, "position"); dest->elemType = GL_FLOAT; dest->size = 3; dest->offset = offset; dest->index = i; dest->normalized = false; offset += sizeof(float) * 3; ++i; ++dest; } if (fmt & VERTEX_COLOR) { strcpy(dest->name, "color"); dest->elemType = GL_UNSIGNED_BYTE; dest->size = 4; dest->offset = offset; dest->index = i; dest->normalized = true; offset += 4; ++i; ++dest; } int numTexCoords = numTextureCoordinates(fmt); for (int j = 0; j < numTexCoords; ++j ) { int coordSize = texCoordSize(j, fmt); if (j == 0) strcpy(dest->name, "uv"); else safe_sprintf(dest->name, "uv%d", j + 1); dest->elemType = GL_FLOAT; dest->size = coordSize; dest->offset = offset; dest->index = i; dest->normalized = true; offset += sizeof(float) * coordSize; ++i; ++dest; } int userSize = userDataSize(fmt); if (userSize > 0) { dest->elemType = GL_FLOAT; dest->size = userSize; dest->offset = offset; dest->index = i; dest->normalized = false; offset += sizeof(float) * userSize; ++i; ++dest; } numElements = i; size = offset; }
// - ------------------------------------------------------------------------------------------ - // pNetAdapterInfo* new_pNetAdapterInfo() { // http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx ULONG IPASize = 16384; IP_ADAPTER_ADDRESSES* IPA = (IP_ADAPTER_ADDRESSES*)new char[IPASize]; // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915%28v=vs.85%29.aspx GetAdaptersAddresses( /*AF_UNSPEC*/AF_INET, 0, NULL, IPA, &IPASize ); // IP_ADAPTER_UNICAST_ADDRESS -- http://msdn.microsoft.com/en-us/library/windows/desktop/aa366066%28v=vs.85%29.aspx // SOCKET_ADDRESS -- http://msdn.microsoft.com/en-us/library/windows/desktop/ms740507%28v=vs.85%29.aspx // sockaddr/sockaddr_in -- http://msdn.microsoft.com/en-us/library/windows/desktop/ms740496%28v=vs.85%29.aspx // Alternatively -- http://www.beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html // Count the number Interfaces with IPv4 addresses // size_t IPv4Count = 0; for ( IP_ADAPTER_ADDRESSES* Current = IPA; Current != 0; Current = Current->Next ) { for ( IP_ADAPTER_UNICAST_ADDRESS* Cur = Current->FirstUnicastAddress; Cur != 0; Cur = Cur->Next ) { if ( Cur->Address.lpSockaddr->sa_family == AF_INET ) { // Found one! // IPv4Count++; break; } } } // Allocate the pNetAdapterInfo's // pNetAdapterInfo* Adapters = new pNetAdapterInfo[IPv4Count+1]; // Allocate NetAdapterInfos per IP // for ( size_t idx = 0; idx < IPv4Count; idx++ ) { Adapters[idx] = new_NetAdapterInfo(); // Internal Function // } Adapters[IPv4Count] = 0; // Last one a null pointer // // Iterate though and populate data // size_t Index = 0; for ( IP_ADAPTER_ADDRESSES* Current = IPA; Current != 0; Current = Current->Next ) { bool HasIPv4 = false; for ( IP_ADAPTER_UNICAST_ADDRESS* Cur = Current->FirstUnicastAddress; Cur != 0; Cur = Cur->Next ) { if ( Cur->Address.lpSockaddr->sa_family == AF_INET ) { sockaddr_in* SAI = (sockaddr_in*)Cur->Address.lpSockaddr; const unsigned char* DataAddr = (const unsigned char*)&(SAI->sin_addr.s_addr); int* IPv4 = (int*)Adapters[Index]->Data.IPv4; *IPv4 = *(int*)DataAddr; safe_sprintf( Adapters[Index]->IP, sizeof(Adapters[Index]->IP), "%s", inet_ntoa( SAI->sin_addr ) ); HasIPv4 = true; break; } } // If an IP address wasn't found, then don't waste this NetAdapterInfo // if ( !HasIPv4 ) continue; // Extract MAC // if ( Current->PhysicalAddressLength > 0 ) { memcpy( Adapters[Index]->Data.MAC, Current->PhysicalAddress, sizeof(Adapters[Index]->Data.MAC) ); sprintf( Adapters[Index]->MAC, "%02x:%02x:%02x:%02x:%02x:%02x", Current->PhysicalAddress[0], Current->PhysicalAddress[1], Current->PhysicalAddress[2], Current->PhysicalAddress[3], Current->PhysicalAddress[4], Current->PhysicalAddress[5] ); } // Extract DNS // for ( IP_ADAPTER_DNS_SERVER_ADDRESS* Cur = Current->FirstDnsServerAddress; Cur != 0; Cur = Cur->Next ) { if ( Cur->Address.lpSockaddr->sa_family == AF_INET ) { sockaddr_in* SAI = (sockaddr_in*)Cur->Address.lpSockaddr; safe_sprintf( Adapters[Index]->DNS, sizeof(Adapters[Index]->DNS), "%s", inet_ntoa( SAI->sin_addr ) ); break; } } // Anycast and Multicast address code, in case I ever decide to use them // // for ( IP_ADAPTER_ANYCAST_ADDRESS* Cur = Current->FirstAnycastAddress; Cur != 0; Cur = Cur->Next ) { // //printf("** %i\n", Cur->Address.lpSockaddr->sa_family); // if ( Cur->Address.lpSockaddr->sa_family == AF_INET ) { // sockaddr_in* SAI = (sockaddr_in*)Cur->Address.lpSockaddr; // printf( "Anycast: %s\n", inet_ntoa( SAI->sin_addr ) ); // } // } // for ( IP_ADAPTER_MULTICAST_ADDRESS* Cur = Current->FirstMulticastAddress; Cur != 0; Cur = Cur->Next ) { // //printf("*** %i\n", Cur->Address.lpSockaddr->sa_family); // if ( Cur->Address.lpSockaddr->sa_family == AF_INET ) { // sockaddr_in* SAI = (sockaddr_in*)Cur->Address.lpSockaddr; // printf( "Multicast: %s\n", inet_ntoa( SAI->sin_addr ) ); // } // } // Copy Name // { // The strings are stored in wchar_t's, so we copy it to our char[] // size_t Length = wcstombs( Adapters[Index]->Name, Current->FriendlyName, sizeof(Adapters[Index]->Name) ); } // Copy Description // { // The strings are stored in wchar_t's, so we copy it to our char[] // size_t Length = wcstombs( Adapters[Index]->Description, Current->Description, sizeof(Adapters[Index]->Description) ); } Index++; } delete IPA; return Adapters; }
/* * Download a file from an URL * Mostly taken from http://support.microsoft.com/kb/234913 * If hProgressDialog is not NULL, this function will send INIT and EXIT messages * to the dialog in question, with WPARAM being set to nonzero for EXIT on success * and also attempt to indicate progress using an IDC_PROGRESS control */ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog) { HWND hProgressBar = NULL; BOOL r = FALSE; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; FILE* fd = NULL; LONG progress_style; unsigned char buf[DOWNLOAD_BUFFER_SIZE]; char agent[64], hostname[64], urlpath[128]; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; int i; char msg[MAX_PATH]; if (hProgressDialog != NULL) { // Use the progress control provided, if any hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS); if (hProgressBar != NULL) { progress_style = GetWindowLong(hProgressBar, GWL_STYLE); SetWindowLong(hProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); SendMessage(hProgressBar, PBM_SETPOS, 0, 0); } SendMessage(hProgressDialog, UM_DOWNLOAD_INIT, 0, 0); } safe_sprintf(msg, sizeof(msg), "Downloading %s: Connecting...", file); print_status(0, FALSE, msg); dprintf("Downloading %s from %s\n", file, url); if ( (!InternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) || (UrlParts.lpszHostName == NULL) || (UrlParts.lpszUrlPath == NULL)) { dprintf("Unable to decode URL: %s\n", WindowsErrorString()); goto out; } hostname[sizeof(hostname)-1] = 0; // Open an Internet session for (i=5; (i>0) && (!InternetGetConnectedState(&dwFlags, 0)); i--) { Sleep(1000); } if (i <= 0) { // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384702.aspx is wrong... SetLastError(ERROR_INTERNET_NOT_INITIALIZED); dprintf("Network is unavailable: %s\n", WinInetErrorString()); goto out; } safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", application_version[0], application_version[1], application_version[2], nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hSession == NULL) { dprintf("Could not open internet session: %s\n", WinInetErrorString()); goto out; } hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) { dprintf("Could not connect to server %s:%d: %s\n", UrlParts.lpszHostName, UrlParts.nPort, WinInetErrorString()); goto out; } hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0", INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL); if (hRequest == NULL) { dprintf("Could not open url %s: %s\n", url, WindowsErrorString()); goto out; } if (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0)) { dprintf("Unable to send request: %s\n", WinInetErrorString()); goto out; } // Get the file size dwSize = sizeof(dwStatus); dwStatus = 404; HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL); if (dwStatus != 200) { download_error = ERROR_SEVERITY_ERROR|ERROR_INTERNET_ITEM_NOT_FOUND; dprintf("Unable to access file: Server status %d\n", dwStatus); goto out; } dwSize = sizeof(dwTotalSize); if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) { dprintf("Unable to retrieve file length: %s\n", WinInetErrorString()); goto out; } dprintf("File length: %d bytes\n", dwTotalSize); fd = fopenU(file, "wb"); if (fd == NULL) { dprintf("Unable to create file '%s': %s\n", file, WinInetErrorString()); goto out; } // Keep checking for data until there is nothing left. dwSize = 0; while (1) { if (download_error) goto out; if (!InternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) break; dwSize += dwDownloaded; SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0); safe_sprintf(msg, sizeof(msg), "Downloading: %0.1f%%", (100.0f*dwSize)/(1.0f*dwTotalSize)); print_status(0, FALSE, msg); if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) { dprintf("Error writing file '%s': %s\n", file, WinInetErrorString()); goto out; } } if (dwSize != dwTotalSize) { dprintf("Could not download complete file - read: %d bytes, expected: %d bytes\n", dwSize, dwTotalSize); download_error = ERROR_WRITE_FAULT; goto out; } else { r = TRUE; dprintf("Successfully downloaded '%s'\n", file); } out: if (hProgressDialog != NULL) SendMessage(hProgressDialog, UM_DOWNLOAD_EXIT, (WPARAM)r, 0); if (fd != NULL) fclose(fd); if (!r) { _unlink(file); print_status(0, FALSE, "Failed to download file."); SetLastError(download_error); MessageBoxU(hMain, WinInetErrorString(), "File download", MB_OK|MB_ICONERROR); } if (hRequest) InternetCloseHandle(hRequest); if (hConnection) InternetCloseHandle(hConnection); if (hSession) InternetCloseHandle(hSession); return r; }
TexturesInspector::TexturesInspector(const Vector2& size) { setSize(size); spSlidingActor slide = new SlidingActor; slide->setSize(size); addChild(slide); float offsetY = 0; std::vector<spNativeTexture> textures = NativeTexture::getCreatedTextures(); spTextField text = initActor(new TextField, arg_color = Color::White, arg_pos = Vector2(1, 1), arg_w = itemSize.x * 3.0f, arg_h = 30.0f, arg_vAlign = TextStyle::VALIGN_TOP, arg_hAlign = TextStyle::HALIGN_LEFT, arg_multiline = true, arg_attachTo = slide ); offsetY += text->getTextRect().getBottom() + 5; spActor content = new Actor; content->setX(2); int numX = (int)(size.x / itemSize.x); int n = 0; int mem = 0; for (std::vector<spNativeTexture>::reverse_iterator i = textures.rbegin(); i != textures.rend(); ++i) { spNativeTexture t = *i; TextureLine* line = new TextureLine(t); float x = (n % numX) * (itemSize.x + 5.0f); float y = (n / numX) * (itemSize.y + 5.0f); line->setX(x); line->setY(y + offsetY); content->addChild(line); ++n; if (t->getHandle()) { TextureFormat fmt = t->getFormat(); int ram = t->getWidth() * t->getHeight(); if (isCompressedFormat(fmt)) { switch (fmt) { case TF_PVRTC_4RGBA: ram /= 2; break; case TF_ETC1: ram /= 2; break; default: break; } } else ram *= getBytesPerPixel(fmt); mem += ram; } } char txt[255]; safe_sprintf(txt, "created textures: %d, vram: %d kb", textures.size(), mem / 1024); text->setText(txt); if (numX > n) numX = n; content->setSize( (itemSize.x + 5.0f) * numX, (itemSize.y + 5.0f) * (n + numX - 1.0f) / numX + offsetY); setWidth(content->getWidth()); slide->setWidth(content->getWidth()); //slide->setSize() slide->setContent(content); }
int main(int argc, char **argv){ int fd, i, j, m, n, op, off, arg, c, d; struct slice all; struct pt *ptp; enum action what = LIST; char *type, *diskdevice, *device, *progname; int verbose = 0; char partname[PARTNAME_SIZE], params[PARTNAME_SIZE + 16]; char * loopdev = NULL; char * delim = NULL; char *uuid = NULL; char *mapname = NULL; int loopro = 0; int hotplug = 0; int loopcreated = 0; int sync = 0; struct stat buf; uint32_t cookie = 0; initpts(); init_crc32(); type = device = diskdevice = NULL; memset(&all, 0, sizeof(all)); memset(&partname, 0, sizeof(partname)); /* Check whether hotplug mode. */ progname = strrchr(argv[0], '/'); if (!progname) progname = argv[0]; else progname++; if (!strcmp(progname, "kpartx.dev")) { /* Hotplug mode */ hotplug = 1; /* Setup for original kpartx variables */ if (!(device = get_hotplug_device())) exit(1); diskdevice = device; what = ADD; } else if (argc < 2) { usage(); exit(1); } while ((arg = getopt(argc, argv, short_opts)) != EOF) switch(arg) { case 'g': force_gpt=1; break; case 't': type = optarg; break; case 'v': verbose = 1; break; case 'p': delim = optarg; break; case 'l': what = LIST; break; case 'a': what = ADD; break; case 'd': what = DELETE; break; case 's': sync = 1; break; default: usage(); exit(1); } if (!sync) dm_udev_set_sync_support(0); if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) { fprintf(stderr, "device mapper prerequisites not met\n"); exit(1); } if (hotplug) { /* already got [disk]device */ } else if (optind == argc-2) { device = argv[optind]; diskdevice = argv[optind+1]; } else if (optind == argc-1) { diskdevice = device = argv[optind]; } else { usage(); exit(1); } if (stat(device, &buf)) { printf("failed to stat() %s\n", device); exit (1); } if (S_ISREG (buf.st_mode)) { /* already looped file ? */ loopdev = find_loop_by_file(device); if (!loopdev && what == DELETE) exit (0); if (!loopdev) { loopdev = find_unused_loop_device(); if (set_loop(loopdev, device, 0, &loopro)) { fprintf(stderr, "can't set up loop\n"); exit (1); } loopcreated = 1; } device = loopdev; } if (delim == NULL) { delim = malloc(DELIM_SIZE); memset(delim, 0, DELIM_SIZE); set_delimiter(device, delim); } off = find_devname_offset(device); if (!loopdev) { uuid = dm_mapuuid((unsigned int)MAJOR(buf.st_rdev), (unsigned int)MINOR(buf.st_rdev)); mapname = dm_mapname((unsigned int)MAJOR(buf.st_rdev), (unsigned int)MINOR(buf.st_rdev)); } if (!uuid) uuid = device + off; if (!mapname) mapname = device + off; fd = open(device, O_RDONLY); if (fd == -1) { perror(device); exit(1); } /* add/remove partitions to the kernel devmapper tables */ int r = 0; for (i = 0; i < ptct; i++) { ptp = &pts[i]; if (type && strcmp(type, ptp->type)) continue; /* here we get partitions */ n = ptp->fn(fd, all, slices, SIZE(slices)); #ifdef DEBUG if (n >= 0) printf("%s: %d slices\n", ptp->type, n); #endif if (n > 0) close(fd); else continue; switch(what) { case LIST: for (j = 0, c = 0, m = 0; j < n; j++) { if (slices[j].size == 0) continue; if (slices[j].container > 0) { c++; continue; } slices[j].minor = m++; printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n", mapname, delim, j+1, slices[j].size, device, slices[j].start); } /* Loop to resolve contained slices */ d = c; while (c) { for (j = 0; j < n; j++) { uint64_t start; int k = slices[j].container - 1; if (slices[j].size == 0) continue; if (slices[j].minor > 0) continue; if (slices[j].container == 0) continue; slices[j].minor = m++; start = slices[j].start - slices[k].start; printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n", mapname, delim, j+1, slices[j].size, slices[k].minor, start); c--; } /* Terminate loop if nothing more to resolve */ if (d == c) break; } if (loopcreated && S_ISREG (buf.st_mode)) { if (del_loop(device)) { if (verbose) printf("can't del loop : %s\n", device); exit(1); } printf("loop deleted : %s\n", device); } break; case DELETE: for (j = n-1; j >= 0; j--) { if (safe_sprintf(partname, "%s%s%d", mapname, delim, j+1)) { fprintf(stderr, "partname too small\n"); exit(1); } strip_slash(partname); if (!slices[j].size || !dm_map_present(partname)) continue; if (!dm_simplecmd(DM_DEVICE_REMOVE, partname, 0, &cookie)) { r++; continue; } if (verbose) printf("del devmap : %s\n", partname); } if (S_ISREG (buf.st_mode)) { if (del_loop(device)) { if (verbose) printf("can't del loop : %s\n", device); exit(1); } printf("loop deleted : %s\n", device); } break; case ADD: for (j = 0, c = 0; j < n; j++) { if (slices[j].size == 0) continue; /* Skip all contained slices */ if (slices[j].container > 0) { c++; continue; } if (safe_sprintf(partname, "%s%s%d", mapname, delim, j+1)) { fprintf(stderr, "partname too small\n"); exit(1); } strip_slash(partname); if (safe_sprintf(params, "%s %" PRIu64 , device, slices[j].start)) { fprintf(stderr, "params too small\n"); exit(1); } op = (dm_map_present(partname) ? DM_DEVICE_RELOAD : DM_DEVICE_CREATE); if (!dm_addmap(op, partname, DM_TARGET, params, slices[j].size, uuid, j+1, buf.st_mode & 0777, buf.st_uid, buf.st_gid, &cookie)) { fprintf(stderr, "create/reload failed on %s\n", partname); r++; } if (op == DM_DEVICE_RELOAD && !dm_simplecmd(DM_DEVICE_RESUME, partname, 1, &cookie)) { fprintf(stderr, "resume failed on %s\n", partname); r++; } dm_devn(partname, &slices[j].major, &slices[j].minor); if (verbose) printf("add map %s (%d:%d): 0 %" PRIu64 " %s %s\n", partname, slices[j].major, slices[j].minor, slices[j].size, DM_TARGET, params); } /* Loop to resolve contained slices */ d = c; while (c) { for (j = 0; j < n; j++) { uint64_t start; int k = slices[j].container - 1; if (slices[j].size == 0) continue; /* Skip all existing slices */ if (slices[j].minor > 0) continue; /* Skip all simple slices */ if (slices[j].container == 0) continue; /* Check container slice */ if (slices[k].size == 0) fprintf(stderr, "Invalid slice %d\n", k); if (safe_sprintf(partname, "%s%s%d", mapname, delim, j+1)) { fprintf(stderr, "partname too small\n"); exit(1); } strip_slash(partname); start = slices[j].start - slices[k].start; if (safe_sprintf(params, "%d:%d %" PRIu64, slices[k].major, slices[k].minor, start)) { fprintf(stderr, "params too small\n"); exit(1); } op = (dm_map_present(partname) ? DM_DEVICE_RELOAD : DM_DEVICE_CREATE); dm_addmap(op, partname, DM_TARGET, params, slices[j].size, uuid, j+1, buf.st_mode & 0777, buf.st_uid, buf.st_gid, &cookie); if (op == DM_DEVICE_RELOAD) dm_simplecmd(DM_DEVICE_RESUME, partname, 1, &cookie); dm_devn(partname, &slices[j].major, &slices[j].minor); if (verbose) printf("add map %s : 0 %" PRIu64 " %s %s\n", partname, slices[j].size, DM_TARGET, params); c--; } /* Terminate loop */ if (d == c) break; } break; default: break; } if (n > 0) break; } dm_udev_wait(cookie); dm_lib_release(); dm_lib_exit(); return r; }
/* * Background thread to check for updates */ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) { BOOL releases_only, found_new_version = FALSE; int status = 0; const char* server_url = RUFUS_URL "/"; int i, j, k, verbose = 0, verpos[4]; static const char* archname[] = {"win_x86", "win_x64"}; static const char* channel[] = {"release", "beta"}; // release channel DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; char* buf = NULL; char agent[64], hostname[64], urlpath[128], mime[32]; OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""}; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; SYSTEMTIME ServerTime, LocalTime; FILETIME FileTime; int64_t local_time = 0, reg_time, server_time, update_interval; BOOL is_x64 = FALSE, (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL; update_check_in_progress = TRUE; verbose = ReadRegistryKey32(REGKEY_HKCU, REGKEY_VERBOSE_UPDATES); // Unless the update was forced, wait a while before performing the update check if (!force_update_check) { // TODO: Also check on inactivity // It would of course be a lot nicer to use a timer and wake the thread, but my // development time is limited and this is FASTER to implement. do { for (i=0; (i<30) && (!force_update_check); i++) Sleep(500); } while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0)))); if (!force_update_check) { if ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1)) { vuprintf("Check for updates disabled, as per registry settings.\n"); goto out; } reg_time = ReadRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE); update_interval = (int64_t)ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL); if (update_interval == 0) { WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); update_interval = DEFAULT_UPDATE_INTERVAL; } GetSystemTime(&LocalTime); if (!SystemTimeToFileTime(&LocalTime, &FileTime)) goto out; local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Local time: %" PRId64 "\n", local_time); if (local_time < reg_time + update_interval) { vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time); goto out; } } } PrintStatus(3000, TRUE, "Checking for " APPLICATION_NAME " updates...\n"); status++; // 1 if (!GetVersionExA(&os_version)) { uprintf("Could not read Windows version - Check for updates cancelled.\n"); goto out; } // Detect if the OS is 64 bit, without relying on external libs if (sizeof(uintptr_t) < 8) { // This application is not 64 bit, but it might be 32 bit running in WOW64 pIsWow64Process = (BOOL (__stdcall *)(HANDLE, PBOOL)) GetProcAddress(GetModuleHandleA("KERNEL32"), "IsWow64Process"); if (pIsWow64Process != NULL) { (*pIsWow64Process)(GetCurrentProcess(), &is_x64); } } else { is_x64 = TRUE; } if ((!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0))) goto out; hostname[sizeof(hostname)-1] = 0; safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hSession == NULL) goto out; hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) goto out; status++; // 2 releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS); for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) { uprintf("Checking %s channel...\n", channel[k]); // At this stage we can query the server for various update version files. // We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver" // and then remove each each of the <os_> components until we find our match. For instance, we may first // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":"_", (k==0)?"":channel[k], archname[is_x64?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); vuprintf("Base update check: %s\n", urlpath); for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) { if ((urlpath[j] == '.') || (urlpath[j] == '_')) { verpos[i++] = j; } } if (i != ARRAYSIZE(verpos)) { uprintf("Broken code in CheckForUpdatesThread()!\n"); goto out; } UrlParts.lpszUrlPath = urlpath; UrlParts.dwUrlPathLength = sizeof(urlpath); for (i=0; i<ARRAYSIZE(verpos); i++) { vvuprintf("Trying %s\n", UrlParts.lpszUrlPath); hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0", INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL); if ((hRequest == NULL) || (!HttpSendRequest(hRequest, NULL, 0, NULL, 0))) goto out; // Ensure that we get a text file dwSize = sizeof(dwStatus); dwStatus = 404; HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL); if (dwStatus == 200) break; InternetCloseHandle(hRequest); hRequest = NULL; safe_strcpy(&urlpath[verpos[i]], 5, ".ver"); } if (dwStatus != 200) { vuprintf("Could not find a %s version file on server %s", channel[k], server_url); if ((releases_only) || (k+1 >= ARRAYSIZE(channel))) goto out; continue; } vuprintf("Found match for %s on server %s.", urlpath, server_url); dwSize = sizeof(mime); HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL); if (strcmp(mime, "text/plain") != 0) goto out; // We also get a date from Apache, which we'll use to avoid out of sync check, // in case some set their clock way into the future and back. // On the other hand, if local clock is set way back in the past, we will never check. dwSize = sizeof(ServerTime); // If we can't get a date we can trust, don't bother... if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL)) || (!SystemTimeToFileTime(&ServerTime, &FileTime)) ) goto out; server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Server time: %" PRId64 "\n", server_time); // Always store the server response time - the only clock we trust! WriteRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE, server_time); // Might as well let the user know if (!force_update_check) { if (local_time > server_time + 600) { uprintf("Your local clock appears more than 10 minutes early - You ought to fix that...\n"); } if (local_time < server_time - 600) { uprintf("Your local clock appears more than 10 minutes late - you ought to fix that...\n"); } } dwSize = sizeof(dwTotalSize); if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) goto out; safe_free(buf); // Make sure the file is NUL terminated buf = (char*)calloc(dwTotalSize+1, 1); if (buf == NULL) goto out; // This is a version file - we should be able to gulp it down in one go if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize)) goto out; status++; vuprintf("Successfully downloaded version file (%d bytes)\n", dwTotalSize); parse_update(buf, dwTotalSize+1); vuprintf("UPDATE DATA:\n"); vuprintf(" version: %d.%d.%d.%d (%s)\n", update.version[0], update.version[1], update.version[2], update.version[3], channel[k]); vuprintf(" platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]); vuprintf(" url: %s\n", update.download_url); found_new_version = (to_uint64_t(update.version) > to_uint64_t(rufus_version)) && ( (os_version.dwMajorVersion > update.platform_min[0]) || ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) ); uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.'); } out: safe_free(buf); if (hRequest) InternetCloseHandle(hRequest); if (hConnection) InternetCloseHandle(hConnection); if (hSession) InternetCloseHandle(hSession); switch(status) { case 1: PrintStatus(3000, TRUE, "Updates: Unable to connect to the internet.\n"); break; case 2: PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n"); break; case 3: case 4: PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n", found_new_version?"A":"No", found_new_version?"is available!":"was found."); default: break; } // Start the new download after cleanup if (found_new_version) { // User may have started an operation while we were checking while ((!force_update_check) && (iso_op_in_progress || format_op_in_progress || (dialog_showing>0))) { Sleep(15000); } DownloadNewVersion(); } force_update_check = FALSE; update_check_in_progress = FALSE; ExitThread(0); }
BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan) { size_t i; int j; FILE* fd; BOOL r = FALSE; iso9660_t* p_iso = NULL; udf_t* p_udf = NULL; udf_dirent_t* p_udf_root; LONG progress_style; char* tmp; char path[64]; const char* scan_text = "Scanning ISO image..."; const char* basedir[] = { "i386", "minint" }; const char* tmp_sif = ".\\txtsetup.sif~"; if ((src_iso == NULL) || (dest_dir == NULL)) return FALSE; scan_only = scan; cdio_log_set_handler(log_handler); psz_extract_dir = dest_dir; progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE); if (scan_only) { total_blocks = 0; memset(&iso_report, 0, sizeof(iso_report)); // String array of all isolinux/syslinux locations StrArrayCreate(&config_path, 8); // Change the Window title and static text SetWindowTextU(hISOProgressDlg, scan_text); SetWindowTextU(hISOFileName, scan_text); // Change progress style to marquee for scanning SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style | PBS_MARQUEE); SendMessage(hISOProgressBar, PBM_SETMARQUEE, TRUE, 0); } else { uprintf("Extracting files...\n"); if (total_blocks == 0) { uprintf("Error: ISO has not been properly scanned.\n"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN); goto out; } nb_blocks = 0; iso_blocking_status = 0; SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0); } ShowWindow(hISOProgressDlg, SW_SHOW); UpdateWindow(hISOProgressDlg); /* First try to open as UDF - fallback to ISO if it failed */ p_udf = udf_open(src_iso); if (p_udf == NULL) goto try_iso; uprintf("Disc image is an UDF image\n"); p_udf_root = udf_get_root(p_udf, true, 0); if (p_udf_root == NULL) { uprintf("Couldn't locate UDF root directory\n"); goto out; } if (scan_only) { if (udf_get_logical_volume_id(p_udf, iso_report.label, sizeof(iso_report.label)) <= 0) iso_report.label[0] = 0; } r = udf_extract_files(p_udf, p_udf_root, ""); goto out; try_iso: p_iso = iso9660_open_ext(src_iso, ISO_EXTENSION_ALL); if (p_iso == NULL) { uprintf("Unable to open image '%s'.\n", src_iso); goto out; } i_joliet_level = iso9660_ifs_get_joliet_level(p_iso); uprintf("Disc image is an ISO9660 image\n"); if (scan_only) { if (iso9660_ifs_get_volume_id(p_iso, &tmp)) { safe_strcpy(iso_report.label, sizeof(iso_report.label), tmp); safe_free(tmp); } else iso_report.label[0] = 0; } r = iso_extract_files(p_iso, ""); out: iso_blocking_status = -1; if (scan_only) { // Remove trailing spaces from the label for (j=safe_strlen(iso_report.label)-1; ((j>=0)&&(isspace(iso_report.label[j]))); j--) iso_report.label[j] = 0; // We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here iso_report.projected_size = total_blocks * ISO_BLOCKSIZE; // We will link the existing isolinux.cfg from a syslinux.cfg we create // If multiple config file exist, choose the one with the shortest path if (iso_report.has_isolinux) { safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[0]); for (i=1; i<config_path.Index; i++) { if (safe_strlen(iso_report.cfg_path) > safe_strlen(config_path.Table[i])) safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[i]); } uprintf("Will use %s for Syslinux\n", iso_report.cfg_path); } if (IS_WINPE(iso_report.winpe)) { // In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif // during scan, to see if /minint was provided for OsLoadOptions, as it decides // whether we should use 0x80 or 0x81 as the disk ID in the MBR safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", basedir[((iso_report.winpe&WINPE_I386) == WINPE_I386)?0:1]); ExtractISOFile(src_iso, path, tmp_sif); tmp = get_token_data(tmp_sif, "OsLoadOptions"); if (tmp != NULL) { for (i=0; i<strlen(tmp); i++) tmp[i] = (char)tolower(tmp[i]); uprintf("Checking txtsetup.sif:\n OsLoadOptions = %s\n", tmp); iso_report.uses_minint = (strstr(tmp, "/minint") != NULL); } _unlink(tmp_sif); safe_free(tmp); } StrArrayDestroy(&config_path); } else if (iso_report.has_isolinux) { safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir); // Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg fd = fopen(path, "r"); if (fd == NULL) { fd = fopen(path, "w"); // No "/syslinux.cfg" => create a new one if (fd == NULL) { uprintf("Unable to create %s - booting from USB will not work\n", path); r = 1; } else { fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", iso_report.cfg_path); for (i=safe_strlen(iso_report.cfg_path); (i>0)&&(iso_report.cfg_path[i]!='/'); i--); if (i>0) { iso_report.cfg_path[i] = 0; fprintf(fd, " APPEND %s/\n", iso_report.cfg_path); iso_report.cfg_path[i] = '/'; } uprintf("Created: %s\n", path); } } if (fd != NULL) fclose(fd); } ShowWindow(hISOProgressDlg, SW_HIDE); if (p_iso != NULL) iso9660_close(p_iso); if (p_udf != NULL) udf_close(p_udf); if ((r != 0) && (FormatStatus == 0)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT)); return (r == 0); }
static DWORD WINAPI SearchProcessThread(LPVOID param) { const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" }; char tmp[MAX_PATH]; NTSTATUS status = STATUS_SUCCESS; PSYSTEM_HANDLE_INFORMATION_EX handles = NULL; POBJECT_NAME_INFORMATION buffer = NULL; ULONG_PTR i; ULONG_PTR pid[2]; ULONG_PTR last_access_denied_pid = 0; ULONG bufferSize; USHORT wHandleNameLen; WCHAR *wHandleName = NULL; HANDLE dupHandle = NULL; HANDLE processHandle = NULL; BOOLEAN bFound = FALSE, bGotExePath, verbose = !_bQuiet; ULONG access_rights = 0; DWORD size; char exe_path[MAX_PATH] = { 0 }; wchar_t wexe_path[MAX_PATH]; int cur_pid; PF_INIT_OR_SET_STATUS(NtQueryObject, Ntdll); PF_INIT_OR_SET_STATUS(NtDuplicateObject, NtDll); PF_INIT_OR_SET_STATUS(NtClose, NtDll); StrArrayClear(&BlockingProcess); if (NT_SUCCESS(status)) status = PhCreateHeap(); if (NT_SUCCESS(status)) status = PhEnumHandlesEx(&handles); if (!NT_SUCCESS(status)) { uprintf("Warning: Could not enumerate process handles: %s", NtStatusError(status)); goto out; } pid[0] = (ULONG_PTR)0; cur_pid = 1; wHandleName = utf8_to_wchar(_HandleName); wHandleNameLen = (USHORT)wcslen(wHandleName); bufferSize = 0x200; buffer = PhAllocate(bufferSize); if (buffer == NULL) goto out; for (i = 0; ; i++) { ULONG attempts = 8; PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = (i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL; if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) { pfNtClose(dupHandle); dupHandle = NULL; } // Update the current handle's process PID and compare against last // Note: Be careful about not trying to overflow our list! pid[cur_pid] = (handleInfo != NULL) ? handleInfo->UniqueProcessId : -1; if (pid[0] != pid[1]) { cur_pid = (cur_pid + 1) % 2; // If we're switching process and found a match, print it if (bFound) { vuprintf("● '%s' (pid: %ld, access: %s)", exe_path, pid[cur_pid], access_rights_str[access_rights & 0x7]); static_sprintf(tmp, "● %s (%s)", exe_path, access_rights_str[access_rights & 0x7]); StrArrayAdd(&BlockingProcess, tmp, TRUE); bFound = FALSE; access_rights = 0; } // Close the previous handle if (processHandle != NULL) { if (processHandle != NtCurrentProcess()) pfNtClose(processHandle); processHandle = NULL; } } CHECK_FOR_USER_CANCEL; // Exit loop condition if (i >= handles->NumberOfHandles) break; // Don't bother with processes we can't access if (handleInfo->UniqueProcessId == last_access_denied_pid) continue; // Filter out handles that aren't opened with Read (bit 0), Write (bit 1) or Execute (bit 5) access if ((handleInfo->GrantedAccess & 0x23) == 0) continue; // Open the process to which the handle we are after belongs, if not already opened if (pid[0] != pid[1]) { status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, (HANDLE)handleInfo->UniqueProcessId); // There exists some processes we can't access if (!NT_SUCCESS(status)) { uuprintf("SearchProcess: Could not open process %ld: %s", handleInfo->UniqueProcessId, NtStatusError(status)); processHandle = NULL; if (status == STATUS_ACCESS_DENIED) { last_access_denied_pid = handleInfo->UniqueProcessId; } continue; } } // Now duplicate this handle onto our own process, so that we can access its properties if (processHandle == NtCurrentProcess()) { if (_bIgnoreSelf) continue; dupHandle = (HANDLE)handleInfo->HandleValue; } else { status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue, NtCurrentProcess(), &dupHandle, 0, 0, 0); if (!NT_SUCCESS(status)) continue; } // Filter non-storage handles. We're not interested in them and they make NtQueryObject() freeze if (GetFileType(dupHandle) != FILE_TYPE_DISK) continue; // A loop is needed because the I/O subsystem likes to give us the wrong return lengths... do { ULONG returnSize; // TODO: We might potentially still need a timeout on ObjectName queries, as PH does... status = pfNtQueryObject(dupHandle, ObjectNameInformation, buffer, bufferSize, &returnSize); if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_BUFFER_TOO_SMALL) { uuprintf("SearchProcess: Realloc from %d to %d", bufferSize, returnSize); bufferSize = returnSize; PhFree(buffer); buffer = PhAllocate(bufferSize); } else { break; } } while (--attempts); if (!NT_SUCCESS(status)) { uuprintf("SearchProcess: NtQueryObject failed for handle %X of process %ld: %s", handleInfo->HandleValue, handleInfo->UniqueProcessId, NtStatusError(status)); continue; } // Don't bother comparing if we are looking for full match and the length is different if ((!_bPartialMatch) && (wHandleNameLen != buffer->Name.Length)) continue; // Likewise, if we are looking for a partial match and the current length is smaller if ((_bPartialMatch) && (wHandleNameLen > buffer->Name.Length)) continue; // Match against our target string if (wcsncmp(wHandleName, buffer->Name.Buffer, wHandleNameLen) != 0) continue; // If we are here, we have a process accessing our target! bFound = TRUE; // Keep a mask of all the access rights being used access_rights |= handleInfo->GrantedAccess; // The Executable bit is in a place we don't like => reposition it if (access_rights & 0x20) access_rights = (access_rights & 0x03) | 0x04; access_mask |= (BYTE) (access_rights & 0x7) + 0x80; // Bit 7 is always set if a process was found // If this is the very first process we find, print a header if (exe_path[0] == 0) vuprintf("WARNING: The following process(es) or service(s) are accessing %s:", _HandleName); // First, we try to get the executable path using GetModuleFileNameEx bGotExePath = (GetModuleFileNameExU(processHandle, 0, exe_path, MAX_PATH - 1) != 0); // The above may not work on Windows 7, so try QueryFullProcessImageName (Vista or later) if (!bGotExePath) { size = MAX_PATH; PF_INIT(QueryFullProcessImageNameW, kernel32); if ( (pfQueryFullProcessImageNameW != NULL) && (bGotExePath = pfQueryFullProcessImageNameW(processHandle, 0, wexe_path, &size)) ) wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path)); } // Still nothing? Try GetProcessImageFileName. Note that GetProcessImageFileName uses // '\Device\Harddisk#\Partition#\' instead drive letters if (!bGotExePath) { bGotExePath = (GetProcessImageFileNameW(processHandle, wexe_path, MAX_PATH) != 0); if (bGotExePath) wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path)); } // Complete failure => Just craft a default process name that includes the PID if (!bGotExePath) { safe_sprintf(exe_path, MAX_PATH, "Unknown_Process_%" PRIu64, (ULONGLONG)handleInfo->UniqueProcessId); } } out: if (exe_path[0] != 0) vuprintf("You should close these applications before attempting to reformat the drive."); else vuprintf("NOTE: Could not identify the process(es) or service(s) accessing %s", _HandleName); free(wHandleName); PhFree(buffer); PhFree(handles); PhDestroyHeap(); ExitThread(0); }
TexturesInspector::TexturesInspector(const Vector2& size) { setSize(size); spSlidingActor slide = new SlidingActor; slide->setSize(size); addChild(slide); float offsetY = 0; std::vector<spNativeTexture> textures = NativeTexture::getCreatedTextures(); spTextField text = initActor(new TextField, arg_color = Color::White, arg_pos = Vector2(1, 1), arg_w = itemSize.x * 3.0f, arg_h = 30.0f, arg_vAlign = TextStyle::VALIGN_TOP, arg_hAlign = TextStyle::HALIGN_LEFT, arg_multiline = true, arg_attachTo = slide ); offsetY += text->getTextRect().getBottom() + 5; spActor content = new Actor; content->setX(2); int numX = (int)(size.x / itemSize.x); int n = 0; int mem = 0; for (std::vector<spNativeTexture>::iterator i = textures.begin(); i != textures.end(); ++i) { spNativeTexture t = *i; TextureLine* line = new TextureLine(t); float x = (n % numX) * (itemSize.x + 5.0f); float y = (n / numX) * (itemSize.y + 5.0f); line->setX(x); line->setY(y + offsetY); content->addChild(line); ++n; mem += t->getSizeVRAM(); } char txt[255]; safe_sprintf(txt, "created textures: %d, vram: %d kb", textures.size(), mem / 1024); text->setText(txt); if (numX > n) numX = n; content->setSize( (itemSize.x + 5.0f) * numX, (itemSize.y + 5.0f) * (n + numX - 1.0f) / numX + offsetY); setWidth(content->getWidth()); slide->setWidth(content->getWidth()); //slide->setSize() slide->setContent(content); }
INT_PTR CALLBACK device_list_wndproc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR tipText[80]; POINT pt; static int oldX, oldY; int newX, newY; LVHITTESTINFO hitTestInfo; LVITEM lvitem; device_context_t* dev_context; BOOL ignored; switch(message) { case WM_MOUSELEAVE: // The mouse pointer has left our window. // Deactivate the tooltip. SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&g_toolItem); g_TrackingMouse = FALSE; return FALSE; case WM_MOUSEMOVE: if (!g_TrackingMouse) { // The mouse has just entered the window. // Request notification when the mouse leaves. TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) }; tme.hwndTrack = hDlg; tme.dwFlags = TME_LEAVE; TrackMouseEvent(&tme); // Activate the tooltip. SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&g_toolItem); g_TrackingMouse = TRUE; } newX = LOWORD(lParam); newY = HIWORD(lParam); // Make sure the mouse has actually moved. The presence of the tooltip // causes Windows to send the message continuously. if ((newX != oldX) || (newY != oldY)) { oldX = newX; oldY = newY; memset(&hitTestInfo,0,sizeof(hitTestInfo)); hitTestInfo.pt.x = newX; hitTestInfo.pt.y = newY; if ((ListView_HitTest(hDlg, &hitTestInfo) == -1) || newX > ListView_GetColumnWidth(hDlg, 0)) { safe_sprintf(tipText, sizeof(tipText) - 1, TEXT("%s"), TEXT("")); SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE,FALSE, (LPARAM)&g_toolItem); } else { SendMessage(g_hwndTrackingTT, TTM_SETDELAYTIME,TTDT_INITIAL, 1000); memset(&lvitem, 0 , sizeof(lvitem)); lvitem.iItem = hitTestInfo.iItem; lvitem.mask = LVIF_PARAM; ignored = ListView_GetItem(hDlg,&lvitem); dev_context = (device_context_t*)lvitem.lParam; // Update the text. safe_sprintf(tipText, sizeof(tipText)-1 , TEXT("%s"), wdi_get_vendor_name(dev_context->wdi->vid)); SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE,TRUE, (LPARAM)&g_toolItem); } g_toolItem.lpszText = tipText; SendMessage(g_hwndTrackingTT, TTM_SETTOOLINFO, 0, (LPARAM)&g_toolItem); // Position the tooltip. // The coordinates are adjusted so that the tooltip does not // overlap the mouse pointer. pt.x = newX; pt.y = newY; ClientToScreen(hDlg, &pt); SendMessage(g_hwndTrackingTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20)); } break; } return CallWindowProc(device_list_wndproc_orig, hDlg, message, wParam, lParam); }
string color2hex(const Color &c) { char str[255]; safe_sprintf(str, "%02x%02x%02x%02x", c.r, c.g, c.b, c.a); return string(str); }
BOOL CALLBACK dialog_proc_3(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam) { static device_context_t *device = NULL; char* bufferLabel = NULL; char* bufferText = NULL; int ret; UINT x,y; UINT TXT_WIDTH = 200; UINT LBL_WIDTH = 150; UINT LBL_HEIGHT = 15; UINT LBL_SEP = 5; HWND hwnd; static HBRUSH hBrushStatic = NULL; RECT rect; switch (message) { case WM_INITDIALOG: SendMessage(dialog,WM_SETICON,ICON_SMALL, (LPARAM)mIcon); SendMessage(dialog,WM_SETICON,ICON_BIG, (LPARAM)mIcon); device = (device_context_t *)lParam; create_tooltip(dialog, g_hInst, 300, tooltips_dlg3); bufferLabel = malloc(MAX_TEXT_LENGTH*2); bufferText = bufferLabel+MAX_TEXT_LENGTH; if (bufferLabel) { GetWindowRect(GetDlgItem(dialog,IDG_MAIN),&rect); TXT_WIDTH = rect.right-rect.left-30-LBL_WIDTH; y = 40; x = 30; safe_sprintf(bufferLabel, MAX_TEXT_LENGTH, "%s", info_text_1); create_labeled_text(bufferLabel,NULL, dialog, g_hInst, x, y, LBL_HEIGHT * 2,LBL_WIDTH+TXT_WIDTH,0, ID_TEXT_HIGHLIGHT_INFO, ID_TEXT_HIGHLIGHT_INFO); y += LBL_HEIGHT*2+LBL_SEP*2; safe_strcpy(bufferLabel, MAX_TEXT_LENGTH, "Vendor ID:"); safe_sprintf(bufferText, MAX_TEXT_LENGTH, "0x%04X", device->wdi->vid); create_labeled_text(bufferLabel,bufferText,dialog,g_hInst,x,y,LBL_HEIGHT,LBL_WIDTH,TXT_WIDTH, ID_INFO_TEXT, ID_INFO_TEXT); y += LBL_HEIGHT+LBL_SEP; safe_strcpy(bufferLabel, MAX_TEXT_LENGTH, "Product ID:"); safe_sprintf(bufferText, MAX_TEXT_LENGTH, "0x%04X", device->wdi->pid); create_labeled_text(bufferLabel,bufferText,dialog,g_hInst,x,y,LBL_HEIGHT,LBL_WIDTH,TXT_WIDTH, ID_INFO_TEXT, ID_INFO_TEXT); if (device->wdi->is_composite) { y += LBL_HEIGHT+LBL_SEP; safe_strcpy(bufferLabel, MAX_TEXT_LENGTH, "Interface # (MI):"); safe_sprintf(bufferText, MAX_TEXT_LENGTH, "0x%02X", device->wdi->mi); create_labeled_text(bufferLabel,bufferText,dialog,g_hInst,x,y,LBL_HEIGHT,LBL_WIDTH,TXT_WIDTH, ID_INFO_TEXT, ID_INFO_TEXT); } y += LBL_HEIGHT+LBL_SEP; safe_strcpy(bufferLabel, MAX_TEXT_LENGTH, "Device description:"); safe_sprintf(bufferText, MAX_TEXT_LENGTH, "%s", device->description); create_labeled_text(bufferLabel,bufferText,dialog,g_hInst,x,y,LBL_HEIGHT,LBL_WIDTH,TXT_WIDTH, ID_INFO_TEXT, ID_INFO_TEXT); y += LBL_HEIGHT+LBL_SEP; safe_strcpy(bufferLabel, MAX_TEXT_LENGTH, "Manufacturer:"); safe_sprintf(bufferText, MAX_TEXT_LENGTH, "%s", device->manufacturer); create_labeled_text(bufferLabel,bufferText,dialog,g_hInst,x,y,LBL_HEIGHT,LBL_WIDTH,TXT_WIDTH, ID_INFO_TEXT, ID_INFO_TEXT); y += LBL_HEIGHT+LBL_SEP*2; if (device->driver_info.dwSignature) { safe_sprintf(bufferLabel, MAX_TEXT_LENGTH, package_contents_fmt_0, "libusb-win32", (int)device->driver_info.dwFileVersionMS>>16, (int)device->driver_info.dwFileVersionMS&0xFFFF, (int)device->driver_info.dwFileVersionLS>>16, (int)device->driver_info.dwFileVersionLS&0xFFFF, "x86, x64, ia64"); } else { safe_sprintf(bufferLabel, MAX_TEXT_LENGTH, "%s", package_contents_fmt_1); } hwnd = create_labeled_text(NULL,bufferLabel,dialog,g_hInst,x,y,LBL_HEIGHT*2, 0, LBL_WIDTH+TXT_WIDTH, ID_TEXT_HIGHLIGHT_INFO, ID_TEXT_HIGHLIGHT_INFO); free(bufferLabel); }
void error_va(const char* format, va_list args) { char tm[32]; safe_sprintf(tm, "%03d error: ", getTime()); out_line_prefix(_eh, tm, format, args); }
/* * Background thread to check for updates */ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) { BOOL releases_only, found_new_version = FALSE; int status = 0; const char* server_url = RUFUS_URL "/"; int i, j, k, max_channel, verbose = 0, verpos[4]; static const char* archname[] = {"win_x86", "win_x64"}; static const char* channel[] = {"release", "beta", "test"}; // release channel const char* accept_types[] = {"*/*\0", NULL}; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; char* buf = NULL; char agent[64], hostname[64], urlpath[128], mime[32]; OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""}; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; SYSTEMTIME ServerTime, LocalTime; FILETIME FileTime; int64_t local_time = 0, reg_time, server_time, update_interval; update_check_in_progress = TRUE; verbose = ReadSetting32(SETTING_VERBOSE_UPDATES); // Without this the FileDialog will produce error 0x8001010E when compiled for Vista or later IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); // Unless the update was forced, wait a while before performing the update check if (!force_update_check) { // It would of course be a lot nicer to use a timer and wake the thread, but my // development time is limited and this is FASTER to implement. do { for (i=0; (i<30) && (!force_update_check); i++) Sleep(500); } while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0)))); if (!force_update_check) { if ((ReadSetting32(SETTING_UPDATE_INTERVAL) == -1)) { vuprintf("Check for updates disabled, as per settings.\n"); goto out; } reg_time = ReadSetting64(SETTING_LAST_UPDATE); update_interval = (int64_t)ReadSetting32(SETTING_UPDATE_INTERVAL); if (update_interval == 0) { WriteSetting32(SETTING_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); update_interval = DEFAULT_UPDATE_INTERVAL; } GetSystemTime(&LocalTime); if (!SystemTimeToFileTime(&LocalTime, &FileTime)) goto out; local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Local time: %" PRId64 "\n", local_time); if (local_time < reg_time + update_interval) { vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time); goto out; } } } PrintInfoDebug(3000, MSG_243); status++; // 1 if (!GetVersionExA(&os_version)) { uprintf("Could not read Windows version - Check for updates cancelled.\n"); goto out; } if ((!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0))) goto out; hostname[sizeof(hostname)-1] = 0; safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", rufus_version[0], rufus_version[1], rufus_version[2], nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hSession == NULL) goto out; hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) goto out; status++; // 2 releases_only = !ReadSettingBool(SETTING_INCLUDE_BETAS); // Test releases get their own distribution channel (and also force beta checks) #if defined(TEST) max_channel = (int)ARRAYSIZE(channel); #else max_channel = releases_only ? 1 : (int)ARRAYSIZE(channel) - 1; #endif for (k=0; (k<max_channel) && (!found_new_version); k++) { uprintf("Checking %s channel...\n", channel[k]); // At this stage we can query the server for various update version files. // We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver" // and then remove each each of the <os_> components until we find our match. For instance, we may first // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":"_", (k==0)?"":channel[k], archname[is_x64()?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); vuprintf("Base update check: %s\n", urlpath); for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) { if ((urlpath[j] == '.') || (urlpath[j] == '_')) { verpos[i++] = j; } } if (i != ARRAYSIZE(verpos)) { uprintf("Broken code in CheckForUpdatesThread()!\n"); goto out; } UrlParts.lpszUrlPath = urlpath; UrlParts.dwUrlPathLength = sizeof(urlpath); for (i=0; i<ARRAYSIZE(verpos); i++) { vvuprintf("Trying %s\n", UrlParts.lpszUrlPath); hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types, INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL); if ((hRequest == NULL) || (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0))) goto out; // Ensure that we get a text file dwSize = sizeof(dwStatus); dwStatus = 404; HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL); if (dwStatus == 200) break; InternetCloseHandle(hRequest); hRequest = NULL; safe_strcpy(&urlpath[verpos[i]], 5, ".ver"); } if (dwStatus != 200) { vuprintf("Could not find a %s version file on server %s", channel[k], server_url); if ((releases_only) || (k+1 >= ARRAYSIZE(channel))) goto out; continue; } vuprintf("Found match for %s on server %s", urlpath, server_url); dwSize = sizeof(mime); HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL); if (strncmp(mime, "text/plain", sizeof("text/plain")-1) != 0) goto out; // We also get a date from Apache, which we'll use to avoid out of sync check, // in case some set their clock way into the future and back. // On the other hand, if local clock is set way back in the past, we will never check. dwSize = sizeof(ServerTime); // If we can't get a date we can trust, don't bother... if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL)) || (!SystemTimeToFileTime(&ServerTime, &FileTime)) ) goto out; server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Server time: %" PRId64 "\n", server_time); // Always store the server response time - the only clock we trust! WriteSetting64(SETTING_LAST_UPDATE, server_time); // Might as well let the user know if (!force_update_check) { if ((local_time > server_time + 600) || (local_time < server_time - 600)) { uprintf("IMPORTANT: Your local clock is more than 10 minutes in the %s. Unless you fix this, " APPLICATION_NAME " may not be able to check for updates...", (local_time > server_time + 600)?"future":"past"); } } dwSize = sizeof(dwTotalSize); if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) goto out; safe_free(buf); // Make sure the file is NUL terminated buf = (char*)calloc(dwTotalSize+1, 1); if (buf == NULL) goto out; // This is a version file - we should be able to gulp it down in one go if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize)) goto out; status++; vuprintf("Successfully downloaded version file (%d bytes)\n", dwTotalSize); parse_update(buf, dwTotalSize+1); vuprintf("UPDATE DATA:\n"); vuprintf(" version: %d.%d.%d (%s)\n", update.version[0], update.version[1], update.version[2], channel[k]); vuprintf(" platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]); vuprintf(" url: %s\n", update.download_url); found_new_version = ((to_uint64_t(update.version) > to_uint64_t(rufus_version)) || (force_update)) && ( (os_version.dwMajorVersion > update.platform_min[0]) || ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) ); uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.'); } out: safe_free(buf); if (hRequest) InternetCloseHandle(hRequest); if (hConnection) InternetCloseHandle(hConnection); if (hSession) InternetCloseHandle(hSession); switch(status) { case 1: PrintInfoDebug(3000, MSG_244); break; case 2: PrintInfoDebug(3000, MSG_245); break; case 3: case 4: PrintInfo(3000, found_new_version?MSG_246:MSG_247); default: break; } // Start the new download after cleanup if (found_new_version) { // User may have started an operation while we were checking while ((!force_update_check) && (iso_op_in_progress || format_op_in_progress || (dialog_showing>0))) { Sleep(15000); } DownloadNewVersion(); } else if (force_update_check) { PostMessage(hMainDialog, UM_NO_UPDATE, 0, 0); } force_update_check = FALSE; update_check_in_progress = FALSE; ExitThread(0); }
void messageln_va(const char* format, va_list args) { char tm[16]; safe_sprintf(tm, "%03d ", getTime()); out_line_prefix(0, tm, format, args); }
/* * Refresh the list of USB devices */ BOOL GetUSBDevices(DWORD devnum) { // The first two are standard Microsoft drivers (including the Windows 8 UASP one). // The rest are the vendor UASP drivers I know of so far - list may be incomplete! const char* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR", "ASUSSTPT" }; const char* scsi_name = "SCSI"; const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" }; // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path htab_table htab_devid = HTAB_EMPTY; StrArray dev_if_path; char letter_name[] = " (?:)"; char uefi_togo_check[] = "?:\\EFI\\Rufus\\ntfs_x64.efi"; BOOL r = FALSE, found = FALSE, is_SCSI; HDEVINFO dev_info = NULL; SP_DEVINFO_DATA dev_info_data; SP_DEVICE_INTERFACE_DATA devint_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; DEVINST parent_inst, grandparent_inst, device_inst; DWORD size, i, j, k, l, datatype, drive_index; ULONG list_size[ARRAYSIZE(storage_name)] = { 0 }, list_start[ARRAYSIZE(storage_name)] = { 0 }, full_list_size, ulFlags; HANDLE hDrive; LONG maxwidth = 0; int s, score, drive_number, remove_drive; char drive_letters[27], *device_id, *devid_list = NULL, entry_msg[128]; char *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str; usb_device_props props; IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); StrArrayClear(&DriveID); StrArrayClear(&DriveLabel); StrArrayCreate(&dev_if_path, 128); // Add a dummy for string index zero, as this is what non matching hashes will point to StrArrayAdd(&dev_if_path, ""); device_id = (char*)malloc(MAX_PATH); if (device_id == NULL) goto out; // Build a hash table associating a CM Device ID of an USB device with the SetupDI Device Interface Path // of its parent hub - this is needed to retrieve the device speed dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (dev_info != INVALID_HANDLE_VALUE) { if (htab_create(DEVID_HTAB_SIZE, &htab_devid)) { dev_info_data.cbSize = sizeof(dev_info_data); for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { if (usb_debug) uprintf("Processing Hub %d:", i + 1); devint_detail_data = NULL; devint_data.cbSize = sizeof(devint_data); // Only care about the first interface (MemberIndex 0) if ( (SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_USB_HUB, 0, &devint_data)) && (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && ((devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size)) != NULL) ) { devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); if (SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { // Find the Device IDs for all the children of this hub if (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) { device_id[0] = 0; s = StrArrayAdd(&dev_if_path, devint_detail_data->DevicePath); if (usb_debug) uprintf(" Hub[%d] = '%s'", s, devint_detail_data->DevicePath); if ((s>= 0) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) { if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; } if (usb_debug) uprintf(" Found ID[%03d]: %s", k, device_id); while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { device_id[0] = 0; if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) { if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; } if (usb_debug) uprintf(" Found ID[%03d]: %s", k, device_id); } } } } } free(devint_detail_data); } } } SetupDiDestroyDeviceInfoList(dev_info); } free(device_id); // Build a single list of Device IDs from all the storage enumerators we know of full_list_size = 0; ulFlags = CM_GETIDLIST_FILTER_SERVICE; if (nWindowsVersion >= WINDOWS_7) ulFlags |= CM_GETIDLIST_FILTER_PRESENT; for (s=0; s<ARRAYSIZE(storage_name); s++) { // Get a list of device IDs for all USB storage devices // This will be used to find if a device is UASP if (CM_Get_Device_ID_List_SizeA(&list_size[s], storage_name[s], ulFlags) != CR_SUCCESS) list_size[s] = 0; if (list_size[s] != 0) full_list_size += list_size[s]-1; // remove extra NUL terminator } devid_list = NULL; if (full_list_size != 0) { full_list_size += 1; // add extra NUL terminator devid_list = (char*)malloc(full_list_size); if (devid_list == NULL) { uprintf("Could not allocate Device ID list\n"); return FALSE; } for (s=0, i=0; s<ARRAYSIZE(storage_name); s++) { list_start[s] = i; if (list_size[s] > 1) { if (CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) continue; if (usb_debug) { uprintf("Processing IDs belonging to %s:", storage_name[s]); for (device_id = &devid_list[i]; *device_id != 0; device_id += strlen(device_id) + 1) uprintf(" %s", device_id); } // The list_size is sometimes larger than required thus we need to find the real end for (i += list_size[s]; i > 2; i--) { if ((devid_list[i-2] != '\0') && (devid_list[i-1] == '\0') && (devid_list[i] == '\0')) break; } } } } // Now use SetupDi to enumerate all our storage devices dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (dev_info == INVALID_HANDLE_VALUE) { uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString()); goto out; } dev_info_data.cbSize = sizeof(dev_info_data); for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { memset(buffer, 0, sizeof(buffer)); method_str = ""; if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME, &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString()); continue; } // UASP drives are listed under SCSI (along with regular SYSTEM drives => "DANGER, WILL ROBINSON!!!") is_SCSI = (safe_stricmp(buffer, scsi_name) == 0); if ((safe_stricmp(buffer, storage_name[0]) != 0) && (!is_SCSI)) continue; // We can't use the friendly name to find if a drive is a VHD, as friendly name string gets translated // according to your locale, so we poke the Hardware ID memset(&props, 0, sizeof(props)); memset(buffer, 0, sizeof(buffer)); props.is_VHD = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID, &datatype, (LPBYTE)buffer, sizeof(buffer), &size) && IsVHD(buffer); if (usb_debug) uprintf("Processing Device: '%s'", buffer); memset(buffer, 0, sizeof(buffer)); if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045)); } else if ((!props.is_VHD) && (devid_list != NULL)) { // Get the properties of the device. We could avoid doing this lookup every time by keeping // a lookup table, but there shouldn't be that many USB storage devices connected... // NB: Each of these Device IDs have an _only_ child, from which we get the Device Instance match. for (device_id = devid_list; *device_id != 0; device_id += strlen(device_id) + 1) { if ( (CM_Locate_DevNodeA(&parent_inst, device_id, 0) == CR_SUCCESS) && (CM_Get_Child(&device_inst, parent_inst, 0) == CR_SUCCESS) && (device_inst == dev_info_data.DevInst) ) { // If we're not dealing with the USBSTOR part of our list, then this is an UASP device props.is_UASP = ((((uintptr_t)device_id)+2) >= ((uintptr_t)devid_list)+list_start[1]); // Now get the properties of the device, and its Device ID, which we need to populate the properties j = htab_hash(device_id, &htab_devid); if (usb_debug) uprintf(" Matched with ID[%03d]: %s", j, device_id); // If the hash didn't match a populated string in dev_if_path[] (htab_devid.table[j].data > 0), // we might have an extra vendor driver in between (e.g. "ASUS USB 3.0 Boost Storage Driver" // for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods) // so try to see if we can match the grandparent. if ( ((uintptr_t)htab_devid.table[j].data == 0) && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { device_id = str; method_str = "[GP]"; j = htab_hash(device_id, &htab_devid); if (usb_debug) uprintf(" Matched with (GP) ID[%03d]: %s", j, device_id); } if ((uintptr_t)htab_devid.table[j].data > 0) { if (usb_debug) uprintf(" Matched with Hub[%d]: '%s'", (uintptr_t)htab_devid.table[j].data, dev_if_path.String[(uintptr_t)htab_devid.table[j].data]); GetUSBProperties(dev_if_path.String[(uintptr_t)htab_devid.table[j].data], device_id, &props); } if (usb_debug) uprintf(" Props VID:PID = %04X:%04X", props.vid, props.pid); // If previous calls still didn't succeed, try reading the VID:PID from the device_id if ((props.vid == 0) && (props.pid == 0)) { BOOL post_backslash = FALSE; method_str = "[ID]"; for (j=0, k=0; (j<strlen(device_id))&&(k<2); j++) { // The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\... if (device_id[j] == '\\') post_backslash = TRUE; if (!post_backslash) continue; if (device_id[j] == '_') { props.pid = (uint16_t)strtoul(&device_id[j+1], NULL, 16); if (k++==0) props.vid = props.pid; } } } break; } } } if (props.is_VHD) { uprintf("Found VHD device '%s'", buffer); } else { if ((props.vid == 0) && (props.pid == 0)) { if (is_SCSI) { // If we have an SCSI drive and couldn't get a VID:PID, we are most likely // dealing with a system drive => eliminate it! if (usb_debug) uprintf(" Non USB => Eliminated"); continue; } safe_strcpy(str, sizeof(str), "????:????"); // Couldn't figure VID:PID } else { static_sprintf(str, "%04X:%04X", props.vid, props.pid); } if (props.speed >= USB_SPEED_MAX) props.speed = 0; uprintf("Found %s%s%s device '%s' (%s) %s\n", props.is_UASP?"UAS (":"", usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str, method_str); if (props.is_LowerSpeed) uprintf("NOTE: This device is an USB 3.0 device operating at lower speed..."); } devint_data.cbSize = sizeof(devint_data); hDrive = INVALID_HANDLE_VALUE; devint_detail_data = NULL; for (j=0; ;j++) { safe_closehandle(hDrive); safe_free(devint_detail_data); if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_DISK, j, &devint_data)) { if(GetLastError() != ERROR_NO_MORE_ITEMS) { uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); } else { uprintf("A device was eliminated because it didn't report itself as a disk\n"); } break; } if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); if (devint_detail_data == NULL) { uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n"); continue; } devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); } else { uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); continue; } } if (devint_detail_data == NULL) { uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); continue; } if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString()); continue; } hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hDrive == INVALID_HANDLE_VALUE) { uprintf("Could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString()); continue; } drive_number = GetDriveNumber(hDrive, devint_detail_data->DevicePath); if (drive_number < 0) continue; drive_index = drive_number + DRIVE_INDEX_MIN; if (!IsMediaPresent(drive_index)) { uprintf("Device eliminated because it appears to contain no media\n"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } if (GetDriveLabel(drive_index, drive_letters, &label)) { if ((!enable_HDDs) && (!props.is_VHD) && ((score = IsHDD(drive_index, (uint16_t)props.vid, (uint16_t)props.pid, buffer)) > 0)) { uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score); uprintf("If this device is not an USB Hard Drive, please e-mail the author of this application\n"); uprintf("NOTE: You can enable the listing of USB Hard Drives in 'Advanced Options' (after clicking the white triangle)"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } // The empty string is returned for drives that don't have any volumes assigned if (drive_letters[0] == 0) { entry = lmprintf(MSG_046, label, drive_number, SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units)); } else { // Find the UEFI:TOGO partition(s) (and eliminate them form our listing) for (k=0; drive_letters[k]; k++) { uefi_togo_check[0] = drive_letters[k]; if (PathFileExistsA(uefi_togo_check)) { for (l=k; drive_letters[l]; l++) drive_letters[l] = drive_letters[l+1]; k--; } } // We have multiple volumes assigned to the same device (multiple partitions) // If that is the case, use "Multiple Volumes" instead of the label safe_strcpy(entry_msg, sizeof(entry_msg), (((drive_letters[0] != 0) && (drive_letters[1] != 0))? lmprintf(MSG_047):label)); for (k=0, remove_drive=0; drive_letters[k] && (!remove_drive); k++) { // Append all the drive letters we detected letter_name[2] = drive_letters[k]; if (right_to_left_mode) safe_strcat(entry_msg, sizeof(entry_msg), RIGHT_TO_LEFT_MARK); safe_strcat(entry_msg, sizeof(entry_msg), letter_name); if (drive_letters[k] == (PathGetDriveNumberU(app_dir) + 'A')) remove_drive = 1; if (drive_letters[k] == (PathGetDriveNumberU(system_dir) + 'A')) remove_drive = 2; } // Make sure that we don't list any drive that should not be listed if (remove_drive) { uprintf("Removing %C: from the list: This is the %s!", drive_letters[--k], (remove_drive==1)?"disk from which " APPLICATION_NAME " is running":"system disk"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } safe_sprintf(&entry_msg[strlen(entry_msg)], sizeof(entry_msg) - strlen(entry_msg), "%s [%s]", (right_to_left_mode)?RIGHT_TO_LEFT_MARK:"", SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units)); entry = entry_msg; } // Must ensure that the combo box is UNSORTED for indexes to be the same StrArrayAdd(&DriveID, buffer); StrArrayAdd(&DriveLabel, label); IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry), drive_index)); maxwidth = max(maxwidth, GetEntryWidth(hDeviceList, entry)); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } } } SetupDiDestroyDeviceInfoList(dev_info); // Adjust the Dropdown width to the maximum text size SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0); if (devnum >= DRIVE_INDEX_MIN) { for (i=0; i<ComboBox_GetCount(hDeviceList); i++) { if ((DWORD)ComboBox_GetItemData(hDeviceList, i) == devnum) { found = TRUE; break; } } } if (!found) i = 0; IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, i)); SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_DEVICE, 0); SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_FILESYSTEM, ComboBox_GetCurSel(hFileSystem)); r = TRUE; out: // Set 'Start' as the selected button, so that tab selection works SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDC_START), TRUE); safe_free(devid_list); StrArrayDestroy(&dev_if_path); htab_destroy(&htab_devid); return r; }
/* * Returns the first drive letter for a volume located on the drive identified by DriveIndex */ char GetDriveLetter(DWORD DriveIndex) { DWORD size; BOOL r; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; UINT drive_type; HANDLE hDrive = INVALID_HANDLE_VALUE; char *drive, drives[26*4]; /* "D:\", "E:\", etc. */ char logical_drive[] = "\\\\.\\#:"; char drive_letter = ' '; CheckDriveIndex(DriveIndex); size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ drive_type = GetDriveTypeA(drive); // NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default // Using Alt-F in Rufus does enable listing, but this mode is unsupported. if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED))) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &size, NULL); safe_closehandle(hDrive); if ((!r) || (size <= 0)) { uprintf("Could not get device number for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { drive_letter = *drive; break; } } out: return drive_letter; }
/* * Returns the drive letters for all volumes located on the drive identified by DriveIndex, * as well as the drive type. This is used as base for the 2 function calls that follow. */ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT* drive_type) { DWORD size; BOOL r = FALSE; HANDLE hDrive = INVALID_HANDLE_VALUE; UINT _drive_type; int i = 0, drive_number; char *drive, drives[26*4 + 1]; /* "D:\", "E:\", etc., plus one NUL */ char logical_drive[] = "\\\\.\\#:"; if (drive_letters != NULL) drive_letters[0] = 0; if (drive_type != NULL) *drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); // This call is weird... The buffer needs to have an extra NUL, but you're // supposed to provide the size without the extra NUL. And the returned size // does not include the NUL either *EXCEPT* if your buffer is too small... // But then again, this doesn't hold true if you have a 105 byte buffer and // pass a 4*26=104 size, as the the call will return 105 (i.e. *FAILURE*) // instead of 104 as it should => screw Microsoft: We'll include the NUL // always, as each drive string is at least 4 chars long anyway. size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: Buffer too small (required %d vs. %d)\n", size, sizeof(drives)); goto out; } r = TRUE; // Required to detect drives that don't have volumes assigned for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } // IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is // not unique! An HDD, a DVD and probably other drives can have the same // value there => Use GetDriveType() to filter out unwanted devices. // See https://github.com/pbatard/rufus/issues/32#issuecomment-3785956 _drive_type = GetDriveTypeA(drive); if ((_drive_type != DRIVE_REMOVABLE) && (_drive_type != DRIVE_FIXED)) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDrive == INVALID_HANDLE_VALUE) { // uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } drive_number = GetDriveNumber(hDrive, logical_drive); safe_closehandle(hDrive); if (drive_number == DriveIndex) { r = TRUE; if (drive_letters != NULL) drive_letters[i++] = *drive; // The drive type should be the same for all volumes, so we can overwrite if (drive_type != NULL) *drive_type = _drive_type; } } out: if (drive_letters != NULL) drive_letters[i] = 0; return r; }
// Returns 0 on success, nonzero on error static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path) { HANDLE file_handle = NULL; DWORD buf_size, wr_size; BOOL r, is_syslinux_cfg, is_old_vesamenu; int i_length; size_t i, nul_pos; char* psz_fullpath = NULL; const char* psz_basename; udf_dirent_t *p_udf_dirent2; uint8_t buf[UDF_BLOCKSIZE]; int64_t i_read, i_file_length; if ((p_udf_dirent == NULL) || (psz_path == NULL)) return 1; while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) { if (FormatStatus) goto out; psz_basename = udf_get_filename(p_udf_dirent); i_length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir) + 24); psz_fullpath = (char*)calloc(sizeof(char), i_length); if (psz_fullpath == NULL) { uprintf("Error allocating file name\n"); goto out; } i_length = safe_sprintf(psz_fullpath, i_length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename); if (i_length < 0) { goto out; } if (udf_is_dir(p_udf_dirent)) { if (!scan_only) _mkdirU(psz_fullpath); p_udf_dirent2 = udf_opendir(p_udf_dirent); if (p_udf_dirent2 != NULL) { if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)])) goto out; } } else { i_file_length = udf_get_file_length(p_udf_dirent); if (check_iso_props(psz_path, &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) { safe_free(psz_fullpath); continue; } // Replace slashes with backslashes and append the size to the path for UI display nul_pos = safe_strlen(psz_fullpath); for (i=0; i<nul_pos; i++) if (psz_fullpath[i] == '/') psz_fullpath[i] = '\\'; safe_strcpy(&psz_fullpath[nul_pos], 24, size_to_hr(i_file_length)); uprintf("Extracting: %s\n", psz_fullpath); SetWindowTextU(hISOFileName, psz_fullpath); // Remove the appended size for extraction psz_fullpath[nul_pos] = 0; if (is_old_vesamenu && use_own_vesamenu) { if (CopyFileA("vesamenu.c32", psz_fullpath, FALSE)) { uprintf(" Replaced with local version\n"); continue; } uprintf(" Could not replace file: %s\n", WindowsErrorString()); } file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) { uprintf(" Unable to create file: %s\n", WindowsErrorString()); goto out; } while (i_file_length > 0) { if (FormatStatus) goto out; memset(buf, 0, UDF_BLOCKSIZE); i_read = udf_read_block(p_udf_dirent, buf, 1); if (i_read < 0) { uprintf(" Error reading UDF file %s\n", &psz_fullpath[strlen(psz_extract_dir)]); goto out; } buf_size = (DWORD)MIN(i_file_length, i_read); ISO_BLOCKING(r = WriteFile(file_handle, buf, buf_size, &wr_size, NULL)); if ((!r) || (buf_size != wr_size)) { uprintf(" Error writing file: %s\n", WindowsErrorString()); goto out; } i_file_length -= i_read; if (nb_blocks++ % PROGRESS_THRESHOLD == 0) { SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks); } } // If you have a fast USB 3.0 device, the default Windows buffering does an // excellent job at compensating for our small blocks read/writes to max out the // device's bandwidth. // The drawback however is with cancellation. With a large file, CloseHandle() // may take forever to complete and is not interruptible. We try to detect this. ISO_BLOCKING(safe_closehandle(file_handle)); if (is_syslinux_cfg) { // Workaround for isolinux config files requiring an ISO label for kernel // append that may be different from our USB label. if (replace_in_token_data(psz_fullpath, "append", iso_report.label, iso_report.usb_label, TRUE) != NULL) uprintf("Patched %s: '%s' -> '%s'\n", psz_fullpath, iso_report.label, iso_report.usb_label); } } safe_free(psz_fullpath); } return 0; out: if (p_udf_dirent != NULL) udf_dirent_free(p_udf_dirent); ISO_BLOCKING(safe_closehandle(file_handle)); safe_free(psz_fullpath); return 1; }