mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-15 16:42:23 -07:00
added /RAD_WRITE_TEMP_FILES
When enabled linker writes image and debug info to temporary files and renames them after all writes are done.
This commit is contained in:
+16
-11
@@ -358,7 +358,7 @@ lnk_manifest_from_inputs(Arena *arena,
|
||||
|
||||
// write linker manifest to temp file
|
||||
String8 linker_manifest_path = push_str8f(scratch.arena, "%S.manifest.temp", manifest_name);
|
||||
lnk_write_data_to_file_path(linker_manifest_path, linker_manifest);
|
||||
lnk_write_data_to_file_path(linker_manifest_path, str8_zero(), linker_manifest);
|
||||
|
||||
// push linker manifest
|
||||
str8_list_push(scratch.arena, &input_manifest_path_list, linker_manifest_path);
|
||||
@@ -3079,7 +3079,7 @@ lnk_write_thread(void *raw_ctx)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
LNK_WriteThreadContext *ctx = raw_ctx;
|
||||
lnk_write_data_to_file_path(ctx->path, ctx->data);
|
||||
lnk_write_data_to_file_path(ctx->path, ctx->temp_path, ctx->data);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
@@ -3254,7 +3254,7 @@ lnk_run(int argc, char **argv)
|
||||
LNK_ObjList obj_list = {0};
|
||||
LNK_LibList lib_index[LNK_InputSource_Count] = {0};
|
||||
String8 image_data = str8_zero();
|
||||
OS_Handle image_write_thread = {0};
|
||||
OS_Handle image_write_thread = {0};
|
||||
|
||||
// init state machine
|
||||
struct StateList state_list = {0};
|
||||
@@ -3763,7 +3763,7 @@ lnk_run(int argc, char **argv)
|
||||
ProfBeginDynamic("Write Manifest To: %.*s", str8_varg(config->manifest_name));
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
String8 manifest_data = lnk_manifest_from_inputs(temp.arena, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, input_manifest_path_list, manifest_dep_list);
|
||||
lnk_write_data_to_file_path(config->manifest_name, manifest_data);
|
||||
lnk_write_data_to_file_path(config->manifest_name, str8_zero(), manifest_data);
|
||||
temp_end(temp);
|
||||
ProfEnd();
|
||||
} break;
|
||||
@@ -4080,10 +4080,14 @@ lnk_run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
LNK_WriteThreadContext *ctx = push_array(scratch.arena, LNK_WriteThreadContext, 1);
|
||||
ctx->path = config->image_name;
|
||||
ctx->data = image_data;
|
||||
image_write_thread = os_thread_launch(lnk_write_thread, ctx, 0);
|
||||
// write image file in background
|
||||
{
|
||||
LNK_WriteThreadContext *ctx = push_array(scratch.arena, LNK_WriteThreadContext, 1);
|
||||
ctx->path = config->image_name;
|
||||
ctx->temp_path = config->temp_image_name;
|
||||
ctx->data = image_data;
|
||||
image_write_thread = os_thread_launch(lnk_write_thread, ctx, 0);
|
||||
}
|
||||
|
||||
if (lnk_get_log_status(LNK_Log_InputObj)) {
|
||||
U64 total_input_size = 0;
|
||||
@@ -4110,7 +4114,7 @@ lnk_run(int argc, char **argv)
|
||||
ProfBegin("Build Imp Lib");
|
||||
lnk_timer_begin(LNK_Timer_Lib);
|
||||
String8List lib_list = lnk_build_import_lib(tp, tp_arena, config->machine, config->time_stamp, config->imp_lib_name, config->image_name, exptab);
|
||||
lnk_write_data_list_to_file_path(config->imp_lib_name, lib_list);
|
||||
lnk_write_data_list_to_file_path(config->imp_lib_name, str8_zero(), lib_list);
|
||||
lnk_timer_end(LNK_Timer_Lib);
|
||||
ProfEnd();
|
||||
} break;
|
||||
@@ -4143,7 +4147,8 @@ lnk_run(int argc, char **argv)
|
||||
input.parsed_symbols,
|
||||
types);
|
||||
|
||||
lnk_write_data_list_to_file_path(config->rad_debug_name, rdi_data);
|
||||
lnk_write_data_list_to_file_path(config->rad_debug_name, config->temp_rad_debug_name, rdi_data);
|
||||
|
||||
lnk_timer_end(LNK_Timer_Rdi);
|
||||
}
|
||||
|
||||
@@ -4177,7 +4182,7 @@ lnk_run(int argc, char **argv)
|
||||
input.parsed_symbols,
|
||||
types);
|
||||
|
||||
lnk_write_data_list_to_file_path(config->pdb_name, pdb_data);
|
||||
lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data);
|
||||
lnk_timer_end(LNK_Timer_Pdb);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
String8 path;
|
||||
String8 temp_path;
|
||||
String8 data;
|
||||
} LNK_WriteThreadContext;
|
||||
|
||||
|
||||
+13
-2
@@ -152,17 +152,17 @@ global read_only struct
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNames, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." },
|
||||
{ LNK_CmdSwitch_Rad_SectVirtOff, "RAD_SECT_VIRT_OFF", ":#", "Set RVA where section data is placed in memory. For internal use only." },
|
||||
{ LNK_CmdSwitch_Rad_SharedThreadPool, "RAD_SHARED_THREAD_POOL", "[:STRING]", "Default value \"" LNK_DEFAULT_THREAD_POOL_NAME "\"" },
|
||||
{ LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Sets maximum number of workers in a thread pool." },
|
||||
{ LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Sets maximum number of workers in a thread pool." },
|
||||
{ LNK_CmdSwitch_Rad_SuppressError, "RAD_SUPPRESS_ERROR", ":#", "" },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapDefined, "RAD_SYMBOL_TABLE_CAP_DEFINED", ":#", "Number of buckets allocated in the symbol table for defined symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapInternal, "RAD_SYMBOL_TABLE_CAP_INTERNAL", ":#", "Number of buckets allocated in the symbol table for internal symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapLib, "RAD_SYMBOL_TABLE_CAP_LIB", ":#", "Number of buckets allocated in the symbol table for library symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapWeak, "RAD_SYMBOL_TABLE_CAP_WEAK", ":#", "Number of buckets allocated in the symbol table for weak symbols." },
|
||||
{ LNK_CmdSwitch_Rad_TargetOs, "RAD_TARGET_OS", ":{WINDOWS,LINUX,MAC}" },
|
||||
{ LNK_CmdSwitch_Rad_WriteTempFiles, "RAD_WRITE_TEMP_FILES", "[:NO]", "When speicifed linker writes image and debug info to temporary files and renames after link is done." },
|
||||
{ LNK_CmdSwitch_Rad_TimeStamp, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." },
|
||||
{ LNK_CmdSwitch_Rad_Version, "RAD_VERSION", "", "Print version and exit." },
|
||||
{ LNK_CmdSwitch_Rad_Workers, "RAD_WORKERS", ":#", "Sets number of workers created in the pool. Number is capped at 1024. When /RAD_SHARED_THREAD_POOL is specified this number cant exceed /RAD_SHARED_THREAD_POOL_MAX_WORKERS." },
|
||||
|
||||
{ LNK_CmdSwitch_Help, "HELP", "", "" },
|
||||
{ LNK_CmdSwitch_Help, "?", "", "" },
|
||||
};
|
||||
@@ -1754,6 +1754,10 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
|
||||
}
|
||||
} break;
|
||||
|
||||
case LNK_CmdSwitch_Rad_WriteTempFiles: {
|
||||
lnk_cmd_switch_parse_flag(obj_path, lib_path, cmd_switch, value_strings, &config->write_temp_files);
|
||||
} break;
|
||||
|
||||
case LNK_CmdSwitch_Rad_TimeStamp: {
|
||||
lnk_cmd_switch_parse_u32(obj_path, lib_path, cmd_switch, value_strings, &config->time_stamp, 0);
|
||||
} break;
|
||||
@@ -2054,6 +2058,13 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line)
|
||||
// :Rad_DebugAltPath
|
||||
config->rad_debug_alt_path = lnk_expand_env_vars_windows(arena, env_vars, config->rad_debug_alt_path);
|
||||
|
||||
// create temporary files names
|
||||
if (config->write_temp_files == LNK_SwitchState_Yes) {
|
||||
config->temp_image_name = push_str8f(arena, "%S.tmp%x", config->image_name, config->time_stamp);
|
||||
config->temp_pdb_name = push_str8f(arena, "%S.tmp%x", config->pdb_name, config->time_stamp);
|
||||
config->temp_rad_debug_name = push_str8f(arena, "%S.tmp%x", config->rad_debug_name, config->time_stamp);
|
||||
}
|
||||
|
||||
if (lnk_get_log_status(LNK_Log_Debug)) {
|
||||
String8 full_cmd_line = str8_list_join(scratch.arena, &raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") });
|
||||
fprintf(stderr, "--------------------------------------------------------------------------------\n");
|
||||
|
||||
@@ -155,6 +155,7 @@ typedef enum
|
||||
LNK_CmdSwitch_Rad_SymbolTableCapInternal,
|
||||
LNK_CmdSwitch_Rad_SymbolTableCapWeak,
|
||||
LNK_CmdSwitch_Rad_SymbolTableCapLib,
|
||||
LNK_CmdSwitch_Rad_WriteTempFiles,
|
||||
LNK_CmdSwitch_Rad_TargetOs,
|
||||
LNK_CmdSwitch_Rad_TimeStamp,
|
||||
LNK_CmdSwitch_Rad_Version,
|
||||
@@ -364,6 +365,10 @@ typedef struct LNK_Config
|
||||
U64 symbol_table_cap_lib;
|
||||
B32 build_imp_lib;
|
||||
B32 build_exp;
|
||||
LNK_SwitchState write_temp_files;
|
||||
String8 temp_image_name;
|
||||
String8 temp_pdb_name;
|
||||
String8 temp_rad_debug_name;
|
||||
} LNK_Config;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -2676,7 +2676,7 @@ lnk_replace_type_names_with_hashes(TP_Context *tp, TP_Arena *arena, CV_DebugT de
|
||||
if (task.make_map) {
|
||||
String8List map = {0};
|
||||
str8_list_concat_in_place_array(&map, task.maps, tp->worker_count);
|
||||
lnk_write_data_list_to_file_path(map_name, map);
|
||||
lnk_write_data_list_to_file_path(map_name, str8_zero(), map);
|
||||
tp_arena_release(&task.map_arena);
|
||||
}
|
||||
|
||||
|
||||
+56
-17
@@ -10,6 +10,15 @@ lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t
|
||||
return !os_handle_match(handle, os_handle_zero());
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
||||
{
|
||||
OS_Handle handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, str8((U8*)path, path_size));
|
||||
Assert(sizeof(handle) <= handle_buffer_max);
|
||||
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
||||
return !os_handle_match(handle, os_handle_zero());
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
||||
{
|
||||
@@ -26,6 +35,14 @@ lnk_close_file(void *raw_handle)
|
||||
os_file_close(handle);
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size)
|
||||
{
|
||||
OS_Handle handle = *(OS_Handle *)raw_handle;
|
||||
B32 is_renamed = os_rename_file_by_handle(handle, str8((U8*)new_file_path, new_file_path_size));
|
||||
return (int)is_renamed;
|
||||
}
|
||||
|
||||
shared_function uint64_t
|
||||
lnk_size_from_file(void *raw_handle)
|
||||
{
|
||||
@@ -163,34 +180,56 @@ lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_write_data_list_to_file_path(String8 path, String8List data)
|
||||
lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List data)
|
||||
{
|
||||
ProfBeginV("Write %M to %S", data.total_size, path);
|
||||
|
||||
B32 is_written = 0;
|
||||
U64 bytes_written = 0;
|
||||
|
||||
OS_Handle handle;
|
||||
if (lnk_open_file_write((char*)path.str, path.size, &handle, sizeof(handle))) {
|
||||
U64 offset = 0;
|
||||
for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) {
|
||||
U64 write_size = lnk_write_file(&handle, offset, data_n->string.str, data_n->string.size);
|
||||
if (write_size != data_n->string.size) {
|
||||
break;
|
||||
B32 open_with_rename = (temp_path.size > 0);
|
||||
OS_Handle file_handle = {0};
|
||||
if (open_with_rename) {
|
||||
lnk_open_file_write_rename((char*)temp_path.str, temp_path.size, &file_handle, sizeof(file_handle));
|
||||
} else {
|
||||
lnk_open_file_write((char*)path.str, path.size, &file_handle, sizeof(file_handle));
|
||||
}
|
||||
|
||||
if (!os_handle_match(file_handle, os_handle_zero())) {
|
||||
// write data nodes
|
||||
{
|
||||
for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) {
|
||||
U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size);
|
||||
if (write_size != data_n->string.size) {
|
||||
break;
|
||||
}
|
||||
bytes_written += data_n->string.size;
|
||||
}
|
||||
offset += data_n->string.size;
|
||||
}
|
||||
|
||||
lnk_close_file(&handle);
|
||||
B32 is_write_complete = (bytes_written == data.total_size);
|
||||
|
||||
is_written = (offset == data.total_size);
|
||||
if (is_written) {
|
||||
if (is_write_complete) {
|
||||
// rename file to original name
|
||||
if (open_with_rename) {
|
||||
if (lnk_rename_file(&file_handle, (char*)path.str, path.size)) {
|
||||
lnk_log(LNK_Log_IO_Write, "Renamed %S -> %S", temp_path, path);
|
||||
} else {
|
||||
lnk_error(LNK_Error_IO, "failed to rename %S -> %S", temp_path, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// log write
|
||||
if (is_write_complete) {
|
||||
if (lnk_get_log_status(LNK_Log_IO_Write)) {
|
||||
lnk_log(LNK_Log_IO_Write, "File \"%S\" %M written", path, data.total_size);
|
||||
}
|
||||
} else {
|
||||
lnk_error(LNK_Error_IO, "incomplete write occurred, %M written, expected %M, file %S",
|
||||
offset, data.total_size, path);
|
||||
lnk_error(LNK_Error_IO, "incomplete write, %M written, expected %M, file %S", bytes_written, data.total_size, path);
|
||||
}
|
||||
|
||||
// clean up handle
|
||||
lnk_close_file(&file_handle);
|
||||
} else {
|
||||
lnk_error(LNK_Error_NoAccess, "don't have access to write to %S", path);
|
||||
}
|
||||
@@ -199,12 +238,12 @@ lnk_write_data_list_to_file_path(String8 path, String8List data)
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_write_data_to_file_path(String8 path, String8 data)
|
||||
lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
String8List data_list = {0};
|
||||
str8_list_push(scratch.arena, &data_list, data);
|
||||
lnk_write_data_list_to_file_path(path, data_list);
|
||||
lnk_write_data_list_to_file_path(path, temp_path, data_list);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -17,7 +17,9 @@ typedef struct
|
||||
|
||||
shared_function int lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function int lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function void lnk_close_file(void *raw_handle);
|
||||
shared_function int lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size);
|
||||
shared_function uint64_t lnk_size_from_file(void *raw_handle);
|
||||
shared_function uint64_t lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max);
|
||||
shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size);
|
||||
@@ -27,8 +29,8 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void
|
||||
internal String8 lnk_read_data_from_file_path(Arena *arena, String8 path);
|
||||
internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array path_arr);
|
||||
|
||||
internal void lnk_write_data_list_to_file_path(String8 path, String8List list);
|
||||
internal void lnk_write_data_to_file_path(String8 path, String8 data);
|
||||
internal void lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List list);
|
||||
internal void lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data);
|
||||
|
||||
internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path);
|
||||
|
||||
|
||||
@@ -151,6 +151,16 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_rename_file(String8 orig_name, String8 new_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, orig_name);
|
||||
B32 is_renamed = os_rename_file_by_handle(file, new_name);
|
||||
os_file_close(file);
|
||||
return is_renamed;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
|
||||
+10
-7
@@ -38,13 +38,14 @@ struct OS_ProcessInfo
|
||||
typedef U32 OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_Inherited = (1<<6),
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_ShareDelete = (1<<6),
|
||||
OS_AccessFlag_Inherited = (1<<7),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -206,6 +207,8 @@ internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_rename_file_by_handle(OS_Handle file, String8 new_name);
|
||||
internal B32 os_rename_file(String8 orig_name, String8 new_name);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
internal B32 os_copy_file_path(String8 dst, String8 src);
|
||||
internal String8 os_full_path_from_path(Arena *arena, String8 path);
|
||||
|
||||
@@ -321,13 +321,14 @@ os_file_open(OS_AccessFlags flags, String8 path)
|
||||
DWORD share_mode = 0;
|
||||
DWORD creation_disposition = OPEN_EXISTING;
|
||||
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0};
|
||||
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
|
||||
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
|
||||
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
|
||||
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
|
||||
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
|
||||
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
|
||||
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; }
|
||||
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
|
||||
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
|
||||
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
|
||||
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
|
||||
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
|
||||
if(flags & OS_AccessFlag_ShareDelete) {share_mode |= FILE_SHARE_DELETE; access_flags |= DELETE;}
|
||||
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
|
||||
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; }
|
||||
if(flags & OS_AccessFlag_Inherited)
|
||||
{
|
||||
security_attributes.bInheritHandle = 1;
|
||||
@@ -469,6 +470,30 @@ os_id_from_file(OS_Handle file)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_rename_file_by_handle(OS_Handle file, String8 new_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
|
||||
HANDLE handle = (HANDLE)file.u64[0];
|
||||
|
||||
String16 new_name16 = str16_from_8(scratch.arena, new_name);
|
||||
|
||||
U64 file_rename_info_size = sizeof(FILE_RENAME_INFO);
|
||||
U64 buffer_size = file_rename_info_size + sizeof(WCHAR)*new_name16.size;
|
||||
U8 *buffer = push_array(scratch.arena, U8, buffer_size);
|
||||
|
||||
FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer;
|
||||
rename_info->ReplaceIfExists = 1;
|
||||
rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]);
|
||||
MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0]));
|
||||
|
||||
BOOL is_renamed = SetFileInformationByHandle(handle, FileRenameInfo, buffer, buffer_size);
|
||||
|
||||
scratch_end(scratch);
|
||||
return is_renamed;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_delete_file_at_path(String8 path)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user