port Windows driver support
diff --git a/cs.c b/cs.c
index ebd8109..e668932 100644
--- a/cs.c
+++ b/cs.c
@@ -17,7 +17,11 @@
 #include "utils.h"
 #include "MCRegisterInfo.h"
 
-#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(CAPSTONE_DIET)
+#if defined(_KERNEL_MODE)
+#include "windows\winkernel_mm.h"
+#endif
+
+#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(CAPSTONE_DIET) && !defined(_KERNEL_MODE)
 #define INSN_CACHE_SIZE 32
 #else
 // reduce stack variable size for kernel/firmware
@@ -82,13 +86,19 @@
 
 unsigned int all_arch = 0;
 
-#ifdef CAPSTONE_USE_SYS_DYN_MEM
-#ifndef CAPSTONE_HAS_OSXKERNEL
+#if defined(CAPSTONE_USE_SYS_DYN_MEM)
+#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
 cs_malloc_t cs_mem_malloc = malloc;
 cs_calloc_t cs_mem_calloc = calloc;
 cs_realloc_t cs_mem_realloc = realloc;
 cs_free_t cs_mem_free = free;
 cs_vsnprintf_t cs_vsnprintf = vsnprintf;
+#elif defined(_KERNEL_MODE)
+cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
+cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
+cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;
+cs_free_t cs_mem_free = cs_winkernel_free;
+cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;
 #else
 extern void* kern_os_malloc(size_t size);
 extern void kern_os_free(void* addr);
@@ -114,7 +124,7 @@
 #endif
 
 CAPSTONE_EXPORT
-unsigned int cs_version(int *major, int *minor)
+unsigned int CAPSTONE_API cs_version(int *major, int *minor)
 {
 	archs_enable();
 
@@ -127,7 +137,7 @@
 }
 
 CAPSTONE_EXPORT
