package sys_windows

import "core:c"

c_char      :: c.char
c_uchar     :: c.uchar
c_int       :: c.int
c_uint      :: c.uint
c_long      :: i32
c_longlong  :: c.longlong
c_ulong     :: u32
c_ulonglong :: c.ulonglong
c_short     :: c.short
c_ushort    :: c.ushort
size_t      :: c.size_t
wchar_t     :: c.wchar_t

DWORD :: c_ulong
DWORDLONG :: c.ulonglong
QWORD :: c.ulonglong
HANDLE :: distinct LPVOID
PHANDLE :: ^HANDLE
HINSTANCE :: HANDLE
HMODULE :: distinct HINSTANCE
HRESULT :: distinct LONG
HWND :: distinct HANDLE
HDC :: distinct HANDLE
HMONITOR :: distinct HANDLE
HICON :: distinct HANDLE
HCURSOR :: distinct HANDLE
HMENU :: distinct HANDLE
HBRUSH :: distinct HANDLE
HGDIOBJ :: distinct HANDLE
HBITMAP :: distinct HANDLE
HGLOBAL :: distinct HANDLE
HHOOK :: distinct HANDLE
HWINEVENTHOOK :: distinct HANDLE
HKEY :: distinct HANDLE
HDESK :: distinct HANDLE
HFONT :: distinct HANDLE
HRGN :: distinct HANDLE
BOOL :: distinct b32
BYTE :: distinct u8
BOOLEAN :: distinct b8
GROUP :: distinct c_uint
LARGE_INTEGER :: distinct c_longlong
ULARGE_INTEGER :: distinct c_ulonglong
PULARGE_INTEGER :: ^ULARGE_INTEGER
LONG :: c_long
UINT :: c_uint
INT  :: c_int
SHORT :: c_short
USHORT :: c_ushort
WCHAR :: wchar_t
SIZE_T :: uint
PSIZE_T :: ^SIZE_T
WORD :: u16
CHAR :: c_char
ULONG_PTR :: uint
PULONG_PTR :: ^ULONG_PTR
LPULONG_PTR :: ^ULONG_PTR
DWORD_PTR :: ULONG_PTR
LONG_PTR :: int
UINT_PTR :: uintptr
ULONG :: c_ulong
ULONGLONG :: c_ulonglong
LONGLONG :: c_longlong
UCHAR :: BYTE
NTSTATUS :: c.long
COLORREF :: DWORD
LPCOLORREF :: ^COLORREF
LPARAM :: LONG_PTR
WPARAM :: UINT_PTR
LRESULT :: LONG_PTR
LPRECT :: ^RECT
LPPOINT :: ^POINT
LSTATUS :: LONG
PHKEY :: ^HKEY
PUSHORT :: ^USHORT
PCHAR :: ^CHAR

UINT8  ::  u8
UINT16 :: u16
UINT32 :: u32
UINT64 :: u64

INT8  ::  i8
INT16 :: i16
INT32 :: i32
INT64 :: i64

ULONG32 :: u32
LONG32  :: i32

ULONG64 :: u64
LONG64  :: i64

DWORD64 :: u64
PDWORD64 :: ^DWORD64

PDWORD_PTR :: ^DWORD_PTR
ATOM :: distinct WORD

wstring :: [^]WCHAR
PWSTR   :: [^]WCHAR

PBYTE :: ^BYTE
LPBYTE :: ^BYTE
PBOOL :: ^BOOL
LPBOOL :: ^BOOL
LPCSTR :: cstring
LPCWSTR :: wstring
LPCTSTR :: wstring
LPDWORD :: ^DWORD
PCSTR :: cstring
PCWSTR :: wstring
PDWORD :: ^DWORD
LPHANDLE :: ^HANDLE
LPOVERLAPPED :: ^OVERLAPPED
LPPROCESS_INFORMATION :: ^PROCESS_INFORMATION
PSECURITY_ATTRIBUTES :: ^SECURITY_ATTRIBUTES
LPSECURITY_ATTRIBUTES :: ^SECURITY_ATTRIBUTES
LPSTARTUPINFOW :: ^STARTUPINFOW
LPTRACKMOUSEEVENT :: ^TRACKMOUSEEVENT
VOID :: rawptr
PVOID :: rawptr
LPVOID :: rawptr
PINT :: ^INT
LPINT :: ^INT
PUINT :: ^UINT
LPUINT :: ^UINT
LPWCH :: ^WCHAR
LPWORD :: ^WORD
PULONG :: ^ULONG
LPWIN32_FIND_DATAW :: ^WIN32_FIND_DATAW
LPWSADATA :: ^WSADATA
LPWSAPROTOCOL_INFO :: ^WSAPROTOCOL_INFO
LPSTR :: ^CHAR
LPWSTR :: ^WCHAR
OLECHAR :: WCHAR
LPOLESTR :: ^OLECHAR
LPFILETIME :: ^FILETIME
LPWSABUF :: ^WSABUF
LPWSAOVERLAPPED :: distinct rawptr
LPWSAOVERLAPPED_COMPLETION_ROUTINE :: distinct rawptr
LPCVOID :: rawptr

PACCESS_TOKEN :: PVOID
PSECURITY_DESCRIPTOR :: PVOID
PSID :: PVOID
PCLAIMS_BLOB :: PVOID

PCONDITION_VARIABLE :: ^CONDITION_VARIABLE
PLARGE_INTEGER :: ^LARGE_INTEGER
PSRWLOCK :: ^SRWLOCK

CREATE_WAITABLE_TIMER_MANUAL_RESET    :: 0x00000001
CREATE_WAITABLE_TIMER_HIGH_RESOLUTION :: 0x00000002

TIMER_QUERY_STATE  :: 0x0001
TIMER_MODIFY_STATE :: 0x0002
TIMER_ALL_ACCESS   :: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | TIMER_QUERY_STATE | TIMER_MODIFY_STATE

TRUE  :: BOOL(true)
FALSE :: BOOL(false)

SIZE :: struct {
	cx: LONG,
	cy: LONG,
}
PSIZE  :: ^SIZE
LPSIZE :: ^SIZE

MAXLONG :: 0x7fffffff

FILE_ATTRIBUTE_READONLY: DWORD : 0x00000001
FILE_ATTRIBUTE_HIDDEN: DWORD : 0x00000002
FILE_ATTRIBUTE_SYSTEM: DWORD : 0x00000004
FILE_ATTRIBUTE_DIRECTORY: DWORD : 0x00000010
FILE_ATTRIBUTE_ARCHIVE: DWORD : 0x00000020
FILE_ATTRIBUTE_DEVICE: DWORD : 0x00000040
FILE_ATTRIBUTE_NORMAL: DWORD : 0x00000080
FILE_ATTRIBUTE_TEMPORARY: DWORD : 0x00000100
FILE_ATTRIBUTE_SPARSE_FILE: DWORD : 0x00000200
FILE_ATTRIBUTE_REPARSE_Point: DWORD : 0x00000400
FILE_ATTRIBUTE_REPARSE_POINT: DWORD : 0x00000400
FILE_ATTRIBUTE_COMPRESSED: DWORD : 0x00000800
FILE_ATTRIBUTE_OFFLINE: DWORD : 0x00001000
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: DWORD : 0x00002000
FILE_ATTRIBUTE_ENCRYPTED: DWORD : 0x00004000

FILE_SHARE_READ: DWORD : 0x00000001
FILE_SHARE_WRITE: DWORD : 0x00000002
FILE_SHARE_DELETE: DWORD : 0x00000004
FILE_GENERIC_ALL: DWORD : 0x10000000
FILE_GENERIC_EXECUTE: DWORD : 0x20000000
FILE_GENERIC_READ: DWORD : 0x80000000
FILE_ALL_ACCESS :: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF

FILE_ACTION_ADDED            :: 0x00000001
FILE_ACTION_REMOVED          :: 0x00000002
FILE_ACTION_MODIFIED         :: 0x00000003
FILE_ACTION_RENAMED_OLD_NAME :: 0x00000004
FILE_ACTION_RENAMED_NEW_NAME :: 0x00000005

FILE_NOTIFY_CHANGE_FILE_NAME   :: 0x00000001
FILE_NOTIFY_CHANGE_DIR_NAME    :: 0x00000002
FILE_NOTIFY_CHANGE_ATTRIBUTES  :: 0x00000004
FILE_NOTIFY_CHANGE_SIZE        :: 0x00000008
FILE_NOTIFY_CHANGE_LAST_WRITE  :: 0x00000010
FILE_NOTIFY_CHANGE_LAST_ACCESS :: 0x00000020
FILE_NOTIFY_CHANGE_CREATION    :: 0x00000040
FILE_NOTIFY_CHANGE_SECURITY    :: 0x00000100

CREATE_NEW: DWORD : 1
CREATE_ALWAYS: DWORD : 2
OPEN_ALWAYS: DWORD : 4
OPEN_EXISTING: DWORD : 3
TRUNCATE_EXISTING: DWORD : 5

FILE_READ_DATA            : DWORD : 0x00000001
FILE_LIST_DIRECTORY       : DWORD : 0x00000001
FILE_WRITE_DATA           : DWORD : 0x00000002
FILE_ADD_FILE             : DWORD : 0x00000002
FILE_APPEND_DATA          : DWORD : 0x00000004
FILE_ADD_SUBDIRECTORY     : DWORD : 0x00000004
FILE_CREATE_PIPE_INSTANCE : DWORD : 0x00000004
FILE_READ_EA              : DWORD : 0x00000008
FILE_WRITE_EA             : DWORD : 0x00000010
FILE_EXECUTE              : DWORD : 0x00000020
FILE_TRAVERSE             : DWORD : 0x00000020
FILE_DELETE_CHILD         : DWORD : 0x00000040
FILE_READ_ATTRIBUTES      : DWORD : 0x00000080
FILE_WRITE_ATTRIBUTES     : DWORD : 0x00000100

GENERIC_READ    : DWORD : 0x80000000
GENERIC_WRITE   : DWORD : 0x40000000
GENERIC_EXECUTE : DWORD : 0x20000000
GENERIC_ALL     : DWORD : 0x10000000

FILE_GENERIC_WRITE: DWORD : STANDARD_RIGHTS_WRITE |
	FILE_WRITE_DATA |
	FILE_WRITE_ATTRIBUTES |
	FILE_WRITE_EA |
	FILE_APPEND_DATA |
	SYNCHRONIZE

FILE_FLAG_OPEN_REPARSE_POINT: DWORD : 0x00200000
FILE_FLAG_BACKUP_SEMANTICS: DWORD : 0x02000000
SECURITY_SQOS_PRESENT: DWORD : 0x00100000

FIONBIO: c_ulong : 0x8004667e

OWNER_SECURITY_INFORMATION               :: 0x00000001
GROUP_SECURITY_INFORMATION               :: 0x00000002
DACL_SECURITY_INFORMATION                :: 0x00000004
SACL_SECURITY_INFORMATION                :: 0x00000008
LABEL_SECURITY_INFORMATION               :: 0x00000010
ATTRIBUTE_SECURITY_INFORMATION           :: 0x00000020
SCOPE_SECURITY_INFORMATION               :: 0x00000040
PROCESS_TRUST_LABEL_SECURITY_INFORMATION :: 0x00000080
ACCESS_FILTER_SECURITY_INFORMATION       :: 0x00000100
BACKUP_SECURITY_INFORMATION              :: 0x00010000
PROTECTED_DACL_SECURITY_INFORMATION      :: 0x80000000
PROTECTED_SACL_SECURITY_INFORMATION      :: 0x40000000
UNPROTECTED_DACL_SECURITY_INFORMATION    :: 0x20000000
UNPROTECTED_SACL_SECURITY_INFORMATION    :: 0x10000000

GET_FILEEX_INFO_LEVELS :: distinct i32
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1


DIAGNOSTIC_REASON_VERSION :: 0

DIAGNOSTIC_REASON_SIMPLE_STRING   :: 0x00000001
DIAGNOSTIC_REASON_DETAILED_STRING :: 0x00000002
DIAGNOSTIC_REASON_NOT_SPECIFIED   :: 0x80000000

ENUM_CURRENT_SETTINGS  : DWORD : 4294967295 // (DWORD)-1
ENUM_REGISTRY_SETTINGS : DWORD : 4294967294 // (DWORD)-2

// Defines for power request APIs

POWER_REQUEST_CONTEXT_VERSION :: DIAGNOSTIC_REASON_VERSION

POWER_REQUEST_CONTEXT_SIMPLE_STRING   :: DIAGNOSTIC_REASON_SIMPLE_STRING
POWER_REQUEST_CONTEXT_DETAILED_STRING :: DIAGNOSTIC_REASON_DETAILED_STRING

REASON_CONTEXT :: struct {
	Version: ULONG,
	Flags: DWORD,
	Reason: struct #raw_union {
		Detailed: struct {
			LocalizedReasonModule: HMODULE,
			LocalizedReasonId: ULONG,
			ReasonStringCount: ULONG,
			ReasonStrings: ^LPWSTR,
		},
		SimpleReasonString: LPWSTR,
	},
}
PREASON_CONTEXT :: ^REASON_CONTEXT

// RRF - Registry Routine Flags (for RegGetValue)
RRF_RT_REG_NONE      :: 0x00000001
RRF_RT_REG_SZ        :: 0x00000002
RRF_RT_REG_EXPAND_SZ :: 0x00000004
RRF_RT_REG_BINARY    :: 0x00000008
RRF_RT_REG_DWORD     :: 0x00000010
RRF_RT_REG_MULTI_SZ  :: 0x00000020
RRF_RT_REG_QWORD     :: 0x00000040
RRF_RT_DWORD         :: (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD)
RRF_RT_QWORD         :: (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD)
RRF_RT_ANY           :: 0x0000ffff
RRF_NOEXPAND         :: 0x10000000
RRF_ZEROONFAILURE    :: 0x20000000

ACCESS_MASK :: DWORD
PACCESS_MASK :: ^ACCESS_MASK
REGSAM :: ACCESS_MASK

// Reserved Key Handles.
HKEY_CLASSES_ROOT                :: HKEY(uintptr(0x80000000))
HKEY_CURRENT_USER                :: HKEY(uintptr(0x80000001))
HKEY_LOCAL_MACHINE               :: HKEY(uintptr(0x80000002))
HKEY_USERS                       :: HKEY(uintptr(0x80000003))
HKEY_PERFORMANCE_DATA            :: HKEY(uintptr(0x80000004))
HKEY_PERFORMANCE_TEXT            :: HKEY(uintptr(0x80000050))
HKEY_PERFORMANCE_NLSTEXT         :: HKEY(uintptr(0x80000060))
HKEY_CURRENT_CONFIG              :: HKEY(uintptr(0x80000005))
HKEY_DYN_DATA                    :: HKEY(uintptr(0x80000006))
HKEY_CURRENT_USER_LOCAL_SETTINGS :: HKEY(uintptr(0x80000007))

// The following are masks for the predefined standard access types
DELETE       : DWORD : 0x00010000
READ_CONTROL : DWORD : 0x00020000
WRITE_DAC    : DWORD : 0x00040000
WRITE_OWNER  : DWORD : 0x00080000
SYNCHRONIZE  : DWORD : 0x00100000

STANDARD_RIGHTS_REQUIRED : DWORD : 0x000F0000
STANDARD_RIGHTS_READ     : DWORD : READ_CONTROL
STANDARD_RIGHTS_WRITE    : DWORD : READ_CONTROL
STANDARD_RIGHTS_EXECUTE  : DWORD : READ_CONTROL
STANDARD_RIGHTS_ALL      : DWORD : 0x001F0000
SPECIFIC_RIGHTS_ALL      : DWORD : 0x0000FFFF

// Registry Specific Access Rights.
KEY_QUERY_VALUE        :: 0x0001
KEY_SET_VALUE          :: 0x0002
KEY_CREATE_SUB_KEY     :: 0x0004
KEY_ENUMERATE_SUB_KEYS :: 0x0008
KEY_NOTIFY             :: 0x0010
KEY_CREATE_LINK        :: 0x0020
KEY_WOW64_32KEY        :: 0x0200
KEY_WOW64_64KEY        :: 0x0100
KEY_WOW64_RES          :: 0x0300

KEY_READ :: (STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE)
KEY_WRITE :: (STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE)
KEY_EXECUTE :: (KEY_READ) & (~SYNCHRONIZE)
KEY_ALL_ACCESS :: (STANDARD_RIGHTS_ALL |
	KEY_QUERY_VALUE |
	KEY_SET_VALUE |
	KEY_CREATE_SUB_KEY |
	KEY_ENUMERATE_SUB_KEYS |
	KEY_NOTIFY |
	KEY_CREATE_LINK) & (~SYNCHRONIZE)

// Open/Create Options
REG_OPTION_RESERVED        :: 0x00000000
REG_OPTION_NON_VOLATILE    :: 0x00000000
REG_OPTION_VOLATILE        :: 0x00000001
REG_OPTION_CREATE_LINK     :: 0x00000002
REG_OPTION_BACKUP_RESTORE  :: 0x00000004
REG_OPTION_OPEN_LINK       :: 0x00000008
REG_OPTION_DONT_VIRTUALIZE :: 0x00000010

REG_LEGAL_OPTION :: REG_OPTION_RESERVED |
	REG_OPTION_NON_VOLATILE |
	REG_OPTION_VOLATILE |
	REG_OPTION_CREATE_LINK |
	REG_OPTION_BACKUP_RESTORE |
	REG_OPTION_OPEN_LINK |
	REG_OPTION_DONT_VIRTUALIZE

REG_OPEN_LEGAL_OPTION :: REG_OPTION_RESERVED |
	REG_OPTION_BACKUP_RESTORE |
	REG_OPTION_OPEN_LINK |
	REG_OPTION_DONT_VIRTUALIZE

// Key creation/open disposition
REG_CREATED_NEW_KEY     :: 0x00000001
REG_OPENED_EXISTING_KEY :: 0x00000002

// hive format to be used by Reg(Nt)SaveKeyEx
REG_STANDARD_FORMAT :: 1
REG_LATEST_FORMAT   :: 2
REG_NO_COMPRESSION  :: 4

// Key restore & hive load flags
REG_WHOLE_HIVE_VOLATILE       :: 0x00000001
REG_REFRESH_HIVE              :: 0x00000002
REG_NO_LAZY_FLUSH             :: 0x00000004
REG_FORCE_RESTORE             :: 0x00000008
REG_APP_HIVE                  :: 0x00000010
REG_PROCESS_PRIVATE           :: 0x00000020
REG_START_JOURNAL             :: 0x00000040
REG_HIVE_EXACT_FILE_GROWTH    :: 0x00000080
REG_HIVE_NO_RM                :: 0x00000100
REG_HIVE_SINGLE_LOG           :: 0x00000200
REG_BOOT_HIVE                 :: 0x00000400
REG_LOAD_HIVE_OPEN_HANDLE     :: 0x00000800
REG_FLUSH_HIVE_FILE_GROWTH    :: 0x00001000
REG_OPEN_READ_ONLY            :: 0x00002000
REG_IMMUTABLE                 :: 0x00004000
REG_NO_IMPERSONATION_FALLBACK :: 0x00008000
REG_APP_HIVE_OPEN_READ_ONLY   :: REG_OPEN_READ_ONLY

// Unload Flags
REG_FORCE_UNLOAD       :: 1
REG_UNLOAD_LEGAL_FLAGS :: REG_FORCE_UNLOAD

// Notify filter values
REG_NOTIFY_CHANGE_NAME       :: 0x00000001
REG_NOTIFY_CHANGE_ATTRIBUTES :: 0x00000002
REG_NOTIFY_CHANGE_LAST_SET   :: 0x00000004
REG_NOTIFY_CHANGE_SECURITY   :: 0x00000008
REG_NOTIFY_THREAD_AGNOSTIC   :: 0x10000000

REG_LEGAL_CHANGE_FILTER :: REG_NOTIFY_CHANGE_NAME |
	REG_NOTIFY_CHANGE_ATTRIBUTES |
	REG_NOTIFY_CHANGE_LAST_SET |
	REG_NOTIFY_CHANGE_SECURITY |
	REG_NOTIFY_THREAD_AGNOSTIC

// Predefined Value Types.
REG_NONE                       :: 0
REG_SZ                         :: 1
REG_EXPAND_SZ                  :: 2
REG_BINARY                     :: 3
REG_DWORD                      :: 4
REG_DWORD_LITTLE_ENDIAN        :: 4
REG_DWORD_BIG_ENDIAN           :: 5
REG_LINK                       :: 6
REG_MULTI_SZ                   :: 7
REG_RESOURCE_LIST              :: 8
REG_FULL_RESOURCE_DESCRIPTOR   :: 9
REG_RESOURCE_REQUIREMENTS_LIST :: 10
REG_QWORD                      :: 11
REG_QWORD_LITTLE_ENDIAN        :: 11

BSMINFO :: struct {
	cbSize: UINT,
	hdesk: HDESK,
	hwnd: HWND,
	luid: LUID,
}
PBSMINFO :: ^BSMINFO

// Broadcast Special Message Recipient list
BSM_ALLCOMPONENTS      :: 0x00000000
BSM_VXDS               :: 0x00000001
BSM_NETDRIVER          :: 0x00000002
BSM_INSTALLABLEDRIVERS :: 0x00000004
BSM_APPLICATIONS       :: 0x00000008
BSM_ALLDESKTOPS        :: 0x00000010

// Broadcast Special Message Flags
BSF_QUERY              :: 0x00000001
BSF_IGNORECURRENTTASK  :: 0x00000002
BSF_FLUSHDISK          :: 0x00000004
BSF_NOHANG             :: 0x00000008
BSF_POSTMESSAGE        :: 0x00000010
BSF_FORCEIFHUNG        :: 0x00000020
BSF_NOTIMEOUTIFNOTHUNG :: 0x00000040
BSF_ALLOWSFW           :: 0x00000080
BSF_SENDNOTIFYMESSAGE  :: 0x00000100
BSF_RETURNHDESK        :: 0x00000200
BSF_LUID               :: 0x00000400

BROADCAST_QUERY_DENY :: 0x424D5144

// Special HWND value for use with PostMessage() and SendMessage()
HWND_BROADCAST :: HWND(uintptr(0xffff))
HWND_MESSAGE   :: HWND(~uintptr(0) - 2) // -3

// Color Types
CTLCOLOR_MSGBOX    :: 0
CTLCOLOR_EDIT      :: 1
CTLCOLOR_LISTBOX   :: 2
CTLCOLOR_BTN       :: 3
CTLCOLOR_DLG       :: 4
CTLCOLOR_SCROLLBAR :: 5
CTLCOLOR_STATIC    :: 6
CTLCOLOR_MAX       :: 7

COLOR_SCROLLBAR           :: 0
COLOR_BACKGROUND          :: 1
COLOR_ACTIVECAPTION       :: 2
COLOR_INACTIVECAPTION     :: 3
COLOR_MENU                :: 4
COLOR_WINDOW              :: 5
COLOR_WINDOWFRAME         :: 6
COLOR_MENUTEXT            :: 7
COLOR_WINDOWTEXT          :: 8
COLOR_CAPTIONTEXT         :: 9
COLOR_ACTIVEBORDER        :: 10
COLOR_INACTIVEBORDER      :: 11
COLOR_APPWORKSPACE        :: 12
COLOR_HIGHLIGHT           :: 13
COLOR_HIGHLIGHTTEXT       :: 14
COLOR_BTNFACE             :: 15
COLOR_BTNSHADOW           :: 16
COLOR_GRAYTEXT            :: 17
COLOR_BTNTEXT             :: 18
COLOR_INACTIVECAPTIONTEXT :: 19
COLOR_BTNHIGHLIGHT        :: 20

COLOR_3DDKSHADOW              :: 21
COLOR_3DLIGHT                 :: 22
COLOR_INFOTEXT                :: 23
COLOR_INFOBK                  :: 24
COLOR_HOTLIGHT                :: 26
COLOR_GRADIENTACTIVECAPTION   :: 27
COLOR_GRADIENTINACTIVECAPTION :: 28
COLOR_MENUHILIGHT             :: 29
COLOR_MENUBAR                 :: 30

COLOR_DESKTOP     :: COLOR_BACKGROUND
COLOR_3DFACE      :: COLOR_BTNFACE
COLOR_3DSHADOW    :: COLOR_BTNSHADOW
COLOR_3DHIGHLIGHT :: COLOR_BTNHIGHLIGHT
COLOR_3DHILIGHT   :: COLOR_BTNHIGHLIGHT
COLOR_BTNHILIGHT  :: COLOR_BTNHIGHLIGHT

// Combo Box Notification Codes
CBN_ERRSPACE     :: -1
CBN_SELCHANGE    :: 1
CBN_DBLCLK       :: 2
CBN_SETFOCUS     :: 3
CBN_KILLFOCUS    :: 4
CBN_EDITCHANGE   :: 5
CBN_EDITUPDATE   :: 6
CBN_DROPDOWN     :: 7
CBN_CLOSEUP      :: 8
CBN_SELENDOK     :: 9
CBN_SELENDCANCEL :: 10

