Add search List api, add DPI awareness func, reduce win32 noise
This commit is contained in:
		
							parent
							
								
									9d0b0a2982
								
							
						
					
					
						commit
						15568a7919
					
				
							
								
								
									
										376
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										376
									
								
								dqn.h
									
									
									
									
									
								
							@ -357,17 +357,21 @@ static_assert(sizeof(Dqn_f64) == 8,                 "Sanity check f64 is 8 bytes
 | 
			
		||||
        #endif // DQN_WITH_WIN_NET
 | 
			
		||||
    #else
 | 
			
		||||
        // Taken from Windows.h
 | 
			
		||||
        typedef unsigned long DWORD;
 | 
			
		||||
        typedef unsigned short WORD;
 | 
			
		||||
        typedef void * BCRYPT_ALG_HANDLE;
 | 
			
		||||
        // typedef unsigned long DWORD;
 | 
			
		||||
        // typedef unsigned short WORD;
 | 
			
		||||
        // typedef int BOOL;
 | 
			
		||||
        // typedef void * HWND;
 | 
			
		||||
        // typedef void * HMODULE;
 | 
			
		||||
        // typedef void * HANDLE;
 | 
			
		||||
        // typedef long NTSTATUS;
 | 
			
		||||
 | 
			
		||||
        typedef union {
 | 
			
		||||
            struct {
 | 
			
		||||
                DWORD LowPart;
 | 
			
		||||
                unsigned long LowPart;
 | 
			
		||||
                long          HighPart;
 | 
			
		||||
            };
 | 
			
		||||
            struct {
 | 
			
		||||
                DWORD LowPart;
 | 
			
		||||
                unsigned long LowPart;
 | 
			
		||||
                long          HighPart;
 | 
			
		||||
            } u;
 | 
			
		||||
            Dqn_i64 QuadPart;
 | 
			
		||||
@ -1392,6 +1396,7 @@ struct Dqn_ListChunk
 | 
			
		||||
    Dqn_isize         size;
 | 
			
		||||
    Dqn_isize         count;
 | 
			
		||||
    Dqn_ListChunk<T> *next;
 | 
			
		||||
    Dqn_ListChunk<T> *prev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
@ -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
 | 
			
		||||
/*
 | 
			
		||||
   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;
 | 
			
		||||
   }
 | 
			
		||||
*/
 | 
			
		||||
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_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);
 | 
			
		||||
@ -2004,11 +2015,16 @@ DQN_API void           Dqn_JsonWriterF64(Dqn_JsonWriter *writer, Dqn_f64 value,
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
struct Dqn_WinErrorMsg
 | 
			
		||||
{
 | 
			
		||||
    DWORD code;
 | 
			
		||||
    unsigned long code;
 | 
			
		||||
    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
 | 
			
		||||
#define Dqn_WinDumpLastError(fmt, ...) Dqn__WinDumpLastError(DQN_STRING(__FILE__), DQN_STRING(__func__), __LINE__, fmt, ##__VA_ARGS__)
 | 
			
		||||
@ -2904,7 +2920,10 @@ DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS)
 | 
			
		||||
            return nullptr;
 | 
			
		||||
 | 
			
		||||
        if (list->tail)
 | 
			
		||||
        {
 | 
			
		||||
            list->tail->next = tail;
 | 
			
		||||
            tail->prev       = list->tail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        list->tail = tail;
 | 
			
		||||
 | 
			
		||||
@ -2919,13 +2938,26 @@ DQN_API T *Dqn__ListMake(Dqn_List<T> *list, Dqn_isize count DQN_CALL_SITE_ARGS)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    if (!list || !iterator || start_index < 0 || list->chunk_size <= 0)
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    if (!iterator->init)
 | 
			
		||||
    {
 | 
			
		||||
        *iterator = {};
 | 
			
		||||
        if (start_index == 0)
 | 
			
		||||
        {
 | 
			
		||||
            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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2951,6 +2983,53 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
    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)
 | 
			
		||||
    #pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
@ -2967,15 +3046,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
    #if !defined(DQN_NO_WIN32_MINIMAL_HEADER)
 | 
			
		||||
 | 
			
		||||
        // Taken from Windows.h
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        // Typedefs
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        typedef int BOOL;
 | 
			
		||||
        typedef void * HWND;
 | 
			
		||||
        typedef void * HMODULE;
 | 
			
		||||
        typedef void * HANDLE;
 | 
			
		||||
        typedef long NTSTATUS;
 | 
			
		||||
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        // Defines
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
@ -3007,8 +3077,8 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
        #define PAGE_READWRITE 0x04
 | 
			
		||||
 | 
			
		||||
        // NOTE: FindFirstFile
 | 
			
		||||
        #define INVALID_HANDLE_VALUE ((HANDLE)(long *)-1)
 | 
			
		||||
        #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
 | 
			
		||||
        #define INVALID_HANDLE_VALUE ((void *)(long *)-1)
 | 
			
		||||
        #define INVALID_FILE_ATTRIBUTES ((unsigned long)-1)
 | 
			
		||||
        #define FIND_FIRST_EX_LARGE_FETCH 0x00000002
 | 
			
		||||
        #define FILE_ATTRIBUTE_DIRECTORY 0x00000010
 | 
			
		||||
        #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
 | 
			
		||||
 | 
			
		||||
        // NOTE: Wininet
 | 
			
		||||
        typedef WORD INTERNET_PORT;
 | 
			
		||||
        typedef unsigned short INTERNET_PORT;
 | 
			
		||||
        #define INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
 | 
			
		||||
        #define INTERNET_DEFAULT_HTTPS_PORT 443 // HTTPS
 | 
			
		||||
        #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 TRUNCATE_EXISTING   5
 | 
			
		||||
 | 
			
		||||
        #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF)
 | 
			
		||||
        #define INVALID_FILE_SIZE ((unsigned long)0xFFFFFFFF)
 | 
			
		||||
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        // Data Structures
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        typedef union {
 | 
			
		||||
            struct {
 | 
			
		||||
                DWORD LowPart;
 | 
			
		||||
                DWORD HighPart;
 | 
			
		||||
                unsigned long LowPart;
 | 
			
		||||
                unsigned long HighPart;
 | 
			
		||||
            } DUMMYSTRUCTNAME;
 | 
			
		||||
            struct {
 | 
			
		||||
                DWORD LowPart;
 | 
			
		||||
                DWORD HighPart;
 | 
			
		||||
                unsigned long LowPart;
 | 
			
		||||
                unsigned long HighPart;
 | 
			
		||||
            } u;
 | 
			
		||||
            Dqn_u64 QuadPart;
 | 
			
		||||
        } ULARGE_INTEGER;
 | 
			
		||||
 | 
			
		||||
        typedef struct
 | 
			
		||||
        {
 | 
			
		||||
            DWORD dwLowDateTime;
 | 
			
		||||
            DWORD dwHighDateTime;
 | 
			
		||||
            unsigned long dwLowDateTime;
 | 
			
		||||
            unsigned long dwHighDateTime;
 | 
			
		||||
        } FILETIME;
 | 
			
		||||
 | 
			
		||||
        typedef struct
 | 
			
		||||
        {
 | 
			
		||||
            DWORD dwFileAttributes;
 | 
			
		||||
            unsigned long dwFileAttributes;
 | 
			
		||||
            FILETIME ftCreationTime;
 | 
			
		||||
            FILETIME ftLastAccessTime;
 | 
			
		||||
            FILETIME ftLastWriteTime;
 | 
			
		||||
            DWORD nFileSizeHigh;
 | 
			
		||||
            DWORD nFileSizeLow;
 | 
			
		||||
            unsigned long nFileSizeHigh;
 | 
			
		||||
            unsigned long nFileSizeLow;
 | 
			
		||||
        } WIN32_FILE_ATTRIBUTE_DATA;
 | 
			
		||||
 | 
			
		||||
        typedef enum
 | 
			
		||||
@ -3082,56 +3152,56 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
        } GET_FILEEX_INFO_LEVELS;
 | 
			
		||||
 | 
			
		||||
        typedef struct {
 | 
			
		||||
            DWORD nLength;
 | 
			
		||||
            unsigned long nLength;
 | 
			
		||||
            void *lpSecurityDescriptor;
 | 
			
		||||
            bool bInheritHandle;
 | 
			
		||||
        } SECURITY_ATTRIBUTES;
 | 
			
		||||
 | 
			
		||||
        typedef struct {
 | 
			
		||||
            union {
 | 
			
		||||
                DWORD dwOemId;          // Obsolete field...do not use
 | 
			
		||||
                unsigned long dwOemId;          // Obsolete field...do not use
 | 
			
		||||
                struct {
 | 
			
		||||
                    Dqn_u16 wProcessorArchitecture;
 | 
			
		||||
                    Dqn_u16 wReserved;
 | 
			
		||||
                } DUMMYSTRUCTNAME;
 | 
			
		||||
            } DUMMYUNIONNAME;
 | 
			
		||||
            DWORD dwPageSize;
 | 
			
		||||
            unsigned long dwPageSize;
 | 
			
		||||
            void *lpMinimumApplicationAddress;
 | 
			
		||||
            void *lpMaximumApplicationAddress;
 | 
			
		||||
            DWORD *dwActiveProcessorMask;
 | 
			
		||||
            DWORD dwNumberOfProcessors;
 | 
			
		||||
            DWORD dwProcessorType;
 | 
			
		||||
            DWORD dwAllocationGranularity;
 | 
			
		||||
            unsigned long *dwActiveProcessorMask;
 | 
			
		||||
            unsigned long dwNumberOfProcessors;
 | 
			
		||||
            unsigned long dwProcessorType;
 | 
			
		||||
            unsigned long dwAllocationGranularity;
 | 
			
		||||
            Dqn_u16 wProcessorLevel;
 | 
			
		||||
            Dqn_u16 wProcessorRevision;
 | 
			
		||||
        } SYSTEM_INFO;
 | 
			
		||||
 | 
			
		||||
        typedef struct {
 | 
			
		||||
            WORD wYear;
 | 
			
		||||
            WORD wMonth;
 | 
			
		||||
            WORD wDayOfWeek;
 | 
			
		||||
            WORD wDay;
 | 
			
		||||
            WORD wHour;
 | 
			
		||||
            WORD wMinute;
 | 
			
		||||
            WORD wSecond;
 | 
			
		||||
            WORD wMilliseconds;
 | 
			
		||||
            unsigned short wYear;
 | 
			
		||||
            unsigned short wMonth;
 | 
			
		||||
            unsigned short wDayOfWeek;
 | 
			
		||||
            unsigned short wDay;
 | 
			
		||||
            unsigned short wHour;
 | 
			
		||||
            unsigned short wMinute;
 | 
			
		||||
            unsigned short wSecond;
 | 
			
		||||
            unsigned short wMilliseconds;
 | 
			
		||||
        } SYSTEMTIME;
 | 
			
		||||
 | 
			
		||||
        typedef struct {
 | 
			
		||||
            DWORD dwFileAttributes;
 | 
			
		||||
            unsigned long dwFileAttributes;
 | 
			
		||||
            FILETIME ftCreationTime;
 | 
			
		||||
            FILETIME ftLastAccessTime;
 | 
			
		||||
            FILETIME ftLastWriteTime;
 | 
			
		||||
            DWORD nFileSizeHigh;
 | 
			
		||||
            DWORD nFileSizeLow;
 | 
			
		||||
            DWORD dwReserved0;
 | 
			
		||||
            DWORD dwReserved1;
 | 
			
		||||
            unsigned long nFileSizeHigh;
 | 
			
		||||
            unsigned long nFileSizeLow;
 | 
			
		||||
            unsigned long dwReserved0;
 | 
			
		||||
            unsigned long dwReserved1;
 | 
			
		||||
            wchar_t cFileName[MAX_PATH];
 | 
			
		||||
            wchar_t cAlternateFileName[14];
 | 
			
		||||
#ifdef _MAC
 | 
			
		||||
            DWORD dwFileType;
 | 
			
		||||
            DWORD dwCreatorType;
 | 
			
		||||
            WORD  wFinderFlags;
 | 
			
		||||
            unsigned long dwFileType;
 | 
			
		||||
            unsigned long dwCreatorType;
 | 
			
		||||
            unsigned short wFinderFlags;
 | 
			
		||||
#endif
 | 
			
		||||
        } WIN32_FIND_DATAW;
 | 
			
		||||
 | 
			
		||||
@ -3148,7 +3218,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
            FindExSearchMaxSearchOp
 | 
			
		||||
        } FINDEX_SEARCH_OPS;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        typedef enum {
 | 
			
		||||
            INTERNET_SCHEME_PARTIAL = -2,
 | 
			
		||||
            INTERNET_SCHEME_UNKNOWN = -1,
 | 
			
		||||
@ -3169,86 +3238,87 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
        } INTERNET_SCHEME;
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
            DWORD   dwSchemeLength;     // length of scheme name
 | 
			
		||||
            unsigned long    dwSchemeLength;     // length of scheme name
 | 
			
		||||
            INTERNET_SCHEME  nScheme;            // enumerated scheme type (if known)
 | 
			
		||||
            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
 | 
			
		||||
            char            *lpszUserName;       // pointer to user name
 | 
			
		||||
            DWORD   dwUserNameLength;   // length of user name
 | 
			
		||||
            unsigned long    dwUserNameLength;   // length of user name
 | 
			
		||||
            char            *lpszPassword;       // pointer to password
 | 
			
		||||
            DWORD   dwPasswordLength;   // length of password
 | 
			
		||||
            unsigned long    dwPasswordLength;   // length of password
 | 
			
		||||
            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)
 | 
			
		||||
            DWORD   dwExtraInfoLength;  // length of extra information
 | 
			
		||||
            unsigned long    dwExtraInfoLength;  // length of extra information
 | 
			
		||||
        } URL_COMPONENTSA;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        // Functions
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
        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          CopyFileW                (wchar_t const *existing_file_name, wchar_t const *new_file_name, BOOL fail_if_exists);
 | 
			
		||||
        BOOL          DeleteFileW              (wchar_t const *existing_file_name);
 | 
			
		||||
        BOOL          RemoveDirectoryW         (wchar_t const *lpPathName);
 | 
			
		||||
        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);
 | 
			
		||||
        /*BOOL*/     int             FindNextFileW              (void *hFindFile, WIN32_FIND_DATAW *lpFindFileData);
 | 
			
		||||
        /*HANDLE*/   void           *FindFirstFileExW           (wchar_t const *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, void *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, void *lpSearchFilter, unsigned long dwAdditionalFlags);
 | 
			
		||||
        /*DWORD*/    unsigned long   GetFileAttributesExW       (wchar_t const *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, WIN32_FILE_ATTRIBUTE_DATA *lpFileInformation);
 | 
			
		||||
        /*BOOL*/     int             GetFileSizeEx              (void *hFile, LARGE_INTEGER *lpFileSize);
 | 
			
		||||
 | 
			
		||||
        HMODULE       LoadLibraryA             (char const *file_name);
 | 
			
		||||
        bool          FreeLibrary              (void *lib_module);
 | 
			
		||||
        void         *GetProcAddress           (void *hmodule, char const *proc_name);
 | 
			
		||||
        unsigned int  GetWindowModuleFileNameA (void *hwnd, char *file_name, unsigned int file_name_max);
 | 
			
		||||
        HMODULE       GetModuleHandleA         (char const *lpModuleName);
 | 
			
		||||
        DWORD         GetModuleFileNameW       (HMODULE hModule, wchar_t *lpFilename, DWORD nSize);
 | 
			
		||||
        /*BOOL*/     int             MoveFileExW                (wchar_t const *lpExistingFileName, wchar_t const *lpNewFileName, unsigned long dwFlags);
 | 
			
		||||
        /*BOOL*/     int             CopyFileW                  (wchar_t const *lpExistingFileName, wchar_t const *lpNewFileName, int bFailIfExists);
 | 
			
		||||
        /*BOOL*/     int             DeleteFileW                (wchar_t const *lpExistingFileName);
 | 
			
		||||
        /*HANDLE*/   void           *CreateFileW                (wchar_t const *lpFileName, unsigned long dwDesiredAccess, unsigned long dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, unsigned long dwCreationDisposition, unsigned long dwFlagsAndAttributes, void *hTemplateFile);
 | 
			
		||||
        /*BOOL*/     int             ReadFile                   (void *hFile, void *lpBuffer, unsigned long nNumberOfBytesToRead, unsigned long *lpNumberOfBytesRead, struct OVERLAPPED *lpOverlapped);
 | 
			
		||||
        /*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);
 | 
			
		||||
        bool          QueryPerformanceFrequency(LARGE_INTEGER *frequency);
 | 
			
		||||
        /*DWORD*/    unsigned long   GetWindowModuleFileNameA   (void *hwnd, char *pszFileName, unsigned int cchFileNameMax);
 | 
			
		||||
        /*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);
 | 
			
		||||
        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);
 | 
			
		||||
        /*DWORD*/    unsigned long   WaitForSingleObject        (void *hHandle, unsigned long dwMilliseconds);
 | 
			
		||||
 | 
			
		||||
        void         *VirtualAlloc             (void *address, size_t size, DWORD allocation_type, DWORD protect);
 | 
			
		||||
        bool          VirtualFree              (void *address, size_t size, DWORD free_type);
 | 
			
		||||
        /*BOOL*/     int             QueryPerformanceCounter    (LARGE_INTEGER *lpPerformanceCount);
 | 
			
		||||
        /*BOOL*/     int             QueryPerformanceFrequency  (LARGE_INTEGER *lpFrequency);
 | 
			
		||||
 | 
			
		||||
        /*HANDLE*/   void           *CreateThread               (SECURITY_ATTRIBUTES *lpThreadAttributes, size_t dwStackSize, unsigned long (*lpStartAddress)(void *), void *lpParameter, unsigned long dwCreationFlags, unsigned long *lpThreadId);
 | 
			
		||||
        /*HANDLE*/   void           *CreateSemaphoreA           (SECURITY_ATTRIBUTES *lpSecurityAttributes, long lInitialCount, long lMaxCount, char *lpName);
 | 
			
		||||
        /*BOOL*/     int             ReleaseSemaphore           (void *semaphore, long lReleaseCount, long *lpPreviousCount);
 | 
			
		||||
                     void            Sleep                      (unsigned long dwMilliseconds);
 | 
			
		||||
 | 
			
		||||
                     void           *VirtualAlloc               (void *lpAddress, size_t dwSize, unsigned long flAllocationType, unsigned long flProtect);
 | 
			
		||||
        /*BOOL*/     int             VirtualFree                (void *lpAddress, size_t dwSize, unsigned long dwFreeType);
 | 
			
		||||
 | 
			
		||||
                     void            GetSystemInfo              (SYSTEM_INFO *system_info);
 | 
			
		||||
                     void            GetSystemTime              (SYSTEMTIME  *lpSystemTime);
 | 
			
		||||
                     void            GetSystemTimeAsFileTime    (FILETIME    *lpFileTime);
 | 
			
		||||
                     void            GetLocalTime               (SYSTEMTIME  *lpSystemTime);
 | 
			
		||||
 | 
			
		||||
        DWORD         FormatMessageA           (DWORD flags, void *source, DWORD message_id, DWORD language_id, char *buffer, DWORD size, va_list *args);
 | 
			
		||||
        DWORD         GetLastError             ();
 | 
			
		||||
        /*DWORD*/    unsigned long   FormatMessageA             (unsigned long dwFlags, void *lpSource, unsigned long dwMessageId, unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize, va_list *Arguments);
 | 
			
		||||
        /*DWORD*/    unsigned long   GetLastError               ();
 | 
			
		||||
 | 
			
		||||
        int           MultiByteToWideChar      (unsigned int CodePage, DWORD dwFlags, char const *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
 | 
			
		||||
        int           WideCharToMultiByte      (unsigned int CodePage, DWORD dwFlags, wchar_t const *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, char const *lpDefaultChar, bool *lpUsedDefaultChar);
 | 
			
		||||
                     int             MultiByteToWideChar        (unsigned int CodePage, unsigned long dwFlags, char const *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
 | 
			
		||||
                     int             WideCharToMultiByte        (unsigned int CodePage, unsigned long dwFlags, wchar_t const *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, char const *lpDefaultChar, bool *lpUsedDefaultChar);
 | 
			
		||||
 | 
			
		||||
        NTSTATUS      BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, wchar_t const *pszAlgId, wchar_t const *pszImplementation, unsigned long dwFlags);
 | 
			
		||||
        NTSTATUS      BCryptGenRandom            (BCRYPT_ALG_HANDLE hAlgorithm, unsigned char *pbBuffer, unsigned long cbBuffer, unsigned long dwFlags);
 | 
			
		||||
        /*NTSTATUS*/ long            BCryptOpenAlgorithmProvider(void *phAlgorithm, wchar_t const *pszAlgId, wchar_t const *pszImplementation, unsigned long dwFlags);
 | 
			
		||||
        /*NTSTATUS*/ long            BCryptGenRandom            (void *hAlgorithm, unsigned char *pbBuffer, unsigned long cbBuffer, unsigned long dwFlags);
 | 
			
		||||
 | 
			
		||||
        BOOL          InternetCrackUrlA          (char const *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSA *lpUrlComponents);
 | 
			
		||||
        void         *InternetOpenA              (char const *lpszAgent, DWORD dwAccessType, char const *lpszProxy, char const *lpszProxyBypass, DWORD dwFlags);
 | 
			
		||||
        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);
 | 
			
		||||
        BOOL          InternetReadFile           (void *hFile, void *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead);
 | 
			
		||||
        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);
 | 
			
		||||
        BOOL          InternetCloseHandle        (void *hInternet);
 | 
			
		||||
        HANDLE        CreateFileW                (wchar_t const *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
 | 
			
		||||
        BOOL          CloseHandle                (HANDLE hObject);
 | 
			
		||||
        BOOL          ReadFile                   (HANDLE hFile, void *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, struct OVERLAPPED *lpOverlapped);
 | 
			
		||||
        BOOL          GetFileSizeEx              (HANDLE hFile, LARGE_INTEGER *lpFileSize);
 | 
			
		||||
        /*BOOLAPI*/  int             InternetCrackUrlA          (char const *lpszUrl, unsigned long dwUrlLength, unsigned long dwFlags, URL_COMPONENTSA *lpUrlComponents);
 | 
			
		||||
        /*HANDLE*/   void           *InternetOpenA              (char const *lpszAgent, unsigned long dwAccessType, char const *lpszProxy, char const *lpszProxyBypass, unsigned long dwFlags);
 | 
			
		||||
        /*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);
 | 
			
		||||
        /*BOOLAPI*/  int             InternetSetOptionA         (void *hInternet, unsigned long dwOption, void *lpBuffer, unsigned long dwBufferLength);
 | 
			
		||||
        /*BOOLAPI*/  int             InternetReadFile           (void *hFile, void *lpBuffer, unsigned long dwNumberOfBytesToRead, unsigned long *lpdwNumberOfBytesRead);
 | 
			
		||||
        /*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)
 | 
			
		||||
#elif defined(DQN_OS_UNIX)
 | 
			
		||||
@ -3264,7 +3334,6 @@ Dqn_b32 Dqn_ListIterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
Dqn_Lib dqn__lib;
 | 
			
		||||
 | 
			
		||||
DQN_API void Dqn__ZeroMemBytes(void *ptr, Dqn_usize count, Dqn_ZeroMem zero_mem)
 | 
			
		||||
{
 | 
			
		||||
    if (zero_mem == Dqn_ZeroMem::Yes)
 | 
			
		||||
@ -3408,7 +3477,7 @@ DQN_API void Dqn_LogVDefault(Dqn_LogType type,
 | 
			
		||||
            Dqn_ThreadScratch scratch  = Dqn_ThreadGetScratch();
 | 
			
		||||
            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__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);
 | 
			
		||||
@ -4221,6 +4290,11 @@ DQN_API Dqn_ArenaMemBlock *Dqn__ArenaAllocateBlock(Dqn_Arena *arena, Dqn_isize r
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case Dqn_ArenaMemProvider::Virtual:
 | 
			
		||||
        {
 | 
			
		||||
            result = DQN_CAST(Dqn_ArenaMemBlock *)VirtualAlloc(nullptr, allocate_size, MEM_RESERVE, PAGE_READWRITE);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case Dqn_ArenaMemProvider::UserMemory:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
@ -4250,7 +4324,7 @@ DQN_API void Dqn__ArenaFreeBlock(Dqn_Arena *arena, Dqn_ArenaMemBlock *block)
 | 
			
		||||
    switch (arena->mem_provider)
 | 
			
		||||
    {
 | 
			
		||||
        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:
 | 
			
		||||
        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_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);
 | 
			
		||||
    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); };
 | 
			
		||||
    LARGE_INTEGER 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)
 | 
			
		||||
        {
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
    // TODO(dqn): We need to chunk this and ensure that readfile read the bytes we wanted.
 | 
			
		||||
    DWORD bytes_read = 0;
 | 
			
		||||
    if (ReadFile(file_handle, result, DQN_CAST(DWORD)win_file_size.QuadPart, &bytes_read, nullptr /*overlapped*/) == 0)
 | 
			
		||||
    unsigned long bytes_read = 0;
 | 
			
		||||
    if (ReadFile(file_handle, result, DQN_CAST(unsigned long)win_file_size.QuadPart, &bytes_read, nullptr /*overlapped*/) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        Dqn_ArenaEndScope(arena_undo);
 | 
			
		||||
        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
 | 
			
		||||
    (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)
 | 
			
		||||
    {
 | 
			
		||||
        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(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;
 | 
			
		||||
    if (!result)
 | 
			
		||||
        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(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;
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        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;
 | 
			
		||||
#if defined(DQN_OS_WIN32)
 | 
			
		||||
    LARGE_INTEGER integer = {};
 | 
			
		||||
    BOOL      qpc_result = QueryPerformanceCounter(&integer);
 | 
			
		||||
    int qpc_result = QueryPerformanceCounter(&integer);
 | 
			
		||||
    (void)qpc_result;
 | 
			
		||||
    DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP");
 | 
			
		||||
    result = integer.QuadPart;
 | 
			
		||||
@ -6597,7 +6672,8 @@ DQN_API void Dqn_LibDumpThreadContextArenaStats(Dqn_String file_path)
 | 
			
		||||
{
 | 
			
		||||
    (void)file_path;
 | 
			
		||||
#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)
 | 
			
		||||
    {
 | 
			
		||||
        // ---------------------------------------------------------------------
 | 
			
		||||
@ -6924,8 +7000,8 @@ DQN_API Dqn_WinErrorMsg Dqn_WinLastError()
 | 
			
		||||
    result.code   = GetLastError();
 | 
			
		||||
    result.str[0] = 0;
 | 
			
		||||
 | 
			
		||||
    DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
 | 
			
		||||
    HMODULE module_to_get_errors_from = nullptr;
 | 
			
		||||
    unsigned long flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
 | 
			
		||||
    void *module_to_get_errors_from = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (result.code >= 12000 && result.code <= 12175) // WinINET Errors
 | 
			
		||||
    {
 | 
			
		||||
@ -6935,16 +7011,54 @@ DQN_API Dqn_WinErrorMsg Dqn_WinLastError()
 | 
			
		||||
 | 
			
		||||
    result.size = FormatMessageA(flags,
 | 
			
		||||
                                 module_to_get_errors_from,                   // LPCVOID lpSource,
 | 
			
		||||
                                 result.code,                                 // DWORD   dwMessageId,
 | 
			
		||||
                                 0,                                           // DWORD   dwLanguageId,
 | 
			
		||||
                                 result.code,                                 // unsigned long   dwMessageId,
 | 
			
		||||
                                 0,                                           // unsigned long   dwLanguageId,
 | 
			
		||||
                                 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);
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    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_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)
 | 
			
		||||
{
 | 
			
		||||
    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?");
 | 
			
		||||
 | 
			
		||||
    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 = {};
 | 
			
		||||
 | 
			
		||||
    // NOTE: required_size is the size required *including* the null-terminator
 | 
			
		||||
    DWORD         required_size  = GetCurrentDirectoryW(0, nullptr);
 | 
			
		||||
    DWORD         desired_size   = required_size + DQN_CAST(DWORD) suffix.size;
 | 
			
		||||
    unsigned long         required_size  = GetCurrentDirectoryW(0, nullptr);
 | 
			
		||||
    unsigned long         desired_size   = required_size + DQN_CAST(unsigned long) suffix.size;
 | 
			
		||||
    Dqn_ArenaScopeData temp_state = Dqn_ArenaBeginScope(arena);
 | 
			
		||||
 | 
			
		||||
    wchar_t *w_path = Dqn_ArenaNewArray(arena, wchar_t, desired_size, Dqn_ZeroMem::No);
 | 
			
		||||
    if (!w_path)
 | 
			
		||||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        // TODO(dqn): Error
 | 
			
		||||
@ -7147,7 +7261,7 @@ DQN_API bool Dqn_WinFolderWIterate(Dqn_StringW path, Dqn_WinFolderIteratorW *it)
 | 
			
		||||
                                      &find_data,            /*LPVOID lpFindFileData,*/
 | 
			
		||||
                                      FindExSearchNameMatch, /*FINDEX_SEARCH_OPS fSearchOp,*/
 | 
			
		||||
                                      nullptr,               /*LPVOID lpSearchFilter,*/
 | 
			
		||||
                                      FIND_FIRST_EX_LARGE_FETCH /*DWORD dwAdditionalFlags)*/);
 | 
			
		||||
                                      FIND_FIRST_EX_LARGE_FETCH /*unsigned long dwAdditionalFlags)*/);
 | 
			
		||||
 | 
			
		||||
        if (it->handle == INVALID_HANDLE_VALUE)
 | 
			
		||||
            return false;
 | 
			
		||||
@ -7347,7 +7461,7 @@ DQN_API bool Dqn_WinNetHandlePump(Dqn_WinNetHandle *handle, char const *http_ver
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    bool result = true;
 | 
			
		||||
    DWORD bytes_read;
 | 
			
		||||
    unsigned long bytes_read;
 | 
			
		||||
    if (InternetReadFile(handle->http_handle, dest, dest_size, &bytes_read))
 | 
			
		||||
    {
 | 
			
		||||
        if (bytes_read == 0)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user