2017-03-23 22:45:32 +00:00
|
|
|
/*
|
|
|
|
* Mr. 4th Dimention - Allen Webster
|
|
|
|
*
|
|
|
|
* 23.03.2017
|
|
|
|
*
|
|
|
|
* UTF8 versions of WIN32 calls.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TOP
|
|
|
|
|
|
|
|
#if !defined(FRED_WIN32_UTF8_CPP)
|
|
|
|
#define FRED_WIN32_UTF8_CPP
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
// TODO(allen): rewrite _EVERYTHING_ that does Win32 UTF16 <-> UTF8
|
2017-11-30 19:02:37 +00:00
|
|
|
internal Win32_UTF16
|
2019-06-01 23:58:28 +00:00
|
|
|
input_8_to_16(Arena *scratch, u8 *in, u32 in_length){
|
2018-11-20 08:18:54 +00:00
|
|
|
Win32_UTF16 r = {};
|
2019-02-14 00:24:03 +00:00
|
|
|
u32 utf16_max = (in_length + 1)*2;
|
2017-11-30 19:02:37 +00:00
|
|
|
u16 *utf16 = push_array(scratch, u16, utf16_max);
|
|
|
|
b32 error = false;
|
2019-02-14 00:24:03 +00:00
|
|
|
u32 utf16_len = (u32)utf8_to_utf16_minimal_checking(utf16, utf16_max - 1, in, in_length, &error);
|
2017-11-30 19:02:37 +00:00
|
|
|
if (!error && utf16_len < utf16_max){
|
|
|
|
utf16[utf16_len] = 0;
|
|
|
|
r.success = true;
|
2019-02-14 00:24:03 +00:00
|
|
|
r.utf8_len = in_length;
|
2017-11-30 19:02:37 +00:00
|
|
|
r.utf16_max = utf16_max;
|
|
|
|
r.utf16_len = utf16_len;
|
|
|
|
r.utf16 = utf16;
|
|
|
|
}
|
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
2019-02-14 00:24:03 +00:00
|
|
|
internal Win32_UTF16
|
2019-06-01 23:58:28 +00:00
|
|
|
input_8_to_16(Arena *scratch, u8 *in){
|
2019-02-14 00:24:03 +00:00
|
|
|
u32 length = 0;
|
|
|
|
for (;in[length];++length);
|
|
|
|
return(input_8_to_16(scratch, in, length));
|
|
|
|
}
|
|
|
|
|
|
|
|
internal Win32_UTF16
|
2019-07-21 18:16:34 +00:00
|
|
|
input_8_to_16(Arena *scratch, String_Const_u8 in){
|
|
|
|
return(input_8_to_16(scratch, in.str, (u32)in.size));
|
2019-02-14 00:24:03 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 22:45:32 +00:00
|
|
|
internal HANDLE
|
2019-06-01 23:58:28 +00:00
|
|
|
CreateFile_utf8(Arena *scratch, u8 *name, DWORD access, DWORD share, LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags, HANDLE template_file){
|
2017-03-23 22:45:32 +00:00
|
|
|
HANDLE result = INVALID_HANDLE_VALUE;
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 name_16 = input_8_to_16(scratch, name);
|
|
|
|
if (name_16.success){
|
|
|
|
result = CreateFileW((LPWSTR)name_16.utf16, access, share, security, creation, flags, template_file);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal DWORD
|
2019-06-01 23:58:28 +00:00
|
|
|
GetFinalPathNameByHandle_utf8(Arena *scratch, HANDLE file, u8 *file_path_out, DWORD path_max, DWORD flags){
|
2017-03-23 22:45:32 +00:00
|
|
|
DWORD result = 0;
|
|
|
|
|
|
|
|
if (file_path_out == 0){
|
|
|
|
result = GetFinalPathNameByHandleW(file, 0, 0, flags);
|
2017-03-30 20:48:33 +00:00
|
|
|
result *= 2;
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
else{
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
|
|
|
u32 path_16_max = KB(32);
|
|
|
|
u16 *path_16 = push_array(scratch, u16, path_16_max);
|
|
|
|
|
|
|
|
DWORD length_16 = GetFinalPathNameByHandleW(file, (LPWSTR)path_16, path_16_max, flags);
|
|
|
|
|
|
|
|
if (length_16 != 0 && length_16 < path_16_max){
|
|
|
|
b32 convert_error = false;
|
|
|
|
u32 path_8_len = (u32)utf16_to_utf8_minimal_checking(file_path_out, path_max-1, path_16, length_16, &convert_error);
|
|
|
|
if (path_8_len < path_max && !convert_error){
|
|
|
|
file_path_out[path_8_len] = 0;
|
|
|
|
result = path_8_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal HANDLE
|
2019-06-01 23:58:28 +00:00
|
|
|
FindFirstFile_utf8(Arena *scratch, u8 *name, LPWIN32_FIND_DATA find_data){
|
2017-03-23 22:45:32 +00:00
|
|
|
HANDLE result = INVALID_HANDLE_VALUE;
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 name_16 = input_8_to_16(scratch, name);
|
|
|
|
if (name_16.success){
|
|
|
|
result = FindFirstFileW((LPWSTR)name_16.utf16, find_data);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal DWORD
|
2019-06-01 23:58:28 +00:00
|
|
|
GetFileAttributes_utf8(Arena *scratch, u8 *name){
|
2017-03-23 22:45:32 +00:00
|
|
|
DWORD result = 0;
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 name_16 = input_8_to_16(scratch, name);
|
|
|
|
if (name_16.success){
|
|
|
|
result = GetFileAttributesW((LPWSTR)name_16.utf16);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal DWORD
|
2019-06-01 23:58:28 +00:00
|
|
|
GetModuleFileName_utf8(Arena *scratch, HMODULE module, u8 *file_out, DWORD max){
|
2017-03-23 22:45:32 +00:00
|
|
|
DWORD result = 0;
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
u32 file_16_max = KB(40);
|
|
|
|
u16 *file_16 = push_array(scratch, u16, file_16_max);
|
|
|
|
DWORD file_16_len = GetModuleFileNameW(module, (LPWSTR)file_16, file_16_max);
|
2019-02-14 03:53:55 +00:00
|
|
|
b32 convert_error = false;
|
|
|
|
u32 file_8_len = (u32)utf16_to_utf8_minimal_checking(file_out, max - 1, file_16, file_16_len, &convert_error);
|
|
|
|
result = file_8_len;
|
|
|
|
if (convert_error || file_8_len >= max){
|
|
|
|
result = 0;
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal BOOL
|
2019-06-01 23:58:28 +00:00
|
|
|
CreateProcess_utf8(Arena *scratch, u8 *app_name, u8 *command, LPSECURITY_ATTRIBUTES security, LPSECURITY_ATTRIBUTES thread, BOOL inherit_handles, DWORD creation, LPVOID environment, u8 *curdir, LPSTARTUPINFO startup, LPPROCESS_INFORMATION process){
|
2017-03-23 22:45:32 +00:00
|
|
|
BOOL result = false;
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 app_name_16 = input_8_to_16(scratch, app_name);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
2017-11-30 19:02:37 +00:00
|
|
|
if (app_name_16.success){
|
|
|
|
Win32_UTF16 command_16 = input_8_to_16(scratch, command);
|
|
|
|
if (command_16.success){
|
|
|
|
Win32_UTF16 curdir_16 = input_8_to_16(scratch, curdir);
|
|
|
|
if (curdir_16.success){
|
|
|
|
result = CreateProcessW((LPWSTR)app_name_16.utf16, (LPWSTR)command_16.utf16, security, thread, inherit_handles, creation, environment, (LPWSTR)curdir_16.utf16, startup, process);
|
|
|
|
}
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal DWORD
|
2019-06-01 23:58:28 +00:00
|
|
|
GetCurrentDirectory_utf8(Arena *scratch, DWORD max, u8 *buffer){
|
2017-03-23 22:45:32 +00:00
|
|
|
DWORD result = 0;
|
|
|
|
|
2019-07-24 07:41:40 +00:00
|
|
|
if (buffer != 0){
|
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
|
|
|
u32 buffer_16_max = KB(40);
|
|
|
|
u16 *buffer_16 = push_array(scratch, u16, buffer_16_max);
|
|
|
|
DWORD buffer_16_len = GetCurrentDirectoryW(buffer_16_max, (LPWSTR)buffer_16);
|
|
|
|
b32 error = false;
|
|
|
|
u32 buffer_8_len = (u32)utf16_to_utf8_minimal_checking(buffer, max-1, buffer_16, buffer_16_len, &error);
|
|
|
|
if (buffer_8_len < max && !error){
|
|
|
|
buffer[buffer_8_len] = 0;
|
|
|
|
result = buffer_8_len;
|
|
|
|
}
|
|
|
|
end_temp(temp);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
result = GetCurrentDirectoryW(0, 0);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal int
|
2019-06-01 23:58:28 +00:00
|
|
|
MessageBox_utf8(Arena *scratch, HWND owner, u8 *text, u8 *caption, UINT type){
|
2017-03-23 22:45:32 +00:00
|
|
|
int result = 0;
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 text_16 = input_8_to_16(scratch, text);
|
|
|
|
if (text_16.success){
|
|
|
|
Win32_UTF16 caption_16 = input_8_to_16(scratch, caption);
|
|
|
|
if (caption_16.success){
|
|
|
|
result = MessageBoxW(owner, (LPWSTR)text_16.utf16, (LPWSTR)caption_16.utf16, type);
|
|
|
|
}
|
|
|
|
}
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-11-30 19:02:37 +00:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal BOOL
|
2019-06-01 23:58:28 +00:00
|
|
|
SetWindowText_utf8(Arena *scratch, HWND window, u8 *string){
|
2017-11-30 19:02:37 +00:00
|
|
|
BOOL result = FALSE;
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2017-11-30 19:02:37 +00:00
|
|
|
Win32_UTF16 string_16 = input_8_to_16(scratch, string);
|
|
|
|
if (string_16.success){
|
|
|
|
result = SetWindowTextW(window, (LPWSTR)string_16.utf16);
|
2017-03-23 22:45:32 +00:00
|
|
|
}
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2019-02-14 00:24:03 +00:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal BOOL
|
2019-06-01 23:58:28 +00:00
|
|
|
GetFileAttributesEx_utf8String(Arena *scratch, String_Const_u8 file_name, GET_FILEEX_INFO_LEVELS info_level_id, LPVOID file_info){
|
2019-02-14 00:24:03 +00:00
|
|
|
BOOL result = FALSE;
|
2019-06-01 23:58:28 +00:00
|
|
|
Temp_Memory temp = begin_temp(scratch);
|
2019-07-21 18:16:34 +00:00
|
|
|
Win32_UTF16 string_16 = input_8_to_16(scratch, file_name);
|
2019-02-14 00:24:03 +00:00
|
|
|
if (string_16.success){
|
|
|
|
result = GetFileAttributesExW((LPWSTR)string_16.utf16, info_level_id, file_info);
|
|
|
|
}
|
2019-06-01 23:58:28 +00:00
|
|
|
end_temp(temp);
|
2017-03-23 22:45:32 +00:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// BOTTOM
|
|
|
|
|