// Combo Box styles
CBS_SIMPLE            :: 0x0001
CBS_DROPDOWN          :: 0x0002
CBS_DROPDOWNLIST      :: 0x0003
CBS_OWNERDRAWFIXED    :: 0x0010
CBS_OWNERDRAWVARIABLE :: 0x0020
CBS_AUTOHSCROLL       :: 0x0040
CBS_OEMCONVERT        :: 0x0080
CBS_SORT              :: 0x0100
CBS_HASSTRINGS        :: 0x0200
CBS_NOINTEGRALHEIGHT  :: 0x0400
CBS_DISABLENOSCROLL   :: 0x0800
CBS_UPPERCASE         :: 0x2000
CBS_LOWERCASE         :: 0x4000

// User Button Notification Codes
BN_CLICKED       :: 0
BN_PAINT         :: 1
BN_HILITE        :: 2
BN_UNHILITE      :: 3
BN_DISABLE       :: 4
BN_DOUBLECLICKED :: 5
BN_PUSHED        :: BN_HILITE
BN_UNPUSHED      :: BN_UNHILITE
BN_DBLCLK        :: BN_DOUBLECLICKED
BN_SETFOCUS      :: 6
BN_KILLFOCUS     :: 7

// Button Control Styles
BS_PUSHBUTTON      :: 0x00000000
BS_DEFPUSHBUTTON   :: 0x00000001
BS_CHECKBOX        :: 0x00000002
BS_AUTOCHECKBOX    :: 0x00000003
BS_RADIOBUTTON     :: 0x00000004
BS_3STATE          :: 0x00000005
BS_AUTO3STATE      :: 0x00000006
BS_GROUPBOX        :: 0x00000007
BS_USERBUTTON      :: 0x00000008
BS_AUTORADIOBUTTON :: 0x00000009
BS_PUSHBOX         :: 0x0000000A
BS_OWNERDRAW       :: 0x0000000B
BS_TYPEMASK        :: 0x0000000F
BS_LEFTTEXT        :: 0x00000020
BS_TEXT            :: 0x00000000
BS_ICON            :: 0x00000040
BS_BITMAP          :: 0x00000080
BS_LEFT            :: 0x00000100
BS_RIGHT           :: 0x00000200
BS_CENTER          :: 0x00000300
BS_TOP             :: 0x00000400
BS_BOTTOM          :: 0x00000800
BS_VCENTER         :: 0x00000C00
BS_PUSHLIKE        :: 0x00001000
BS_MULTILINE       :: 0x00002000
BS_NOTIFY          :: 0x00004000
BS_FLAT            :: 0x00008000
BS_RIGHTBUTTON     :: BS_LEFTTEXT
BS_SPLITBUTTON     :: 0x0000000C
BS_DEFSPLITBUTTON  :: 0x0000000D
BS_COMMANDLINK     :: 0x0000000E
BS_DEFCOMMANDLINK  :: 0x0000000F

// Button Control Messages
BST_UNCHECKED     :: 0x0000
BST_CHECKED       :: 0x0001
BST_INDETERMINATE :: 0x0002
BST_PUSHED        :: 0x0004
BST_FOCUS         :: 0x0008

// Static Control Constants
SS_LEFT            :: 0x00000000
SS_CENTER          :: 0x00000001
SS_RIGHT           :: 0x00000002
SS_ICON            :: 0x00000003
SS_BLACKRECT       :: 0x00000004
SS_GRAYRECT        :: 0x00000005
SS_WHITERECT       :: 0x00000006
SS_BLACKFRAME      :: 0x00000007
SS_GRAYFRAME       :: 0x00000008
SS_WHITEFRAME      :: 0x00000009
SS_USERITEM        :: 0x0000000A
SS_SIMPLE          :: 0x0000000B
SS_LEFTNOWORDWRAP  :: 0x0000000C
SS_OWNERDRAW       :: 0x0000000D
SS_BITMAP          :: 0x0000000E
SS_ENHMETAFILE     :: 0x0000000F
SS_ETCHEDHORZ      :: 0x00000010
SS_ETCHEDVERT      :: 0x00000011
SS_ETCHEDFRAME     :: 0x00000012
SS_TYPEMASK        :: 0x0000001F
SS_REALSIZECONTROL :: 0x00000040
SS_NOPREFIX        :: 0x00000080
SS_NOTIFY          :: 0x00000100
SS_CENTERIMAGE     :: 0x00000200
SS_RIGHTJUST       :: 0x00000400
SS_REALSIZEIMAGE   :: 0x00000800
SS_SUNKEN          :: 0x00001000
SS_EDITCONTROL     :: 0x00002000
SS_ENDELLIPSIS     :: 0x00004000
SS_PATHELLIPSIS    :: 0x00008000
SS_WORDELLIPSIS    :: 0x0000C000
SS_ELLIPSISMASK    :: 0x0000C000

// Edit Control Styles
ES_LEFT        :: 0x0000
ES_CENTER      :: 0x0001
ES_RIGHT       :: 0x0002
ES_MULTILINE   :: 0x0004
ES_UPPERCASE   :: 0x0008
ES_LOWERCASE   :: 0x0010
ES_PASSWORD    :: 0x0020
ES_AUTOVSCROLL :: 0x0040
ES_AUTOHSCROLL :: 0x0080
ES_NOHIDESEL   :: 0x0100
ES_OEMCONVERT  :: 0x0400
ES_READONLY    :: 0x0800
ES_WANTRETURN  :: 0x1000
ES_NUMBER      :: 0x2000

// Edit Control Notification Codes
EN_SETFOCUS     :: 0x0100
EN_KILLFOCUS    :: 0x0200
EN_CHANGE       :: 0x0300
EN_UPDATE       :: 0x0400
EN_ERRSPACE     :: 0x0500
EN_MAXTEXT      :: 0x0501
EN_HSCROLL      :: 0x0601
EN_VSCROLL      :: 0x0602
EN_ALIGN_LTR_EC :: 0x0700
EN_ALIGN_RTL_EC :: 0x0701

// Font Weights
FW_DONTCARE   :: 0
FW_THIN       :: 100
FW_EXTRALIGHT :: 200
FW_LIGHT      :: 300
FW_NORMAL     :: 400
FW_MEDIUM     :: 500
FW_SEMIBOLD   :: 600
FW_BOLD       :: 700
FW_EXTRABOLD  :: 800
FW_HEAVY      :: 900

FW_ULTRALIGHT :: FW_EXTRALIGHT
FW_REGULAR    :: FW_NORMAL
FW_DEMIBOLD   :: FW_SEMIBOLD
FW_ULTRABOLD  :: FW_EXTRABOLD
FW_BLACK      :: FW_HEAVY

PTIMERAPCROUTINE :: #type proc "system" (lpArgToCompletionRoutine: LPVOID, dwTimerLowValue, dwTimerHighValue: DWORD)

TIMERPROC :: #type proc "system" (HWND, UINT, UINT_PTR, DWORD)

WNDPROC :: #type proc "system" (HWND, UINT, WPARAM, LPARAM) -> LRESULT

HOOKPROC :: #type proc "system" (code: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT

WINEVENTPROC :: #type proc "system" (
	hWinEventHook: HWINEVENTHOOK,
	event: DWORD,
	hwnd: HWND,
	idObject, idChild: LONG,
	idEventThread, dwmsEventTime: DWORD,
)

CWPRETSTRUCT :: struct {
	lResult: LRESULT,
	lParam: LPARAM,
	wParam: WPARAM,
	message: UINT,
	hwnd: HWND,
}

MSLLHOOKSTRUCT :: struct {
	pt: POINT,
	mouseData: DWORD,
	flags: DWORD,
	time: DWORD,
	dwExtraInfo: ULONG_PTR,
}

KBDLLHOOKSTRUCT :: struct {
	vkCode: DWORD,
	scanCode: DWORD,
	flags: DWORD,
	time: DWORD,
	dwExtraInfo: ULONG_PTR,
}

MOUSEINPUT :: struct {
	dx: LONG,
	dy: LONG,
	mouseData: DWORD,
	dwFlags: DWORD,
	time: DWORD,
	dwExtraInfo: ULONG_PTR,
}

KEYBDINPUT :: struct {
	wVk: WORD,
	wScan: WORD,
	dwFlags: DWORD,
	time: DWORD,
	dwExtraInfo: ULONG_PTR,
}

HARDWAREINPUT :: struct {
	uMsg: DWORD,
	wParamL: WORD,
	wParamH: WORD,
}

INPUT_TYPE :: enum DWORD {
	MOUSE = 0,
	KEYBOARD = 1,
	HARDWARE = 2,
}

INPUT :: struct {
	type: INPUT_TYPE,
	using _: struct #raw_union {
		mi: MOUSEINPUT,
		ki: KEYBDINPUT,
		hi: HARDWAREINPUT,
	},
}

MOUSEEVENTF_MOVE :: 0x0001
MOUSEEVENTF_LEFTDOWN :: 0x0002
MOUSEEVENTF_LEFTUP :: 0x0004
MOUSEEVENTF_RIGHTDOWN :: 0x0008
MOUSEEVENTF_RIGHTUP :: 0x0010
MOUSEEVENTF_MIDDLEDOWN :: 0x0020
MOUSEEVENTF_MIDDLEUP :: 0x0040
MOUSEEVENTF_XDOWN :: 0x0080
MOUSEEVENTF_XUP :: 0x0100
MOUSEEVENTF_WHEEL :: 0x0800
MOUSEEVENTF_HWHEEL :: 0x1000
MOUSEEVENTF_MOVE_NOCOALESCE :: 0x2000
MOUSEEVENTF_VIRTUALDESK :: 0x4000
MOUSEEVENTF_ABSOLUTE :: 0x8000

WNDCLASSA :: struct {
	style: UINT,
	lpfnWndProc: WNDPROC,
	cbClsExtra: c_int,
	cbWndExtra: c_int,
	hInstance: HINSTANCE,
	hIcon: HICON,
	hCursor: HCURSOR,
	hbrBackground: HBRUSH,
	lpszMenuName: LPCSTR,
	lpszClassName: LPCSTR,
}

WNDCLASSW :: struct {
	style: UINT,
	lpfnWndProc: WNDPROC,
	cbClsExtra: c_int,
	cbWndExtra: c_int,
	hInstance: HINSTANCE,
	hIcon: HICON,
	hCursor: HCURSOR,
	hbrBackground: HBRUSH,
	lpszMenuName: LPCWSTR,
	lpszClassName: LPCWSTR,
}

WNDCLASSEXA :: struct {
	cbSize: UINT,
	style: UINT,
	lpfnWndProc: WNDPROC,
	cbClsExtra: c_int,
	cbWndExtra: c_int,
	hInstance: HINSTANCE,
	hIcon: HICON,
	hCursor: HCURSOR,
	hbrBackground: HBRUSH,
	lpszMenuName: LPCSTR,
	lpszClassName: LPCSTR,
	hIconSm: HICON,
}

WNDCLASSEXW :: struct {
	cbSize: UINT,
	style: UINT,
	lpfnWndProc: WNDPROC,
	cbClsExtra: c_int,
	cbWndExtra: c_int,
	hInstance: HINSTANCE,
	hIcon: HICON,
	hCursor: HCURSOR,
	hbrBackground: HBRUSH,
	lpszMenuName: LPCWSTR,
	lpszClassName: LPCWSTR,
	hIconSm: HICON,
}

MSG :: struct {
	hwnd: HWND,
	message: UINT,
	wParam: WPARAM,
	lParam: LPARAM,
	time: DWORD,
	pt: POINT,
}

LPMSG :: ^MSG

NOTIFYICONDATAW :: struct {
	cbSize: DWORD,
	hWnd: HWND,
	uID: UINT,
	uFlags: UINT,
	uCallbackMessage: UINT,
	hIcon: HICON,
	szTip: [128]WCHAR,
	dwState: DWORD,
	dwStateMask: DWORD,
	szInfo: [256]WCHAR,
	using _: struct #raw_union {
		uTimeout: UINT,
		uVersion: UINT,
	},
	szInfoTitle: [64]WCHAR,
	dwInfoFlags: DWORD,
	guidItem: GUID,
	hBalloonIcon: HICON,
}

NIF_MESSAGE :: 0x00000001
NIF_ICON :: 0x00000002
NIF_TIP :: 0x00000004
NIF_STATE :: 0x00000008
NIF_INFO :: 0x00000010
NIF_GUID :: 0x00000020
NIF_REALTIME :: 0x00000040
NIF_SHOWTIP :: 0x00000080

NIM_ADD :: 0x00000000
NIM_MODIFY :: 0x00000001
NIM_DELETE :: 0x00000002
NIM_SETFOCUS :: 0x00000003
NIM_SETVERSION :: 0x00000004

// Menu flags for Add/Check/EnableMenuItem()
MF_INSERT :: 0x00000000
MF_CHANGE :: 0x00000080
MF_APPEND :: 0x00000100
MF_DELETE :: 0x00000200
MF_REMOVE :: 0x00001000

MF_BYCOMMAND :: 0x00000000
MF_BYPOSITION :: 0x00000400

MF_SEPARATOR :: 0x00000800

MF_ENABLED :: 0x00000000
MF_GRAYED :: 0x00000001
MF_DISABLED :: 0x00000002

MF_UNCHECKED :: 0x00000000
MF_CHECKED :: 0x00000008
MF_USECHECKBITMAPS :: 0x00000200

MF_STRING :: 0x00000000
MF_BITMAP :: 0x00000004
MF_OWNERDRAW :: 0x00000100

MF_POPUP :: 0x00000010
MF_MENUBARBREAK :: 0x00000020
MF_MENUBREAK :: 0x00000040

MF_UNHILITE :: 0x00000000
MF_HILITE :: 0x00000080

MF_DEFAULT :: 0x00001000
MF_SYSMENU :: 0x00002000
MF_HELP :: 0x00004000
MF_RIGHTJUSTIFY :: 0x00004000

MF_MOUSESELECT :: 0x00008000
MF_END :: 0x00000080  // Obsolete -- only used by old RES files

// Flags for TrackPopupMenu
TPM_LEFTBUTTON :: 0x0000
TPM_RIGHTBUTTON :: 0x0002
TPM_LEFTALIGN :: 0x0000
TPM_CENTERALIGN :: 0x0004
TPM_RIGHTALIGN :: 0x0008
TPM_TOPALIGN :: 0x0000
TPM_VCENTERALIGN :: 0x0010
TPM_BOTTOMALIGN :: 0x0020

TPM_HORIZONTAL :: 0x0000     /* Horz alignment matters more */
TPM_VERTICAL :: 0x0040     /* Vert alignment matters more */
TPM_NONOTIFY :: 0x0080     /* Don't send any notification msgs */
TPM_RETURNCMD :: 0x0100
TPM_RECURSE :: 0x0001
TPM_HORPOSANIMATION :: 0x0400
TPM_HORNEGANIMATION :: 0x0800
TPM_VERPOSANIMATION :: 0x1000
TPM_VERNEGANIMATION :: 0x2000
TPM_NOANIMATION :: 0x4000
TPM_LAYOUTRTL :: 0x8000
TPM_WORKAREA :: 0x10000

// WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
HTERROR       :: -2
HTTRANSPARENT :: -1
HTNOWHERE     :: 0
HTCLIENT      :: 1
HTCAPTION     :: 2
HTSYSMENU     :: 3
HTGROWBOX     :: 4
HTSIZE        :: HTGROWBOX
HTMENU        :: 5
HTHSCROLL     :: 6
HTVSCROLL     :: 7
HTMINBUTTON   :: 8
HTMAXBUTTON   :: 9
HTLEFT        :: 10
HTRIGHT       :: 11
HTTOP         :: 12
HTTOPLEFT     :: 13
HTTOPRIGHT    :: 14
HTBOTTOM      :: 15
HTBOTTOMLEFT  :: 16
HTBOTTOMRIGHT :: 17
HTBORDER      :: 18
HTREDUCE      :: HTMINBUTTON
HTZOOM        :: HTMAXBUTTON
HTSIZEFIRST   :: HTLEFT
HTSIZELAST    :: HTBOTTOMRIGHT
HTOBJECT      :: 19
HTCLOSE       :: 20
HTHELP        :: 21

TEXTMETRICW :: struct {
	tmHeight: LONG,
	tmAscent: LONG,
	tmDescent: LONG,
	tmInternalLeading: LONG,
	tmExternalLeading: LONG,
	tmAveCharWidth: LONG,
	tmMaxCharWidth: LONG,
	tmWeight: LONG,
	tmOverhang: LONG,
	tmDigitizedAspectX: LONG,
	tmDigitizedAspectY: LONG,
	tmFirstChar: WCHAR,
	tmLastChar: WCHAR,
	tmDefaultChar: WCHAR,
	tmBreakChar: WCHAR,
	tmItalic: BYTE,
	tmUnderlined: BYTE,
	tmStruckOut: BYTE,
	tmPitchAndFamily: BYTE,
	tmCharSet: BYTE,
}
LPTEXTMETRICW :: ^TEXTMETRICW

PAINTSTRUCT :: struct {
	hdc: HDC,
	fErase: BOOL,
	rcPaint: RECT,
	fRestore: BOOL,
	fIncUpdate: BOOL,
	rgbReserved: [32]BYTE,
}

TRACKMOUSEEVENT :: struct {
	cbSize: DWORD,
	dwFlags: DWORD,
	hwndTrack: HWND,
	dwHoverTime: DWORD,
}

WIN32_FIND_DATAW :: struct {
	dwFileAttributes:   DWORD,
	ftCreationTime:     FILETIME,
	ftLastAccessTime:   FILETIME,
	ftLastWriteTime:    FILETIME,
	nFileSizeHigh:      DWORD,
	nFileSizeLow:       DWORD,
	dwReserved0:        DWORD,
	dwReserved1:        DWORD,
	cFileName:          [MAX_PATH]WCHAR,
	cAlternateFileName: [14]WCHAR,
	_OBSOLETE_dwFileType:    DWORD, // Obsolete. Do not use.
	_OBSOLETE_dwCreatorType: DWORD, // Obsolete. Do not use
	_OBSOLETE_wFinderFlags:  WORD,  // Obsolete. Do not use
}

FILE_ID_128 :: struct {
	Identifier: [16]BYTE,
}

FILE_ID_INFO :: struct {
	VolumeSerialNumber: ULONGLONG,
	FileId:             FILE_ID_128,
}

CREATESTRUCTA :: struct {
	lpCreateParams: LPVOID,
	hInstance:      HINSTANCE,
	hMenu:          HMENU,
	hwndParent:     HWND,
	cy:             c_int,
	cx:             c_int,
	y:              c_int,
	x:              c_int,
	style:          LONG,
	lpszName:       LPCSTR,
	lpszClass:      LPCSTR,
	dwExStyle:      DWORD,
}

CREATESTRUCTW:: struct {
	lpCreateParams: LPVOID,
	hInstance:      HINSTANCE,
	hMenu:          HMENU,
	hwndParent:     HWND,
	cy:             c_int,
	cx:             c_int,
	y:              c_int,
	x:              c_int,
	style:          LONG,
	lpszName:       LPCWSTR,
	lpszClass:      LPCWSTR,
	dwExStyle:      DWORD,
}

MAX_LINKID_TEXT :: 48
L_MAX_URL_LENGTH :: 2048 + 32 + len("://")

LITEM :: struct {
	mask: UINT,
	iLink: c_int,
	state: UINT,
	stateMask: UINT,
	szID: [MAX_LINKID_TEXT]WCHAR,
	szUrl: [L_MAX_URL_LENGTH]WCHAR,
}

NMLINK :: struct {
	hdr: NMHDR,
	item: LITEM,
}

NMHDR :: struct {
	hwndFrom: HWND,
	idFrom:   UINT_PTR,
	code:     UINT,      // NM_ code
}

NCCALCSIZE_PARAMS :: struct {
	rgrc: [3]RECT,
	lppos: PWINDOWPOS,
}

// Generic WM_NOTIFY notification codes
NM_OUTOFMEMORY          :: ~uintptr(0) // -1
NM_CLICK                :: NM_OUTOFMEMORY-1  // uses NMCLICK struct
NM_DBLCLK               :: NM_OUTOFMEMORY-2
NM_RETURN               :: NM_OUTOFMEMORY-3
NM_RCLICK               :: NM_OUTOFMEMORY-4  // uses NMCLICK struct
NM_RDBLCLK              :: NM_OUTOFMEMORY-5
NM_SETFOCUS             :: NM_OUTOFMEMORY-6
NM_KILLFOCUS            :: NM_OUTOFMEMORY-7
NM_CUSTOMDRAW           :: NM_OUTOFMEMORY-11
NM_HOVER                :: NM_OUTOFMEMORY-12
NM_NCHITTEST            :: NM_OUTOFMEMORY-13 // uses NMMOUSE struct
NM_KEYDOWN              :: NM_OUTOFMEMORY-14 // uses NMKEY struct
NM_RELEASEDCAPTURE      :: NM_OUTOFMEMORY-15
NM_SETCURSOR            :: NM_OUTOFMEMORY-16 // uses NMMOUSE struct
NM_CHAR                 :: NM_OUTOFMEMORY-17 // uses NMCHAR struct
NM_TOOLTIPSCREATED      :: NM_OUTOFMEMORY-18 // notify of when the tooltips window is create
NM_LDOWN                :: NM_OUTOFMEMORY-19
NM_RDOWN                :: NM_OUTOFMEMORY-20
NM_THEMECHANGED         :: NM_OUTOFMEMORY-21
NM_FONTCHANGED          :: NM_OUTOFMEMORY-22
NM_CUSTOMTEXT           :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM

PCZZWSTR :: ^WCHAR

SHFILEOPSTRUCTW :: struct {
	hwnd: HWND,
	wFunc: UINT,
	pFrom: PCZZWSTR,
	pTo: PCZZWSTR,
	fFlags: FILEOP_FLAGS,
	fAnyOperationsAborted: BOOL,
	hNameMappings: LPVOID,
	lpszProgressTitle: PCWSTR, // only used if FOF_SIMPLEPROGRESS
}
LPSHFILEOPSTRUCTW :: ^SHFILEOPSTRUCTW

// Shell File Operations
FO_MOVE   :: 0x0001
FO_COPY   :: 0x0002
FO_DELETE :: 0x0003
FO_RENAME :: 0x0004

// SHFILEOPSTRUCT.fFlags and IFileOperation::SetOperationFlags() flag values
FOF_MULTIDESTFILES        :: 0x0001
FOF_CONFIRMMOUSE          :: 0x0002
FOF_SILENT                :: 0x0004  // don't display progress UI (confirm prompts may be displayed still)
FOF_RENAMEONCOLLISION     :: 0x0008  // automatically rename the source files to avoid the collisions
FOF_NOCONFIRMATION        :: 0x0010  // don't display confirmation UI, assume "yes" for cases that can be bypassed, "no" for those that can not
FOF_WANTMAPPINGHANDLE     :: 0x0020  // Fill in SHFILEOPSTRUCT.hNameMappings
                                     // Must be freed using SHFreeNameMappings
FOF_ALLOWUNDO             :: 0x0040  // enable undo including Recycle behavior for IFileOperation::Delete()
FOF_FILESONLY             :: 0x0080  // only operate on the files (non folders), both files and folders are assumed without this
FOF_SIMPLEPROGRESS        :: 0x0100  // means don't show names of files
FOF_NOCONFIRMMKDIR        :: 0x0200  // don't dispplay confirmatino UI before making any needed directories, assume "Yes" in these cases
FOF_NOERRORUI             :: 0x0400  // don't put up error UI, other UI may be displayed, progress, confirmations
FOF_NOCOPYSECURITYATTRIBS :: 0x0800  // dont copy file security attributes (ACLs)
FOF_NORECURSION           :: 0x1000  // don't recurse into directories for operations that would recurse
FOF_NO_CONNECTED_ELEMENTS :: 0x2000  // don't operate on connected elements ("xxx_files" folders that go with .htm files)
FOF_WANTNUKEWARNING       :: 0x4000  // during delete operation, warn if object is being permanently destroyed instead of recycling (partially overrides FOF_NOCONFIRMATION)
FOF_NORECURSEREPARSE      :: 0x8000  // deprecated; the operations engine always does the right thing on FolderLink objects (symlinks, reparse points, folder shortcuts)
FOF_NO_UI                 :: (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR) // don't display any UI at all

FILEOP_FLAGS :: WORD

