diff --git a/src/base/base_strings.c b/src/base/base_strings.c index dffc8da4..5a4b91fa 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -946,11 +946,11 @@ str8_array_from_list(Arena *arena, String8List *list) { String8Array array; array.count = list->node_count; - array.strings = push_array_no_zero(arena, String8, array.count); + array.v = push_array_no_zero(arena, String8, array.count); U64 idx = 0; for(String8Node *n = list->first; n != 0; n = n->next, idx += 1) { - array.strings[idx] = n->string; + array.v[idx] = n->string; } return array; } @@ -960,7 +960,7 @@ str8_array_reserve(Arena *arena, U64 count) { String8Array arr; arr.count = 0; - arr.strings = push_array(arena, String8, count); + arr.v = push_array(arena, String8, count); return arr; } diff --git a/src/base/base_strings.h b/src/base/base_strings.h index e4261089..839694d0 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -63,7 +63,7 @@ struct String8List typedef struct String8Array String8Array; struct String8Array { - String8 *strings; + String8 *v; U64 count; }; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 2da7554b..07717234 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -2811,12 +2811,9 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) if(ui_clicked(sig)) { String8 new_path = str8_chop_last_slash(str8_chop_last_slash(path_query.path)); - if(new_path.size != 0) - { - new_path = path_normalized_from_string(scratch.arena, new_path); - String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path); - df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); - } + new_path = path_normalized_from_string(scratch.arena, new_path); + String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); + df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); } } @@ -2893,11 +2890,11 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) if(ui_clicked(file_sig)) { String8 existing_path = str8_chop_last_slash(path_query.path); - String8 new_path = push_str8f(scratch.arena, "%S/%S/", existing_path, file->filename); + String8 new_path = push_str8f(scratch.arena, "%S%s%S/", existing_path, existing_path.size != 0 ? "/" : "", file->filename); new_path = path_normalized_from_string(scratch.arena, new_path); if(file->props.flags & FilePropertyFlag_IsFolder) { - String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path); + String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); } else diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index ea8863da..d618d405 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -34,7 +34,7 @@ typedef struct OS_FileIter OS_FileIter; struct OS_FileIter { OS_FileIterFlags flags; - U8 memory[600]; + U8 memory[800]; }; typedef struct OS_FileInfo OS_FileInfo; diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index b6c33613..47b4a7b3 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -198,7 +198,7 @@ os_init(void) w32_VirtualAlloc2_func = (W32_VirtualAlloc2_Type*)GetProcAddress(module, "VirtualAlloc2"); w32_MapViewOfFile3_func = (W32_MapViewOfFile3_Type*)GetProcAddress(module, "MapViewOfFile3"); w32_SetThreadDescription_func = (W32_SetThreadDescription_Type*)GetProcAddress(module, "SetThreadDescription"); - + FreeLibrary(module); } } @@ -964,7 +964,27 @@ os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags) OS_FileIter *iter = push_array(arena, OS_FileIter, 1); iter->flags = flags; W32_FileIter *w32_iter = (W32_FileIter*)iter->memory; - w32_iter->handle = FindFirstFileW((WCHAR*)path16.str, &w32_iter->find_data); + if(path.size == 0) + { + w32_iter->is_volume_iter = 1; + WCHAR buffer[512] = {0}; + DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer); + String8List drive_strings = {0}; + for(U64 off = 0; off < (U64)length;) + { + String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off); + off += next_drive_string_16.size+1; + String8 next_drive_string = str8_from_16(arena, next_drive_string_16); + next_drive_string = str8_chop_last_slash(next_drive_string); + str8_list_push(scratch.arena, &drive_strings, next_drive_string); + } + w32_iter->drive_strings = str8_array_from_list(arena, &drive_strings); + w32_iter->drive_strings_iter_idx = 0; + } + else + { + w32_iter->handle = FindFirstFileW((WCHAR*)path16.str, &w32_iter->find_data); + } scratch_end(scratch); return iter; } @@ -975,55 +995,76 @@ os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out) B32 result = 0; OS_FileIterFlags flags = iter->flags; W32_FileIter *w32_iter = (W32_FileIter*)iter->memory; - if (!(flags & OS_FileIterFlag_Done) && w32_iter->handle != INVALID_HANDLE_VALUE) + switch(w32_iter->is_volume_iter) { - do + //- rjf: file iteration + default: + case 0: { - // check is usable - B32 usable_file = 1; - - WCHAR *file_name = w32_iter->find_data.cFileName; - DWORD attributes = w32_iter->find_data.dwFileAttributes; - if (file_name[0] == '.'){ - if (flags & OS_FileIterFlag_SkipHiddenFiles){ - usable_file = 0; - } - else if (file_name[1] == 0){ - usable_file = 0; - } - else if (file_name[1] == '.' && file_name[2] == 0){ - usable_file = 0; - } + if (!(flags & OS_FileIterFlag_Done) && w32_iter->handle != INVALID_HANDLE_VALUE) + { + do + { + // check is usable + B32 usable_file = 1; + + WCHAR *file_name = w32_iter->find_data.cFileName; + DWORD attributes = w32_iter->find_data.dwFileAttributes; + if (file_name[0] == '.'){ + if (flags & OS_FileIterFlag_SkipHiddenFiles){ + usable_file = 0; + } + else if (file_name[1] == 0){ + usable_file = 0; + } + else if (file_name[1] == '.' && file_name[2] == 0){ + usable_file = 0; + } + } + if (attributes & FILE_ATTRIBUTE_DIRECTORY){ + if (flags & OS_FileIterFlag_SkipFolders){ + usable_file = 0; + } + } + else{ + if (flags & OS_FileIterFlag_SkipFiles){ + usable_file = 0; + } + } + + // emit if usable + if (usable_file){ + info_out->name = str8_from_16(arena, str16_cstring((U16*)file_name)); + info_out->props.size = (U64)w32_iter->find_data.nFileSizeLow | (((U64)w32_iter->find_data.nFileSizeHigh)<<32); + w32_dense_time_from_file_time(&info_out->props.created, &w32_iter->find_data.ftCreationTime); + w32_dense_time_from_file_time(&info_out->props.modified, &w32_iter->find_data.ftLastWriteTime); + info_out->props.flags = w32_file_property_flags_from_dwFileAttributes(attributes); + result = 1; + if (!FindNextFileW(w32_iter->handle, &w32_iter->find_data)){ + iter->flags |= OS_FileIterFlag_Done; + } + break; + } + }while(FindNextFileW(w32_iter->handle, &w32_iter->find_data)); } - if (attributes & FILE_ATTRIBUTE_DIRECTORY){ - if (flags & OS_FileIterFlag_SkipFolders){ - usable_file = 0; - } - } - else{ - if (flags & OS_FileIterFlag_SkipFiles){ - usable_file = 0; - } - } - - // emit if usable - if (usable_file){ - info_out->name = str8_from_16(arena, str16_cstring((U16*)file_name)); - info_out->props.size = (U64)w32_iter->find_data.nFileSizeLow | (((U64)w32_iter->find_data.nFileSizeHigh)<<32); - w32_dense_time_from_file_time(&info_out->props.created, &w32_iter->find_data.ftCreationTime); - w32_dense_time_from_file_time(&info_out->props.modified, &w32_iter->find_data.ftLastWriteTime); - info_out->props.flags = w32_file_property_flags_from_dwFileAttributes(attributes); - result = 1; - if (!FindNextFileW(w32_iter->handle, &w32_iter->find_data)){ - iter->flags |= OS_FileIterFlag_Done; - } - break; - } - }while(FindNextFileW(w32_iter->handle, &w32_iter->find_data)); + }break; - if (!result){ - iter->flags |= OS_FileIterFlag_Done; - } + //- rjf: volume iteration + case 1: + { + result = w32_iter->drive_strings_iter_idx < w32_iter->drive_strings.count; + if(result != 0) + { + MemoryZeroStruct(info_out); + info_out->name = w32_iter->drive_strings.v[w32_iter->drive_strings_iter_idx]; + info_out->props.flags |= FilePropertyFlag_IsFolder; + w32_iter->drive_strings_iter_idx += 1; + } + }break; + } + if(!result) + { + iter->flags |= OS_FileIterFlag_Done; } return result; } diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h index 90794b7a..0b104f58 100644 --- a/src/os/core/win32/os_core_win32.h +++ b/src/os/core/win32/os_core_win32.h @@ -23,6 +23,9 @@ struct W32_FileIter { HANDLE handle; WIN32_FIND_DATAW find_data; + B32 is_volume_iter; + String8Array drive_strings; + U64 drive_strings_iter_idx; }; StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(W32_FileIter), file_iter_memory_size);