Add search List api, add DPI awareness func, reduce win32 noise
This commit is contained in:
parent
9d0b0a2982
commit
15568a7919
426
dqn.h
426
dqn.h
@ -357,18 +357,22 @@ static_assert(sizeof(Dqn_f64) == 8, "Sanity check f64 is 8 bytes
|
|||||||
#endif // DQN_WITH_WIN_NET
|
#endif // DQN_WITH_WIN_NET
|
||||||
#else
|
#else
|
||||||
// Taken from Windows.h
|
// Taken from Windows.h
|
||||||
typedef unsigned long DWORD;
|
// typedef unsigned long DWORD;
|
||||||
typedef unsigned short WORD;
|
// typedef unsigned short WORD;
|
||||||
typedef void * BCRYPT_ALG_HANDLE;
|
// typedef int BOOL;
|
||||||
|
// typedef void * HWND;
|
||||||
|
// typedef void * HMODULE;
|
||||||
|
// typedef void * HANDLE;
|
||||||
|
// typedef long NTSTATUS;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
DWORD LowPart;
|
unsigned long LowPart;
|
||||||
long HighPart;
|
long HighPart;
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
DWORD LowPart;
|
unsigned long LowPart;
|
||||||
long HighPart;
|
long HighPart;
|
||||||
} u;
|
} u;
|
||||||
Dqn_i64 QuadPart;
|
Dqn_i64 QuadPart;
|
||||||
} LARGE_INTEGER;
|
} LARGE_INTEGER;
|
||||||
@ -1392,6 +1396,7 @@ struct Dqn_ListChunk
|
|||||||
Dqn_isize size;
|
Dqn_isize size;
|
||||||
Dqn_isize count;
|
Dqn_isize count;
|
||||||
Dqn_ListChunk<T> *next;
|
Dqn_ListChunk<T> *next;
|
||||||
|
Dqn_ListChunk<T> *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1406,11 +1411,11 @@ struct Dqn_ListIterator
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct Dqn_List
|
struct Dqn_List
|
||||||
{
|
{
|
||||||
Dqn_Arena *arena;
|
Dqn_Arena *arena;
|
||||||
Dqn_isize count; // Cumulative count of all items made across all list chunks
|
Dqn_isize count; // Cumulative count of all items made across all list chunks
|
||||||
Dqn_isize chunk_size; // When new ListChunk's are required, the minimum 'data' entries to allocate for that node.
|
Dqn_isize chunk_size; // When new ListChunk's are required, the minimum 'data' entries to allocate for that node.
|
||||||
Dqn_ListChunk<T> *head;
|
Dqn_ListChunk<T> *head;
|
||||||
Dqn_ListChunk<T> *tail;
|
Dqn_ListChunk<T> *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> DQN_API Dqn_List<T> Dqn_ListInitWithArena(Dqn_Arena *arena, Dqn_isize chunk_size = 128);
|
template <typename T> DQN_API Dqn_List<T> Dqn_ListInitWithArena(Dqn_Arena *arena, Dqn_isize chunk_size = 128);
|
||||||
@ -1418,12 +1423,18 @@ template <typename T> DQN_API Dqn_List<T> Dqn_ListInitWithArena(Dqn_Arena *aren
|
|||||||
// Produce an iterator for the data in the list
|
// Produce an iterator for the data in the list
|
||||||
/*
|
/*
|
||||||
Dqn_List<int> list = {};
|
Dqn_List<int> list = {};
|
||||||
for (Dqn_ListIterator<int> it = {}; Dqn_ListIterate(&list, &it);)
|
for (Dqn_ListIterator<int> it = {}; Dqn_ListIterate(&list, &it, 0);)
|
||||||
{
|
{
|
||||||
int *item = it.data;
|
int *item = it.data;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
template <typename T> DQN_API Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator);
|
// start_index: The index to start iterating from
|
||||||
|
template <typename T> DQN_API Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator, Dqn_isize start_index);
|
||||||
|
|
||||||
|
// at_chunk: (Optional) The chunk that the index belongs to will be set in this parameter if given
|
||||||
|
// return: The element, or null pointer if it is not a valid index.
|
||||||
|
template <typename T> DQN_API T *Dqn_ListAt(Dqn_List<T> *list, Dqn_isize index, Dqn_ListChunk<T> *at_chunk);
|
||||||
|
|
||||||
#define Dqn_ListTaggedMake(list, count, tag) Dqn__ListMake(list, count DQN_CALL_SITE(tag))
|
#define Dqn_ListTaggedMake(list, count, tag) Dqn__ListMake(list, count DQN_CALL_SITE(tag))
|
||||||
#define Dqn_ListMake(list, count) Dqn__ListMake(list, count DQN_CALL_SITE(""))
|
#define Dqn_ListMake(list, count) Dqn__ListMake(list, count DQN_CALL_SITE(""))
|
||||||
template <typename T> DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS);
|
template <typename T> DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS);
|
||||||
@ -2004,18 +2015,23 @@ DQN_API void Dqn_JsonWriterF64(Dqn_JsonWriter *writer, Dqn_f64 value,
|
|||||||
// -------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------
|
||||||
struct Dqn_WinErrorMsg
|
struct Dqn_WinErrorMsg
|
||||||
{
|
{
|
||||||
DWORD code;
|
unsigned long code;
|
||||||
char str[DQN_KILOBYTES(64) - 1]; // Maximum error size
|
char str[DQN_KILOBYTES(64) - 1]; // Maximum error size
|
||||||
DWORD size;
|
unsigned long size;
|
||||||
};
|
};
|
||||||
DQN_API Dqn_WinErrorMsg Dqn_WinLastError ();
|
DQN_API Dqn_WinErrorMsg Dqn_WinLastError();
|
||||||
|
|
||||||
|
// Call once at application start-up to ensure that the application is DPI aware
|
||||||
|
// on Windows and ensure that application UI is scaled up appropriately for the
|
||||||
|
// monitor.
|
||||||
|
DQN_API void Dqn_WinMakeProcessDPIAware();
|
||||||
|
|
||||||
// Automatically dumps to DQN_LOG_E
|
// Automatically dumps to DQN_LOG_E
|
||||||
#define Dqn_WinDumpLastError(fmt, ...) Dqn__WinDumpLastError(DQN_STRING(__FILE__), DQN_STRING(__func__), __LINE__, fmt, ##__VA_ARGS__)
|
#define Dqn_WinDumpLastError(fmt, ...) Dqn__WinDumpLastError(DQN_STRING(__FILE__), DQN_STRING(__func__), __LINE__, fmt, ##__VA_ARGS__)
|
||||||
DQN_API void Dqn__WinDumpLastError(Dqn_String file, Dqn_String function, Dqn_uint line, char const *fmt, ...);
|
DQN_API void Dqn__WinDumpLastError(Dqn_String file, Dqn_String function, Dqn_uint line, char const *fmt, ...);
|
||||||
|
|
||||||
// return: The size required not including the null-terminator
|
// return: The size required not including the null-terminator
|
||||||
DQN_API int Dqn_WinUTF8ToWCharSizeRequired(Dqn_String src);
|
DQN_API int Dqn_WinUTF8ToWCharSizeRequired(Dqn_String src);
|
||||||
|
|
||||||
// Converts the UTF8 string into a wide string. This function always
|
// Converts the UTF8 string into a wide string. This function always
|
||||||
// null-terminates the buffer. If you use the SizeRequired(...) function, this
|
// null-terminates the buffer. If you use the SizeRequired(...) function, this
|
||||||
@ -2904,7 +2920,10 @@ DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (list->tail)
|
if (list->tail)
|
||||||
|
{
|
||||||
list->tail->next = tail;
|
list->tail->next = tail;
|
||||||
|
tail->prev = list->tail;
|
||||||
|
}
|
||||||
|
|
||||||
list->tail = tail;
|
list->tail = tail;
|
||||||
|
|
||||||
@ -2919,14 +2938,27 @@ DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
DQN_API Dqn_b32 Dqn_ListIterateFrom(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator, Dqn_isize start_index)
|
||||||
{
|
{
|
||||||
Dqn_b32 result = false;
|
Dqn_b32 result = false;
|
||||||
|
if (!list || !iterator || start_index < 0 || list->chunk_size <= 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
if (!iterator->init)
|
if (!iterator->init)
|
||||||
{
|
{
|
||||||
*iterator = {};
|
*iterator = {};
|
||||||
iterator->chunk = list->head;
|
if (start_index == 0)
|
||||||
iterator->init = true;
|
{
|
||||||
|
iterator->chunk = list->head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dqn_ListAt(list, start_index, &iterator->chunk);
|
||||||
|
if (list->chunk_size > 0)
|
||||||
|
iterator->chunk_data_index = start_index % list->chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator->init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iterator->chunk)
|
if (iterator->chunk)
|
||||||
@ -2951,6 +2983,53 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DQN_API T *Dqn_ListAt(Dqn_List<T> *list, Dqn_isize index, Dqn_ListChunk<T> **at_chunk)
|
||||||
|
{
|
||||||
|
if (!list || !list->chunk_size || index < 0 || index >= list->count)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Dqn_isize total_chunks = list->count / (list->chunk_size + (list->chunk_size - 1));
|
||||||
|
Dqn_isize desired_chunk = index / list->chunk_size;
|
||||||
|
Dqn_isize forward_scan_dist = desired_chunk;
|
||||||
|
Dqn_isize backward_scan_dist = total_chunks - desired_chunk;
|
||||||
|
|
||||||
|
// NOTE: Linearly scan forwards/backwards to the chunk we need. We don't
|
||||||
|
// have random access to chunks
|
||||||
|
Dqn_isize current_chunk = 0;
|
||||||
|
Dqn_ListChunk<T> **chunk = nullptr;
|
||||||
|
if (forward_scan_dist <= backward_scan_dist)
|
||||||
|
{
|
||||||
|
for (chunk = &list->head;
|
||||||
|
*chunk && current_chunk != desired_chunk;
|
||||||
|
*chunk = (*chunk)->next, current_chunk++)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_chunk = total_chunks;
|
||||||
|
for (chunk = &list->tail;
|
||||||
|
*chunk && current_chunk != desired_chunk;
|
||||||
|
*chunk = (*chunk)->prev, current_chunk--)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T *result = nullptr;
|
||||||
|
if (*chunk)
|
||||||
|
{
|
||||||
|
Dqn_isize relative_index = index % list->chunk_size;
|
||||||
|
result = (*chunk)->data + relative_index;
|
||||||
|
DQN_ASSERT(relative_index < (*chunk)->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result && at_chunk)
|
||||||
|
*at_chunk = *chunk;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DQN_COMPILER_W32_MSVC)
|
#if defined(DQN_COMPILER_W32_MSVC)
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
@ -2967,15 +3046,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
#if !defined(DQN_NO_WIN32_MINIMAL_HEADER)
|
#if !defined(DQN_NO_WIN32_MINIMAL_HEADER)
|
||||||
|
|
||||||
// Taken from Windows.h
|
// Taken from Windows.h
|
||||||
// ---------------------------------------------------------------------
|
|
||||||
// Typedefs
|
|
||||||
// ---------------------------------------------------------------------
|
|
||||||
typedef int BOOL;
|
|
||||||
typedef void * HWND;
|
|
||||||
typedef void * HMODULE;
|
|
||||||
typedef void * HANDLE;
|
|
||||||
typedef long NTSTATUS;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Defines
|
// Defines
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
@ -3007,8 +3077,8 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
#define PAGE_READWRITE 0x04
|
#define PAGE_READWRITE 0x04
|
||||||
|
|
||||||
// NOTE: FindFirstFile
|
// NOTE: FindFirstFile
|
||||||
#define INVALID_HANDLE_VALUE ((HANDLE)(long *)-1)
|
#define INVALID_HANDLE_VALUE ((void *)(long *)-1)
|
||||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
#define INVALID_FILE_ATTRIBUTES ((unsigned long)-1)
|
||||||
#define FIND_FIRST_EX_LARGE_FETCH 0x00000002
|
#define FIND_FIRST_EX_LARGE_FETCH 0x00000002
|
||||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||||
@ -3022,7 +3092,7 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
#define MOVEFILE_COPY_ALLOWED 0x00000002
|
#define MOVEFILE_COPY_ALLOWED 0x00000002
|
||||||
|
|
||||||
// NOTE: Wininet
|
// NOTE: Wininet
|
||||||
typedef WORD INTERNET_PORT;
|
typedef unsigned short INTERNET_PORT;
|
||||||
#define INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
|
#define INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
|
||||||
#define INTERNET_DEFAULT_HTTPS_PORT 443 // HTTPS
|
#define INTERNET_DEFAULT_HTTPS_PORT 443 // HTTPS
|
||||||
#define INTERNET_SERVICE_HTTP 3
|
#define INTERNET_SERVICE_HTTP 3
|
||||||
@ -3042,37 +3112,37 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
#define OPEN_ALWAYS 4
|
#define OPEN_ALWAYS 4
|
||||||
#define TRUNCATE_EXISTING 5
|
#define TRUNCATE_EXISTING 5
|
||||||
|
|
||||||
#define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF)
|
#define INVALID_FILE_SIZE ((unsigned long)0xFFFFFFFF)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Data Structures
|
// Data Structures
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
DWORD LowPart;
|
unsigned long LowPart;
|
||||||
DWORD HighPart;
|
unsigned long HighPart;
|
||||||
} DUMMYSTRUCTNAME;
|
} DUMMYSTRUCTNAME;
|
||||||
struct {
|
struct {
|
||||||
DWORD LowPart;
|
unsigned long LowPart;
|
||||||
DWORD HighPart;
|
unsigned long HighPart;
|
||||||
} u;
|
} u;
|
||||||
Dqn_u64 QuadPart;
|
Dqn_u64 QuadPart;
|
||||||
} ULARGE_INTEGER;
|
} ULARGE_INTEGER;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
DWORD dwLowDateTime;
|
unsigned long dwLowDateTime;
|
||||||
DWORD dwHighDateTime;
|
unsigned long dwHighDateTime;
|
||||||
} FILETIME;
|
} FILETIME;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
DWORD dwFileAttributes;
|
unsigned long dwFileAttributes;
|
||||||
FILETIME ftCreationTime;
|
FILETIME ftCreationTime;
|
||||||
FILETIME ftLastAccessTime;
|
FILETIME ftLastAccessTime;
|
||||||
FILETIME ftLastWriteTime;
|
FILETIME ftLastWriteTime;
|
||||||
DWORD nFileSizeHigh;
|
unsigned long nFileSizeHigh;
|
||||||
DWORD nFileSizeLow;
|
unsigned long nFileSizeLow;
|
||||||
} WIN32_FILE_ATTRIBUTE_DATA;
|
} WIN32_FILE_ATTRIBUTE_DATA;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -3082,56 +3152,56 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
} GET_FILEEX_INFO_LEVELS;
|
} GET_FILEEX_INFO_LEVELS;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD nLength;
|
unsigned long nLength;
|
||||||
void *lpSecurityDescriptor;
|
void *lpSecurityDescriptor;
|
||||||
bool bInheritHandle;
|
bool bInheritHandle;
|
||||||
} SECURITY_ATTRIBUTES;
|
} SECURITY_ATTRIBUTES;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
DWORD dwOemId; // Obsolete field...do not use
|
unsigned long dwOemId; // Obsolete field...do not use
|
||||||
struct {
|
struct {
|
||||||
Dqn_u16 wProcessorArchitecture;
|
Dqn_u16 wProcessorArchitecture;
|
||||||
Dqn_u16 wReserved;
|
Dqn_u16 wReserved;
|
||||||
} DUMMYSTRUCTNAME;
|
} DUMMYSTRUCTNAME;
|
||||||
} DUMMYUNIONNAME;
|
} DUMMYUNIONNAME;
|
||||||
DWORD dwPageSize;
|
unsigned long dwPageSize;
|
||||||
void *lpMinimumApplicationAddress;
|
void *lpMinimumApplicationAddress;
|
||||||
void *lpMaximumApplicationAddress;
|
void *lpMaximumApplicationAddress;
|
||||||
DWORD *dwActiveProcessorMask;
|
unsigned long *dwActiveProcessorMask;
|
||||||
DWORD dwNumberOfProcessors;
|
unsigned long dwNumberOfProcessors;
|
||||||
DWORD dwProcessorType;
|
unsigned long dwProcessorType;
|
||||||
DWORD dwAllocationGranularity;
|
unsigned long dwAllocationGranularity;
|
||||||
Dqn_u16 wProcessorLevel;
|
Dqn_u16 wProcessorLevel;
|
||||||
Dqn_u16 wProcessorRevision;
|
Dqn_u16 wProcessorRevision;
|
||||||
} SYSTEM_INFO;
|
} SYSTEM_INFO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
WORD wYear;
|
unsigned short wYear;
|
||||||
WORD wMonth;
|
unsigned short wMonth;
|
||||||
WORD wDayOfWeek;
|
unsigned short wDayOfWeek;
|
||||||
WORD wDay;
|
unsigned short wDay;
|
||||||
WORD wHour;
|
unsigned short wHour;
|
||||||
WORD wMinute;
|
unsigned short wMinute;
|
||||||
WORD wSecond;
|
unsigned short wSecond;
|
||||||
WORD wMilliseconds;
|
unsigned short wMilliseconds;
|
||||||
} SYSTEMTIME;
|
} SYSTEMTIME;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD dwFileAttributes;
|
unsigned long dwFileAttributes;
|
||||||
FILETIME ftCreationTime;
|
FILETIME ftCreationTime;
|
||||||
FILETIME ftLastAccessTime;
|
FILETIME ftLastAccessTime;
|
||||||
FILETIME ftLastWriteTime;
|
FILETIME ftLastWriteTime;
|
||||||
DWORD nFileSizeHigh;
|
unsigned long nFileSizeHigh;
|
||||||
DWORD nFileSizeLow;
|
unsigned long nFileSizeLow;
|
||||||
DWORD dwReserved0;
|
unsigned long dwReserved0;
|
||||||
DWORD dwReserved1;
|
unsigned long dwReserved1;
|
||||||
wchar_t cFileName[MAX_PATH];
|
wchar_t cFileName[MAX_PATH];
|
||||||
wchar_t cAlternateFileName[14];
|
wchar_t cAlternateFileName[14];
|
||||||
#ifdef _MAC
|
#ifdef _MAC
|
||||||
DWORD dwFileType;
|
unsigned long dwFileType;
|
||||||
DWORD dwCreatorType;
|
unsigned long dwCreatorType;
|
||||||
WORD wFinderFlags;
|
unsigned short wFinderFlags;
|
||||||
#endif
|
#endif
|
||||||
} WIN32_FIND_DATAW;
|
} WIN32_FIND_DATAW;
|
||||||
|
|
||||||
@ -3148,7 +3218,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
FindExSearchMaxSearchOp
|
FindExSearchMaxSearchOp
|
||||||
} FINDEX_SEARCH_OPS;
|
} FINDEX_SEARCH_OPS;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
INTERNET_SCHEME_PARTIAL = -2,
|
INTERNET_SCHEME_PARTIAL = -2,
|
||||||
INTERNET_SCHEME_UNKNOWN = -1,
|
INTERNET_SCHEME_UNKNOWN = -1,
|
||||||
@ -3169,86 +3238,87 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
} INTERNET_SCHEME;
|
} INTERNET_SCHEME;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD dwStructSize; // size of this structure. Used in version check
|
unsigned long dwStructSize; // size of this structure. Used in version check
|
||||||
char *lpszScheme; // pointer to scheme name
|
char *lpszScheme; // pointer to scheme name
|
||||||
DWORD dwSchemeLength; // length of scheme name
|
unsigned long dwSchemeLength; // length of scheme name
|
||||||
INTERNET_SCHEME nScheme; // enumerated scheme type (if known)
|
INTERNET_SCHEME nScheme; // enumerated scheme type (if known)
|
||||||
char *lpszHostName; // pointer to host name
|
char *lpszHostName; // pointer to host name
|
||||||
DWORD dwHostNameLength; // length of host name
|
unsigned long dwHostNameLength; // length of host name
|
||||||
INTERNET_PORT nPort; // converted port number
|
INTERNET_PORT nPort; // converted port number
|
||||||
char *lpszUserName; // pointer to user name
|
char *lpszUserName; // pointer to user name
|
||||||
DWORD dwUserNameLength; // length of user name
|
unsigned long dwUserNameLength; // length of user name
|
||||||
char *lpszPassword; // pointer to password
|
char *lpszPassword; // pointer to password
|
||||||
DWORD dwPasswordLength; // length of password
|
unsigned long dwPasswordLength; // length of password
|
||||||
char *lpszUrlPath; // pointer to URL-path
|
char *lpszUrlPath; // pointer to URL-path
|
||||||
DWORD dwUrlPathLength; // length of URL-path
|
unsigned long dwUrlPathLength; // length of URL-path
|
||||||
char *lpszExtraInfo; // pointer to extra information (e.g. ?foo or #foo)
|
char *lpszExtraInfo; // pointer to extra information (e.g. ?foo or #foo)
|
||||||
DWORD dwExtraInfoLength; // length of extra information
|
unsigned long dwExtraInfoLength; // length of extra information
|
||||||
} URL_COMPONENTSA;
|
} URL_COMPONENTSA;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Functions
|
// Functions
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
bool CreateDirectoryW (wchar_t const *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes);
|
/*BOOL*/ int CreateDirectoryW (wchar_t const *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes);
|
||||||
|
/*BOOL*/ int RemoveDirectoryW (wchar_t const *lpPathName);
|
||||||
|
/*DWORD*/ unsigned long GetCurrentDirectoryW (unsigned long nBufferLength, wchar_t *lpBuffer);
|
||||||
|
|
||||||
BOOL MoveFileExW (wchar_t const *lpExistingFileName, wchar_t const *lpNewFileName, DWORD flags);
|
/*BOOL*/ int FindNextFileW (void *hFindFile, WIN32_FIND_DATAW *lpFindFileData);
|
||||||
BOOL CopyFileW (wchar_t const *existing_file_name, wchar_t const *new_file_name, BOOL fail_if_exists);
|
/*HANDLE*/ void *FindFirstFileExW (wchar_t const *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, void *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, void *lpSearchFilter, unsigned long dwAdditionalFlags);
|
||||||
BOOL DeleteFileW (wchar_t const *existing_file_name);
|
/*DWORD*/ unsigned long GetFileAttributesExW (wchar_t const *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, WIN32_FILE_ATTRIBUTE_DATA *lpFileInformation);
|
||||||
BOOL RemoveDirectoryW (wchar_t const *lpPathName);
|
/*BOOL*/ int GetFileSizeEx (void *hFile, LARGE_INTEGER *lpFileSize);
|
||||||
DWORD GetCurrentDirectoryW (DWORD nBufferLength, wchar_t *lpBuffer);
|
|
||||||
bool FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData);
|
|
||||||
HANDLE FindFirstFileExW (wchar_t const *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, void *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, void *lpSearchFilter, DWORD dwAdditionalFlags);
|
|
||||||
DWORD GetFileAttributesExW (wchar_t const *file_name, GET_FILEEX_INFO_LEVELS info_level, WIN32_FILE_ATTRIBUTE_DATA *file_information);
|
|
||||||
|
|
||||||
HMODULE LoadLibraryA (char const *file_name);
|
/*BOOL*/ int MoveFileExW (wchar_t const *lpExistingFileName, wchar_t const *lpNewFileName, unsigned long dwFlags);
|
||||||
bool FreeLibrary (void *lib_module);
|
/*BOOL*/ int CopyFileW (wchar_t const *lpExistingFileName, wchar_t const *lpNewFileName, int bFailIfExists);
|
||||||
void *GetProcAddress (void *hmodule, char const *proc_name);
|
/*BOOL*/ int DeleteFileW (wchar_t const *lpExistingFileName);
|
||||||
unsigned int GetWindowModuleFileNameA (void *hwnd, char *file_name, unsigned int file_name_max);
|
/*HANDLE*/ void *CreateFileW (wchar_t const *lpFileName, unsigned long dwDesiredAccess, unsigned long dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, unsigned long dwCreationDisposition, unsigned long dwFlagsAndAttributes, void *hTemplateFile);
|
||||||
HMODULE GetModuleHandleA (char const *lpModuleName);
|
/*BOOL*/ int ReadFile (void *hFile, void *lpBuffer, unsigned long nNumberOfBytesToRead, unsigned long *lpNumberOfBytesRead, struct OVERLAPPED *lpOverlapped);
|
||||||
DWORD GetModuleFileNameW (HMODULE hModule, wchar_t *lpFilename, DWORD nSize);
|
/*BOOL*/ int CloseHandle (void *hObject);
|
||||||
|
|
||||||
DWORD WaitForSingleObject (HANDLE handle, DWORD milliseconds);
|
/*HMODULE*/ void *LoadLibraryA (char const *lpFileName);
|
||||||
|
/*BOOL*/ int FreeLibrary (void *hModule);
|
||||||
|
/*FARPROC*/ void *GetProcAddress (void *hModule, char const *lpProcName);
|
||||||
|
|
||||||
bool QueryPerformanceCounter (LARGE_INTEGER *performance_count);
|
/*DWORD*/ unsigned long GetWindowModuleFileNameA (void *hwnd, char *pszFileName, unsigned int cchFileNameMax);
|
||||||
bool QueryPerformanceFrequency(LARGE_INTEGER *frequency);
|
/*HMODULE*/ void *GetModuleHandleA (char const *lpModuleName);
|
||||||
|
/*DWORD*/ unsigned long GetModuleFileNameW (void *hModule, wchar_t *lpFilename, unsigned long nSize);
|
||||||
|
|
||||||
HANDLE CreateThread (SECURITY_ATTRIBUTES *thread_attributes, size_t stack_size, DWORD (*start_function)(void *), void *user_context, DWORD creation_flags, DWORD *thread_id);
|
/*DWORD*/ unsigned long WaitForSingleObject (void *hHandle, unsigned long dwMilliseconds);
|
||||||
HANDLE CreateSemaphoreA (SECURITY_ATTRIBUTES *security_attributes, long initial_count, long max_count, char *lpName);
|
|
||||||
bool ReleaseSemaphore (HANDLE semaphore, long release_count, long *prev_count);
|
|
||||||
void Sleep (DWORD dwMilliseconds);
|
|
||||||
|
|
||||||
void *VirtualAlloc (void *address, size_t size, DWORD allocation_type, DWORD protect);
|
/*BOOL*/ int QueryPerformanceCounter (LARGE_INTEGER *lpPerformanceCount);
|
||||||
bool VirtualFree (void *address, size_t size, DWORD free_type);
|
/*BOOL*/ int QueryPerformanceFrequency (LARGE_INTEGER *lpFrequency);
|
||||||
|
|
||||||
void GetSystemInfo (SYSTEM_INFO *system_info);
|
/*HANDLE*/ void *CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, size_t dwStackSize, unsigned long (*lpStartAddress)(void *), void *lpParameter, unsigned long dwCreationFlags, unsigned long *lpThreadId);
|
||||||
void GetSystemTime (SYSTEMTIME *lpSystemTime);
|
/*HANDLE*/ void *CreateSemaphoreA (SECURITY_ATTRIBUTES *lpSecurityAttributes, long lInitialCount, long lMaxCount, char *lpName);
|
||||||
void GetSystemTimeAsFileTime (FILETIME *lpFileTime);
|
/*BOOL*/ int ReleaseSemaphore (void *semaphore, long lReleaseCount, long *lpPreviousCount);
|
||||||
void GetLocalTime (SYSTEMTIME *lpSystemTime);
|
void Sleep (unsigned long dwMilliseconds);
|
||||||
|
|
||||||
DWORD FormatMessageA (DWORD flags, void *source, DWORD message_id, DWORD language_id, char *buffer, DWORD size, va_list *args);
|
void *VirtualAlloc (void *lpAddress, size_t dwSize, unsigned long flAllocationType, unsigned long flProtect);
|
||||||
DWORD GetLastError ();
|
/*BOOL*/ int VirtualFree (void *lpAddress, size_t dwSize, unsigned long dwFreeType);
|
||||||
|
|
||||||
int MultiByteToWideChar (unsigned int CodePage, DWORD dwFlags, char const *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
void GetSystemInfo (SYSTEM_INFO *system_info);
|
||||||
int WideCharToMultiByte (unsigned int CodePage, DWORD dwFlags, wchar_t const *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, char const *lpDefaultChar, bool *lpUsedDefaultChar);
|
void GetSystemTime (SYSTEMTIME *lpSystemTime);
|
||||||
|
void GetSystemTimeAsFileTime (FILETIME *lpFileTime);
|
||||||
|
void GetLocalTime (SYSTEMTIME *lpSystemTime);
|
||||||
|
|
||||||
NTSTATUS BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, wchar_t const *pszAlgId, wchar_t const *pszImplementation, unsigned long dwFlags);
|
/*DWORD*/ unsigned long FormatMessageA (unsigned long dwFlags, void *lpSource, unsigned long dwMessageId, unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize, va_list *Arguments);
|
||||||
NTSTATUS BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, unsigned char *pbBuffer, unsigned long cbBuffer, unsigned long dwFlags);
|
/*DWORD*/ unsigned long GetLastError ();
|
||||||
|
|
||||||
BOOL InternetCrackUrlA (char const *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSA *lpUrlComponents);
|
int MultiByteToWideChar (unsigned int CodePage, unsigned long dwFlags, char const *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
||||||
void *InternetOpenA (char const *lpszAgent, DWORD dwAccessType, char const *lpszProxy, char const *lpszProxyBypass, DWORD dwFlags);
|
int WideCharToMultiByte (unsigned int CodePage, unsigned long dwFlags, wchar_t const *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, char const *lpDefaultChar, bool *lpUsedDefaultChar);
|
||||||
void *InternetConnectA (void *hInternet, char const *lpszServerName, INTERNET_PORT nServerPort, char const *lpszUserName, char const *lpszPassword, DWORD dwService, DWORD dwFlags, DWORD *dwContext);
|
|
||||||
bool InternetSetOptionA (void *hInternet, DWORD dwOption, void *lpBuffer, DWORD dwBufferLength);
|
/*NTSTATUS*/ long BCryptOpenAlgorithmProvider(void *phAlgorithm, wchar_t const *pszAlgId, wchar_t const *pszImplementation, unsigned long dwFlags);
|
||||||
BOOL InternetReadFile (void *hFile, void *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead);
|
/*NTSTATUS*/ long BCryptGenRandom (void *hAlgorithm, unsigned char *pbBuffer, unsigned long cbBuffer, unsigned long dwFlags);
|
||||||
void *HttpOpenRequestA (void *hConnect, char const *lpszVerb, char const *lpszObjectName, char const *lpszVersion, char const *lpszReferrer, char const **lplpszAcceptTypes, DWORD dwFlags, DWORD *dwContext);
|
|
||||||
BOOL HttpSendRequestA (void *hRequest, char const *lpszHeaders, DWORD dwHeadersLength, void *lpOptional, DWORD dwOptionalLength);
|
/*BOOLAPI*/ int InternetCrackUrlA (char const *lpszUrl, unsigned long dwUrlLength, unsigned long dwFlags, URL_COMPONENTSA *lpUrlComponents);
|
||||||
BOOL InternetCloseHandle (void *hInternet);
|
/*HANDLE*/ void *InternetOpenA (char const *lpszAgent, unsigned long dwAccessType, char const *lpszProxy, char const *lpszProxyBypass, unsigned long dwFlags);
|
||||||
HANDLE CreateFileW (wchar_t const *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
/*HANDLE*/ void *InternetConnectA (void *hInternet, char const *lpszServerName, INTERNET_PORT nServerPort, char const *lpszUserName, char const *lpszPassword, unsigned long dwService, unsigned long dwFlags, unsigned long *dwContext);
|
||||||
BOOL CloseHandle (HANDLE hObject);
|
/*BOOLAPI*/ int InternetSetOptionA (void *hInternet, unsigned long dwOption, void *lpBuffer, unsigned long dwBufferLength);
|
||||||
BOOL ReadFile (HANDLE hFile, void *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, struct OVERLAPPED *lpOverlapped);
|
/*BOOLAPI*/ int InternetReadFile (void *hFile, void *lpBuffer, unsigned long dwNumberOfBytesToRead, unsigned long *lpdwNumberOfBytesRead);
|
||||||
BOOL GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize);
|
/*BOOLAPI*/ int InternetCloseHandle (void *hInternet);
|
||||||
|
/*HANDLE*/ void *HttpOpenRequestA (void *hConnect, char const *lpszVerb, char const *lpszObjectName, char const *lpszVersion, char const *lpszReferrer, char const **lplpszAcceptTypes, unsigned long dwFlags, unsigned long *dwContext);
|
||||||
|
/*BOOLAPI*/ int HttpSendRequestA (void *hRequest, char const *lpszHeaders, unsigned long dwHeadersLength, void *lpOptional, unsigned long dwOptionalLength);
|
||||||
}
|
}
|
||||||
#endif // !defined(DQN_NO_WIN32_MINIMAL_HEADER)
|
#endif // !defined(DQN_NO_WIN32_MINIMAL_HEADER)
|
||||||
#elif defined(DQN_OS_UNIX)
|
#elif defined(DQN_OS_UNIX)
|
||||||
@ -3264,7 +3334,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Dqn_Lib dqn__lib;
|
Dqn_Lib dqn__lib;
|
||||||
|
|
||||||
DQN_API void Dqn__ZeroMemBytes(void *ptr, Dqn_usize count, Dqn_ZeroMem zero_mem)
|
DQN_API void Dqn__ZeroMemBytes(void *ptr, Dqn_usize count, Dqn_ZeroMem zero_mem)
|
||||||
{
|
{
|
||||||
if (zero_mem == Dqn_ZeroMem::Yes)
|
if (zero_mem == Dqn_ZeroMem::Yes)
|
||||||
@ -3408,7 +3477,7 @@ DQN_API void Dqn_LogVDefault(Dqn_LogType type,
|
|||||||
Dqn_ThreadScratch scratch = Dqn_ThreadGetScratch();
|
Dqn_ThreadScratch scratch = Dqn_ThreadGetScratch();
|
||||||
Dqn_String exe_dir = Dqn_OSExecutableDirectory(scratch.arena);
|
Dqn_String exe_dir = Dqn_OSExecutableDirectory(scratch.arena);
|
||||||
Dqn_String log_file = Dqn_StringFmt(scratch.arena, "%.*s/dqn.log", DQN_STRING_FMT(exe_dir));
|
Dqn_String log_file = Dqn_StringFmt(scratch.arena, "%.*s/dqn.log", DQN_STRING_FMT(exe_dir));
|
||||||
dqn__lib.log_file = fopen(log_file.str, "a");
|
fopen_s(DQN_CAST(FILE **)&dqn__lib.log_file, log_file.str, "a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Dqn_TicketMutexEnd(&dqn__lib.log_file_mutex);
|
Dqn_TicketMutexEnd(&dqn__lib.log_file_mutex);
|
||||||
@ -4221,6 +4290,11 @@ DQN_API Dqn_ArenaMemBlock *Dqn__ArenaAllocateBlock(Dqn_Arena *arena, Dqn_isize r
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Dqn_ArenaMemProvider::Virtual:
|
case Dqn_ArenaMemProvider::Virtual:
|
||||||
|
{
|
||||||
|
result = DQN_CAST(Dqn_ArenaMemBlock *)VirtualAlloc(nullptr, allocate_size, MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Dqn_ArenaMemProvider::UserMemory:
|
case Dqn_ArenaMemProvider::UserMemory:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4250,7 +4324,7 @@ DQN_API void Dqn__ArenaFreeBlock(Dqn_Arena *arena, Dqn_ArenaMemBlock *block)
|
|||||||
switch (arena->mem_provider)
|
switch (arena->mem_provider)
|
||||||
{
|
{
|
||||||
case Dqn_ArenaMemProvider::CRT: DQN_FREE(block); break;
|
case Dqn_ArenaMemProvider::CRT: DQN_FREE(block); break;
|
||||||
case Dqn_ArenaMemProvider::Virtual:
|
case Dqn_ArenaMemProvider::Virtual: VirtualFree(block, block->size, MEM_RELEASE);
|
||||||
case Dqn_ArenaMemProvider::UserMemory:
|
case Dqn_ArenaMemProvider::UserMemory:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5725,7 +5799,7 @@ DQN_API char *Dqn__FileRead(char const *file_path, Dqn_isize file_path_size, Dqn
|
|||||||
Dqn_String file_path_string = Dqn_StringInit(file_path, file_path_size);
|
Dqn_String file_path_string = Dqn_StringInit(file_path, file_path_size);
|
||||||
Dqn_StringW file_path_string_w = Dqn_WinArenaUTF8ToWChar(file_path_string, scratch.arena);
|
Dqn_StringW file_path_string_w = Dqn_WinArenaUTF8ToWChar(file_path_string, scratch.arena);
|
||||||
|
|
||||||
HANDLE file_handle =
|
void *file_handle =
|
||||||
CreateFileW(file_path_string_w.str, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, nullptr);
|
CreateFileW(file_path_string_w.str, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, nullptr);
|
||||||
if (file_handle == INVALID_HANDLE_VALUE)
|
if (file_handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@ -5736,7 +5810,7 @@ DQN_API char *Dqn__FileRead(char const *file_path, Dqn_isize file_path_size, Dqn
|
|||||||
DQN_DEFER { CloseHandle(file_handle); };
|
DQN_DEFER { CloseHandle(file_handle); };
|
||||||
LARGE_INTEGER win_file_size;
|
LARGE_INTEGER win_file_size;
|
||||||
bool get_file_size_result = GetFileSizeEx(file_handle, &win_file_size);
|
bool get_file_size_result = GetFileSizeEx(file_handle, &win_file_size);
|
||||||
if (!get_file_size_result || win_file_size.QuadPart > (DWORD)-1)
|
if (!get_file_size_result || win_file_size.QuadPart > (unsigned long)-1)
|
||||||
{
|
{
|
||||||
if (!get_file_size_result)
|
if (!get_file_size_result)
|
||||||
{
|
{
|
||||||
@ -5756,8 +5830,8 @@ DQN_API char *Dqn__FileRead(char const *file_path, Dqn_isize file_path_size, Dqn
|
|||||||
auto *result = DQN_CAST(char *) Dqn__ArenaAllocate(arena, win_file_size.QuadPart + 1, alignof(char), Dqn_ZeroMem::No DQN_CALL_SITE_ARGS_INPUT);
|
auto *result = DQN_CAST(char *) Dqn__ArenaAllocate(arena, win_file_size.QuadPart + 1, alignof(char), Dqn_ZeroMem::No DQN_CALL_SITE_ARGS_INPUT);
|
||||||
|
|
||||||
// TODO(dqn): We need to chunk this and ensure that readfile read the bytes we wanted.
|
// TODO(dqn): We need to chunk this and ensure that readfile read the bytes we wanted.
|
||||||
DWORD bytes_read = 0;
|
unsigned long bytes_read = 0;
|
||||||
if (ReadFile(file_handle, result, DQN_CAST(DWORD)win_file_size.QuadPart, &bytes_read, nullptr /*overlapped*/) == 0)
|
if (ReadFile(file_handle, result, DQN_CAST(unsigned long)win_file_size.QuadPart, &bytes_read, nullptr /*overlapped*/) == 0)
|
||||||
{
|
{
|
||||||
Dqn_ArenaEndScope(arena_undo);
|
Dqn_ArenaEndScope(arena_undo);
|
||||||
Dqn_WinDumpLastError("ReadFile");
|
Dqn_WinDumpLastError("ReadFile");
|
||||||
@ -5824,7 +5898,8 @@ DQN_API Dqn_b32 Dqn_FileWriteFile(char const *file_path, Dqn_isize file_path_siz
|
|||||||
// TODO(dqn): Use OS apis
|
// TODO(dqn): Use OS apis
|
||||||
(void)file_path_size;
|
(void)file_path_size;
|
||||||
|
|
||||||
FILE *file_handle = fopen(file_path, "w+b");
|
FILE *file_handle = nullptr;
|
||||||
|
fopen_s(&file_handle, file_path, "w+b");
|
||||||
if (!file_handle)
|
if (!file_handle)
|
||||||
{
|
{
|
||||||
DQN_LOG_E("Failed to open file '%s' using fopen\n", file_path);
|
DQN_LOG_E("Failed to open file '%s' using fopen\n", file_path);
|
||||||
@ -5966,7 +6041,7 @@ DQN_API Dqn_b32 Dqn_FileCopy(Dqn_String src, Dqn_String dest, Dqn_b32 overwrite)
|
|||||||
Dqn_WinUTF8ToWChar(src, src_w, DQN_CAST(int)Dqn_ArrayCountInt(src_w));
|
Dqn_WinUTF8ToWChar(src, src_w, DQN_CAST(int)Dqn_ArrayCountInt(src_w));
|
||||||
Dqn_WinUTF8ToWChar(dest, dest_w, DQN_CAST(int)Dqn_ArrayCountInt(dest_w));
|
Dqn_WinUTF8ToWChar(dest, dest_w, DQN_CAST(int)Dqn_ArrayCountInt(dest_w));
|
||||||
|
|
||||||
BOOL fail_if_exists = overwrite == false;
|
int fail_if_exists = overwrite == false;
|
||||||
result = CopyFileW(src_w, dest_w, fail_if_exists) != 0;
|
result = CopyFileW(src_w, dest_w, fail_if_exists) != 0;
|
||||||
if (!result)
|
if (!result)
|
||||||
Dqn_WinDumpLastError("Failed to copy from %.*s to %.*s", DQN_STRING_FMT(src), DQN_STRING_FMT(dest));
|
Dqn_WinDumpLastError("Failed to copy from %.*s to %.*s", DQN_STRING_FMT(src), DQN_STRING_FMT(dest));
|
||||||
@ -6143,7 +6218,7 @@ DQN_API Dqn_b32 Dqn_FileMove(Dqn_String src, Dqn_String dest, Dqn_b32 overwrite)
|
|||||||
Dqn_WinUTF8ToWChar(src, src_w, DQN_CAST(int)Dqn_ArrayCountI(src_w));
|
Dqn_WinUTF8ToWChar(src, src_w, DQN_CAST(int)Dqn_ArrayCountI(src_w));
|
||||||
Dqn_WinUTF8ToWChar(dest, dest_w, DQN_CAST(int)Dqn_ArrayCountI(dest_w));
|
Dqn_WinUTF8ToWChar(dest, dest_w, DQN_CAST(int)Dqn_ArrayCountI(dest_w));
|
||||||
|
|
||||||
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
unsigned long flags = MOVEFILE_COPY_ALLOWED;
|
||||||
if (overwrite) flags |= MOVEFILE_REPLACE_EXISTING;
|
if (overwrite) flags |= MOVEFILE_REPLACE_EXISTING;
|
||||||
|
|
||||||
result = MoveFileExW(src_w, dest_w, flags) != 0;
|
result = MoveFileExW(src_w, dest_w, flags) != 0;
|
||||||
@ -6312,7 +6387,7 @@ DQN_API Dqn_b32 Dqn_OSSecureRNGBytes(void *buffer, Dqn_u32 size)
|
|||||||
if (!init)
|
if (!init)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NTSTATUS gen_status = BCryptGenRandom(dqn__lib.win32_bcrypt_rng_handle, DQN_CAST(unsigned char *)buffer, size, 0 /*flags*/);
|
long gen_status = BCryptGenRandom(dqn__lib.win32_bcrypt_rng_handle, DQN_CAST(unsigned char *)buffer, size, 0 /*flags*/);
|
||||||
if (gen_status != 0)
|
if (gen_status != 0)
|
||||||
{
|
{
|
||||||
DQN_LOG_E("Failed to generate random bytes: %d", gen_status);
|
DQN_LOG_E("Failed to generate random bytes: %d", gen_status);
|
||||||
@ -6503,7 +6578,7 @@ DQN_API Dqn_u64 Dqn_PerfCounterNow()
|
|||||||
Dqn_u64 result = 0;
|
Dqn_u64 result = 0;
|
||||||
#if defined(DQN_OS_WIN32)
|
#if defined(DQN_OS_WIN32)
|
||||||
LARGE_INTEGER integer = {};
|
LARGE_INTEGER integer = {};
|
||||||
BOOL qpc_result = QueryPerformanceCounter(&integer);
|
int qpc_result = QueryPerformanceCounter(&integer);
|
||||||
(void)qpc_result;
|
(void)qpc_result;
|
||||||
DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP");
|
DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP");
|
||||||
result = integer.QuadPart;
|
result = integer.QuadPart;
|
||||||
@ -6597,7 +6672,8 @@ DQN_API void Dqn_LibDumpThreadContextArenaStats(Dqn_String file_path)
|
|||||||
{
|
{
|
||||||
(void)file_path;
|
(void)file_path;
|
||||||
#if defined(DQN_DEBUG_THREAD_CONTEXT)
|
#if defined(DQN_DEBUG_THREAD_CONTEXT)
|
||||||
FILE *file = fopen(file_path.str, "a+b");
|
FILE *file = nullptr;
|
||||||
|
fopen_s(&file, file_path.str, "a+b");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
@ -6924,8 +7000,8 @@ DQN_API Dqn_WinErrorMsg Dqn_WinLastError()
|
|||||||
result.code = GetLastError();
|
result.code = GetLastError();
|
||||||
result.str[0] = 0;
|
result.str[0] = 0;
|
||||||
|
|
||||||
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
unsigned long flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||||
HMODULE module_to_get_errors_from = nullptr;
|
void *module_to_get_errors_from = nullptr;
|
||||||
|
|
||||||
if (result.code >= 12000 && result.code <= 12175) // WinINET Errors
|
if (result.code >= 12000 && result.code <= 12175) // WinINET Errors
|
||||||
{
|
{
|
||||||
@ -6935,16 +7011,54 @@ DQN_API Dqn_WinErrorMsg Dqn_WinLastError()
|
|||||||
|
|
||||||
result.size = FormatMessageA(flags,
|
result.size = FormatMessageA(flags,
|
||||||
module_to_get_errors_from, // LPCVOID lpSource,
|
module_to_get_errors_from, // LPCVOID lpSource,
|
||||||
result.code, // DWORD dwMessageId,
|
result.code, // unsigned long dwMessageId,
|
||||||
0, // DWORD dwLanguageId,
|
0, // unsigned long dwLanguageId,
|
||||||
result.str, // LPSTR lpBuffer,
|
result.str, // LPSTR lpBuffer,
|
||||||
DQN_CAST(DWORD) Dqn_ArrayCountI(result.str), // DWORD nSize,
|
DQN_CAST(unsigned long) Dqn_ArrayCountI(result.str), // unsigned long nSize,
|
||||||
nullptr // va_list * Arguments);
|
nullptr // va_list * Arguments);
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DQN_NO_WIN32_MINIMAL_HEADER)
|
||||||
|
#include <shellscalingapi.h> // SetProcessDpiAwareProc
|
||||||
|
#else
|
||||||
|
typedef enum PROCESS_DPI_AWARENESS
|
||||||
|
{
|
||||||
|
PROCESS_DPI_UNAWARE = 0,
|
||||||
|
PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||||
|
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||||
|
} PROCESS_DPI_AWARENESS;
|
||||||
|
|
||||||
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((void *)-4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DQN_API void Dqn_WinMakeProcessDPIAware()
|
||||||
|
{
|
||||||
|
typedef bool SetProcessDpiAwareProc(void);
|
||||||
|
typedef bool SetProcessDpiAwarenessProc(PROCESS_DPI_AWARENESS);
|
||||||
|
typedef bool SetProcessDpiAwarenessContextProc(void * /*DPI_AWARENESS_CONTEXT*/);
|
||||||
|
|
||||||
|
// NOTE(doyle): Taken from cmuratori/refterm snippet on DPI awareness. It
|
||||||
|
// appears we can make this robust by just loading user32.dll and using
|
||||||
|
// GetProcAddress on the DPI function. If it's not there, we're on an old
|
||||||
|
// version of windows, so we can call an older version of the API.
|
||||||
|
void *lib_handle = LoadLibraryA("user32.dll");
|
||||||
|
if (auto *set_process_dpi_awareness_context = DQN_CAST(SetProcessDpiAwarenessContextProc *)GetProcAddress(lib_handle, "SetProcessDpiAwarenessContext"))
|
||||||
|
{
|
||||||
|
set_process_dpi_awareness_context(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
}
|
||||||
|
else if (auto *set_process_dpi_awareness = DQN_CAST(SetProcessDpiAwarenessProc *)GetProcAddress(lib_handle, "SetProcessDpiAwareness"))
|
||||||
|
{
|
||||||
|
set_process_dpi_awareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
|
}
|
||||||
|
else if (auto *set_process_dpi_aware = DQN_CAST(SetProcessDpiAwareProc *)GetProcAddress(lib_handle, "SetProcessDpiAware"))
|
||||||
|
{
|
||||||
|
set_process_dpi_aware();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DQN_API void Dqn__WinDumpLastError(Dqn_String file, Dqn_String function, Dqn_uint line, char const *fmt, ...)
|
DQN_API void Dqn__WinDumpLastError(Dqn_String file, Dqn_String function, Dqn_uint line, char const *fmt, ...)
|
||||||
{
|
{
|
||||||
Dqn_WinErrorMsg msg = Dqn_WinLastError();
|
Dqn_WinErrorMsg msg = Dqn_WinLastError();
|
||||||
@ -7064,7 +7178,7 @@ DQN_API Dqn_String Dqn_WinArenaWCharToUTF8(Dqn_StringW src, Dqn_Arena *arena)
|
|||||||
DQN_API Dqn_StringW Dqn_WinExecutableDirectoryW(Dqn_Arena *arena)
|
DQN_API Dqn_StringW Dqn_WinExecutableDirectoryW(Dqn_Arena *arena)
|
||||||
{
|
{
|
||||||
wchar_t buffer[DQN_OS_WIN32_MAX_PATH];
|
wchar_t buffer[DQN_OS_WIN32_MAX_PATH];
|
||||||
int file_path_size = GetModuleFileNameW(nullptr /*module*/, buffer, DQN_CAST(DWORD)Dqn_ArrayCountI(buffer));
|
int file_path_size = GetModuleFileNameW(nullptr /*module*/, buffer, DQN_CAST(unsigned long)Dqn_ArrayCountI(buffer));
|
||||||
DQN_HARD_ASSERT_MSG(GetLastError() != ERROR_INSUFFICIENT_BUFFER, "How the hell?");
|
DQN_HARD_ASSERT_MSG(GetLastError() != ERROR_INSUFFICIENT_BUFFER, "How the hell?");
|
||||||
|
|
||||||
int directory_size = file_path_size;
|
int directory_size = file_path_size;
|
||||||
@ -7106,15 +7220,15 @@ DQN_API Dqn_StringW Dqn_WinCurrentDirW(Dqn_Arena *arena, Dqn_StringW suffix)
|
|||||||
Dqn_StringW result = {};
|
Dqn_StringW result = {};
|
||||||
|
|
||||||
// NOTE: required_size is the size required *including* the null-terminator
|
// NOTE: required_size is the size required *including* the null-terminator
|
||||||
DWORD required_size = GetCurrentDirectoryW(0, nullptr);
|
unsigned long required_size = GetCurrentDirectoryW(0, nullptr);
|
||||||
DWORD desired_size = required_size + DQN_CAST(DWORD) suffix.size;
|
unsigned long desired_size = required_size + DQN_CAST(unsigned long) suffix.size;
|
||||||
Dqn_ArenaScopeData temp_state = Dqn_ArenaBeginScope(arena);
|
Dqn_ArenaScopeData temp_state = Dqn_ArenaBeginScope(arena);
|
||||||
|
|
||||||
wchar_t *w_path = Dqn_ArenaNewArray(arena, wchar_t, desired_size, Dqn_ZeroMem::No);
|
wchar_t *w_path = Dqn_ArenaNewArray(arena, wchar_t, desired_size, Dqn_ZeroMem::No);
|
||||||
if (!w_path)
|
if (!w_path)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DWORD bytes_written_wo_null_terminator = GetCurrentDirectoryW(desired_size, w_path);
|
unsigned long bytes_written_wo_null_terminator = GetCurrentDirectoryW(desired_size, w_path);
|
||||||
if ((bytes_written_wo_null_terminator + 1) != required_size)
|
if ((bytes_written_wo_null_terminator + 1) != required_size)
|
||||||
{
|
{
|
||||||
// TODO(dqn): Error
|
// TODO(dqn): Error
|
||||||
@ -7147,7 +7261,7 @@ DQN_API bool Dqn_WinFolderWIterate(Dqn_StringW path, Dqn_WinFolderIteratorW *it)
|
|||||||
&find_data, /*LPVOID lpFindFileData,*/
|
&find_data, /*LPVOID lpFindFileData,*/
|
||||||
FindExSearchNameMatch, /*FINDEX_SEARCH_OPS fSearchOp,*/
|
FindExSearchNameMatch, /*FINDEX_SEARCH_OPS fSearchOp,*/
|
||||||
nullptr, /*LPVOID lpSearchFilter,*/
|
nullptr, /*LPVOID lpSearchFilter,*/
|
||||||
FIND_FIRST_EX_LARGE_FETCH /*DWORD dwAdditionalFlags)*/);
|
FIND_FIRST_EX_LARGE_FETCH /*unsigned long dwAdditionalFlags)*/);
|
||||||
|
|
||||||
if (it->handle == INVALID_HANDLE_VALUE)
|
if (it->handle == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
@ -7347,7 +7461,7 @@ DQN_API bool Dqn_WinNetHandlePump(Dqn_WinNetHandle *handle, char const *http_ver
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
DWORD bytes_read;
|
unsigned long bytes_read;
|
||||||
if (InternetReadFile(handle->http_handle, dest, dest_size, &bytes_read))
|
if (InternetReadFile(handle->http_handle, dest, dest_size, &bytes_read))
|
||||||
{
|
{
|
||||||
if (bytes_read == 0)
|
if (bytes_read == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user