DEVMODEW :: struct {
	dmDeviceName:   [32]wchar_t,
	dmSpecVersion:   WORD,
	dmDriverVersion: WORD,
	dmSize:          WORD,
	dmDriverExtra:   WORD,
	dmFields:        DWORD,
	using _: struct #raw_union {
		// Printer only fields.
		using _: struct {
			dmOrientation:   c_short,
			dmPaperSize:     c_short,
			dmPaperLength:   c_short,
			dmPaperWidth:    c_short,
			dmScale:         c_short,
			dmCopies:        c_short,
			dmDefaultSource: c_short,
			dmPrintQuality:  c_short,
		},
		// Display only fields.
		using _: struct {
			dmPosition:           POINT,
			dmDisplayOrientation: DWORD,
			dmDisplayFixedOutput: DWORD,
		},
	},
	dmColor:       c_short,
	dmDuplex:      c_short,
	dmYResolution: c_short,
	dmTTOption:    c_short,
	dmCollate:     c_short,
	dmFormName:    [32]wchar_t,
	dmLogPixels:   WORD,
	dmBitsPerPel:  DWORD,
	dmPelsWidth:   DWORD,
	dmPelsHeight:  DWORD,
	using _: struct #raw_union {
		dmDisplayFlags: DWORD,
		dmNup:          DWORD,
	},
	dmDisplayFrequency: DWORD,
	dmICMMethod:        DWORD,
	dmICMIntent:        DWORD,
	dmMediaType:        DWORD,
	dmDitherType:       DWORD,
	dmReserved1:        DWORD,
	dmReserved2:        DWORD,
	dmPanningWidth:     DWORD,
	dmPanningHeight:    DWORD,
}

// MessageBox() Flags
MB_OK                :: 0x00000000
MB_OKCANCEL          :: 0x00000001
MB_ABORTRETRYIGNORE  :: 0x00000002
MB_YESNOCANCEL       :: 0x00000003
MB_YESNO             :: 0x00000004
MB_RETRYCANCEL       :: 0x00000005
MB_CANCELTRYCONTINUE :: 0x00000006

MB_ICONHAND        :: 0x00000010
MB_ICONQUESTION    :: 0x00000020
MB_ICONEXCLAMATION :: 0x00000030
MB_ICONASTERISK    :: 0x00000040
MB_USERICON        :: 0x00000080
MB_ICONWARNING     :: MB_ICONEXCLAMATION
MB_ICONERROR       :: MB_ICONHAND
MB_ICONINFORMATION :: MB_ICONASTERISK
MB_ICONSTOP        :: MB_ICONHAND

MB_DEFBUTTON1 :: 0x00000000
MB_DEFBUTTON2 :: 0x00000100
MB_DEFBUTTON3 :: 0x00000200
MB_DEFBUTTON4 :: 0x00000300

MB_APPLMODAL   :: 0x00000000
MB_SYSTEMMODAL :: 0x00001000
MB_TASKMODAL   :: 0x00002000
MB_HELP        :: 0x00004000 // Help Button

MB_NOFOCUS              :: 0x00008000
MB_SETFOREGROUND        :: 0x00010000
MB_DEFAULT_DESKTOP_ONLY :: 0x00020000
MB_TOPMOST              :: 0x00040000
MB_RIGHT                :: 0x00080000
MB_RTLREADING           :: 0x00100000

MB_SERVICE_NOTIFICATION      :: 0x00200000
MB_SERVICE_NOTIFICATION_NT3X :: 0x00040000

MB_TYPEMASK :: 0x0000000F
MB_ICONMASK :: 0x000000F0
MB_DEFMASK  :: 0x00000F00
MB_MODEMASK :: 0x00003000
MB_MISCMASK :: 0x0000C000

// Dialog Box Command IDs
IDOK       :: 1
IDCANCEL   :: 2
IDABORT    :: 3
IDRETRY    :: 4
IDIGNORE   :: 5
IDYES      :: 6
IDNO       :: 7
IDCLOSE    :: 8
IDHELP     :: 9
IDTRYAGAIN :: 10
IDCONTINUE :: 11
IDTIMEOUT  :: 32000

CS_VREDRAW         : UINT : 0x0001
CS_HREDRAW         : UINT : 0x0002
CS_DBLCLKS         : UINT : 0x0008
CS_OWNDC           : UINT : 0x0020
CS_CLASSDC         : UINT : 0x0040
CS_PARENTDC        : UINT : 0x0080
CS_NOCLOSE         : UINT : 0x0200
CS_SAVEBITS        : UINT : 0x0800
CS_BYTEALIGNCLIENT : UINT : 0x1000
CS_BYTEALIGNWINDOW : UINT : 0x2000
CS_GLOBALCLASS     : UINT : 0x4000
CS_DROPSHADOW      : UINT : 0x0002_0000

AURL_ENABLEURL          :: 1
AURL_ENABLEEMAILADDR    :: 2
AURL_ENABLETELNO        :: 4
AURL_ENABLEEAURLS       :: 8
AURL_ENABLEDRIVELETTERS :: 16
AURL_DISABLEMIXEDLGC    :: 32 // Disable mixed Latin Greek Cyrillic IDNs

WS_BORDER           : UINT : 0x0080_0000
WS_CAPTION          : UINT : 0x00C0_0000
WS_CHILD            : UINT : 0x4000_0000
WS_CHILDWINDOW      : UINT : WS_CHILD
WS_CLIPCHILDREN     : UINT : 0x0200_0000
WS_CLIPSIBLINGS     : UINT : 0x0400_0000
WS_DISABLED         : UINT : 0x0800_0000
WS_DLGFRAME         : UINT : 0x0040_0000
WS_GROUP            : UINT : 0x0002_0000
WS_HSCROLL          : UINT : 0x0010_0000
WS_ICONIC           : UINT : 0x2000_0000
WS_MAXIMIZE         : UINT : 0x0100_0000
WS_MAXIMIZEBOX      : UINT : 0x0001_0000
WS_MINIMIZE         : UINT : 0x2000_0000
WS_MINIMIZEBOX      : UINT : 0x0002_0000
WS_OVERLAPPED       : UINT : 0x0000_0000
WS_OVERLAPPEDWINDOW : UINT : WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
WS_POPUP			: UINT : 0x8000_0000
WS_POPUPWINDOW      : UINT : WS_POPUP | WS_BORDER | WS_SYSMENU
WS_SIZEBOX          : UINT : 0x0004_0000
WS_SYSMENU          : UINT : 0x0008_0000
WS_TABSTOP          : UINT : 0x0001_0000
WS_THICKFRAME       : UINT : 0x0004_0000
WS_TILED            : UINT : 0x0000_0000
WS_TILEDWINDOW      : UINT : WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE
WS_VISIBLE          : UINT : 0x1000_0000
WS_VSCROLL          : UINT : 0x0020_0000

WS_EX_ACCEPTFILES           : UINT : 0x0000_0010
WS_EX_APPWINDOW             : UINT : 0x0004_0000
WS_EX_CLIENTEDGE            : UINT : 0x0000_0200
WS_EX_COMPOSITED            : UINT : 0x0200_0000
WS_EX_CONTEXTHELP           : UINT : 0x0000_0400
WS_EX_CONTROLPARENT         : UINT : 0x0001_0000
WS_EX_DLGMODALFRAME         : UINT : 0x0000_0001
WS_EX_DRAGDETECT            : UINT : 0x0000_0002 // undocumented
WS_EX_LAYERED               : UINT : 0x0008_0000
WS_EX_LAYOUTRTL             : UINT : 0x0040_0000
WS_EX_LEFT                  : UINT : 0x0000_0000
WS_EX_LEFTSCROLLBAR         : UINT : 0x0000_4000
WS_EX_LTRREADING            : UINT : 0x0000_0000
WS_EX_MDICHILD              : UINT : 0x0000_0040
WS_EX_NOACTIVATE            : UINT : 0x0800_0000
WS_EX_NOINHERITLAYOUT       : UINT : 0x0010_0000
WS_EX_NOPARENTNOTIFY        : UINT : 0x0000_0004
WS_EX_NOREDIRECTIONBITMAP   : UINT : 0x0020_0000
WS_EX_OVERLAPPEDWINDOW      : UINT : WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE
WS_EX_PALETTEWINDOW         : UINT : WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
WS_EX_RIGHT                 : UINT : 0x0000_1000
WS_EX_RIGHTSCROLLBAR        : UINT : 0x0000_0000
WS_EX_RTLREADING            : UINT : 0x0000_2000
WS_EX_STATICEDGE            : UINT : 0x0002_0000
WS_EX_TOOLWINDOW            : UINT : 0x0000_0080
WS_EX_TOPMOST               : UINT : 0x0000_0008
WS_EX_TRANSPARENT           : UINT : 0x0000_0020
WS_EX_WINDOWEDGE            : UINT : 0x0000_0100

PBS_SMOOTH        :: 0x01
PBS_VERTICAL      :: 0x04
PBS_MARQUEE       :: 0x08
PBS_SMOOTHREVERSE :: 0x10

PBST_NORMAL :: 0x0001
PBST_ERROR  :: 0x0002
PBST_PAUSED :: 0x0003

QS_ALLEVENTS      : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY
QS_ALLINPUT       : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE
QS_ALLPOSTMESSAGE : UINT : 0x0100
QS_HOTKEY         : UINT : 0x0080
QS_INPUT          : UINT : QS_MOUSE | QS_KEY | QS_RAWINPUT
QS_KEY            : UINT : 0x0001
QS_MOUSE          : UINT : QS_MOUSEMOVE | QS_MOUSEBUTTON
QS_MOUSEBUTTON    : UINT : 0x0004
QS_MOUSEMOVE      : UINT : 0x0002
QS_PAINT          : UINT : 0x0020
QS_POSTMESSAGE    : UINT : 0x0008
QS_RAWINPUT       : UINT : 0x0400
QS_SENDMESSAGE    : UINT : 0x0040
QS_TIMER          : UINT : 0x0010

PM_NOREMOVE : UINT : 0x0000
PM_REMOVE   : UINT : 0x0001
PM_NOYIELD  : UINT : 0x0002

PM_QS_INPUT       : UINT : QS_INPUT << 16
PM_QS_PAINT       : UINT : QS_PAINT << 16
PM_QS_POSTMESSAGE : UINT : (QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16
PM_QS_SENDMESSAGE : UINT : QS_SENDMESSAGE << 16

SW_HIDE            : c_int : 0
SW_SHOWNORMAL      : c_int : SW_NORMAL
SW_NORMAL          : c_int : 1
SW_SHOWMINIMIZED   : c_int : 2
SW_SHOWMAXIMIZED   : c_int : SW_MAXIMIZE
SW_MAXIMIZE        : c_int : 3
SW_SHOWNOACTIVATE  : c_int : 4
SW_SHOW            : c_int : 5
SW_MINIMIZE        : c_int : 6
SW_SHOWMINNOACTIVE : c_int : 7
SW_SHOWNA          : c_int : 8
SW_RESTORE         : c_int : 9
SW_SHOWDEFAULT     : c_int : 10
SW_FORCEMINIMIZE   : c_int : 11

// SetWindowPos Flags
SWP_NOSIZE         :: 0x0001
SWP_NOMOVE         :: 0x0002
SWP_NOZORDER       :: 0x0004
SWP_NOREDRAW       :: 0x0008
SWP_NOACTIVATE     :: 0x0010
SWP_FRAMECHANGED   :: 0x0020 // The frame changed: send WM_NCCALCSIZE
SWP_SHOWWINDOW     :: 0x0040
SWP_HIDEWINDOW     :: 0x0080
SWP_NOCOPYBITS     :: 0x0100
SWP_NOOWNERZORDER  :: 0x0200 // Don't do owner Z ordering
SWP_NOSENDCHANGING :: 0x0400 // Don't send WM_WINDOWPOSCHANGING

SWP_DRAWFRAME    :: SWP_FRAMECHANGED
SWP_NOREPOSITION :: SWP_NOOWNERZORDER

SWP_DEFERERASE     :: 0x2000 // same as SWP_DEFERDRAWING
SWP_ASYNCWINDOWPOS :: 0x4000 // same as SWP_CREATESPB

CSIDL_APPDATA        :: 0x001a // <user name>\Application Data
CSIDL_COMMON_APPDATA :: 0x0023 // All Users\Application Data
CSIDL_PROFILE 		 :: 0x0028 // <user name>\

HWND_TOP       :: HWND( uintptr(0))     //  0
HWND_BOTTOM    :: HWND( uintptr(1))     //  1
HWND_TOPMOST   :: HWND(~uintptr(0))     // -1
HWND_NOTOPMOST :: HWND(~uintptr(0) - 1) // -2

// Window field offsets for GetWindowLong()
GWL_STYLE   :: -16
GWL_EXSTYLE :: -20
GWL_ID      :: -12

when ODIN_ARCH == .i386 {
	GWL_WNDPROC    :: -4
	GWL_HINSTANCE  :: -6
	GWL_HWNDPARENT :: -8
	GWL_USERDATA   :: -21
}

GWLP_WNDPROC    :: -4
GWLP_HINSTANCE  :: -6
GWLP_HWNDPARENT :: -8
GWLP_USERDATA   :: -21
GWLP_ID         :: -12

// Class field offsets for GetClassLong()
GCL_CBWNDEXTRA :: -18
GCL_CBCLSEXTRA :: -20
GCL_STYLE      :: -26
GCW_ATOM       :: -32

when ODIN_ARCH == .i386 {
	GCL_MENUNAME      :: -8
	GCL_HBRBACKGROUND :: -10
	GCL_HCURSOR       :: -12
	GCL_HICON         :: -14
	GCL_HMODULE       :: -16
	GCL_WNDPROC       :: -24
	GCL_HICONSM       :: -34
}

GCLP_MENUNAME      :: -8
GCLP_HBRBACKGROUND :: -10
GCLP_HCURSOR       :: -12
GCLP_HICON         :: -14
GCLP_HMODULE       :: -16
GCLP_WNDPROC       :: -24
GCLP_HICONSM       :: -34

// GetSystemMetrics() codes
SM_CXSCREEN          :: 0
SM_CYSCREEN          :: 1
SM_CXVSCROLL         :: 2
SM_CYHSCROLL         :: 3
SM_CYCAPTION         :: 4
SM_CXBORDER          :: 5
SM_CYBORDER          :: 6
SM_CXDLGFRAME        :: 7
SM_CYDLGFRAME        :: 8
SM_CYVTHUMB          :: 9
SM_CXHTHUMB          :: 10
SM_CXICON            :: 11
SM_CYICON            :: 12
SM_CXCURSOR          :: 13
SM_CYCURSOR          :: 14
SM_CYMENU            :: 15
SM_CXFULLSCREEN      :: 16
SM_CYFULLSCREEN      :: 17
SM_CYKANJIWINDOW     :: 18
SM_MOUSEPRESENT      :: 19
SM_CYVSCROLL         :: 20
SM_CXHSCROLL         :: 21
SM_DEBUG             :: 22
SM_SWAPBUTTON        :: 23
SM_RESERVED1         :: 24
SM_RESERVED2         :: 25
SM_RESERVED3         :: 26
SM_RESERVED4         :: 27
SM_CXMIN             :: 28
SM_CYMIN             :: 29
SM_CXSIZE            :: 30
SM_CYSIZE            :: 31
SM_CXFRAME           :: 32
SM_CYFRAME           :: 33
SM_CXMINTRACK        :: 34
SM_CYMINTRACK        :: 35
SM_CXDOUBLECLK       :: 36
SM_CYDOUBLECLK       :: 37
SM_CXICONSPACING     :: 38
SM_CYICONSPACING     :: 39
SM_MENUDROPALIGNMENT :: 40
SM_PENWINDOWS        :: 41
SM_DBCSENABLED       :: 42
SM_CMOUSEBUTTONS     :: 43

SM_CXFIXEDFRAME :: SM_CXDLGFRAME  // ;win40 name change
SM_CYFIXEDFRAME :: SM_CYDLGFRAME  // ;win40 name change
SM_CXSIZEFRAME  :: SM_CXFRAME     // ;win40 name change
SM_CYSIZEFRAME  :: SM_CYFRAME     // ;win40 name change

SM_SECURE       :: 44
SM_CXEDGE       :: 45
SM_CYEDGE       :: 46
SM_CXMINSPACING :: 47
SM_CYMINSPACING :: 48
SM_CXSMICON     :: 49
SM_CYSMICON     :: 50
SM_CYSMCAPTION  :: 51
SM_CXSMSIZE     :: 52
SM_CYSMSIZE     :: 53
SM_CXMENUSIZE   :: 54
SM_CYMENUSIZE   :: 55
SM_ARRANGE      :: 56
SM_CXMINIMIZED  :: 57
SM_CYMINIMIZED  :: 58
SM_CXMAXTRACK   :: 59
SM_CYMAXTRACK   :: 60
SM_CXMAXIMIZED  :: 61
SM_CYMAXIMIZED  :: 62
SM_NETWORK      :: 63
SM_CLEANBOOT    :: 67
SM_CXDRAG       :: 68
SM_CYDRAG       :: 69

SM_SHOWSOUNDS        :: 70
SM_CXMENUCHECK       :: 71   // Use instead of GetMenuCheckMarkDimensions()!
SM_CYMENUCHECK       :: 72
SM_SLOWMACHINE       :: 73
SM_MIDEASTENABLED    :: 74
SM_MOUSEWHEELPRESENT :: 75
SM_XVIRTUALSCREEN    :: 76
SM_YVIRTUALSCREEN    :: 77
SM_CXVIRTUALSCREEN   :: 78
SM_CYVIRTUALSCREEN   :: 79
SM_CMONITORS         :: 80
SM_SAMEDISPLAYFORMAT :: 81
SM_IMMENABLED        :: 82
SM_CXFOCUSBORDER     :: 83
SM_CYFOCUSBORDER     :: 84
SM_TABLETPC          :: 86
SM_MEDIACENTER       :: 87
SM_STARTER           :: 88
SM_SERVERR2          :: 89

SM_MOUSEHORIZONTALWHEELPRESENT :: 91

SM_CXPADDEDBORDER :: 92
SM_DIGITIZER      :: 94
SM_MAXIMUMTOUCHES :: 95
SM_CMETRICS       :: 97

SM_REMOTESESSION        :: 0x1000
SM_SHUTTINGDOWN         :: 0x2000
SM_REMOTECONTROL        :: 0x2001
SM_CARETBLINKINGENABLED :: 0x2002
SM_CONVERTIBLESLATEMODE :: 0x2003
SM_SYSTEMDOCKED         :: 0x2004

// System Menu Command Values
SC_SIZE         :: 0xF000
SC_MOVE         :: 0xF010
SC_MINIMIZE     :: 0xF020
SC_MAXIMIZE     :: 0xF030
SC_NEXTWINDOW   :: 0xF040
SC_PREVWINDOW   :: 0xF050
SC_CLOSE        :: 0xF060
SC_VSCROLL      :: 0xF070
SC_HSCROLL      :: 0xF080
SC_MOUSEMENU    :: 0xF090
SC_KEYMENU      :: 0xF100
SC_ARRANGE      :: 0xF110
SC_RESTORE      :: 0xF120
SC_TASKLIST     :: 0xF130
SC_SCREENSAVE   :: 0xF140
SC_HOTKEY       :: 0xF150
SC_DEFAULT      :: 0xF160
SC_MONITORPOWER :: 0xF170
SC_CONTEXTHELP  :: 0xF180
SC_SEPARATOR    :: 0xF00F
SCF_ISSECURE    :: 0x00000001
SC_ICON         :: SC_MINIMIZE
SC_ZOOM         :: SC_MAXIMIZE

CW_USEDEFAULT : c_int : -2147483648

SIZE_RESTORED  :: 0
SIZE_MINIMIZED :: 1
SIZE_MAXIMIZED :: 2
SIZE_MAXSHOW   :: 3
SIZE_MAXHIDE   :: 4

WMSZ_LEFT        :: 1
WMSZ_RIGHT       :: 2
WMSZ_TOP         :: 3
WMSZ_TOPLEFT     :: 4
WMSZ_TOPRIGHT    :: 5
WMSZ_BOTTOM      :: 6
WMSZ_BOTTOMLEFT  :: 7
WMSZ_BOTTOMRIGHT :: 8

// Note CLASSKEY overrides CLASSNAME
SEE_MASK_DEFAULT   :: 0x00000000
SEE_MASK_CLASSNAME :: 0x00000001   // SHELLEXECUTEINFO.lpClass is valid
SEE_MASK_CLASSKEY  :: 0x00000003   // SHELLEXECUTEINFO.hkeyClass is valid
// Note SEE_MASK_INVOKEIDLIST(0xC) implies SEE_MASK_IDLIST(0x04)
SEE_MASK_IDLIST            :: 0x00000004   // SHELLEXECUTEINFO.lpIDList is valid
SEE_MASK_INVOKEIDLIST      :: 0x0000000c   // enable IContextMenu based verbs
SEE_MASK_ICON              :: 0x00000010   // not used
SEE_MASK_HOTKEY            :: 0x00000020   // SHELLEXECUTEINFO.dwHotKey is valid
SEE_MASK_NOCLOSEPROCESS    :: 0x00000040   // SHELLEXECUTEINFO.hProcess
SEE_MASK_CONNECTNETDRV     :: 0x00000080   // enables re-connecting disconnected network drives
SEE_MASK_NOASYNC           :: 0x00000100   // block on the call until the invoke has completed, use for callers that exit after calling ShellExecuteEx()
SEE_MASK_FLAG_DDEWAIT      :: SEE_MASK_NOASYNC // Use SEE_MASK_NOASYNC instead of SEE_MASK_FLAG_DDEWAIT as it more accuratly describes the behavior
SEE_MASK_DOENVSUBST        :: 0x00000200   // indicates that SHELLEXECUTEINFO.lpFile contains env vars that should be expanded
SEE_MASK_FLAG_NO_UI        :: 0x00000400   // disable UI including error messages
SEE_MASK_UNICODE           :: 0x00004000
SEE_MASK_NO_CONSOLE        :: 0x00008000
SEE_MASK_ASYNCOK           :: 0x00100000
SEE_MASK_HMONITOR          :: 0x00200000   // SHELLEXECUTEINFO.hMonitor
SEE_MASK_NOZONECHECKS      :: 0x00800000
SEE_MASK_NOQUERYCLASSSTORE :: 0x01000000
SEE_MASK_WAITFORINPUTIDLE  :: 0x02000000
SEE_MASK_FLAG_LOG_USAGE    :: 0x04000000

// When SEE_MASK_FLAG_HINST_IS_SITE is specified SHELLEXECUTEINFO.hInstApp is used as an
// _In_ parameter and specifies a IUnknown* to be used as a site pointer. The site pointer
// is used to provide services to shell execute, the handler binding process and the verb handlers
// once they are invoked.
SEE_MASK_FLAG_HINST_IS_SITE :: 0x08000000

SHELLEXECUTEINFOW :: struct {
	cbSize: DWORD,               // in, required, sizeof of this structure
	fMask: ULONG,                // in, SEE_MASK_XXX values
	hwnd: HWND,                  // in, optional
	lpVerb: LPCWSTR,            // in, optional when unspecified the default verb is choosen
	lpFile: LPCWSTR,            // in, either this value or lpIDList must be specified
	lpParameters: LPCWSTR,      // in, optional
	lpDirectory: LPCWSTR,       // in, optional
	nShow: c.int,                  // in, required
	hInstApp: HINSTANCE,         // out when SEE_MASK_NOCLOSEPROCESS is specified
	lpIDList: rawptr,             // in, valid when SEE_MASK_IDLIST is specified, PCIDLIST_ABSOLUTE, for use with SEE_MASK_IDLIST & SEE_MASK_INVOKEIDLIST
	lpClass: LPCWSTR,           // in, valid when SEE_MASK_CLASSNAME is specified
	hkeyClass: HKEY,             // in, valid when SEE_MASK_CLASSKEY is specified
	dwHotKey: DWORD,             // in, valid when SEE_MASK_HOTKEY is specified
	DUMMYUNIONNAME: struct #raw_union {
		hIcon: HANDLE,           // not used
		hMonitor: HANDLE,        // in, valid when SEE_MASK_HMONITOR specified
	},
	hProcess: HANDLE,            // out, valid when SEE_MASK_NOCLOSEPROCESS specified
}
LPSHELLEXECUTEINFOW :: ^SHELLEXECUTEINFOW

// Key State Masks for Mouse Messages
MK_LBUTTON  :: 0x0001
MK_RBUTTON  :: 0x0002
MK_SHIFT    :: 0x0004
MK_CONTROL  :: 0x0008
MK_MBUTTON  :: 0x0010
MK_XBUTTON1 :: 0x0020
MK_XBUTTON2 :: 0x0040

// Value for rolling one detent
WHEEL_DELTA :: 120

// Setting to scroll one page for SPI_GET/SETWHEELSCROLLLINES
WHEEL_PAGESCROLL :: max(UINT)

// XButton values are WORD flags
XBUTTON1 :: 0x0001
XBUTTON2 :: 0x0002
// Were there to be an XBUTTON3, its value would be 0x0004

MAPVK_VK_TO_VSC    :: 0
MAPVK_VSC_TO_VK    :: 1
MAPVK_VK_TO_CHAR   :: 2
MAPVK_VSC_TO_VK_EX :: 3
MAPVK_VK_TO_VSC_EX :: 4