-bool cs_support(int query)
+bool CAPSTONE_API cs_support(int query)
 {
 	archs_enable();
 
@@ -161,7 +171,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_err cs_errno(csh handle)
+cs_err CAPSTONE_API cs_errno(csh handle)
 {
 	struct cs_struct *ud;
 	if (!handle)
@@ -173,7 +183,7 @@
 }
 
 CAPSTONE_EXPORT
-const char *cs_strerror(cs_err code)
+const char * CAPSTONE_API cs_strerror(cs_err code)
 {
 	switch(code) {
 		default:
@@ -212,7 +222,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle)
+cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
 {
 	cs_err err;
 	struct cs_struct *ud;
@@ -233,7 +243,7 @@
 		ud->errnum = CS_ERR_OK;
 		ud->arch = arch;
 		ud->mode = mode;
-		ud->big_endian = mode & CS_MODE_BIG_ENDIAN;
+		ud->big_endian = (mode & CS_MODE_BIG_ENDIAN) != 0;
 		// by default, do not break instruction into details
 		ud->detail = CS_OPT_OFF;
 
@@ -257,7 +267,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_err cs_close(csh *handle)
+cs_err CAPSTONE_API cs_close(csh *handle)
 {
 	struct cs_struct *ud;
 	struct insn_mnem *next, *tmp;
@@ -298,7 +308,7 @@
 #ifndef CAPSTONE_DIET
 	char *sp, *mnem;
 #endif
-	unsigned int copy_size = MIN(sizeof(insn->bytes), insn->size);
+	uint16_t copy_size = MIN(sizeof(insn->bytes), insn->size);
 
 	// fill the instruction bytes.
 	// we might skip some redundant bytes in front in the case of X86
@@ -363,7 +373,7 @@
 	switch(handle->arch) {
 		default:
 			// should never reach
-			return -1;
+			return (uint8_t)-1;
 		case CS_ARCH_ARM:
 			// skip 2 bytes on Thumb mode.
 			if (handle->mode & CS_MODE_THUMB)
@@ -394,7 +404,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_err cs_option(csh ud, cs_opt_type type, size_t value)
+cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
 {
 	struct cs_struct *handle;
 	cs_opt_mnem *opt;
@@ -512,25 +522,34 @@
 	char *p = opstr;
 	int len;
 	size_t i;
+	size_t available = sizeof(((cs_insn*)NULL)->op_str);
 
 	if (!size) {
 		opstr[0] = '\0';
 		return;
 	}
 
-	len = sprintf(p, "0x%02x", buffer[0]);
+	len = cs_snprintf(p, available, "0x%02x", buffer[0]);
 	p+= len;
+	available -= len;
 
 	for(i = 1; i < size; i++) {
-		len = sprintf(p, ", 0x%02x", buffer[i]);
+		len = cs_snprintf(p, available, ", 0x%02x", buffer[i]);
+		if (len < 0) {
+			break;
+		}
+		if ((size_t)len > available - 1) {
+			break;
+		}
 		p+= len;
+		available -= len;
 	}
 }
 
 // dynamicly allocate memory to contain disasm insn
 // NOTE: caller must free() the allocated memory itself to avoid memory leaking
 CAPSTONE_EXPORT
-size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
+size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
 {
 	struct cs_struct *handle;
 	MCInst mci;
@@ -728,13 +747,13 @@
 
 CAPSTONE_EXPORT
 CAPSTONE_DEPRECATED
-size_t cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
+size_t CAPSTONE_API cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
 {
 	return cs_disasm(ud, buffer, size, offset, count, insn);
 }
 
 CAPSTONE_EXPORT
-void cs_free(cs_insn *insn, size_t count)
+void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
 {
 	size_t i;
 
@@ -747,7 +766,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_insn *cs_malloc(csh ud)
+cs_insn * CAPSTONE_API cs_malloc(csh ud)
 {
 	cs_insn *insn;
 	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
@@ -775,7 +794,7 @@
 
 // iterator for instruction "single-stepping"
 CAPSTONE_EXPORT
-bool cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
+bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
 		uint64_t *address, cs_insn *insn)
 {
 	struct cs_struct *handle;
@@ -862,7 +881,7 @@
 
 // return friendly name of regiser in a string
 CAPSTONE_EXPORT
-const char *cs_reg_name(csh ud, unsigned int reg)
+const char * CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
 {
 	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
 
@@ -874,7 +893,7 @@
 }
 
 CAPSTONE_EXPORT
-const char *cs_insn_name(csh ud, unsigned int insn)
+const char * CAPSTONE_API cs_insn_name(csh ud, unsigned int insn)
 {
 	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
 
@@ -886,7 +905,7 @@
 }
 
 CAPSTONE_EXPORT
-const char *cs_group_name(csh ud, unsigned int group)
+const char * CAPSTONE_API cs_group_name(csh ud, unsigned int group)
 {
 	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
 
@@ -898,7 +917,7 @@
 }
 
 CAPSTONE_EXPORT
-bool cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
+bool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
 {
 	struct cs_struct *handle;
 	if (!ud)
@@ -925,7 +944,7 @@
 }
 
 CAPSTONE_EXPORT
-bool cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id)
+bool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id)
 {
 	struct cs_struct *handle;
 	if (!ud)
@@ -952,7 +971,7 @@
 }
 
 CAPSTONE_EXPORT
-bool cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id)
+bool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id)
 {
 	struct cs_struct *handle;
 	if (!ud)
@@ -979,7 +998,7 @@
 }
 
 CAPSTONE_EXPORT
-int cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
+int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
 {
 	struct cs_struct *handle;
 	unsigned int count = 0, i;
@@ -1055,7 +1074,7 @@
 }
 
 CAPSTONE_EXPORT
-int cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
+int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
 		unsigned int post)
 {
 	struct cs_struct *handle;
@@ -1156,7 +1175,7 @@
 }
 
 CAPSTONE_EXPORT
-cs_err cs_regs_access(csh ud, const cs_insn *insn,
+cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn,
 		cs_regs regs_read, uint8_t *regs_read_count,
 		cs_regs regs_write, uint8_t *regs_write_count)
 {