Index: /trunk/Common/cm_string.h
===================================================================
--- /trunk/Common/cm_string.h	(revision 69)
+++ /trunk/Common/cm_string.h	(revision 70)
@@ -7,4 +7,6 @@
 
 int cm_hex(const char* str, int len);
+bool cm_nocase_endswith(const char* str, const char* end);
+bool cm_endswith(const char* str, const char* end);
 char* cm_html_escape(const char* str);
 char* cm_url_escape(const char* str);
Index: /trunk/Common/string.c
===================================================================
--- /trunk/Common/string.c	(revision 69)
+++ /trunk/Common/string.c	(revision 70)
@@ -8,4 +8,6 @@
 
 char* cm_strcat(const char* a, const char* b) {
+	if(a == NULL) a = "";
+	if(b == NULL) b = "";
 	char* str = malloc(strlen(a) + strlen(b) + 1);
 	memcpy(str, a, strlen(a));
@@ -23,4 +25,22 @@
 
 char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
+
+bool cm_endswith(const char* str, const char* end) {
+	if(strlen(str) < strlen(end)) return false;
+	int i;
+	for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
+		if(str[i] != end[i - strlen(str) + strlen(end)]) return false;
+	}
+	return true;
+}
+
+bool cm_nocase_endswith(const char* str, const char* end) {
+	if(strlen(str) < strlen(end)) return false;
+	int i;
+	for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
+		if(tolower(str[i]) != tolower(end[i - strlen(str) + strlen(end)])) return false;
+	}
+	return true;
+}
 
 char* cm_trimstart(const char* str) {
Index: /trunk/Server/http.c
===================================================================
--- /trunk/Server/http.c	(revision 69)
+++ /trunk/Server/http.c	(revision 70)
@@ -83,5 +83,5 @@
 #endif
 		int len = tw_read(ssl, sock, buffer, 512);
-		if(len <= 0){
+		if(len <= 0) {
 			bad = true;
 			break;
@@ -285,9 +285,11 @@
 			if(req->path[i + 1] == 0) continue;
 			cbuf[0] = cm_hex(req->path + i + 1, 2);
-			char* tmp = result;
-			result = cm_strcat(tmp, cbuf);
-			free(tmp);
+			if(cbuf[0] != '\\') {
+				char* tmp = result;
+				result = cm_strcat(tmp, cbuf);
+				free(tmp);
+			}
 			i += 2;
-		} else {
+		} else if(req->path[i] != '\\') {
 			cbuf[0] = req->path[i];
 			char* tmp = result;
@@ -325,5 +327,5 @@
 				}
 			} else if(strcmp(pth, ".") == 0) {
-			} else if(oldc != '\\') {
+			} else {
 				char* tmp = p;
 				p = cm_strcat3(tmp, pth, cbuf);
Index: /trunk/Server/main.c
===================================================================
--- /trunk/Server/main.c	(revision 69)
+++ /trunk/Server/main.c	(revision 70)
@@ -37,15 +37,15 @@
 SERVICE_STATUS_HANDLE status_handle;
 
-void WINAPI servhandler(DWORD control){
-	switch(control){
-		case SERVICE_CONTROL_STOP:
-		case SERVICE_CONTROL_SHUTDOWN:
-			status.dwCurrentState = SERVICE_STOP_PENDING;
-			break;
+void WINAPI servhandler(DWORD control) {
+	switch(control) {
+	case SERVICE_CONTROL_STOP:
+	case SERVICE_CONTROL_SHUTDOWN:
+		status.dwCurrentState = SERVICE_STOP_PENDING;
+		break;
 	}
 	SetServiceStatus(status_handle, &status);
 }
 
-void WINAPI servmain(DWORD argc, LPSTR* argv){
+void WINAPI servmain(DWORD argc, LPSTR* argv) {
 	logfile = fopen(PREFIX "/logs/tewi.log", "a");
 	if(logfile == NULL) logfile = stderr;
@@ -61,5 +61,5 @@
 	if(SetServiceStatus(status_handle, &status) == 0) return;
 	int st = startup(argc, argv);
-	if(st != -1){
+	if(st != -1) {
 		status.dwWin32ExitCode = NO_ERROR;
 		status.dwServiceSpecificExitCode = st;
@@ -88,8 +88,8 @@
 }
 
-int startup(int argc, char** argv){
+int startup(int argc, char** argv) {
 	int i;
 	const char* confpath = PREFIX "/etc/tewi.conf";
-	if(argv != NULL){
+	if(argv != NULL) {
 		for(i = 1; i < argc; i++) {
 			if(argv[i][0] == '-') {
@@ -97,9 +97,9 @@
 					if(!cm_do_log) {
 						cm_do_log = true;
-	#ifndef NO_SSL
+#ifndef NO_SSL
 						cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
-	#else
+#else
 						cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
-	#endif
+#endif
 					} else {
 						cm_do_log = true;
Index: /trunk/Server/server.c
===================================================================
--- /trunk/Server/server.c	(revision 69)
+++ /trunk/Server/server.c	(revision 70)
@@ -51,4 +51,8 @@
 SOCKADDR addresses[MAX_PORTS];
 int sockets[MAX_PORTS];
+
+#ifdef __MINGW32__
+const char* reserved_names[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
+#endif
 
 /* https://qiita.com/gyu-don/items/5a640c6d2252a860c8cd */
@@ -429,5 +433,5 @@
 		int i;
 		time_t cmtime = 0;
-		if(req.headers != NULL){
+		if(req.headers != NULL) {
 			for(i = 0; req.headers[i] != NULL; i += 2) {
 				if(cm_strcaseequ(req.headers[i], "Host")) {
@@ -480,6 +484,29 @@
 			char* path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
 			cm_log("Server", "Filesystem path is %s", path);
+			bool rej = false;
+#ifdef __MINGW32__
+			for(i = 0; i < sizeof(reserved_names) / sizeof(reserved_names[0]); i++) {
+				char* n = cm_strcat("/", reserved_names[i]);
+				if(cm_nocase_endswith(path, n)) {
+					tw_http_error(s, sock, 403, name, port);
+					free(n);
+					rej = true;
+					cm_log("Server", "XP Patch ; rejecting access to device");
+					break;
+				}
+				free(n);
+				char* y = cm_strcat3("/", reserved_names[i], ":");
+				if(cm_nocase_endswith(path, y)) {
+					tw_http_error(s, sock, 403, name, port);
+					free(y);
+					rej = true;
+					cm_log("Server", "XP Patch ; rejecting access to device");
+					break;
+				}
+				free(y);
+			}
+#endif
 			struct stat st;
-			if(stat(path, &st) == 0) {
+			if(!rej && stat(path, &st) == 0) {
 				if(!tw_permission_allowed(path, addr, req, vhost_entry)) {
 					tw_http_error(s, sock, 403, name, port);
@@ -648,4 +675,5 @@
 									addstring(&str, "<pre><code>%h</code></pre>\n", rmbuf);
 									fclose(fr);
+									free(rmbuf);
 								}
 								free(fpth);
@@ -682,9 +710,9 @@
 		free(vhost);
 		free(host);
-		tw_free_request(&req);
 	} else if(ret == -1) {
 	} else {
 		tw_http_error(s, sock, 400, name, port);
 	}
+	tw_free_request(&req);
 cleanup:
 #ifndef NO_SSL
@@ -718,5 +746,5 @@
 #ifdef __MINGW32__
 	struct thread_entry threads[2048];
-	for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++){
+	for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
 		threads[i].used = false;
 	}
@@ -732,11 +760,11 @@
 		if(ret == -1) {
 			break;
-		}else if(ret == 0){
-#ifdef __MINGW32__
-			for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++){
-				if(threads[i].used){
+		} else if(ret == 0) {
+#ifdef __MINGW32__
+			for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
+				if(threads[i].used) {
 					DWORD ex;
 					GetExitCodeThread(threads[i].handle, &ex);
-					if(ex != STILL_ACTIVE){
+					if(ex != STILL_ACTIVE) {
 						CloseHandle(threads[i].handle);
 						threads[i].used = false;
@@ -746,5 +774,5 @@
 #endif
 #ifdef SERVICE
-			if(status.dwCurrentState == SERVICE_STOP_PENDING){
+			if(status.dwCurrentState == SERVICE_STOP_PENDING) {
 				break;
 			}
@@ -766,9 +794,9 @@
 					e->addr = claddr;
 					int j;
-					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++){
-						if(threads[j].used){
+					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
+						if(threads[j].used) {
 							DWORD ex;
 							GetExitCodeThread(threads[j].handle, &ex);
-							if(ex != STILL_ACTIVE){
+							if(ex != STILL_ACTIVE) {
 								CloseHandle(threads[j].handle);
 								threads[j].used = false;
@@ -776,6 +804,6 @@
 						}
 					}
-					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++){
-						if(!threads[j].used){
+					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
+						if(!threads[j].used) {
 							threads[j].handle = (HANDLE)_beginthreadex(NULL, 0, tw_server_pass, e, 0, NULL);
 							threads[j].used = true;
Index: /trunk/Server/tw_version.h
===================================================================
--- /trunk/Server/tw_version.h	(revision 69)
+++ /trunk/Server/tw_version.h	(revision 70)
@@ -4,5 +4,5 @@
 #define __TW_VERSION_H__
 
-#define TW_VERSION "1.00\0"
+#define TW_VERSION "1.01\0"
 
 const char* tw_get_version(void);