TME_HOVER     :: 0x00000001
TME_LEAVE     :: 0x00000002
TME_NONCLIENT :: 0x00000010
TME_QUERY     :: 0x40000000
TME_CANCEL    :: 0x80000000
HOVER_DEFAULT :: 0xFFFFFFFF

USER_TIMER_MAXIMUM :: 0x7FFFFFFF
USER_TIMER_MINIMUM :: 0x0000000A

// WM_ACTIVATE state values
WA_INACTIVE    :: 0
WA_ACTIVE      :: 1
WA_CLICKACTIVE :: 2

// Struct pointed to by WM_GETMINMAXINFO lParam
MINMAXINFO :: struct {
	ptReserved: POINT,
	ptMaxSize: POINT,
	ptMaxPosition: POINT,
	ptMinTrackSize: POINT,
	ptMaxTrackSize: POINT,
}
PMINMAXINFO  :: ^MINMAXINFO
LPMINMAXINFO :: PMINMAXINFO

MONITORINFO :: struct {
	cbSize: DWORD,
	rcMonitor: RECT,
	rcWork: RECT,
	dwFlags: DWORD,
}
LPMONITORINFO :: ^MONITORINFO

CCHDEVICENAME :: 32
MONITORINFOEXW :: struct {
	using _: MONITORINFO,
	szDevice: [CCHDEVICENAME]WCHAR,
}

// SetWindowsHook() codes
WH_MIN             :: -1
WH_MSGFILTER       :: -1
WH_JOURNALRECORD   :: 0
WH_JOURNALPLAYBACK :: 1
WH_KEYBOARD        :: 2
WH_GETMESSAGE      :: 3
WH_CALLWNDPROC     :: 4
WH_CBT             :: 5
WH_SYSMSGFILTER    :: 6
WH_MOUSE           :: 7
WH_HARDWARE        :: 8
WH_DEBUG           :: 9
WH_SHELL           :: 10
WH_FOREGROUNDIDLE  :: 11
WH_CALLWNDPROCRET  :: 12
WH_KEYBOARD_LL     :: 13
WH_MOUSE_LL        :: 14
WH_MAX             :: 14
WH_MINHOOK         :: WH_MIN
WH_MAXHOOK         :: WH_MAX

// Hook Codes
HC_ACTION      :: 0
HC_GETNEXT     :: 1
HC_SKIP        :: 2
HC_NOREMOVE    :: 3
HC_NOREM       :: HC_NOREMOVE
HC_SYSMODALON  :: 4
HC_SYSMODALOFF :: 5

// CBT Hook Codes
HCBT_MOVESIZE     :: 0
HCBT_MINMAX       :: 1
HCBT_QS           :: 2
HCBT_CREATEWND    :: 3
HCBT_DESTROYWND   :: 4
HCBT_ACTIVATE     :: 5
HCBT_CLICKSKIPPED :: 6
HCBT_KEYSKIPPED   :: 7
HCBT_SYSCOMMAND   :: 8
HCBT_SETFOCUS     :: 9

_IDC_APPSTARTING := rawptr(uintptr(32650))
_IDC_ARROW       := rawptr(uintptr(32512))
_IDC_CROSS       := rawptr(uintptr(32515))
_IDC_HAND        := rawptr(uintptr(32649))
_IDC_HELP        := rawptr(uintptr(32651))
_IDC_IBEAM       := rawptr(uintptr(32513))
_IDC_ICON        := rawptr(uintptr(32641))
_IDC_NO          := rawptr(uintptr(32648))
_IDC_SIZE        := rawptr(uintptr(32640))
_IDC_SIZEALL     := rawptr(uintptr(32646))
_IDC_SIZENESW    := rawptr(uintptr(32643))
_IDC_SIZENS      := rawptr(uintptr(32645))
_IDC_SIZENWSE    := rawptr(uintptr(32642))
_IDC_SIZEWE      := rawptr(uintptr(32644))
_IDC_UPARROW     := rawptr(uintptr(32516))
_IDC_WAIT        := rawptr(uintptr(32514))

IDC_APPSTARTING := cstring(_IDC_APPSTARTING)
IDC_ARROW       := cstring(_IDC_ARROW)
IDC_CROSS       := cstring(_IDC_CROSS)
IDC_HAND        := cstring(_IDC_HAND)
IDC_HELP        := cstring(_IDC_HELP)
IDC_IBEAM       := cstring(_IDC_IBEAM)
IDC_ICON        := cstring(_IDC_ICON)
IDC_NO          := cstring(_IDC_NO)
IDC_SIZE        := cstring(_IDC_SIZE)
IDC_SIZEALL     := cstring(_IDC_SIZEALL)
IDC_SIZENESW    := cstring(_IDC_SIZENESW)
IDC_SIZENS      := cstring(_IDC_SIZENS)
IDC_SIZENWSE    := cstring(_IDC_SIZENWSE)
IDC_SIZEWE      := cstring(_IDC_SIZEWE)
IDC_UPARROW     := cstring(_IDC_UPARROW)
IDC_WAIT        := cstring(_IDC_WAIT)


_IDI_APPLICATION := rawptr(uintptr(32512))
_IDI_HAND        := rawptr(uintptr(32513))
_IDI_QUESTION    := rawptr(uintptr(32514))
_IDI_EXCLAMATION := rawptr(uintptr(32515))
_IDI_ASTERISK    := rawptr(uintptr(32516))
_IDI_WINLOGO     := rawptr(uintptr(32517))
_IDI_SHIELD      := rawptr(uintptr(32518))
IDI_APPLICATION  := cstring(_IDI_APPLICATION)
IDI_HAND         := cstring(_IDI_HAND)
IDI_QUESTION     := cstring(_IDI_QUESTION)
IDI_EXCLAMATION  := cstring(_IDI_EXCLAMATION)
IDI_ASTERISK     := cstring(_IDI_ASTERISK)
IDI_WINLOGO      := cstring(_IDI_WINLOGO)
IDI_SHIELD       := cstring(_IDI_SHIELD)
IDI_WARNING      := IDI_EXCLAMATION
IDI_ERROR        := IDI_HAND
IDI_INFORMATION  := IDI_ASTERISK

IMAGE_BITMAP      :: 0
IMAGE_ICON        :: 1
IMAGE_CURSOR      :: 2
IMAGE_ENHMETAFILE :: 3

LR_DEFAULTCOLOR     :: 0x00000000
LR_MONOCHROME       :: 0x00000001
LR_COLOR            :: 0x00000002
LR_COPYRETURNORG    :: 0x00000004
LR_COPYDELETEORG    :: 0x00000008
LR_LOADFROMFILE     :: 0x00000010
LR_LOADTRANSPARENT  :: 0x00000020
LR_DEFAULTSIZE      :: 0x00000040
LR_VGACOLOR         :: 0x00000080
LR_LOADMAP3DCOLORS  :: 0x00001000
LR_CREATEDIBSECTION :: 0x00002000
LR_COPYFROMRESOURCE :: 0x00004000
LR_SHARED           :: 0x00008000

// DIB color table identifiers
DIB_RGB_COLORS :: 0
DIB_PAL_COLORS :: 1

// constants for CreateDIBitmap
CBM_INIT :: 0x04 // initialize bitmap

// Region Flags
ERROR         :: 0
NULLREGION    :: 1
SIMPLEREGION  :: 2
COMPLEXREGION :: 3
RGN_ERROR     :: ERROR

// StretchBlt() Modes
BLACKONWHITE      :: 1
WHITEONBLACK      :: 2
COLORONCOLOR      :: 3
HALFTONE          :: 4
MAXSTRETCHBLTMODE :: 4

// Binary raster ops
R2_BLACK       :: 1  // 0
R2_NOTMERGEPEN :: 2  // DPon
R2_MASKNOTPEN  :: 3  // DPna
R2_NOTCOPYPEN  :: 4  // PN
R2_MASKPENNOT  :: 5  // PDna
R2_NOT         :: 6  // Dn
R2_XORPEN      :: 7  // DPx
R2_NOTMASKPEN  :: 8  // DPan
R2_MASKPEN     :: 9  // DPa
R2_NOTXORPEN   :: 10 // DPxn
R2_NOP         :: 11 // D
R2_MERGENOTPEN :: 12 // DPno
R2_COPYPEN     :: 13 // P
R2_MERGEPENNOT :: 14 // PDno
R2_MERGEPEN    :: 15 // DPo
R2_WHITE       :: 16 // 1
R2_LAST        :: 16

// Ternary raster operations
SRCCOPY        : DWORD : 0x00CC0020 // dest = source
SRCPAINT       : DWORD : 0x00EE0086 // dest = source OR dest
SRCAND         : DWORD : 0x008800C6 // dest = source AND dest
SRCINVERT      : DWORD : 0x00660046 // dest = source XOR dest
SRCERASE       : DWORD : 0x00440328 // dest = source AND (NOT dest)
NOTSRCCOPY     : DWORD : 0x00330008 // dest = (NOT source)
NOTSRCERASE    : DWORD : 0x001100A6 // dest = (NOT src) AND (NOT dest)
MERGECOPY      : DWORD : 0x00C000CA // dest = (source AND pattern
MERGEPAINT     : DWORD : 0x00BB0226 // dest = (NOT source) OR dest
PATCOPY        : DWORD : 0x00F00021 // dest = pattern
PATPAINT       : DWORD : 0x00FB0A09 // dest = DPSnoo
PATINVERT      : DWORD : 0x005A0049 // dest = pattern XOR dest
DSTINVERT      : DWORD : 0x00550009 // dest = (NOT dest)
BLACKNESS      : DWORD : 0x00000042 // dest = BLACK
WHITENESS      : DWORD : 0x00FF0062 // dest = WHITE
NOMIRRORBITMAP : DWORD : 0x80000000 // Do not Mirror the bitmap in this call
CAPTUREBLT     : DWORD : 0x40000000 // Include layered windows

// Stock Logical Objects
WHITE_BRUSH         :: 0
LTGRAY_BRUSH        :: 1
GRAY_BRUSH          :: 2
DKGRAY_BRUSH        :: 3
BLACK_BRUSH         :: 4
NULL_BRUSH          :: 5
HOLLOW_BRUSH        :: NULL_BRUSH
WHITE_PEN           :: 6
BLACK_PEN           :: 7
NULL_PEN            :: 8
OEM_FIXED_FONT      :: 10
ANSI_FIXED_FONT     :: 11
ANSI_VAR_FONT       :: 12
SYSTEM_FONT         :: 13
DEVICE_DEFAULT_FONT :: 14
DEFAULT_PALETTE     :: 15
SYSTEM_FIXED_FONT   :: 16
DEFAULT_GUI_FONT    :: 17
DC_BRUSH            :: 18
DC_PEN              :: 19
STOCK_LAST          :: 19

CLR_INVALID :: 0xFFFFFFFF

RGBQUAD :: struct {
	rgbBlue: BYTE,
	rgbGreen: BYTE,
	rgbRed: BYTE,
	rgbReserved: BYTE,
}

PIXELFORMATDESCRIPTOR :: struct {
	nSize: WORD,
	nVersion: WORD,
	dwFlags: DWORD,
	iPixelType: BYTE,
	cColorBits: BYTE,
	cRedBits: BYTE,
	cRedShift: BYTE,
	cGreenBits: BYTE,
	cGreenShift: BYTE,
	cBlueBits: BYTE,
	cBlueShift: BYTE,
	cAlphaBits: BYTE,
	cAlphaShift: BYTE,
	cAccumBits: BYTE,
	cAccumRedBits: BYTE,
	cAccumGreenBits: BYTE,
	cAccumBlueBits: BYTE,
	cAccumAlphaBits: BYTE,
	cDepthBits: BYTE,
	cStencilBits: BYTE,
	cAuxBuffers: BYTE,
	iLayerType: BYTE,
	bReserved: BYTE,
	dwLayerMask: DWORD,
	dwVisibleMask: DWORD,
	dwDamageMask: DWORD,
}

BITMAPINFOHEADER :: struct {
	biSize: DWORD,
	biWidth: LONG,
	biHeight: LONG,
	biPlanes: WORD,
	biBitCount: WORD,
	biCompression: DWORD,
	biSizeImage: DWORD,
	biXPelsPerMeter: LONG,
	biYPelsPerMeter: LONG,
	biClrUsed: DWORD,
	biClrImportant: DWORD,
}

BITMAPINFO :: struct {
	bmiHeader: BITMAPINFOHEADER,
	bmiColors: [1]RGBQUAD,
}

BITMAP :: struct {
	bmType:       LONG,
	bmWidth:      LONG,
	bmHeight:     LONG,
	bmWidthBytes: LONG,
	bmPlanes:     WORD,
	bmBitsPixel:  WORD,
	bmBits:       LPVOID,
}

// pixel types
PFD_TYPE_RGBA       :: 0
PFD_TYPE_COLORINDEX :: 1

// layer types
PFD_MAIN_PLANE     :: 0
PFD_OVERLAY_PLANE  :: 1
PFD_UNDERLAY_PLANE :: -1

// PIXELFORMATDESCRIPTOR flags
PFD_DOUBLEBUFFER         :: 0x00000001
PFD_STEREO               :: 0x00000002
PFD_DRAW_TO_WINDOW       :: 0x00000004
PFD_DRAW_TO_BITMAP       :: 0x00000008
PFD_SUPPORT_GDI          :: 0x00000010
PFD_SUPPORT_OPENGL       :: 0x00000020
PFD_GENERIC_FORMAT       :: 0x00000040
PFD_NEED_PALETTE         :: 0x00000080
PFD_NEED_SYSTEM_PALETTE  :: 0x00000100
PFD_SWAP_EXCHANGE        :: 0x00000200
PFD_SWAP_COPY            :: 0x00000400
PFD_SWAP_LAYER_BUFFERS   :: 0x00000800
PFD_GENERIC_ACCELERATED  :: 0x00001000
PFD_SUPPORT_DIRECTDRAW   :: 0x00002000
PFD_DIRECT3D_ACCELERATED :: 0x00004000
PFD_SUPPORT_COMPOSITION  :: 0x00008000

// PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only
PFD_DEPTH_DONTCARE        :: 0x20000000
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000
PFD_STEREO_DONTCARE       :: 0x80000000

// constants for the biCompression field
BI_RGB       :: 0
BI_RLE8      :: 1
BI_RLE4      :: 2
BI_BITFIELDS :: 3
BI_JPEG      :: 4
BI_PNG       :: 5

MAXIMUM_REPARSE_DATA_BUFFER_SIZE :: 16 * 1024
FSCTL_GET_REPARSE_POINT: DWORD : 0x900a8
IO_REPARSE_TAG_SYMLINK: DWORD : 0xa000000c
IO_REPARSE_TAG_MOUNT_POINT: DWORD : 0xa0000003
SYMLINK_FLAG_RELATIVE: DWORD : 0x00000001
FSCTL_SET_REPARSE_POINT: DWORD : 0x900a4

SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD : 0x1
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD : 0x2

STD_INPUT_HANDLE:  DWORD : ~DWORD(0) -10 + 1
STD_OUTPUT_HANDLE: DWORD : ~DWORD(0) -11 + 1
STD_ERROR_HANDLE:  DWORD : ~DWORD(0) -12 + 1

PROGRESS_CONTINUE: DWORD : 0

INVALID_HANDLE :: HANDLE(~uintptr(0))
INVALID_HANDLE_VALUE :: INVALID_HANDLE

FACILITY_NT_BIT: DWORD : 0x1000_0000

FORMAT_MESSAGE_ALLOCATE_BUFFER :: 0x00000100
FORMAT_MESSAGE_IGNORE_INSERTS  :: 0x00000200
FORMAT_MESSAGE_FROM_STRING     :: 0x00000400
FORMAT_MESSAGE_FROM_HMODULE    :: 0x00000800
FORMAT_MESSAGE_FROM_SYSTEM     :: 0x00001000
FORMAT_MESSAGE_ARGUMENT_ARRAY  :: 0x00002000
FORMAT_MESSAGE_MAX_WIDTH_MASK  :: 0x000000FF

LMEM_FIXED    :: 0x0000
LMEM_MOVEABLE :: 0x0002
LMEM_ZEROINIT :: 0x0040
LHND          :: 0x0042
LPTR          :: 0x0040
NONZEROLHND   :: LMEM_MOVEABLE
NONZEROLPTR   :: LMEM_FIXED

TLS_OUT_OF_INDEXES: DWORD : 0xFFFFFFFF

DLL_THREAD_DETACH: DWORD : 3
DLL_PROCESS_DETACH: DWORD : 0

INFINITE :: ~DWORD(0)

DUPLICATE_SAME_ACCESS: DWORD : 0x00000002

CONDITION_VARIABLE_INIT :: CONDITION_VARIABLE{}
SRWLOCK_INIT :: SRWLOCK{}

STARTF_USESTDHANDLES: DWORD : 0x00000100

VOLUME_NAME_DOS: DWORD : 0x0

MOVEFILE_COPY_ALLOWED: DWORD: 0x2
MOVEFILE_CREATE_HARDLINK: DWORD: 0x10
MOVEFILE_DELAY_UNTIL_REBOOT: DWORD: 0x4
MOVEFILE_FAIL_IF_NOT_TRACKABLE: DWORD: 0x20
MOVEFILE_REPLACE_EXISTING: DWORD : 0x1
MOVEFILE_WRITE_THROUGH: DWORD: 0x8

FILE_BEGIN: DWORD : 0
FILE_CURRENT: DWORD : 1
FILE_END: DWORD : 2

WAIT_OBJECT_0: DWORD : 0x00000000
WAIT_TIMEOUT: DWORD : 258
WAIT_FAILED: DWORD : 0xFFFFFFFF

PIPE_ACCESS_INBOUND: DWORD : 0x00000001
PIPE_ACCESS_OUTBOUND: DWORD : 0x00000002
PIPE_ACCESS_DUPLEX: DWORD : 0x00000003
FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
PIPE_WAIT: DWORD : 0x00000000
PIPE_TYPE_BYTE: DWORD : 0x00000000
PIPE_TYPE_MESSAGE: DWORD : 0x00000004
PIPE_REJECT_REMOTE_CLIENTS: DWORD : 0x00000008
PIPE_READMODE_BYTE: DWORD : 0x00000000
PIPE_READMODE_MESSAGE: DWORD : 0x00000002
PIPE_ACCEPT_REMOTE_CLIENTS: DWORD : 0x00000000

FD_SETSIZE :: 64

STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD : 0x00010000

INVALID_SET_FILE_POINTER :: ~DWORD(0)

HEAP_ZERO_MEMORY: DWORD : 0x00000008

HANDLE_FLAG_INHERIT: DWORD : 0x00000001
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 0x00000002

GENERIC_MAPPING :: struct {
	GenericRead: ACCESS_MASK,
	GenericWrite: ACCESS_MASK,
	GenericExecute: ACCESS_MASK,
	GenericAll: ACCESS_MASK,
}
PGENERIC_MAPPING :: ^GENERIC_MAPPING

SECURITY_IMPERSONATION_LEVEL :: enum {
	SecurityAnonymous,
	SecurityIdentification,
	SecurityImpersonation,
	SecurityDelegation,
}

SECURITY_INFORMATION :: DWORD
ANYSIZE_ARRAY :: 1

PLUID_AND_ATTRIBUTES :: ^LUID_AND_ATTRIBUTES
LUID_AND_ATTRIBUTES :: struct {
	Luid: LUID,
	Attributes: DWORD,
}

PRIVILEGE_SET :: struct {
	PrivilegeCount: DWORD,
	Control: DWORD,
	Privilege: [ANYSIZE_ARRAY]LUID_AND_ATTRIBUTES,
}
PPRIVILEGE_SET :: ^PRIVILEGE_SET

// Token Specific Access Rights.
TOKEN_ASSIGN_PRIMARY    :: 0x0001
TOKEN_DUPLICATE         :: 0x0002
TOKEN_IMPERSONATE       :: 0x0004
TOKEN_QUERY             :: 0x0008
TOKEN_QUERY_SOURCE      :: 0x0010
TOKEN_ADJUST_PRIVILEGES :: 0x0020
TOKEN_ADJUST_GROUPS     :: 0x0040
TOKEN_ADJUST_DEFAULT    :: 0x0080
TOKEN_ADJUST_SESSIONID  :: 0x0100

TOKEN_ALL_ACCESS_P :: STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY |\
	TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT

TOKEN_ALL_ACCESS                :: TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID
TOKEN_READ                      :: STANDARD_RIGHTS_READ | TOKEN_QUERY
TOKEN_WRITE                     :: STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT
TOKEN_EXECUTE                   :: STANDARD_RIGHTS_EXECUTE
TOKEN_TRUST_CONSTRAINT_MASK     :: STANDARD_RIGHTS_READ | TOKEN_QUERY | TOKEN_QUERY_SOURCE
TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 :: TOKEN_QUERY | TOKEN_QUERY_SOURCE
TOKEN_ACCESS_PSEUDO_HANDLE      :: TOKEN_ACCESS_PSEUDO_HANDLE_WIN8


CP_ACP        :: 0     // default to ANSI code page
CP_OEMCP      :: 1     // default to OEM  code page
CP_MACCP      :: 2     // default to MAC  code page
CP_THREAD_ACP :: 3     // current thread's ANSI code page
CP_SYMBOL     :: 42    // SYMBOL translations
CP_UTF7       :: 65000 // UTF-7 translation
CP_UTF8       :: 65001 // UTF-8 translation

MB_ERR_INVALID_CHARS :: 8
WC_ERR_INVALID_CHARS :: 128


MAX_PATH :: 0x00000104
MAX_PATH_WIDE :: 0x8000

INVALID_FILE_ATTRIBUTES  :: DWORD(0xffff_ffff)

FILE_TYPE_DISK :: 0x0001
FILE_TYPE_CHAR :: 0x0002
FILE_TYPE_PIPE :: 0x0003

RECT  :: struct {left, top, right, bottom: LONG}
POINT :: struct {x, y: LONG}

PWINDOWPOS :: ^WINDOWPOS
WINDOWPOS :: struct {
	hwnd: HWND,
	hwndInsertAfter: HWND,
	x: c_int,
	y: c_int,
	cx: c_int,
	cy: c_int,
	flags: UINT,
}

when size_of(uintptr) == 4 {
	WSADATA :: struct {
		wVersion: WORD,
		wHighVersion: WORD,
		szDescription: [WSADESCRIPTION_LEN + 1]u8,
		szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
		iMaxSockets: u16,
		iMaxUdpDg: u16,
		lpVendorInfo: ^u8,
	}
} else when size_of(uintptr) == 8 {
	WSADATA :: struct {
		wVersion: WORD,
		wHighVersion: WORD,
		iMaxSockets: u16,
		iMaxUdpDg: u16,
		lpVendorInfo: ^u8,
		szDescription: [WSADESCRIPTION_LEN + 1]u8,
		szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
	}
} else {
	#panic("unknown word size")
}

WSABUF :: struct {
	len: ULONG,
	buf: ^CHAR,
}

WSAPROTOCOL_INFO :: struct {
	dwServiceFlags1: DWORD,
	dwServiceFlags2: DWORD,
	dwServiceFlags3: DWORD,
	dwServiceFlags4: DWORD,
	dwProviderFlags: DWORD,
	ProviderId: GUID,
	dwCatalogEntryId: DWORD,
	ProtocolChain: WSAPROTOCOLCHAIN,
	iVersion: c_int,
	iAddressFamily: c_int,
	iMaxSockAddr: c_int,
	iMinSockAddr: c_int,
	iSocketType: c_int,
	iProtocol: c_int,
	iProtocolMaxOffset: c_int,
	iNetworkByteOrder: c_int,
	iSecurityScheme: c_int,
	dwMessageSize: DWORD,
	dwProviderReserved: DWORD,
	szProtocol: [WSAPROTOCOL_LEN + 1]u16,
}

WIN32_FILE_ATTRIBUTE_DATA :: struct {
	dwFileAttributes: DWORD,
	ftCreationTime: FILETIME,
	ftLastAccessTime: FILETIME,
	ftLastWriteTime: FILETIME,
	nFileSizeHigh: DWORD,
	nFileSizeLow: DWORD,
}

FILE_INFO_BY_HANDLE_CLASS :: enum c_int {
	FileBasicInfo = 0,
	FileStandardInfo = 1,
	FileNameInfo = 2,
	FileRenameInfo = 3,
	FileDispositionInfo = 4,
	FileAllocationInfo = 5,
	FileEndOfFileInfo = 6,
	FileStreamInfo = 7,
	FileCompressionInfo = 8,
	FileAttributeTagInfo = 9,
	FileIdBothDirectoryInfo = 10,        // 0xA
	FileIdBothDirectoryRestartInfo = 11, // 0xB
	FileIoPriorityHintInfo = 12,         // 0xC
	FileRemoteProtocolInfo = 13,         // 0xD
	FileFullDirectoryInfo = 14,          // 0xE
	FileFullDirectoryRestartInfo = 15,   // 0xF
	FileStorageInfo = 16,                // 0x10
	FileAlignmentInfo = 17,              // 0x11
	FileIdInfo = 18,                     // 0x12
	FileIdExtdDirectoryInfo = 19,        // 0x13
	FileIdExtdDirectoryRestartInfo = 20, // 0x14
	MaximumFileInfoByHandlesClass,
}

