void FilePanel::scan_dir( const std::string& root_path, const std::string& rel_path, std::list<PanelItemData>& pid_list, FileListProgress& progress ) { std::string path = add_trailing_slash( root_path ) + rel_path; bool more = true; WIN32_FIND_DATAW find_data; HANDLE h_find = FindFirstFileW( long_path( add_trailing_slash( path ) + L"*" ).data( ), &find_data ); try { if ( h_find == INVALID_HANDLE_VALUE ) { // special case: symlink that denies access to directory, try real path if ( GetLastError( ) == ERROR_ACCESS_DENIED ) { DWORD attr = GetFileAttributesW( long_path( path ).data( ) ); CHECK_SYS( attr != INVALID_FILE_ATTRIBUTES ); if ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) { h_find = FindFirstFileW( long_path( add_trailing_slash( get_real_path( path ) ) + L"*" ).data( ), &find_data ); } else CHECK_SYS( false ); } } if ( h_find == INVALID_HANDLE_VALUE ) { CHECK_SYS( GetLastError( ) == ERROR_NO_MORE_FILES ); more = false; } } catch ( ... ) { if ( flat_mode ) { more = false; } else throw; } ALLOC_RSRC( ; );
TempFile::TempFile() { Buffer<wchar_t> buf(MAX_PATH); DWORD len = GetTempPathW(static_cast<DWORD>(buf.size()), buf.data()); CHECK(len <= buf.size()); CHECK_SYS(len); wstring temp_path = wstring(buf.data(), len); CHECK_SYS(GetTempFileNameW(temp_path.c_str(), L"", 0, buf.data())); path.assign(buf.data()); }
wstring format_file_time(const FILETIME& file_time) { FILETIME local_ft; CHECK_SYS(FileTimeToLocalFileTime(&file_time, &local_ft)); SYSTEMTIME st; CHECK_SYS(FileTimeToSystemTime(&local_ft, &st)); Buffer<wchar_t> buf(1024); CHECK_SYS(GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, nullptr, buf.data(), static_cast<int>(buf.size()))); wstring date_str = buf.data(); CHECK_SYS(GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, nullptr, buf.data(), static_cast<int>(buf.size()))); wstring time_str = buf.data(); return date_str + L' ' + time_str; }
FindData get_find_data(const wstring& path) { FindData find_data; HANDLE h_find = FindFirstFileW(long_path(path).c_str(), &find_data); CHECK_SYS(h_find != INVALID_HANDLE_VALUE); FindClose(h_find); return find_data; }
wstring get_temp_path() { Buffer<wchar_t> buf(MAX_PATH); DWORD len = GetTempPathW(static_cast<DWORD>(buf.size()), buf.data()); CHECK(len <= buf.size()); CHECK_SYS(len); return wstring(buf.data(), len); }
WindowClass::WindowClass(const wstring& name, WindowProc window_proc): name(name) { WNDCLASSW wndclass; memset(&wndclass, 0, sizeof(wndclass)); wndclass.lpfnWndProc = window_proc; wndclass.cbWndExtra = sizeof(this); wndclass.hInstance = g_h_instance; wndclass.lpszClassName = name.c_str(); CHECK_SYS(RegisterClassW(&wndclass)); }
bool wait_for_single_object(HANDLE handle, DWORD timeout) { DWORD res = WaitForSingleObject(handle, timeout); CHECK_SYS(res != WAIT_FAILED); if (res == WAIT_OBJECT_0) return true; else if (res == WAIT_TIMEOUT) return false; else FAIL(E_FAIL); }
wstring ansi_to_unicode(const string& str, unsigned code_page) { unsigned str_size = static_cast<unsigned>(str.size()); if (str_size == 0) return wstring(); int size = MultiByteToWideChar(code_page, 0, str.data(), str_size, nullptr, 0); Buffer<wchar_t> out(size); size = MultiByteToWideChar(code_page, 0, str.data(), str_size, out.data(), size); CHECK_SYS(size); return wstring(out.data(), size); }
string unicode_to_ansi(const wstring& str, unsigned code_page) { unsigned str_size = static_cast<unsigned>(str.size()); if (str_size == 0) return string(); int size = WideCharToMultiByte(code_page, 0, str.data(), str_size, nullptr, 0, nullptr, nullptr); Buffer<char> out(size); size = WideCharToMultiByte(code_page, 0, str.data(), str_size, out.data(), size, nullptr, nullptr); CHECK_SYS(size); return string(out.data(), size); }
wstring expand_env_vars(const wstring& str) { Buffer<wchar_t> buf(MAX_PATH); unsigned size = ExpandEnvironmentStringsW(str.c_str(), buf.data(), static_cast<DWORD>(buf.size())); if (size > buf.size()) { buf.resize(size); size = ExpandEnvironmentStringsW(str.c_str(), buf.data(), static_cast<DWORD>(buf.size())); } CHECK_SYS(size); return wstring(buf.data(), size - 1); }
wstring get_full_path_name(const wstring& path) { Buffer<wchar_t> buf(MAX_PATH); DWORD size = GetFullPathNameW(path.c_str(), static_cast<DWORD>(buf.size()), buf.data(), nullptr); if (size > buf.size()) { buf.resize(size); size = GetFullPathNameW(path.c_str(), static_cast<DWORD>(buf.size()), buf.data(), nullptr); } CHECK_SYS(size); return wstring(buf.data(), size); }
wstring get_current_directory() { Buffer<wchar_t> buf(MAX_PATH); DWORD size = GetCurrentDirectoryW(static_cast<DWORD>(buf.size()), buf.data()); if (size > buf.size()) { buf.resize(size); size = GetCurrentDirectoryW(static_cast<DWORD>(buf.size()), buf.data()); } CHECK_SYS(size); return wstring(buf.data(), size); }
bool next( ) { if ( h_enum == INVALID_HANDLE_VALUE ) { h_enum = FindFirstVolumeW( volume_path.get( ), c_buf_size ); if ( h_enum == INVALID_HANDLE_VALUE ) { if ( GetLastError( ) == ERROR_NO_MORE_FILES ) { return false; } CHECK_SYS( false ); } } else { BOOL res = FindNextVolumeW( h_enum, volume_path.get( ), c_buf_size ); if ( !res ) { if ( GetLastError( ) == ERROR_NO_MORE_FILES ) { return false; } CHECK_SYS( false ); } } return true; }
wstring search_path(const wstring& file_name) { Buffer<wchar_t> path(MAX_PATH); wchar_t* name_ptr; DWORD size = SearchPathW(nullptr, file_name.c_str(), nullptr, path.size(), path.data(), &name_ptr); if (size > path.size()) { path.resize(size); size = SearchPathW(nullptr, file_name.c_str(), nullptr, path.size(), path.data(), &name_ptr); } CHECK_SYS(size); CHECK(size < path.size()); return wstring(path.data(), size); }
IconRsrc load_icon_rsrc(HMODULE h_module, LPCTSTR name, WORD lang_id) { IconRsrc icon_rsrc; icon_rsrc.id = name; icon_rsrc.lang_id = lang_id; HRSRC h_rsrc = FindResourceEx(h_module, RT_GROUP_ICON, name, lang_id); CHECK_SYS(h_rsrc); HGLOBAL h_global = LoadResource(h_module, h_rsrc); CHECK_SYS(h_global); unsigned char* res_data = static_cast<unsigned char*>(LockResource(h_global)); CHECK_SYS(res_data); const IconGroupHeader* header = reinterpret_cast<const IconGroupHeader*>(res_data); for (unsigned i = 0; i < header->count; i++) { IconImageRsrc image_rsrc; const IconGroupEntry* entry = reinterpret_cast<const IconGroupEntry*>(res_data + sizeof(IconGroupHeader) + i * sizeof(IconGroupEntry)); image_rsrc.id = entry->id; image_rsrc.lang_id = lang_id; image_rsrc.image.width = entry->width; image_rsrc.image.height = entry->height; image_rsrc.image.color_cnt = entry->color_cnt; image_rsrc.image.plane_cnt = entry->plane_cnt; image_rsrc.image.bit_cnt = entry->bit_cnt; HRSRC h_rsrc = FindResourceEx(h_module, RT_ICON, MAKEINTRESOURCE(entry->id), lang_id); CHECK_SYS(h_rsrc); HGLOBAL h_global = LoadResource(h_module, h_rsrc); CHECK_SYS(h_global); unsigned char* icon_data = static_cast<unsigned char*>(LockResource(h_global)); CHECK_SYS(icon_data); image_rsrc.image.bitmap.assign(icon_data, icon_data + entry->size); icon_rsrc.images.push_back(image_rsrc); } return icon_rsrc; }
unsigned MessageWindow::message_loop(HANDLE h_abort) { while (true) { DWORD res = MsgWaitForMultipleObjects(1, &h_abort, FALSE, INFINITE, QS_POSTMESSAGE | QS_SENDMESSAGE); CHECK_SYS(res != WAIT_FAILED); if (res == WAIT_OBJECT_0) { FAIL(E_ABORT); } else if (res == WAIT_OBJECT_0 + 1) { MSG msg; while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return static_cast<unsigned>(msg.wParam); } } else FAIL(E_FAIL); } }
bool next( ) { if ( ptr == nullptr ) { unsigned buf_size = MAX_PATH; drives.reset( new wchar_t[ buf_size ] ); DWORD len = GetLogicalDriveStringsW( buf_size, drives.get( ) ); if ( len > buf_size ) { buf_size = len; drives.reset( new wchar_t[ buf_size ] ); len = GetLogicalDriveStringsW( buf_size, drives.get( ) ); } CHECK_SYS( len ); ptr = drives.get( ); } else { ptr = ptr + wcslen( ptr ) + 1; } return *ptr != 0; }
list<wstring> get_volume_mount_points( const wstring& volume_guid_path ) { unsigned buf_size = MAX_PATH; unique_ptr<wchar_t[ ]> buffer( new wchar_t[ buf_size ] ); DWORD len; BOOL res = GetVolumePathNamesForVolumeNameW( add_trailing_slash( volume_guid_path ).c_str( ), buffer.get( ), buf_size, &len ); if ( !res ) { if ( GetLastError( ) == ERROR_MORE_DATA ) { buf_size = len; buffer.reset( new wchar_t[ buf_size ] ); res = GetVolumePathNamesForVolumeNameW( add_trailing_slash( volume_guid_path ).c_str( ), buffer.get( ), buf_size, &len ); } CHECK_SYS( res ); } list<wstring> result; const wchar_t* path = buffer.get( ); while ( *path ) { unsigned len = wcslen( path ); result.push_back( wstring( path, len ) ); path += len + 1; } return result; }
u64 FileInfo::load_mft_record(u64 mft_rec_num, Array<u8>& ntfs_file_rec_buf) { NTFS_FILE_RECORD_INPUT_BUFFER ntfs_file_rec_in; ntfs_file_rec_in.FileReferenceNumber.QuadPart = mft_rec_num; unsigned ntfs_file_rec_out_size = NTFS_FILE_REC_HEADER_SIZE + volume->file_rec_size; DWORD bytes_ret; CHECK_SYS(DeviceIoControl(volume->handle, FSCTL_GET_NTFS_FILE_RECORD, &ntfs_file_rec_in, sizeof(ntfs_file_rec_in), ntfs_file_rec_buf.buf(ntfs_file_rec_out_size), ntfs_file_rec_out_size, &bytes_ret, NULL)); ntfs_file_rec_buf.set_size(bytes_ret); CHECK_FMT(ntfs_file_rec_buf.size() >= NTFS_FILE_REC_HEADER_SIZE); const NTFS_FILE_RECORD_OUTPUT_BUFFER* ntfs_file_rec_out = reinterpret_cast<const NTFS_FILE_RECORD_OUTPUT_BUFFER*>(ntfs_file_rec_buf.data()); CHECK_FMT(ntfs_file_rec_buf.size() == NTFS_FILE_REC_HEADER_SIZE + ntfs_file_rec_out->FileRecordLength); CHECK_FMT(ntfs_file_rec_out->FileRecordLength >= sizeof(MFT_RECORD)); mft_rec_num = FILE_REF(ntfs_file_rec_out->FileReferenceNumber.QuadPart); ntfs_file_rec_buf.remove(0, NTFS_FILE_REC_HEADER_SIZE); const MFT_RECORD* mft_rec = reinterpret_cast<const MFT_RECORD*>(ntfs_file_rec_buf.data()); CHECK_FMT(mft_rec->magic == magic_FILE); return mft_rec_num; }
void finalize() { CHECK_SYS(EndUpdateResource(handle, FALSE)); handle = nullptr; }
void Key::delete_sub_key(const wchar_t* name) { CHECK_SYS(delete_sub_key_nt(name)); }
ResourceUpdate(const wstring& file_path) { handle = BeginUpdateResource(file_path.c_str(), FALSE); CHECK_SYS(handle); }
void update(const wchar_t* type, const wchar_t* name, WORD lang_id, const unsigned char* data, DWORD size) { assert(handle); CHECK_SYS(UpdateResource(handle, type, name, lang_id, reinterpret_cast<LPVOID>(const_cast<unsigned char*>(data)), size)); }
void Key::set_int(const wchar_t* name, unsigned value) { CHECK_SYS(set_int_nt(name, value)); }
RsrcModule(const wstring& file_path) { h_module = LoadLibraryEx(file_path.c_str(), nullptr, LOAD_LIBRARY_AS_DATAFILE); CHECK_SYS(h_module); }
void Key::set_str(const wchar_t* name, const wstring& value) { CHECK_SYS(set_str_nt(name, value)); }
void Key::set_binary(const wchar_t* name, const unsigned char* value, unsigned size) { CHECK_SYS(set_binary_nt(name, value, size)); }
void Key::delete_value(const wchar_t* name) { CHECK_SYS(delete_value_nt(name)); }
vector<wstring> Key::enum_sub_keys() { vector<wstring> names; CHECK_SYS(enum_sub_keys_nt(names)); return names; }
TempFile::TempFile() { Buffer<wchar_t> buf(MAX_PATH); wstring temp_path = get_temp_path(); CHECK_SYS(GetTempFileNameW(temp_path.c_str(), L"", 0, buf.data())); path.assign(buf.data()); }