FILE_BASIC_INFO :: struct {
	CreationTime: LARGE_INTEGER,
	LastAccessTime: LARGE_INTEGER,
	LastWriteTime: LARGE_INTEGER,
	ChangeTime: LARGE_INTEGER,
	FileAttributes: DWORD,
}

FILE_END_OF_FILE_INFO :: struct {
	EndOfFile: LARGE_INTEGER,
}

FILE_NOTIFY_INFORMATION :: struct {
	next_entry_offset: DWORD,
	action:            DWORD,
	file_name_length:  DWORD,
	file_name:         [1]WCHAR,
}

REPARSE_DATA_BUFFER :: struct {
	ReparseTag: c_uint,
	ReparseDataLength: c_ushort,
	Reserved: c_ushort,
	rest: [0]byte,
}

SYMBOLIC_LINK_REPARSE_BUFFER :: struct {
	SubstituteNameOffset: c_ushort,
	SubstituteNameLength: c_ushort,
	PrintNameOffset: c_ushort,
	PrintNameLength: c_ushort,
	Flags: c_ulong,
	PathBuffer: WCHAR,
}

MOUNT_POINT_REPARSE_BUFFER :: struct {
	SubstituteNameOffset: c_ushort,
	SubstituteNameLength: c_ushort,
	PrintNameOffset: c_ushort,
	PrintNameLength: c_ushort,
	PathBuffer: WCHAR,
}

LPPROGRESS_ROUTINE :: #type proc "system" (
	TotalFileSize: LARGE_INTEGER,
	TotalBytesTransferred: LARGE_INTEGER,
	StreamSize: LARGE_INTEGER,
	StreamBytesTransferred: LARGE_INTEGER,
	dwStreamNumber: DWORD,
	dwCallbackReason: DWORD,
	hSourceFile: HANDLE,
	hDestinationFile: HANDLE,
	lpData: LPVOID,
) -> DWORD

CONDITION_VARIABLE :: struct {
	ptr: LPVOID,
}
SRWLOCK :: struct {
	ptr: LPVOID,
}
CRITICAL_SECTION :: struct {
	CriticalSectionDebug: LPVOID,
	LockCount: LONG,
	RecursionCount: LONG,
	OwningThread: HANDLE,
	LockSemaphore: HANDLE,
	SpinCount: ULONG_PTR,
}

REPARSE_MOUNTPOINT_DATA_BUFFER :: struct {
	ReparseTag: DWORD,
	ReparseDataLength: DWORD,
	Reserved: WORD,
	ReparseTargetLength: WORD,
	ReparseTargetMaximumLength: WORD,
	Reserved1: WORD,
	ReparseTarget: WCHAR,
}

GUID :: struct {
	Data1: DWORD,
	Data2: WORD,
	Data3: WORD,
	Data4: [8]BYTE,
}

LUID :: struct {
	LowPart:  DWORD,
	HighPart: LONG,
}

PLUID :: ^LUID

PGUID   :: ^GUID
PCGUID  :: ^GUID
LPGUID  :: ^GUID
LPCGUID :: ^GUID
REFIID  :: ^GUID

REFGUID :: GUID
IID :: GUID
CLSID :: GUID
REFCLSID :: ^CLSID

CLSCTX_INPROC_SERVER                  :: 0x1
CLSCTX_INPROC_HANDLER                 :: 0x2
CLSCTX_LOCAL_SERVER                   :: 0x4
CLSCTX_INPROC_SERVER16                :: 0x8
CLSCTX_REMOTE_SERVER                  :: 0x10
CLSCTX_INPROC_HANDLER16               :: 0x20
CLSCTX_RESERVED1                      :: 0x40
CLSCTX_RESERVED2                      :: 0x80
CLSCTX_RESERVED3                      :: 0x100
CLSCTX_RESERVED4                      :: 0x200
CLSCTX_NO_CODE_DOWNLOAD               :: 0x400
CLSCTX_RESERVED5                      :: 0x800
CLSCTX_NO_CUSTOM_MARSHAL              :: 0x1000
CLSCTX_ENABLE_CODE_DOWNLOAD           :: 0x2000
CLSCTX_NO_FAILURE_LOG                 :: 0x4000
CLSCTX_DISABLE_AAA                    :: 0x8000
CLSCTX_ENABLE_AAA                     :: 0x10000
CLSCTX_FROM_DEFAULT_CONTEXT           :: 0x20000
CLSCTX_ACTIVATE_X86_SERVER            :: 0x40000
CLSCTX_ACTIVATE_32_BIT_SERVER         :: CLSCTX_ACTIVATE_X86_SERVER
CLSCTX_ACTIVATE_64_BIT_SERVER         :: 0x80000
CLSCTX_ENABLE_CLOAKING                :: 0x100000
CLSCTX_APPCONTAINER                   :: 0x400000
CLSCTX_ACTIVATE_AAA_AS_IU             :: 0x800000
CLSCTX_RESERVED6                      :: 0x1000000
CLSCTX_ACTIVATE_ARM32_SERVER          :: 0x2000000
CLSCTX_ALLOW_LOWER_TRUST_REGISTRATION :: 0x4000000
CLSCTX_PS_DLL                         :: 0x80000000

WSAPROTOCOLCHAIN :: struct {
	ChainLen: c_int,
	ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
}

SECURITY_ATTRIBUTES :: struct {
	nLength: DWORD,
	lpSecurityDescriptor: LPVOID,
	bInheritHandle: BOOL,
}

PROCESS_INFORMATION :: struct {
	hProcess: HANDLE,
	hThread: HANDLE,
	dwProcessId: DWORD,
	dwThreadId: DWORD,
}

STARTUPINFOW :: struct {
	cb: DWORD,
	lpReserved: LPWSTR,
	lpDesktop: LPWSTR,
	lpTitle: LPWSTR,
	dwX: DWORD,
	dwY: DWORD,
	dwXSize: DWORD,
	dwYSize: DWORD,
	dwXCountChars: DWORD,
	dwYCountChars: DWORD,
	dwFillAttribute: DWORD,
	dwFlags: DWORD,
	wShowWindow: WORD,
	cbReserved2: WORD,
	lpReserved2: LPBYTE,
	hStdInput: HANDLE,
	hStdOutput: HANDLE,
	hStdError: HANDLE,
}

FILETIME :: struct {
	dwLowDateTime: DWORD,
	dwHighDateTime: DWORD,
}

FILETIME_as_unix_nanoseconds :: proc "contextless" (ft: FILETIME) -> i64 {
	t := i64(u64(ft.dwLowDateTime) | u64(ft.dwHighDateTime) << 32)
	return (t - 116444736000000000) * 100
}

OBJECT_ATTRIBUTES :: struct {
	Length:                   c_ulong,
	RootDirectory:            HANDLE,
	ObjectName:               ^UNICODE_STRING,
	Attributes:               c_ulong,
	SecurityDescriptor:       rawptr,
	SecurityQualityOfService: rawptr,
}

UNICODE_STRING :: struct {
	Length:        u16    `fmt:"-"`,
	MaximumLength: u16    `fmt:"-"`,
	Buffer:        [^]u16 `fmt:"s,Length"`,
}

OVERLAPPED :: struct {
	Internal: ^c_ulong,
	InternalHigh: ^c_ulong,
	Offset: DWORD,
	OffsetHigh: DWORD,
	hEvent: HANDLE,
}

OVERLAPPED_ENTRY :: struct {
	lpCompletionKey:            ULONG_PTR,
	lpOverlapped:               ^OVERLAPPED,
	Internal:                   ULONG_PTR,
	dwNumberOfBytesTransferred: DWORD,
}

LPOVERLAPPED_COMPLETION_ROUTINE :: #type proc "system" (
	dwErrorCode: DWORD,
	dwNumberOfBytesTransfered: DWORD,
	lpOverlapped: LPOVERLAPPED,
)

ADDRESS_MODE :: enum c_int {
	AddrMode1616,
	AddrMode1632,
	AddrModeReal,
	AddrModeFlat,
}

EXCEPTION_DISPOSITION :: enum c_int {
	ExceptionContinueExecution,
	ExceptionContinueSearch,
	ExceptionNestedException,
	ExceptionCollidedUnwind,
}

fd_set :: struct {
	fd_count: c_uint,
	fd_array: [FD_SETSIZE]SOCKET,
}

timeval :: struct {
	tv_sec: c_long,
	tv_usec: c_long,
}


EXCEPTION_CONTINUE_SEARCH: LONG : 0
EXCEPTION_CONTINUE_EXECUTION: LONG : -1
EXCEPTION_EXECUTE_HANDLER: LONG : 1

EXCEPTION_MAXIMUM_PARAMETERS :: 15

EXCEPTION_DATATYPE_MISALIGNMENT     :: 0x80000002
EXCEPTION_BREAKPOINT                :: 0x80000003
EXCEPTION_ACCESS_VIOLATION          :: 0xC0000005
EXCEPTION_ILLEGAL_INSTRUCTION       :: 0xC000001D
EXCEPTION_ARRAY_BOUNDS_EXCEEDED     :: 0xC000008C
EXCEPTION_INT_DIVIDE_BY_ZERO        :: 0xC0000094
EXCEPTION_INT_OVERFLOW              :: 0xC0000095
EXCEPTION_STACK_OVERFLOW            :: 0xC00000FD
STATUS_PRIVILEGED_INSTRUCTION       :: 0xC0000096


EXCEPTION_RECORD :: struct {
	ExceptionCode: DWORD,
	ExceptionFlags: DWORD,
	ExceptionRecord: ^EXCEPTION_RECORD,
	ExceptionAddress: LPVOID,
	NumberParameters: DWORD,
	ExceptionInformation: [EXCEPTION_MAXIMUM_PARAMETERS]LPVOID,
}


CONTEXT :: struct {
	P1Home: DWORD64,
	P2Home: DWORD64,
	P3Home: DWORD64,
	P4Home: DWORD64,
	P5Home: DWORD64,
	P6Home: DWORD64,
	ContextFlags: DWORD,
	MxCsr: DWORD,
	SegCs: WORD,
	SegDs: WORD,
	SegEs: WORD,
	SegFs: WORD,
	SegGs: WORD,
	SegSs: WORD,
	EFlags: DWORD,
	Dr0: DWORD64,
	Dr1: DWORD64,
	Dr2: DWORD64,
	Dr3: DWORD64,
	Dr6: DWORD64,
	Dr7: DWORD64,
	Rax: DWORD64,
	Rcx: DWORD64,
	Rdx: DWORD64,
	Rbx: DWORD64,
	Rsp: DWORD64,
	Rbp: DWORD64,
	Rsi: DWORD64,
	Rdi: DWORD64,
	R8: DWORD64,
	R9: DWORD64,
	R10: DWORD64,
	R11: DWORD64,
	R12: DWORD64,
	R13: DWORD64,
	R14: DWORD64,
	R15: DWORD64,
	Rip: DWORD64,
	_: struct #raw_union {
		FltSave: XMM_SAVE_AREA32,
		Q: [16]NEON128,
		D: [32]ULONGLONG,
		_: struct {
			Header: [2]M128A,
			Legacy: [8]M128A,
			Xmm0: M128A,
			Xmm1: M128A,
			Xmm2: M128A,
			Xmm3: M128A,
			Xmm4: M128A,
			Xmm5: M128A,
			Xmm6: M128A,
			Xmm7: M128A,
			Xmm8: M128A,
			Xmm9: M128A,
			Xmm10: M128A,
			Xmm11: M128A,
			Xmm12: M128A,
			Xmm13: M128A,
			Xmm14: M128A,
			Xmm15: M128A,
		},
		S: [32]DWORD,
	},
	VectorRegister: [26]M128A,
	VectorControl: DWORD64,
	DebugControl: DWORD64,
	LastBranchToRip: DWORD64,
	LastBranchFromRip: DWORD64,
	LastExceptionToRip: DWORD64,
	LastExceptionFromRip: DWORD64,
}

PCONTEXT :: ^CONTEXT
LPCONTEXT :: ^CONTEXT

when size_of(uintptr) == 32 { 
	XSAVE_FORMAT :: struct #align(16) {
		ControlWord: WORD,
		StatusWord: WORD,
		TagWord: BYTE,
		Reserved1: BYTE,
		ErrorOpcode: WORD,
		ErrorOffset: DWORD,
		ErrorSelector: WORD,
		Reserved2: WORD,
		DataOffset: DWORD,
		DataSelector: WORD,
		Reserved3: WORD,
		MxCsr: DWORD,
		MxCsr_Mask: DWORD,
		FloatRegisters: [8]M128A,
		// 32-bit specific
		XmmRegisters: [8]M128A,
		Reserved4: [192]BYTE,
		StackControl: [7]DWORD,
		Cr0NpxState: DWORD,
	}
} else {
	XSAVE_FORMAT :: struct #align(16) {
		ControlWord: WORD,
		StatusWord: WORD,
		TagWord: BYTE,
		Reserved1: BYTE,
		ErrorOpcode: WORD,
		ErrorOffset: DWORD,
		ErrorSelector: WORD,
		Reserved2: WORD,
		DataOffset: DWORD,
		DataSelector: WORD,
		Reserved3: WORD,
		MxCsr: DWORD,
		MxCsr_Mask: DWORD,
		FloatRegisters: [8]M128A,
		// 64-bit specific
		XmmRegisters: [16]M128A,
		Reserved4: [96]BYTE,
	}
}

XMM_SAVE_AREA32 :: XSAVE_FORMAT

M128A :: struct {
	Low: ULONGLONG,
	High: LONGLONG,
}

NEON128 :: struct {
	Low: ULONGLONG,
	High: LONGLONG,
}

EXCEPTION_POINTERS :: struct {
	ExceptionRecord: ^EXCEPTION_RECORD,
	ContextRecord:   ^CONTEXT,
}

PVECTORED_EXCEPTION_HANDLER :: #type proc "system" (ExceptionInfo: ^EXCEPTION_POINTERS) -> LONG

CONSOLE_READCONSOLE_CONTROL :: struct {
	nLength:           ULONG,
	nInitialChars:     ULONG,
	dwCtrlWakeupMask:  ULONG,
	dwControlKeyState: ULONG,
}

PCONSOLE_READCONSOLE_CONTROL :: ^CONSOLE_READCONSOLE_CONTROL

BY_HANDLE_FILE_INFORMATION :: struct {
	dwFileAttributes:     DWORD,
	ftCreationTime:       FILETIME,
	ftLastAccessTime:     FILETIME,
	ftLastWriteTime:      FILETIME,
	dwVolumeSerialNumber: DWORD,
	nFileSizeHigh:        DWORD,
	nFileSizeLow:         DWORD,
	nNumberOfLinks:       DWORD,
	nFileIndexHigh:       DWORD,
	nFileIndexLow:        DWORD,
}

LPBY_HANDLE_FILE_INFORMATION :: ^BY_HANDLE_FILE_INFORMATION

FILE_STANDARD_INFO :: struct {
	AllocationSize: LARGE_INTEGER,
	EndOfFile:      LARGE_INTEGER,
	NumberOfLinks:  DWORD,
	DeletePending:  BOOLEAN,
	Directory:      BOOLEAN,
}

FILE_ATTRIBUTE_TAG_INFO :: struct {
	FileAttributes: DWORD,
	ReparseTag: DWORD,
}

PADDRINFOEXW :: ^ADDRINFOEXW
LPADDRINFOEXW :: ^ADDRINFOEXW
ADDRINFOEXW :: struct {
	ai_flags:     c_int,
	ai_family:    c_int,
	ai_socktype:  c_int,
	ai_protocol:  c_int,
	ai_addrlen:   size_t,
	ai_canonname: wstring,
	ai_addr:      ^sockaddr,
	ai_blob:      rawptr,
	ai_bloblen:   size_t,
	ai_provider:  LPGUID,
	ai_next:      ^ADDRINFOEXW,
}

LPLOOKUPSERVICE_COMPLETION_ROUTINE :: #type proc "system" (
	dwErrorCode: DWORD,
	dwNumberOfBytesTransfered: DWORD,
	lpOverlapped: LPOVERLAPPED,
)


// https://docs.microsoft.com/en-gb/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
SYSTEM_INFO :: struct {
	using _: struct #raw_union {
		dwOemID: DWORD,
		using _: struct #raw_union {
			wProcessorArchitecture: WORD,
			wReserved: WORD, // reserved
		},
	},
	dwPageSize: DWORD,
	lpMinimumApplicationAddress: LPVOID,
	lpMaximumApplicationAddress: LPVOID,
	dwActiveProcessorMask: DWORD_PTR,
	dwNumberOfProcessors: DWORD,
	dwProcessorType: DWORD,
	dwAllocationGranularity: DWORD,
	wProcessorLevel: WORD,
	wProcessorRevision: WORD,
}

// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
OSVERSIONINFOEXW :: struct {
	dwOSVersionInfoSize: ULONG,
	dwMajorVersion:      ULONG,
	dwMinorVersion:      ULONG,
	dwBuildNumber:       ULONG,
	dwPlatformId:        ULONG,
	szCSDVersion:        [128]WCHAR,
	wServicePackMajor:   USHORT,
	wServicePackMinor:   USHORT,
	wSuiteMask:          USHORT,
	wProductType:        UCHAR,
	wReserved:           UCHAR,
}

LoadLibraryEx_Flag :: enum DWORD {
	LOAD_LIBRARY_AS_DATAFILE            = 1,  // 1 <<  1: 0x0002,
	LOAD_WITH_ALTERED_SEARCH_PATH       = 3,  // 1 <<  3: 0x0008,
	LOAD_IGNORE_CODE_AUTHZ_LEVEL        = 4,  // 1 <<  4: 0x0010,
	LOAD_LIBRARY_AS_IMAGE_RESOURCE      = 5,  // 1 <<  5: 0x0020,
	LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE  = 6,  // 1 <<  6: 0x0040,
	LOAD_LIBRARY_REQUIRE_SIGNED_TARGET  = 7,  // 1 <<  7: 0x0080,
	LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR    = 8,  // 1 <<  8: 0x0100,
	LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 9,  // 1 <<  9: 0x0200,
	LOAD_LIBRARY_SEARCH_USER_DIRS       = 10, // 1 << 10: 0x0400,
	LOAD_LIBRARY_SEARCH_SYSTEM32        = 11, // 1 << 11: 0x0800,
	LOAD_LIBRARY_SEARCH_DEFAULT_DIRS    = 12, // 1 << 12: 0x1000,
	LOAD_LIBRARY_SAFE_CURRENT_DIRS      = 13, // 1 << 13: 0x2000,
}
LoadLibraryEx_Flags :: distinct bit_set[LoadLibraryEx_Flag]

// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-quota_limits
// Used in LogonUserExW
PQUOTA_LIMITS :: struct {
	PagedPoolLimit: SIZE_T,
	NonPagedPoolLimit: SIZE_T,
	MinimumWorkingSetSize: SIZE_T,
	MaximumWorkingSetSize: SIZE_T,
	PagefileLimit: SIZE_T,
	TimeLimit: LARGE_INTEGER,
}

Logon32_Type :: enum DWORD {
	INTERACTIVE       = 2,
	NETWORK           = 3,
	BATCH             = 4,
	SERVICE           = 5,
	UNLOCK            = 7,
	NETWORK_CLEARTEXT = 8,
	NEW_CREDENTIALS   = 9,
}

Logon32_Provider :: enum DWORD {
	DEFAULT = 0,
	WINNT35 = 1,
	WINNT40 = 2,
	WINNT50 = 3,
	VIRTUAL = 4,
}

// https://docs.microsoft.com/en-us/windows/win32/api/profinfo/ns-profinfo-profileinfow
// Used in LoadUserProfileW

PROFILEINFOW :: struct {
	dwSize: DWORD,
	dwFlags: DWORD,
	lpUserName: LPWSTR,
	lpProfilePath: LPWSTR,
	lpDefaultPath: LPWSTR,
	lpServerName: LPWSTR,
	lpPolicyPath: LPWSTR,
	hProfile: HANDLE,
}

SECURITY_MAX_SID_SIZE :: 68

// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid
SID :: struct #packed {
	Revision:            byte,
	SubAuthorityCount:   byte,
	IdentifierAuthority: SID_IDENTIFIER_AUTHORITY,
	SubAuthority:        [15]DWORD, // Array of DWORDs
}
#assert(size_of(SID) == SECURITY_MAX_SID_SIZE)

SID_IDENTIFIER_AUTHORITY :: struct #packed {
	Value: [6]u8,
}
#assert(size_of(SID_IDENTIFIER_AUTHORITY) == 6)

// For NetAPI32
// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.14393.0/shared/lmerr.h
// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.14393.0/shared/LMaccess.h

UNLEN      :: 256        // Maximum user name length
LM20_UNLEN ::  20        // LM 2.0 Maximum user name length

GNLEN      :: UNLEN      // Group name
LM20_GNLEN :: LM20_UNLEN // LM 2.0 Group name

PWLEN      :: 256        // Maximum password length
LM20_PWLEN ::  14        // LM 2.0 Maximum password length

USER_PRIV :: enum DWORD {
	Guest = 0,
	User  = 1,
	Admin = 2,
	Mask  = 0x3,
}

USER_INFO_FLAG :: enum DWORD {
	Script                          = 0,  // 1 <<  0: 0x0001,
	AccountDisable                  = 1,  // 1 <<  1: 0x0002,
	HomeDir_Required                = 3,  // 1 <<  3: 0x0008,
	Lockout                         = 4,  // 1 <<  4: 0x0010,
	Passwd_NotReqd                  = 5,  // 1 <<  5: 0x0020,
	Passwd_Cant_Change              = 6,  // 1 <<  6: 0x0040,
	Encrypted_Text_Password_Allowed = 7,  // 1 <<  7: 0x0080,

	Temp_Duplicate_Account          = 8,  // 1 <<  8: 0x0100,
	Normal_Account                  = 9,  // 1 <<  9: 0x0200,
	InterDomain_Trust_Account       = 11, // 1 << 11: 0x0800,
	Workstation_Trust_Account       = 12, // 1 << 12: 0x1000,
	Server_Trust_Account            = 13, // 1 << 13: 0x2000,
}
USER_INFO_FLAGS :: distinct bit_set[USER_INFO_FLAG]

USER_INFO_1 :: struct #packed {
	name: LPWSTR,
	password: LPWSTR,     // Max password length is defined in LM20_PWLEN.
	password_age: DWORD,
	priv: USER_PRIV,
	home_dir: LPWSTR,
	comment: LPWSTR,
	flags: USER_INFO_FLAGS,
	script_path: LPWSTR,
}
// #assert(size_of(USER_INFO_1) == 50)

LOCALGROUP_MEMBERS_INFO_0 :: struct #packed {
	sid: ^SID,
}

NET_API_STATUS :: enum DWORD {
	Success = 0,
	ERROR_ACCESS_DENIED = 5,
	MemberInAlias = 1378,
	NetNotStarted = 2102,
	UnknownServer = 2103,
	ShareMem = 2104,
	NoNetworkResource = 2105,
	RemoteOnly = 2106,
	DevNotRedirected = 2107,
	ServerNotStarted = 2114,
	ItemNotFound = 2115,
	UnknownDevDir = 2116,
	RedirectedPath = 2117,
	DuplicateShare = 2118,
	NoRoom = 2119,
	TooManyItems = 2121,
	InvalidMaxUsers = 2122,
	BufTooSmall = 2123,
	RemoteErr = 2127,
	LanmanIniError = 2131,
	NetworkError = 2136,
	WkstaInconsistentState = 2137,
	WkstaNotStarted = 2138,
	BrowserNotStarted = 2139,
	InternalError = 2140,
	BadTransactConfig = 2141,
	InvalidAPI = 2142,
	BadEventName = 2143,
	DupNameReboot = 2144,
	CfgCompNotFound = 2146,
	CfgParamNotFound = 2147,
	LineTooLong = 2149,
	QNotFound = 2150,
	JobNotFound = 2151,
	DestNotFound = 2152,
	DestExists = 2153,
	QExists = 2154,
	QNoRoom = 2155,
	JobNoRoom = 2156,
	DestNoRoom = 2157,
	DestIdle = 2158,
	DestInvalidOp = 2159,
	ProcNoRespond = 2160,
	SpoolerNotLoaded = 2161,
	DestInvalidState = 2162,
	QInvalidState = 2163,
	JobInvalidState = 2164,
	SpoolNoMemory = 2165,
	DriverNotFound = 2166,
	DataTypeInvalid = 2167,
	ProcNotFound = 2168,
	ServiceTableLocked = 2180,
	ServiceTableFull = 2181,
	ServiceInstalled = 2182,
	ServiceEntryLocked = 2183,
	ServiceNotInstalled = 2184,
	BadServiceName = 2185,
	ServiceCtlTimeout = 2186,
	ServiceCtlBusy = 2187,
	BadServiceProgName = 2188,
	ServiceNotCtrl = 2189,
	ServiceKillProc = 2190,
	ServiceCtlNotValid = 2191,
	NotInDispatchTbl = 2192,
	BadControlRecv = 2193,
	ServiceNotStarting = 2194,
	AlreadyLoggedOn = 2200,
	NotLoggedOn = 2201,
	BadUsername = 2202,
	BadPassword = 2203,
	UnableToAddName_W = 2204,
	UnableToAddName_F = 2205,
	UnableToDelName_W = 2206,
	UnableToDelName_F = 2207,
	LogonsPaused = 2209,
	LogonServerConflict = 2210,
	LogonNoUserPath = 2211,
	LogonScriptError = 2212,
	StandaloneLogon = 2214,
	LogonServerNotFound = 2215,
	LogonDomainExists = 2216,
	NonValidatedLogon = 2217,
	ACFNotFound = 2219,
	GroupNotFound = 2220,
	UserNotFound = 2221,
	ResourceNotFound = 2222,
	GroupExists = 2223,
	UserExists = 2224,
	ResourceExists = 2225,
	NotPrimary = 2226,
	ACFNotLoaded = 2227,
	ACFNoRoom = 2228,
	ACFFileIOFail = 2229,
	ACFTooManyLists = 2230,
	UserLogon = 2231,
	ACFNoParent = 2232,
	CanNotGrowSegment = 2233,
	SpeGroupOp = 2234,
	NotInCache = 2235,
	UserInGroup = 2236,
	UserNotInGroup = 2237,
	AccountUndefined = 2238,
	AccountExpired = 2239,
	InvalidWorkstation = 2240,
	InvalidLogonHours = 2241,
	PasswordExpired = 2242,
	PasswordCantChange = 2243,
	PasswordHistConflict = 2244,
	PasswordTooShort = 2245,
	PasswordTooRecent = 2246,
	InvalidDatabase = 2247,
	DatabaseUpToDate = 2248,
	SyncRequired = 2249,
	UseNotFound = 2250,
	BadAsgType = 2251,
	DeviceIsShared = 2252,
	SameAsComputerName = 2253,
	NoComputerName = 2270,
	MsgAlreadyStarted = 2271,
	MsgInitFailed = 2272,
	NameNotFound = 2273,
	AlreadyForwarded = 2274,
	AddForwarded = 2275,
	AlreadyExists = 2276,
	TooManyNames = 2277,
	DelComputerName = 2278,
	LocalForward = 2279,
	GrpMsgProcessor = 2280,
	PausedRemote = 2281,
	BadReceive = 2282,
	NameInUse = 2283,
	MsgNotStarted = 2284,
	NotLocalName = 2285,
	NoForwardName = 2286,
	RemoteFull = 2287,
	NameNotForwarded = 2288,
	TruncatedBroadcast = 2289,
	InvalidDevice = 2294,
	WriteFault = 2295,
	DuplicateName = 2297,
	DeleteLater = 2298,
	IncompleteDel = 2299,
	MultipleNets = 2300,
	NetNameNotFound = 2310,
	DeviceNotShared = 2311,
	ClientNameNotFound = 2312,
	FileIdNotFound = 2314,
	ExecFailure = 2315,
	TmpFile = 2316,
	TooMuchData = 2317,
	DeviceShareConflict = 2318,
	BrowserTableIncomplete = 2319,
	NotLocalDomain = 2320,
	IsDfsShare = 2321,
	DevInvalidOpCode = 2331,
	DevNotFound = 2332,
	DevNotOpen = 2333,
	BadQueueDevString = 2334,
	BadQueuePriority = 2335,
	NoCommDevs = 2337,
	QueueNotFound = 2338,
	BadDevString = 2340,
	BadDev = 2341,
	InUseBySpooler = 2342,
	CommDevInUse = 2343,
	InvalidComputer = 2351,
	MaxLenExceeded = 2354,
	BadComponent = 2356,
	CantType = 2357,
	TooManyEntries = 2362,
	ProfileFileTooBig = 2370,
	ProfileOffset = 2371,
	ProfileCleanup = 2372,
	ProfileUnknownCmd = 2373,
	ProfileLoadErr = 2374,
	ProfileSaveErr = 2375,
	LogOverflow = 2377,
	LogFileChanged = 2378,
	LogFileCorrupt = 2379,
	SourceIsDir = 2380,
	BadSource = 2381,
	BadDest = 2382,
	DifferentServers = 2383,
	RunSrvPaused = 2385,
	ErrCommRunSrv = 2389,
	ErrorExecingGhost = 2391,
	ShareNotFound = 2392,
	InvalidLana = 2400,
	OpenFiles = 2401,
	ActiveConns = 2402,
	BadPasswordCore = 2403,
	DevInUse = 2404,
	LocalDrive = 2405,
	AlertExists = 2430,
	TooManyAlerts = 2431,
	NoSuchAlert = 2432,
	BadRecipient = 2433,
	AcctLimitExceeded = 2434,
	InvalidLogSeek = 2440,
	BadUasConfig = 2450,
	InvalidUASOp = 2451,
	LastAdmin = 2452,
	DCNotFound = 2453,
	LogonTrackingError = 2454,
	NetlogonNotStarted = 2455,
	CanNotGrowUASFile = 2456,
	TimeDiffAtDC = 2457,
	PasswordMismatch = 2458,
	NoSuchServer = 2460,
	NoSuchSession = 2461,
	NoSuchConnection = 2462,
	TooManyServers = 2463,
	TooManySessions = 2464,
	TooManyConnections = 2465,
	TooManyFiles = 2466,
	NoAlternateServers = 2467,
	TryDownLevel = 2470,
	UPSDriverNotStarted = 2480,
	UPSInvalidConfig = 2481,
	UPSInvalidCommPort = 2482,
	UPSSignalAsserted = 2483,
	UPSShutdownFailed = 2484,
	BadDosRetCode = 2500,
	ProgNeedsExtraMem = 2501,
	BadDosFunction = 2502,
	RemoteBootFailed = 2503,
	BadFileCheckSum = 2504,
	NoRplBootSystem = 2505,
	RplLoadrNetBiosErr = 2506,
	RplLoadrDiskErr = 2507,
	ImageParamErr = 2508,
	TooManyImageParams = 2509,
	NonDosFloppyUsed = 2510,
	RplBootRestart = 2511,
	RplSrvrCallFailed = 2512,
	CantConnectRplSrvr = 2513,
	CantOpenImageFile = 2514,
	CallingRplSrvr = 2515,
	StartingRplBoot = 2516,
	RplBootServiceTerm = 2517,
	RplBootStartFailed = 2518,
	RPL_CONNECTED = 2519,
	BrowserConfiguredToNotRun = 2550,
	RplNoAdaptersStarted = 2610,
	RplBadRegistry = 2611,
	RplBadDatabase = 2612,
	RplRplfilesShare = 2613,
	RplNotRplServer = 2614,
	RplCannotEnum = 2615,
	RplWkstaInfoCorrupted = 2616,
	RplWkstaNotFound = 2617,
	RplWkstaNameUnavailable = 2618,
	RplProfileInfoCorrupted = 2619,
	RplProfileNotFound = 2620,
	RplProfileNameUnavailable = 2621,
	RplProfileNotEmpty = 2622,
	RplConfigInfoCorrupted = 2623,
	RplConfigNotFound = 2624,
	RplAdapterInfoCorrupted = 2625,
	RplInternal = 2626,
	RplVendorInfoCorrupted = 2627,
	RplBootInfoCorrupted = 2628,
	RplWkstaNeedsUserAcct = 2629,
	RplNeedsRPLUSERAcct = 2630,
	RplBootNotFound = 2631,
	RplIncompatibleProfile = 2632,
	RplAdapterNameUnavailable = 2633,
	RplConfigNotEmpty = 2634,
	RplBootInUse = 2635,
	RplBackupDatabase = 2636,
	RplAdapterNotFound = 2637,
	RplVendorNotFound = 2638,
	RplVendorNameUnavailable = 2639,
	RplBootNameUnavailable = 2640,
	RplConfigNameUnavailable = 2641,
	DfsInternalCorruption = 2660,
	DfsVolumeDataCorrupt = 2661,
	DfsNoSuchVolume = 2662,
	DfsVolumeAlreadyExists = 2663,
	DfsAlreadyShared = 2664,
	DfsNoSuchShare = 2665,
	DfsNotALeafVolume = 2666,
	DfsLeafVolume = 2667,
	DfsVolumeHasMultipleServers = 2668,
	DfsCantCreateJunctionPoint = 2669,
	DfsServerNotDfsAware = 2670,
	DfsBadRenamePath = 2671,
	DfsVolumeIsOffline = 2672,
	DfsNoSuchServer = 2673,
	DfsCyclicalName = 2674,
	DfsNotSupportedInServerDfs = 2675,
	DfsDuplicateService = 2676,
	DfsCantRemoveLastServerShare = 2677,
	DfsVolumeIsInterDfs = 2678,
	DfsInconsistent = 2679,
	DfsServerUpgraded = 2680,
	DfsDataIsIdentical = 2681,
	DfsCantRemoveDfsRoot = 2682,
	DfsChildOrParentInDfs = 2683,
	DfsInternalError = 2690,
	SetupAlreadyJoined = 2691,
	SetupNotJoined = 2692,
	SetupDomainController = 2693,
	DefaultJoinRequired = 2694,
	InvalidWorkgroupName = 2695,
	NameUsesIncompatibleCodePage = 2696,
	ComputerAccountNotFound = 2697,
	PersonalSku = 2698,
	SetupCheckDNSConfig = 2699,
	PasswordMustChange = 2701,
	AccountLockedOut = 2702,
	PasswordTooLong = 2703,
	PasswordNotComplexEnough = 2704,
	PasswordFilterError = 2705,
}


SYSTEMTIME :: struct {
	year:         WORD,
	month:        WORD,
	day_of_week:  WORD,
	day:          WORD,
	hour:         WORD,
	minute:       WORD,
	second:       WORD,
	milliseconds: WORD,
}

TIME_ZONE_INFORMATION :: struct {
	Bias:         LONG,
	StandardName: [32]WCHAR,
	StandardDate: SYSTEMTIME,
	StandardBias: LONG,
	DaylightName: [32]WCHAR,
	DaylightDate: SYSTEMTIME,
	DaylightBias: LONG,
}


@(private="file")
IMAGE_DOS_HEADER :: struct {
	e_magic:    WORD,
	e_cblp:     WORD,
	e_cp:       WORD,
	e_crlc:     WORD,
	e_cparhdr:  WORD,
	e_minalloc: WORD,
	e_maxalloc: WORD,
	e_ss:       WORD,
	e_sp:       WORD,
	e_csum:     WORD,
	e_ip:       WORD,
	e_cs:       WORD,
	e_lfarlc:   WORD,
	e_ovno:     WORD,
	e_res_0:    WORD,
	e_res_1:    WORD,
	e_res_2:    WORD,
	e_res_3:    WORD,
	e_oemid:    WORD,
	e_oeminfo:  WORD,
	e_res2_0:   WORD,
	e_res2_1:   WORD,
	e_res2_2:   WORD,
	e_res2_3:   WORD,
	e_res2_4:   WORD,
	e_res2_5:   WORD,
	e_res2_6:   WORD,
	e_res2_7:   WORD,
	e_res2_8:   WORD,
	e_res2_9:   WORD,
	e_lfanew:   DWORD,
}

IMAGE_DATA_DIRECTORY :: struct {
	VirtualAddress: DWORD,
	Size:           DWORD,
}

IMAGE_FILE_HEADER :: struct {
	Machine:              WORD,
	NumberOfSections:     WORD,
	TimeDateStamp:        DWORD,
	PointerToSymbolTable: DWORD,
	NumberOfSymbols:      DWORD,
	SizeOfOptionalHeader: WORD,
	Characteristics:      WORD,
}

IMAGE_OPTIONAL_HEADER64 :: struct {
	Magic:                        WORD,
	MajorLinkerVersion:           BYTE,
	MinorLinkerVersion:           BYTE,
	SizeOfCode:                   DWORD,
	SizeOfInitializedData:        DWORD,
	SizeOfUninitializedData:      DWORD,
	AddressOfEntryPoint:          DWORD,
	BaseOfCode:                   DWORD,
	ImageBase:                    QWORD,
	SectionAlignment:             DWORD,
	FileAlignment:                DWORD,
	MajorOperatingSystemVersion:  WORD,
	MinorOperatingSystemVersion:  WORD,
	MajorImageVersion:            WORD,
	MinorImageVersion:            WORD,
	MajorSubsystemVersion:        WORD,
	MinorSubsystemVersion:        WORD,
	Win32VersionValue:            DWORD,
	SizeOfImage:                  DWORD,
	SizeOfHeaders:                DWORD,
	CheckSum:                     DWORD,
	Subsystem:                    WORD,
	DllCharacteristics:           WORD,
	SizeOfStackReserve:           QWORD,
	SizeOfStackCommit:            QWORD,
	SizeOfHeapReserve:            QWORD,
	SizeOfHeapCommit:             QWORD,
	LoaderFlags:                  DWORD,
	NumberOfRvaAndSizes:          DWORD,
	ExportTable:                  IMAGE_DATA_DIRECTORY,
	ImportTable:                  IMAGE_DATA_DIRECTORY,
	ResourceTable:                IMAGE_DATA_DIRECTORY,
	ExceptionTable:               IMAGE_DATA_DIRECTORY,
	CertificateTable:             IMAGE_DATA_DIRECTORY,
	BaseRelocationTable:          IMAGE_DATA_DIRECTORY,
	Debug:                        IMAGE_DATA_DIRECTORY,
	Architecture:                 IMAGE_DATA_DIRECTORY,
	GlobalPtr:                    IMAGE_DATA_DIRECTORY,
	TLSTable:                     IMAGE_DATA_DIRECTORY,
	LoadConfigTable:              IMAGE_DATA_DIRECTORY,
	BoundImport:                  IMAGE_DATA_DIRECTORY,
	IAT:                          IMAGE_DATA_DIRECTORY,
	DelayImportDescriptor:        IMAGE_DATA_DIRECTORY,
	CLRRuntimeHeader:             IMAGE_DATA_DIRECTORY,
	Reserved:                     IMAGE_DATA_DIRECTORY,
}

IMAGE_NT_HEADERS64 :: struct {
	Signature:      DWORD,
	FileHeader:     IMAGE_FILE_HEADER,
	OptionalHeader: IMAGE_OPTIONAL_HEADER64,
}

IMAGE_EXPORT_DIRECTORY :: struct {
	Characteristics:       DWORD,
	TimeDateStamp:         DWORD,
	MajorVersion:          WORD,
	MinorVersion:          WORD,
	Name:                  DWORD,
	Base:                  DWORD,
	NumberOfFunctions:     DWORD,
	NumberOfNames:         DWORD,
	AddressOfFunctions:    DWORD, // RVA from base of image
	AddressOfNames:        DWORD, // RVA from base of image
	AddressOfNameOrdinals: DWORD, // RVA from base of image
}

SICHINTF :: DWORD
SHCONTF :: DWORD
SFGAOF :: ULONG
FILEOPENDIALOGOPTIONS :: DWORD
REFPROPERTYKEY :: ^PROPERTYKEY
REFPROPVARIANT :: ^PROPVARIANT

SIGDN :: enum c_int {
	NORMALDISPLAY               = 0,
	PARENTRELATIVEPARSING       = -2147385343, // 0x80018001
	DESKTOPABSOLUTEPARSING      = -2147319808, // 0x80028000
	PARENTRELATIVEEDITING       = -2147282943, // 0x80031001
	DESKTOPABSOLUTEEDITING      = -2147172352, // 0x8004c000
	FILESYSPATH                 = -2147123200, // 0x80058000
	URL                         = -2147057664, // 0x80068000
	PARENTRELATIVEFORADDRESSBAR = -2146975743, // 0x8007c001
	PARENTRELATIVE              = -2146959359, // 0x80080001
	PARENTRELATIVEFORUI         = -2146877439, // 0x80094001
}

SIATTRIBFLAGS :: enum c_int {
  AND	= 0x1,
  OR	= 0x2,
  APPCOMPAT	= 0x3,
  MASK	= 0x3,
  ALLITEMS	= 0x4000,
}

FDAP :: enum c_int {
	BOTTOM = 0,
	TOP = 1,
}

FDE_SHAREVIOLATION_RESPONSE :: enum c_int {
	DEFAULT = 0,
	ACCEPT = 1,
	REFUSE = 2,
}

GETPROPERTYSTOREFLAGS :: enum c_int {
	DEFAULT	= 0,
	HANDLERPROPERTIESONLY	= 0x1,
	READWRITE	= 0x2,
	TEMPORARY	= 0x4,
	FASTPROPERTIESONLY	= 0x8,
	OPENSLOWITEM	= 0x10,
	DELAYCREATION	= 0x20,
	BESTEFFORT	= 0x40,
	NO_OPLOCK	= 0x80,
	PREFERQUERYPROPERTIES	= 0x100,
	EXTRINSICPROPERTIES	= 0x200,
	EXTRINSICPROPERTIESONLY	= 0x400,
	VOLATILEPROPERTIES	= 0x800,
	VOLATILEPROPERTIESONLY	= 0x1000,
	MASK_VALID	= 0x1fff,
}

PROPERTYKEY :: struct {
	fmtid: GUID,
	pid: DWORD,
}

BIND_OPTS :: struct {
	cbStruct: DWORD,
	grfFlags: DWORD,
	grfMode: DWORD,
	dwTickCountDeadline: DWORD,
}

STATSTG :: struct {
	pwcsName: LPOLESTR,
	type: DWORD,
	cbSize: ULARGE_INTEGER,
	mtime: FILETIME,
	ctime: FILETIME,
	atime: FILETIME,
	grfMode: DWORD,
	grfLocksSupported: DWORD,
	clsid: CLSID,
	grfStateBits: DWORD,
	reserved: DWORD,
}

COMDLG_FILTERSPEC :: struct {
	pszName, pszSpec: LPCWSTR,
}

DECIMAL :: struct {
	wReserved: USHORT,
	_: struct #raw_union {
		_: struct {
			scale, sign: BYTE,
		},
		signscale: USHORT,
	},
	Hi32: ULONG,
	_: struct #raw_union {
		_: struct {
			Lo32, Mid32: ULONG,
		},
		Lo64: ULONGLONG,
	},
}

// NOTE(ftphikari): bigger definition of this struct is ignored
PROPVARIANT :: struct {
	decVal: DECIMAL,
}

SICHINT_DISPLAY                       :: 0
SICHINT_ALLFIELDS                     :: -2147483648 // 0x80000000
SICHINT_CANONICAL                     :: 0x10000000
SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL :: 0x20000000

FOS_OVERWRITEPROMPT          :: 0x2
FOS_STRICTFILETYPES          :: 0x4
FOS_NOCHANGEDIR              :: 0x8
FOS_PICKFOLDERS              :: 0x20
FOS_FORCEFILESYSTEM          :: 0x40
FOS_ALLNONSTORAGEITEMS       :: 0x80
FOS_NOVALIDATE               :: 0x100
FOS_ALLOWMULTISELECT         :: 0x200
FOS_PATHMUSTEXIST            :: 0x800
FOS_FILEMUSTEXIST            :: 0x1000
FOS_CREATEPROMPT             :: 0x2000
FOS_SHAREAWARE               :: 0x4000
FOS_NOREADONLYRETURN         :: 0x8000
FOS_NOTESTFILECREATE         :: 0x10000
FOS_HIDEMRUPLACES            :: 0x20000
FOS_HIDEPINNEDPLACES         :: 0x40000
FOS_NODEREFERENCELINKS       :: 0x100000
FOS_OKBUTTONNEEDSINTERACTION :: 0x200000
FOS_DONTADDTORECENT          :: 0x2000000
FOS_FORCESHOWHIDDEN          :: 0x10000000
FOS_DEFAULTNOMINIMODE        :: 0x20000000
FOS_FORCEPREVIEWPANEON       :: 0x40000000
FOS_SUPPORTSTREAMABLEITEMS   :: 0x80000000

SHCONTF_CHECKING_FOR_CHILDREN :: 0x10
SHCONTF_FOLDERS               :: 0x20
SHCONTF_NONFOLDERS            :: 0x40
SHCONTF_INCLUDEHIDDEN         :: 0x80
SHCONTF_INIT_ON_FIRST_NEXT    :: 0x100
SHCONTF_NETPRINTERSRCH        :: 0x200
SHCONTF_SHAREABLE             :: 0x400
SHCONTF_STORAGE               :: 0x800
SHCONTF_NAVIGATION_ENUM       :: 0x1000
SHCONTF_FASTITEMS             :: 0x2000
SHCONTF_FLATLIST              :: 0x4000
SHCONTF_ENABLE_ASYNC          :: 0x8000
SHCONTF_INCLUDESUPERHIDDEN    :: 0x10000

SHACF_DEFAULT               :: 0x00000000  // Currently (SHACF_FILESYSTEM | SHACF_URLALL)
SHACF_FILESYSTEM            :: 0x00000001  // This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
SHACF_URLALL                :: (SHACF_URLHISTORY | SHACF_URLMRU)
SHACF_URLHISTORY            :: 0x00000002  // URLs in the User's History
SHACF_URLMRU                :: 0x00000004  // URLs in the User's Recently Used list.
SHACF_USETAB                :: 0x00000008  // Use the tab to move thru the autocomplete possibilities instead of to the next dialog/window control.
SHACF_FILESYS_ONLY          :: 0x00000010  // This includes the File System
SHACF_FILESYS_DIRS          :: 0x00000020  // Same as SHACF_FILESYS_ONLY except it only includes directories, UNC servers, and UNC server shares.
SHACF_VIRTUAL_NAMESPACE     :: 0x00000040  // Also include the virtual namespace
SHACF_AUTOSUGGEST_FORCE_ON  :: 0x10000000  // Ignore the registry default and force the feature on.
SHACF_AUTOSUGGEST_FORCE_OFF :: 0x20000000  // Ignore the registry default and force the feature off.
SHACF_AUTOAPPEND_FORCE_ON   :: 0x40000000  // Ignore the registry default and force the feature on. (Also know as AutoComplete)
SHACF_AUTOAPPEND_FORCE_OFF  :: 0x80000000  // Ignore the registry default and force the feature off. (Also know as AutoComplete)

LWSTDAPI :: HRESULT

CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}}
CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}}
CLSID_TaskbarList := &GUID{0x56FDF344, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}

IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}}
IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}}
IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}}
IID_ITaskbarList := &GUID{0x56FDF342, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}
IID_ITaskbarList2 := &GUID{0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}}
IID_ITaskbarList3 := &GUID{0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf}}

IModalWindow :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IModalWindowVtbl,
}
IModalWindowVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Show: proc "system" (this: ^IModalWindow, hwndOwner: HWND) -> HRESULT,
}

ISequentialStream :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^ISequentialStreamVtbl,
}
ISequentialStreamVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Read:  proc "system" (this: ^ISequentialStream, pv: rawptr, cb: ULONG, pcbRead: ^ULONG) -> HRESULT,
	Write: proc "system" (this: ^ISequentialStream, pv: rawptr, cb: ULONG, pcbWritten: ^ULONG) -> HRESULT,
}

IStream :: struct #raw_union {
	#subtype ISequentialStream: ISequentialStream,
	using Vtbl: ^IStreamVtbl,
}
IStreamVtbl :: struct {
	using ISequentialStreamVtbl: ISequentialStreamVtbl,
	Seek:         proc "system" (this: ^IStream, dlibMove: LARGE_INTEGER, dwOrigin: DWORD, plibNewPosition: ^ULARGE_INTEGER) -> HRESULT,
	SetSize:      proc "system" (this: ^IStream, libNewSize: ULARGE_INTEGER) -> HRESULT,
	CopyTo:       proc "system" (this: ^IStream, pstm: ^IStream, cb: ULARGE_INTEGER, pcbRead: ^ULARGE_INTEGER, pcbWritten: ^ULARGE_INTEGER) -> HRESULT,
	Commit:       proc "system" (this: ^IStream, grfCommitFlags: DWORD) -> HRESULT,
	Revert:       proc "system" (this: ^IStream) -> HRESULT,
	LockRegion:   proc "system" (this: ^IStream, libOffset: ULARGE_INTEGER, cb: ULARGE_INTEGER, dwLockType: DWORD) -> HRESULT,
	UnlockRegion: proc "system" (this: ^IStream, libOffset: ULARGE_INTEGER, cb: ULARGE_INTEGER, dwLockType: DWORD) -> HRESULT,
	Stat:         proc "system" (this: ^IStream, pstatstg: ^STATSTG, grfStatFlag: DWORD) -> HRESULT,
	Clone:        proc "system" (this: ^IStream, ppstm: ^^IStream) -> HRESULT,
}

IPersist :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IPersistVtbl,
}
IPersistVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	GetClassID: proc "system" (this: ^IPersist, pClassID: ^CLSID) -> HRESULT,
}

IPersistStream :: struct #raw_union {
	#subtype IPersist: IPersist,
	using Vtbl: ^IPersistStreamVtbl,
}
IPersistStreamVtbl :: struct {
	using IPersistVtbl: IPersistVtbl,
	IsDirty:    proc "system" (this: ^IPersistStream) -> HRESULT,
	Load:       proc "system" (this: ^IPersistStream, pStm: ^IStream) -> HRESULT,
	Save:       proc "system" (this: ^IPersistStream, pStm: ^IStream, fClearDirty: BOOL) -> HRESULT,
	GetSizeMax: proc "system" (this: ^IPersistStream, pcbSize: ^ULARGE_INTEGER) -> HRESULT,
}

IMoniker :: struct #raw_union {
	#subtype IPersistStream: IPersistStream,
	using Vtbl: ^IMonikerVtbl,
}
IMonikerVtbl :: struct {
	using IPersistStreamVtbl: IPersistStreamVtbl,
	BindToObject:        proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, riidResult: REFIID, ppvResult: ^rawptr) -> HRESULT,
	BindToStorage:       proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, riid: REFIID, ppvObj: ^rawptr) -> HRESULT,
	Reduce:              proc "system" (this: ^IMoniker, pbc: ^IBindCtx, dwReduceHowFar: DWORD, ppmkToLeft: ^^IMoniker, ppmkReduced: ^^IMoniker) -> HRESULT,
	ComposeWith:         proc "system" (this: ^IMoniker, pmkRight: ^IMoniker, fOnlyIfNotGeneric: BOOL, ppmkComposite: ^^IMoniker) -> HRESULT,
	Enum:                proc "system" (this: ^IMoniker, fForward: BOOL, ppenumMoniker: ^^IEnumMoniker) -> HRESULT,
	IsEqual:             proc "system" (this: ^IMoniker, pmkOtherMoniker: ^IMoniker) -> HRESULT,
	Hash:                proc "system" (this: ^IMoniker, pdwHash: ^DWORD) -> HRESULT,
	IsRunning:           proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, pmkNewlyRunning: ^IMoniker) -> HRESULT,
	GetTimeOfLastChange: proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, pFileTime: ^FILETIME) -> HRESULT,
	Inverse:             proc "system" (this: ^IMoniker, ppmk: ^^IMoniker) -> HRESULT,
	CommonPrefixWith:    proc "system" (this: ^IMoniker, pmkOther: ^IMoniker, ppmkPrefix: ^^IMoniker) -> HRESULT,
	RelativePathTo:      proc "system" (this: ^IMoniker, pmkOther: ^IMoniker, ppmkRelPath: ^^IMoniker) -> HRESULT,
	GetDisplayName:      proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, ppszDisplayName: ^LPOLESTR) -> HRESULT,
	ParseDisplayName:    proc "system" (this: ^IMoniker, pbc: ^IBindCtx, pmkToLeft: ^IMoniker, pszDisplayName: LPOLESTR, pchEaten: ^ULONG, ppmkOut: ^^IMoniker) -> HRESULT,
	IsSystemMoniker:     proc "system" (this: ^IMoniker, pdwMksys: ^DWORD) -> HRESULT,
}

IEnumMoniker :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IEnumMonikerVtbl,
}
IEnumMonikerVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Next:  proc "system" (this: ^IEnumMoniker, celt: ULONG, rgelt: ^^IMoniker, pceltFetched: ^ULONG) -> HRESULT,
	Skip:  proc "system" (this: ^IEnumMoniker, celt: ULONG) -> HRESULT,
	Reset: proc "system" (this: ^IEnumMoniker) -> HRESULT,
	Clone: proc "system" (this: ^IEnumMoniker, ppenum: ^^IEnumMoniker) -> HRESULT,
}

IRunningObjectTable :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IRunningObjectTableVtbl,
}
IRunningObjectTableVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Register:            proc "system" (this: ^IRunningObjectTable, grfFlags: DWORD, punkObject: ^IUnknown, pmkObjectName: ^IMoniker, pdwRegister: ^DWORD) -> HRESULT,
	Revoke:              proc "system" (this: ^IRunningObjectTable, dwRegister: DWORD) -> HRESULT,
	IsRunning:           proc "system" (this: ^IRunningObjectTable, pmkObjectName: ^IMoniker) -> HRESULT,
	GetObject:           proc "system" (this: ^IRunningObjectTable, pmkObjectName: ^IMoniker, ppunkObject: ^^IUnknown) -> HRESULT,
	NoteChangeTime:      proc "system" (this: ^IRunningObjectTable, dwRegister: DWORD, pfiletime: ^FILETIME) -> HRESULT,
	GetTimeOfLastChange: proc "system" (this: ^IRunningObjectTable, pmkObjectName: ^IMoniker, pfiletime: ^FILETIME) -> HRESULT,
	EnumRunning:         proc "system" (this: ^IRunningObjectTable, ppenumMoniker: ^^IEnumMoniker) -> HRESULT,
}

IEnumString :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IEnumStringVtbl,
}
IEnumStringVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Next:  proc "system" (this: ^IEnumString, celt: ULONG, rgelt: ^LPOLESTR, pceltFetched: ^ULONG) -> HRESULT,
	Skip:  proc "system" (this: ^IEnumString, celt: ULONG) -> HRESULT,
	Reset: proc "system" (this: ^IEnumString) -> HRESULT,
	Clone: proc "system" (this: ^IEnumString, ppenum: ^^IEnumString) -> HRESULT,
}

IBindCtx :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IBindCtxVtbl,
}
IBindCtxVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	RegisterObjectBound:   proc "system" (this: ^IBindCtx, punk: ^IUnknown) -> HRESULT,
	RevokeObjectBound:     proc "system" (this: ^IBindCtx, punk: ^IUnknown) -> HRESULT,
	ReleaseBoundObjects:   proc "system" (this: ^IBindCtx) -> HRESULT,
	SetBindOptions:        proc "system" (this: ^IBindCtx, pbindopts: ^BIND_OPTS) -> HRESULT,
	GetBindOptions:        proc "system" (this: ^IBindCtx, pbindopts: ^BIND_OPTS) -> HRESULT,
	GetRunningObjectTable: proc "system" (this: ^IBindCtx, pprot: ^^IRunningObjectTable) -> HRESULT,
	RegisterObjectParam:   proc "system" (this: ^IBindCtx, pszKey: LPOLESTR, punk: ^IUnknown) -> HRESULT,
	GetObjectParam:        proc "system" (this: ^IBindCtx, pszKey: LPOLESTR, ppunk: ^^IUnknown) -> HRESULT,
	EnumObjectParam:       proc "system" (this: ^IBindCtx, ppenum: ^^IEnumString) -> HRESULT,
	RevokeObjectParam:     proc "system" (this: ^IBindCtx, pszKey: LPOLESTR) -> HRESULT,
}

IEnumShellItems :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IEnumShellItemsVtbl,
}
IEnumShellItemsVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	Next:  proc "system" (this: ^IEnumShellItems, celt: ULONG, rgelt: ^^IShellItem, pceltFetched: ^ULONG) -> HRESULT,
	Skip:  proc "system" (this: ^IEnumShellItems, celt: ULONG) -> HRESULT,
	Reset: proc "system" (this: ^IEnumShellItems) -> HRESULT,
	Clone: proc "system" (this: ^IEnumShellItems, ppenum: ^^IEnumShellItems) -> HRESULT,
}

IShellItem :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IShellItemVtbl,
}
IShellItemVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	BindToHandler:  proc "system" (this: ^IShellItem, pbc: ^IBindCtx, bhid: REFGUID, riid: REFIID, ppv: ^rawptr) -> HRESULT,
	GetParent:      proc "system" (this: ^IShellItem, ppsiFolder: ^^IShellItem) -> HRESULT,
	GetDisplayName: proc "system" (this: ^IShellItem, sigdnName: SIGDN, ppszName: ^LPWSTR) -> HRESULT,
	GetAttributes:  proc "system" (this: ^IShellItem, sfgaoMask: SFGAOF, psfgaoAttribs: ^SFGAOF) -> HRESULT,
	Compare:        proc "system" (this: ^IShellItem, psi: ^IShellItem, hint: SICHINTF, piOrder: ^c_int) -> HRESULT,
}

IShellItemArray :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IShellItemArrayVtbl,
}
IShellItemArrayVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	BindToHandler:              proc "system" (this: ^IShellItemArray, pbc: ^IBindCtx, bhid: REFGUID, riid: REFIID, ppvOut: ^rawptr) -> HRESULT,
	GetPropertyStore:           proc "system" (this: ^IShellItemArray, flags: GETPROPERTYSTOREFLAGS, riid: REFIID, ppv: ^rawptr) -> HRESULT,
	GetPropertyDescriptionList: proc "system" (this: ^IShellItemArray, keyType: REFPROPERTYKEY, riid: REFIID, ppv: ^rawptr) -> HRESULT,
	GetAttributes:              proc "system" (this: ^IShellItemArray, AttribFlags: SIATTRIBFLAGS, sfgaoMask: SFGAOF, psfgaoAttribs: ^SFGAOF) -> HRESULT,
	GetCount:                   proc "system" (this: ^IShellItemArray, pdwNumItems: ^DWORD) -> HRESULT,
	GetItemAt:                  proc "system" (this: ^IShellItemArray, dwIndex: DWORD, ppsi: ^^IShellItem) -> HRESULT,
	EnumItems:                  proc "system" (this: ^IShellItemArray, ppenumShellItems: ^^IEnumShellItems) -> HRESULT,
}

IFileDialogEvents :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IFileDialogEventsVtbl,
}
IFileDialogEventsVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	OnFileOk:          proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog) -> HRESULT,
	OnFolderChanging:  proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog, psiFolder: ^IShellItem) -> HRESULT,
	OnFolderChange:    proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog) -> HRESULT,
	OnSelectionChange: proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog) -> HRESULT,
	OnShareViolation:  proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog, psi: ^IShellItem, pResponse: ^FDE_SHAREVIOLATION_RESPONSE) -> HRESULT,
	OnTypeChange:      proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog) -> HRESULT,
	OnOverwrite:       proc "system" (this: ^IFileDialogEvents, pfd: ^IFileDialog, psi: ^IShellItem, pResponse: ^FDE_SHAREVIOLATION_RESPONSE) -> HRESULT,
}

IShellItemFilter :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IShellItemFilterVtbl,
}
IShellItemFilterVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	IncludeItem:         proc "system" (this: ^IShellItemFilter, psi: ^IShellItem) -> HRESULT,
	GetEnumFlagsForItem: proc "system" (this: ^IShellItemFilter, psi: ^IShellItem, pgrfFlags: ^SHCONTF) -> HRESULT,
}

IFileDialog :: struct #raw_union {
	#subtype IModalWindow: IModalWindow,
	using Vtbl: ^IFileDialogVtbl,
}
IFileDialogVtbl :: struct {
	using IModalWindowVtbl: IModalWindowVtbl,
	SetFileTypes:        proc "system" (this: ^IFileDialog, cFileTypes: UINT, rgFilterSpec: ^COMDLG_FILTERSPEC) -> HRESULT,
	SetFileTypeIndex:    proc "system" (this: ^IFileDialog, iFileType: UINT) -> HRESULT,
	GetFileTypeIndex:    proc "system" (this: ^IFileDialog, piFileType: ^UINT) -> HRESULT,
	Advise:              proc "system" (this: ^IFileDialog, pfde: ^IFileDialogEvents, pdwCookie: ^DWORD) -> HRESULT,
	Unadvise:            proc "system" (this: ^IFileDialog, dwCookie: DWORD) -> HRESULT,
	SetOptions:          proc "system" (this: ^IFileDialog, fos: FILEOPENDIALOGOPTIONS) -> HRESULT,
	GetOptions:          proc "system" (this: ^IFileDialog, pfos: ^FILEOPENDIALOGOPTIONS) -> HRESULT,
	SetDefaultFolder:    proc "system" (this: ^IFileDialog, psi: ^IShellItem) -> HRESULT,
	SetFolder:           proc "system" (this: ^IFileDialog, psi: ^IShellItem) -> HRESULT,
	GetFolder:           proc "system" (this: ^IFileDialog, ppsi: ^^IShellItem) -> HRESULT,
	GetCurrentSelection: proc "system" (this: ^IFileDialog, ppsi: ^^IShellItem) -> HRESULT,
	SetFileName:         proc "system" (this: ^IFileDialog, pszName: LPCWSTR) -> HRESULT,
	GetFileName:         proc "system" (this: ^IFileDialog, pszName: ^LPCWSTR) -> HRESULT,
	SetTitle:            proc "system" (this: ^IFileDialog, pszTitle: LPCWSTR) -> HRESULT,
	SetOkButtonLabel:    proc "system" (this: ^IFileDialog, pszText: LPCWSTR) -> HRESULT,
	SetFileNameLabel:    proc "system" (this: ^IFileDialog, pszLabel: LPCWSTR) -> HRESULT,
	GetResult:           proc "system" (this: ^IFileDialog, ppsi: ^^IShellItem) -> HRESULT,
	AddPlace:            proc "system" (this: ^IFileDialog, psi: ^IShellItem, fdap: FDAP) -> HRESULT,
	SetDefaultExtension: proc "system" (this: ^IFileDialog, pszDefaultExtension: LPCWSTR) -> HRESULT,
	Close:               proc "system" (this: ^IFileDialog, hr: HRESULT) -> HRESULT,
	SetClientGuid:       proc "system" (this: ^IFileDialog, guid: REFGUID) -> HRESULT,
	ClearClientData:     proc "system" (this: ^IFileDialog) -> HRESULT,
	SetFilter:           proc "system" (this: ^IFileDialog, pFilter: ^IShellItemFilter) -> HRESULT,
}

IFileOpenDialog :: struct #raw_union {
	#subtype IFileDialog: IFileDialog,
	using Vtbl: ^IFileOpenDialogVtbl,
}
IFileOpenDialogVtbl :: struct {
	using IFileDialogVtbl: IFileDialogVtbl,
	GetResults:       proc "system" (this: ^IFileOpenDialog, ppenum: ^^IShellItemArray) -> HRESULT,
	GetSelectedItems: proc "system" (this: ^IFileOpenDialog, ppsai: ^^IShellItemArray) -> HRESULT,
}

IPropertyStore :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IPropertyStoreVtbl,
}
IPropertyStoreVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	GetCount: proc "system" (this: ^IPropertyStore, cProps: ^DWORD) -> HRESULT,
	GetAt:    proc "system" (this: ^IPropertyStore, iProp: DWORD, pkey: ^PROPERTYKEY) -> HRESULT,
	GetValue: proc "system" (this: ^IPropertyStore, key: REFPROPERTYKEY, pv: ^PROPVARIANT) -> HRESULT,
	SetValue: proc "system" (this: ^IPropertyStore, key: REFPROPERTYKEY, propvar: REFPROPVARIANT) -> HRESULT,
	Commit:   proc "system" (this: ^IPropertyStore) -> HRESULT,
}

IPropertyDescriptionList :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IPropertyDescriptionListVtbl,
}
IPropertyDescriptionListVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	GetCount: proc "system" (this: ^IPropertyDescriptionList, pcElem: ^UINT) -> HRESULT,
	GetAt:    proc "system" (this: ^IPropertyDescriptionList, iElem: UINT, riid: REFIID, ppv: ^rawptr) -> HRESULT,
}

IFileOperationProgressSink :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^IFileOperationProgressSinkVtbl,
}
IFileOperationProgressSinkVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	StartOperations:  proc "system" (this: ^IFileOperationProgressSink) -> HRESULT,
	FinishOperations: proc "system" (this: ^IFileOperationProgressSink, hrResult: HRESULT) -> HRESULT,
	PreRenameItem:    proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, pszNewName: LPCWSTR) -> HRESULT,
	PostRenameItem:   proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, pszNewName: LPCWSTR, hrRename: HRESULT, psiNewlyCreated: ^IShellItem) -> HRESULT,
	PreMoveItem:      proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR) -> HRESULT,
	PostMoveItem:     proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR, hrMove: HRESULT, psiNewlyCreated: ^IShellItem) -> HRESULT,
	PreCopyItem:      proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR) -> HRESULT,
	PostCopyItem:     proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR, hrMove: HRESULT, psiNewlyCreated: ^IShellItem) -> HRESULT,
	PreDeleteItem:    proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem) -> HRESULT,
	PostDeleteItem:   proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiItem: ^IShellItem, hrDelete: HRESULT, psiNewlyCreated: ^IShellItem) -> HRESULT,
	PreNewItem:       proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR) -> HRESULT,
	PostNewItem:      proc "system" (this: ^IFileOperationProgressSink, dwFlags: DWORD, psiDestinationFolder: ^IShellItem, pszNewName: LPCWSTR, pszTemplateName: LPCWSTR, dwFileAttributes: DWORD, hrNew: HRESULT, psiNewItem: ^IShellItem) -> HRESULT,
	UpdateProgress:   proc "system" (this: ^IFileOperationProgressSink, iWorkTotal: UINT, iWorkSoFar: UINT) -> HRESULT,
	ResetTimer:       proc "system" (this: ^IFileOperationProgressSink) -> HRESULT,
	PauseTimer:       proc "system" (this: ^IFileOperationProgressSink) -> HRESULT,
	ResumeTimer:      proc "system" (this: ^IFileOperationProgressSink) -> HRESULT,
}

IFileSaveDialog :: struct #raw_union {
	#subtype IFileDialog: IFileDialog,
	using Vtbl: ^IFileSaveDialogVtbl,
}
IFileSaveDialogVtbl :: struct {
	using IFileDialogVtbl: IFileDialogVtbl,
	SetSaveAsItem:          proc "system" (this: ^IFileSaveDialog, psi: ^IShellItem) -> HRESULT,
	SetProperties:          proc "system" (this: ^IFileSaveDialog, pStore: ^IPropertyStore) -> HRESULT,
	SetCollectedProperties: proc "system" (this: ^IFileSaveDialog, pList: ^IPropertyDescriptionList, fAppendDefault: BOOL) -> HRESULT,
	GetProperties:          proc "system" (this: ^IFileSaveDialog, ppStore: ^^IPropertyStore) -> HRESULT,
	ApplyProperties:        proc "system" (this: ^IFileSaveDialog, psi: ^IShellItem, pStore: ^IPropertyStore, hwnd: HWND, pSink: ^IFileOperationProgressSink) -> HRESULT,
}

ITaskbarList :: struct #raw_union {
	#subtype IUnknown: IUnknown,
	using Vtbl: ^ITaskbarListVtbl,
}
ITaskbarListVtbl :: struct {
	using IUnknownVtbl: IUnknownVtbl,
	HrInit: proc "system" (this: ^ITaskbarList) -> HRESULT,
	AddTab: proc "system" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
	DeleteTab: proc "system" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
	ActivateTab: proc "system" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
	SetActiveAlt: proc "system" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
}

ITaskbarList2 :: struct #raw_union {
	#subtype ITaskbarList: ITaskbarList,
	using Vtbl: ^ITaskbarList2Vtbl,
}
ITaskbarList2Vtbl :: struct {
	using ITaskbarListVtbl: ITaskbarListVtbl,
	MarkFullscreenWindow: proc "system" (this: ^ITaskbarList2, hwnd: HWND, fFullscreen: BOOL) -> HRESULT,
}

TBPFLAG :: enum c_int {
	NOPROGRESS    = 0,
	INDETERMINATE = 0x1,
	NORMAL        = 0x2,
	ERROR         = 0x4,
	PAUSED        = 0x8,
}

THUMBBUTTONFLAGS :: enum c_int {
	ENABLED        = 0,
	DISABLED       = 0x1,
	DISMISSONCLICK = 0x2,
	NOBACKGROUND   = 0x4,
	HIDDEN         = 0x8,
	NONINTERACTIVE = 0x10,
}

THUMBBUTTONMASK :: enum c_int {
	BITMAP  = 0x1,
	ICON    = 0x2,
	TOOLTIP = 0x4,
	FLAGS   = 0x8,
}

THUMBBUTTON :: struct {
	dwMask: THUMBBUTTONMASK,
	iId: UINT,
	iBitmap: UINT,
	hIcon: HICON,
	szTip: [260]WCHAR,
	dwFlags: THUMBBUTTONFLAGS,
}
LPTHUMBBUTTON :: ^THUMBBUTTON

HIMAGELIST :: ^IUnknown

ITaskbarList3 :: struct #raw_union {
	#subtype ITaskbarList2: ITaskbarList2,
	using Vtbl: ^ITaskbarList3Vtbl,
}
ITaskbarList3Vtbl :: struct {
	using ITaskbarList2Vtbl: ITaskbarList2Vtbl,
	SetProgressValue: proc "system" (this: ^ITaskbarList3, hwnd: HWND, ullCompleted: ULONGLONG, ullTotal: ULONGLONG) -> HRESULT,
	SetProgressState: proc "system" (this: ^ITaskbarList3, hwnd: HWND, tbpFlags: TBPFLAG) -> HRESULT,
	RegisterTab: proc "system" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND) -> HRESULT,
	UnregisterTab: proc "system" (this: ^ITaskbarList3, hwndTab: HWND) -> HRESULT,
	SetTabOrder: proc "system" (this: ^ITaskbarList3, hwndTab: HWND, hwndInsertBefore: HWND) -> HRESULT,
	SetTabActive: proc "system" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND, dwReserved: DWORD) -> HRESULT,
	ThumbBarAddButtons: proc "system" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
	ThumbBarUpdateButtons: proc "system" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
	ThumbBarSetImageList: proc "system" (this: ^ITaskbarList3, hwnd: HWND, himl: HIMAGELIST) -> HRESULT,
	SetOverlayIcon: proc "system" (this: ^ITaskbarList3, hwnd: HWND, hIcon: HICON, pszDescription: LPCWSTR) -> HRESULT,
	SetThumbnailTooltip: proc "system" (this: ^ITaskbarList3, hwnd: HWND, pszTip: LPCWSTR) -> HRESULT,
	SetThumbnailClip: proc "system" (this: ^ITaskbarList3, hwnd: HWND, prcClip: ^RECT) -> HRESULT,
}

MEMORYSTATUSEX :: struct {
	dwLength:                DWORD,
	dwMemoryLoad:            DWORD,
	ullTotalPhys:            DWORDLONG,
	ullAvailPhys:            DWORDLONG,
	ullTotalPageFil:         DWORDLONG,
	ullAvailPageFil:         DWORDLONG,
	ullTotalVirtual:         DWORDLONG,
	ullAvailVirtual:         DWORDLONG,
	ullAvailExtendedVirtual: DWORDLONG,
}

Windows_Product_Type :: enum DWORD {
	BUSINESS                            = 0x00000006, // Business
	BUSINESS_N                          = 0x00000010, // Business N
	CLUSTER_SERVER                      = 0x00000012, // HPC Edition
	CLUSTER_SERVER_V                    = 0x00000040, // Server Hyper Core V
	CORE                                = 0x00000065, // Windows 10 Home
	CORE_COUNTRYSPECIFIC                = 0x00000063, // Windows 10 Home China
	CORE_N                              = 0x00000062, // Windows 10 Home N
	CORE_SINGLELANGUAGE                 = 0x00000064, // Windows 10 Home Single Language
	DATACENTER_EVALUATION_SERVER        = 0x00000050, // Server Datacenter (evaluation installation)
	DATACENTER_A_SERVER_CORE            = 0x00000091, // Server Datacenter, Semi-Annual Channel (core installation)
	STANDARD_A_SERVER_CORE              = 0x00000092, // Server Standard, Semi-Annual Channel (core installation)
	DATACENTER_SERVER                   = 0x00000008, // Server Datacenter (full installation. For Server Core installations of Windows Server 2012 and later, use the method, Determining whether Server Core is running.)
	DATACENTER_SERVER_CORE              = 0x0000000C, // Server Datacenter (core installation, Windows Server 2008 R2 and earlier)
	DATACENTER_SERVER_CORE_V            = 0x00000027, // Server Datacenter without Hyper-V (core installation)
	DATACENTER_SERVER_V                 = 0x00000025, // Server Datacenter without Hyper-V (full installation)
	EDUCATION                           = 0x00000079, // Windows 10 Education
	EDUCATION_N                         = 0x0000007A, // Windows 10 Education N
	ENTERPRISE                          = 0x00000004, // Windows 10 Enterprise
	ENTERPRISE_E                        = 0x00000046, // Windows 10 Enterprise E
	ENTERPRISE_EVALUATION               = 0x00000048, // Windows 10 Enterprise Evaluation
	ENTERPRISE_N                        = 0x0000001B, // Windows 10 Enterprise N
	ENTERPRISE_N_EVALUATION             = 0x00000054, // Windows 10 Enterprise N Evaluation
	ENTERPRISE_S                        = 0x0000007D, // Windows 10 Enterprise 2015 LTSB
	ENTERPRISE_S_EVALUATION             = 0x00000081, // Windows 10 Enterprise 2015 LTSB Evaluation
	ENTERPRISE_S_N                      = 0x0000007E, // Windows 10 Enterprise 2015 LTSB N
	ENTERPRISE_S_N_EVALUATION           = 0x00000082, // Windows 10 Enterprise 2015 LTSB N Evaluation
	ENTERPRISE_SERVER                   = 0x0000000A, // Server Enterprise (full installation)
	ENTERPRISE_SERVER_CORE              = 0x0000000E, // Server Enterprise (core installation)
	ENTERPRISE_SERVER_CORE_V            = 0x00000029, // Server Enterprise without Hyper-V (core installation)
	ENTERPRISE_SERVER_IA64              = 0x0000000F, // Server Enterprise for Itanium-based Systems
	ENTERPRISE_SERVER_V                 = 0x00000026, // Server Enterprise without Hyper-V (full installation)
	ESSENTIALBUSINESS_SERVER_ADDL       = 0x0000003C, // Windows Essential Server Solution Additional
	ESSENTIALBUSINESS_SERVER_ADDLSVC    = 0x0000003E, // Windows Essential Server Solution Additional SVC
	ESSENTIALBUSINESS_SERVER_MGMT       = 0x0000003B, // Windows Essential Server Solution Management
	ESSENTIALBUSINESS_SERVER_MGMTSVC    = 0x0000003D, // Windows Essential Server Solution Management SVC
	HOME_BASIC                          = 0x00000002, // Home Basic
	HOME_BASIC_E                        = 0x00000043, // Not supported
	HOME_BASIC_N                        = 0x00000005, // Home Basic N
	HOME_PREMIUM                        = 0x00000003, // Home Premium
	HOME_PREMIUM_E                      = 0x00000044, // Not supported
	HOME_PREMIUM_N                      = 0x0000001A, // Home Premium N
	HOME_PREMIUM_SERVER                 = 0x00000022, // Windows Home Server 2011
	HOME_SERVER                         = 0x00000013, // Windows Storage Server 2008 R2 Essentials
	HYPERV                              = 0x0000002A, // Microsoft Hyper-V Server
	IOTENTERPRISE                       = 0x000000BC, // Windows IoT Enterprise
	IOTENTERPRISE_S                     = 0x000000BF, // Windows IoT Enterprise LTSC
	IOTUAP                              = 0x0000007B, // Windows 10 IoT Core
	IOTUAPCOMMERCIAL                    = 0x00000083, // Windows 10 IoT Core Commercial
	MEDIUMBUSINESS_SERVER_MANAGEMENT    = 0x0000001E, // Windows Essential Business Server Management Server
	MEDIUMBUSINESS_SERVER_MESSAGING     = 0x00000020, // Windows Essential Business Server Messaging Server
	MEDIUMBUSINESS_SERVER_SECURITY      = 0x0000001F, // Windows Essential Business Server Security Server
	MOBILE_CORE                         = 0x00000068, // Windows 10 Mobile
	MOBILE_ENTERPRISE                   = 0x00000085, // Windows 10 Mobile Enterprise
	MULTIPOINT_PREMIUM_SERVER           = 0x0000004D, // Windows MultiPoint Server Premium (full installation)
	MULTIPOINT_STANDARD_SERVER          = 0x0000004C, // Windows MultiPoint Server Standard (full installation)
	PRO_WORKSTATION                     = 0x000000A1, // Windows 10 Pro for Workstations
	PRO_WORKSTATION_N                   = 0x000000A2, // Windows 10 Pro for Workstations N
	PROFESSIONAL                        = 0x00000030, // Windows 10 Pro
	PROFESSIONAL_E                      = 0x00000045, // Not supported
	PROFESSIONAL_N                      = 0x00000031, // Windows 10 Pro N
	PROFESSIONAL_WMC                    = 0x00000067, // Professional with Media Center
	SB_SOLUTION_SERVER                  = 0x00000032, // Windows Small Business Server 2011 Essentials
	SB_SOLUTION_SERVER_EM               = 0x00000036, // Server For SB Solutions EM
	SERVER_FOR_SB_SOLUTIONS             = 0x00000033, // Server For SB Solutions
	SERVER_FOR_SB_SOLUTIONS_EM          = 0x00000037, // Server For SB Solutions EM
	SERVER_FOR_SMALLBUSINESS            = 0x00000018, // Windows Server 2008 for Windows Essential Server Solutions
	SERVER_FOR_SMALLBUSINESS_V          = 0x00000023, // Windows Server 2008 without Hyper-V for Windows Essential Server Solutions
	SERVER_FOUNDATION                   = 0x00000021, // Server Foundation
	SMALLBUSINESS_SERVER                = 0x00000009, // Windows Small Business Server
	SMALLBUSINESS_SERVER_PREMIUM        = 0x00000019, // Small Business Server Premium
	SMALLBUSINESS_SERVER_PREMIUM_CORE   = 0x0000003F, // Small Business Server Premium (core installation)
	SOLUTION_EMBEDDEDSERVER             = 0x00000038, // Windows MultiPoint Server
	STANDARD_EVALUATION_SERVER          = 0x0000004F, // Server Standard (evaluation installation)
	STANDARD_SERVER                     = 0x00000007, // Server Standard (full installation. For Server Core installations of Windows Server 2012 and later, use the method, Determining whether Server Core is running.)
	STANDARD_SERVER_CORE                = 0x0000000D, // Server Standard (core installation, Windows Server 2008 R2 and earlier)
	STANDARD_SERVER_CORE_V              = 0x00000028, // Server Standard without Hyper-V (core installation)
	STANDARD_SERVER_V                   = 0x00000024, // Server Standard without Hyper-V
	STANDARD_SERVER_SOLUTIONS           = 0x00000034, // Server Solutions Premium
	STANDARD_SERVER_SOLUTIONS_CORE      = 0x00000035, // Server Solutions Premium (core installation)
	STARTER                             = 0x0000000B, // Starter
	STARTER_E                           = 0x00000042, // Not supported
	STARTER_N                           = 0x0000002F, // Starter N
	STORAGE_ENTERPRISE_SERVER           = 0x00000017, // Storage Server Enterprise
	STORAGE_ENTERPRISE_SERVER_CORE      = 0x0000002E, // Storage Server Enterprise (core installation)
	STORAGE_EXPRESS_SERVER              = 0x00000014, // Storage Server Express
	STORAGE_EXPRESS_SERVER_CORE         = 0x0000002B, // Storage Server Express (core installation)
	STORAGE_STANDARD_EVALUATION_SERVER  = 0x00000060, // Storage Server Standard (evaluation installation)
	STORAGE_STANDARD_SERVER             = 0x00000015, // Storage Server Standard
	STORAGE_STANDARD_SERVER_CORE        = 0x0000002C, // Storage Server Standard (core installation)
	STORAGE_WORKGROUP_EVALUATION_SERVER = 0x0000005F, // Storage Server Workgroup (evaluation installation)
	STORAGE_WORKGROUP_SERVER            = 0x00000016, // Storage Server Workgroup
	STORAGE_WORKGROUP_SERVER_CORE       = 0x0000002D, // Storage Server Workgroup (core installation)
	ULTIMATE                            = 0x00000001, // Ultimate
	ULTIMATE_E                          = 0x00000047, // Not supported
	ULTIMATE_N                          = 0x0000001C, // Ultimate N
	UNDEFINED                           = 0x00000000, // An unknown product
	WEB_SERVER                          = 0x00000011, // Web Server (full installation)
	WEB_SERVER_CORE                     = 0x0000001D, // Web Server (core installation)
}

ENABLE_ECHO_INPUT : DWORD : 0x0004
ENABLE_INSERT_MODE : DWORD : 0x0020
ENABLE_LINE_INPUT : DWORD : 0x0002
ENABLE_MOUSE_INPUT : DWORD : 0x0010
ENABLE_PROCESSED_INPUT : DWORD : 0x0001
ENABLE_QUICK_EDIT_MODE : DWORD : 0x0040
ENABLE_WINDOW_INPUT : DWORD : 0x0008
ENABLE_VIRTUAL_TERMINAL_INPUT : DWORD : 0x0200
ENABLE_PROCESSED_OUTPUT : DWORD : 0x0001
ENABLE_WRAP_AT_EOL_OUTPUT : DWORD : 0x0002
ENABLE_VIRTUAL_TERMINAL_PROCESSING : DWORD : 0x0004
DISABLE_NEWLINE_AUTO_RETURN : DWORD : 0x0008
ENABLE_LVB_GRID_WORLDWIDE : DWORD : 0x0010

CTRL_C_EVENT : DWORD : 0
CTRL_BREAK_EVENT : DWORD : 1
CTRL_CLOSE_EVENT : DWORD : 2
CTRL_LOGOFF_EVENT : DWORD : 5
CTRL_SHUTDOWN_EVENT : DWORD : 6

COORD :: struct {
	X: SHORT,
	Y: SHORT,
}

SMALL_RECT :: struct {
	Left: SHORT,
	Top: SHORT,
	Right: SHORT,
	Bottom: SHORT,
}

CONSOLE_SCREEN_BUFFER_INFO :: struct {
	dwSize: COORD,
	dwCursorPosition: COORD,
	wAttributes: WORD,
	srWindow: SMALL_RECT,
	dwMaximumWindowSize: COORD,
}

CONSOLE_CURSOR_INFO :: struct {
	dwSize: DWORD,
	bVisible: BOOL,
}


PCONSOLE_SCREEN_BUFFER_INFO :: ^CONSOLE_SCREEN_BUFFER_INFO
PCONSOLE_CURSOR_INFO :: ^CONSOLE_CURSOR_INFO

Event_Type :: enum WORD {
	KEY_EVENT = 0x0001,
	MOUSE_EVENT = 0x0002,
	WINDOW_BUFFER_SIZE_EVENT = 0x0004,
	MENU_EVENT = 0x0008,
	FOCUS_EVENT = 0x0010,
}

INPUT_RECORD :: struct {
	EventType: Event_Type,
	Event: struct #raw_union {
		KeyEvent: KEY_EVENT_RECORD,
		MouseEvent: MOUSE_EVENT_RECORD,
		WindowBufferSizeEvent: WINDOW_BUFFER_SIZE_RECORD,
		MenuEvent: MENU_EVENT_RECORD,
		FocusEvent: FOCUS_EVENT_RECORD,
	},
}

Control_Key_State_Bits :: enum {
	RIGHT_ALT_PRESSED,
	LEFT_ALT_PRESSED,
	RIGHT_CTRL_PRESSED,
	LEFT_CTRL_PRESSED,
	SHIFT_PRESSED,
	NUMLOCK_ON,
	SCROLLLOCK_ON,
	CAPSLOCK_ON,
	ENHANCED_KEY,
}
Control_Key_State :: bit_set[Control_Key_State_Bits; DWORD]

KEY_EVENT_RECORD :: struct {
	bKeyDown: BOOL,
	wRepeatCount: WORD,
	wVirtualKeyCode: WORD,
	wVirtualScanCode: WORD,
	uChar: struct #raw_union {
		UnicodeChar: WCHAR,
		AsciiChar: CHAR,
	},
	dwControlKeyState: Control_Key_State,
}

MOUSE_EVENT_RECORD :: struct {
	dwMousePosition: COORD,
	dwButtonState: DWORD,
	dwControlKeyState: DWORD,
	dwEventFlags: DWORD,
}

WINDOW_BUFFER_SIZE_RECORD :: struct {
	dwSize: COORD,
}

MENU_EVENT_RECORD :: struct {
	dwCommandId: UINT,
}

FOCUS_EVENT_RECORD :: struct {
	bSetFocus: BOOL,
}


//
// Networking
//
WSA_FLAG_OVERLAPPED             :: 1
WSA_FLAG_MULTIPOINT_C_ROOT      :: 2
WSA_FLAG_MULTIPOINT_C_LEAF      :: 4
WSA_FLAG_MULTIPOINT_D_ROOT      :: 8
WSA_FLAG_MULTIPOINT_D_LEAF      :: 16
WSA_FLAG_ACCESS_SYSTEM_SECURITY :: 32
WSA_FLAG_NO_HANDLE_INHERIT      :: 128
WSADESCRIPTION_LEN :: 256
WSASYS_STATUS_LEN  :: 128
WSAPROTOCOL_LEN    :: 255
INVALID_SOCKET :: ~SOCKET(0)
SOMAXCONN    :: 128 // The number of messages that can be queued in memory after being received; use 2-4 for Bluetooth.
                    // This is for the 'backlog' parameter to listen().
SOCKET_ERROR :: -1

// Networking errors
WSAEINTR               :: 10004 // Call interrupted. CancelBlockingCall was called. (This is different on Linux.)
WSAEACCES              :: 10013 // If you try to bind a Udp socket to the broadcast address without the socket option set.
WSAEFAULT              :: 10014 // A pointer that was passed to a WSA function is invalid, such as a buffer size is smaller than you said it was
WSAEINVAL              :: 10022 // Invalid argument supplied
WSAEMFILE              :: 10024 // SOCKET handles exhausted
WSAEWOULDBLOCK         :: 10035 // No data is ready yet
WSAENOTSOCK            :: 10038 // Not a socket.
WSAEINPROGRESS         :: 10036 // WS1.1 call is in progress or callback function is still being processed
WSAEALREADY            :: 10037 // Already connecting in parallel.
WSAEMSGSIZE            :: 10040 // Message was truncated because it exceeded max datagram size.
WSAEPROTOTYPE          :: 10041 // Wrong protocol for the provided socket
WSAENOPROTOOPT         :: 10042 // TODO
WSAEPROTONOSUPPORT     :: 10043 // Protocol not supported
WSAESOCKTNOSUPPORT     :: 10044 // Socket type not supported in the given address family
WSAEAFNOSUPPORT        :: 10047 // Address family not supported
WSAEOPNOTSUPP          :: 10045 // Attempt to accept on non-stream socket, etc.
WSAEADDRINUSE          :: 10048 // Endpoint being bound is in use by another socket.
WSAEADDRNOTAVAIL       :: 10049 // Not a valid local IP address on this computer.
WSAENETDOWN            :: 10050 // Network subsystem failure on the local machine.
WSAENETUNREACH         :: 10051 // The local machine is not connected to the network.
WSAENETRESET           :: 10052 // Keepalive failure detected, or TTL exceeded when receiving UDP packets.
WSAECONNABORTED        :: 10053 // Connection has been aborted by software in the host machine.
WSAECONNRESET          :: 10054 // The connection was reset while trying to accept, read or write.
WSAENOBUFS             :: 10055 // No buffer space is available. The outgoing queue may be full in which case you should probably try again after a pause.
WSAEISCONN             :: 10056 // The socket is already connected.
WSAENOTCONN            :: 10057 // The socket is not connected yet, or no address was supplied to sendto.
WSAESHUTDOWN           :: 10058 // The socket has been shutdown in the direction required.
WSAETIMEDOUT           :: 10060 // The timeout duration was reached before any data was received / before all data was sent.
WSAECONNREFUSED        :: 10061 // The remote machine is not listening on that endpoint.
WSAEHOSTDOWN           :: 10064 // Destination host was down.
WSAEHOSTUNREACH        :: 10065 // The remote machine is not connected to the network.
WSAENOTINITIALISED     :: 10093 // Needs WSAStartup call
WSAEINVALIDPROCTABLE   :: 10104 // Invalid or incomplete procedure table was returned
WSAEINVALIDPROVIDER    :: 10105 // Service provider version is not 2.2
WSAEPROVIDERFAILEDINIT :: 10106 // Service provider failed to initialize

// Address families
AF_UNSPEC : c_int : 0  // Unspecified
AF_INET   : c_int : 2  // IPv4
AF_INET6  : c_int : 23 // IPv6
AF_IRDA   : c_int : 26 // Infrared
AF_BTH    : c_int : 32 // Bluetooth

// Socket types
SOCK_STREAM    : c_int : 1 // TCP
SOCK_DGRAM     : c_int : 2 // UDP
SOCK_RAW       : c_int : 3 // Requires options IP_HDRINCL for v4, IPV6_HDRINCL for v6, on the socket
SOCK_RDM       : c_int : 4 // Requires "Reliable Multicast Protocol" to be installed - see WSAEnumProtocols
SOCK_SEQPACKET : c_int : 5 // Provides psuedo-stream packet based on DGRAMs.

// Protocols
IPPROTO_IP      : c_int : 0
IPPROTO_ICMP    : c_int : 1   // (AF_UNSPEC, AF_INET, AF_INET6) + SOCK_RAW | not specified
IPPROTO_IGMP    : c_int : 2   // (AF_UNSPEC, AF_INET, AF_INET6) + SOCK_RAW | not specified
BTHPROTO_RFCOMM : c_int : 3   // Bluetooth: AF_BTH + SOCK_STREAM
IPPROTO_TCP     : c_int : 6   // (AF_INET, AF_INET6) + SOCK_STREAM
IPPROTO_UDP     : c_int : 17  // (AF_INET, AF_INET6) + SOCK_DGRAM
IPPROTO_ICMPV6  : c_int : 58  // (AF_UNSPEC, AF_INET, AF_INET6) + SOCK_RAW
IPPROTO_RM      : c_int : 113 // AF_INET + SOCK_RDM [requires "Reliable Multicast Protocol" to be installed - see WSAEnumProtocols]

// Shutdown manners
SD_RECEIVE : c_int : 0
SD_SEND    : c_int : 1
SD_BOTH    : c_int : 2

// Socket 'levels'
SOL_SOCKET   : c_int : 0xffff // Socket options for any socket.
IPPROTO_IPV6 : c_int : 41     // Socket options for IPV6.

// Options for any sockets
SO_ACCEPTCONN         : c_int : 0x0002
SO_REUSEADDR          : c_int : 0x0004
SO_KEEPALIVE          : c_int : 0x0008
SO_SNDTIMEO           : c_int : 0x1005
SO_RCVTIMEO           : c_int : 0x1006
SO_EXCLUSIVEADDRUSE   : c_int : ~SO_REUSEADDR
SO_CONDITIONAL_ACCEPT : c_int : 0x3002
SO_DONTLINGER         : c_int : ~SO_LINGER
SO_OOBINLINE          : c_int : 0x0100
SO_LINGER             : c_int : 0x0080
SO_RCVBUF             : c_int : 0x1002
SO_SNDBUF             : c_int : 0x1001
SO_ERROR              : c_int : 0x1007
SO_BROADCAST          : c_int : 0x0020

TCP_NODELAY: c_int : 0x0001
IP_TTL: c_int : 4
IPV6_V6ONLY: c_int : 27
IP_MULTICAST_LOOP: c_int : 11
IPV6_MULTICAST_LOOP: c_int : 11
IP_MULTICAST_TTL: c_int : 10
IP_ADD_MEMBERSHIP: c_int : 12

IPV6_ADD_MEMBERSHIP: c_int : 12
IPV6_DROP_MEMBERSHIP: c_int : 13

MAX_PROTOCOL_CHAIN: DWORD : 7

// Used with the SO_LINGER socket option to setsockopt().
LINGER :: struct {
	l_onoff: c.ushort,
	l_linger: c.ushort,
}
// Send/Receive flags.
MSG_OOB  : c_int : 1 // `send`/`recv` should process out-of-band data.
MSG_PEEK : c_int : 2 // `recv` should not remove the data from the buffer. Only valid for non-overlapped operations.


SOCKET :: distinct uintptr // TODO
socklen_t :: c_int
ADDRESS_FAMILY :: USHORT

ip_mreq :: struct {
	imr_multiaddr: in_addr,
	imr_interface: in_addr,
}

ipv6_mreq :: struct {
	ipv6mr_multiaddr: in6_addr,
	ipv6mr_interface: c_uint,
}

SOCKADDR_STORAGE_LH :: struct {
	ss_family:  ADDRESS_FAMILY,
	__ss_pad1:  [6]CHAR,
	__ss_align: i64,
	__ss_pad2:  [112]CHAR,
}

ADDRINFOA :: struct {
	ai_flags:     c_int,
	ai_family:    c_int,
	ai_socktype:  c_int,
	ai_protocol:  c_int,
	ai_addrlen:   size_t,
	ai_canonname: ^c_char,
	ai_addr:      ^SOCKADDR,
	ai_next:      ^ADDRINFOA,
}

sockaddr :: struct {
	sa_family: USHORT,
	sa_data:   [14]byte,
}

sockaddr_in :: struct {
	sin_family: ADDRESS_FAMILY,
	sin_port:   u16be,
	sin_addr:   in_addr,
	sin_zero:   [8]CHAR,
}
sockaddr_in6 :: struct {
	sin6_family:   ADDRESS_FAMILY,
	sin6_port:     u16be,
	sin6_flowinfo: c_ulong,
	sin6_addr:     in6_addr,
	sin6_scope_id: c_ulong,
}

in_addr :: struct {
	s_addr: u32,
}

in6_addr :: struct {
	s6_addr: [16]u8,
}


DNS_STATUS :: distinct DWORD // zero is success
DNS_INFO_NO_RECORDS :: 9501
DNS_QUERY_NO_RECURSION :: 0x00000004

DNS_RECORD :: struct {
    pNext: ^DNS_RECORD,
    pName: cstring,
    wType: WORD,
    wDataLength: USHORT,
    Flags: DWORD,
    dwTtl: DWORD,
    _: DWORD,
    Data: struct #raw_union {
        CNAME: DNS_PTR_DATAA,
        A:     u32be,  // Ipv4 Address
        AAAA:  u128be, // Ipv6 Address
        TXT:   DNS_TXT_DATAA,
        NS:    DNS_PTR_DATAA,
        MX:    DNS_MX_DATAA,
        SRV:   DNS_SRV_DATAA,
    },
}

DNS_TXT_DATAA :: struct {
    dwStringCount: DWORD,
    pStringArray:  cstring,
}

DNS_PTR_DATAA :: cstring

DNS_MX_DATAA :: struct {
    pNameExchange: cstring, // the hostname
    wPreference: WORD,      // lower values preferred
    _: WORD,                // padding.
}
DNS_SRV_DATAA :: struct {
	pNameTarget: cstring,
	wPriority:   u16,
	wWeight:     u16,
	wPort:       u16,
	_:           WORD, // padding
}

SOCKADDR :: struct {
	sa_family: ADDRESS_FAMILY,
	sa_data:   [14]CHAR,
}

DTR_Control :: enum byte {
	Disable = 0,
	Enable = 1,
	Handshake = 2,
}
RTS_Control :: enum byte {
	Disable   = 0,
	Enable    = 1,
	Handshake = 2,
	Toggle    = 3,
}
Parity :: enum byte {
	None  = 0,
	Odd   = 1,
	Even  = 2,
	Mark  = 3,
	Space = 4,
}
Stop_Bits :: enum byte {
	One = 0,
	One_And_A_Half = 1,
	Two = 2,
}

DCB :: struct {
	DCBlength:  DWORD,
	BaudRate:   DWORD,
	using _: bit_field DWORD {
		fBinary:           bool        | 1,
		fParity:           bool        | 1,
		fOutxCtsFlow:      bool        | 1,
		fOutxDsrFlow:      bool        | 1,
		fDtrControl:       DTR_Control | 2,
		fDsrSensitivity:   bool        | 1,
		fTXContinueOnXoff: bool        | 1,
		fOutX:             bool        | 1,
		fInX:              bool        | 1,
		fErrorChar:        bool        | 1,
		fNull:             bool        | 1,
		fRtsControl:       RTS_Control | 2,
		fAbortOnError:     bool        | 1,
	},
	wReserved:  WORD,
	XOnLim:     WORD,
	XOffLim:    WORD,
	ByteSize:   BYTE,
	Parity:     Parity,
	StopBits:   Stop_Bits,
	XonChar:    byte,
	XoffChar:   byte,
	ErrorChar:  byte,
	EofChar:    byte,
	EvtChar:    byte,
	wReserved1: WORD,
}

COMMTIMEOUTS :: struct {
	ReadIntervalTimeout: DWORD,
	ReadTotalTimeoutMultiplier: DWORD,
	ReadTotalTimeoutConstant: DWORD,
	WriteTotalTimeoutMultiplier: DWORD,
	WriteTotalTimeoutConstant: DWORD,
}

Com_Stat_Bits :: enum {
	fCtsHold,
	fDsrHold,
	fRlsdHold,
	fXoffHold,
	fXoffSent,
	fEof,
	fTxim,
}
COMSTAT :: struct {
	bits: bit_set[Com_Stat_Bits; DWORD],
	cbInQue: DWORD,
	cbOutQue: DWORD,
}

Com_Error_Bits :: enum {
	RXOVER,
	OVERRUN,
	RXPARITY,
	FRAME,
	BREAK,
}
Com_Error :: bit_set[Com_Error_Bits; DWORD]

