diff --git a/Kernel/Makefile b/Kernel/Makefile
index 7c23b103f378a434bdf15630528bb0670d932e1d..83c12407b48f4fa20df78199db11eb1eb17527af 100644
--- a/Kernel/Makefile
+++ b/Kernel/Makefile
@@ -31,7 +31,7 @@ OBJ += messages.o modules.o syscalls.o system.o threads.o
 OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
 OBJ += drv/kb.o drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/dma.o drv/pci.o drv/vga.o
 OBJ += binary.o bin/elf.o bin/pe.o
-OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o
+OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o vfs/handle.o
 OBJ += vfs/fs/root.o vfs/fs/devfs.o
 OBJ += $(addprefix drv/, $(addsuffix .o,$(DRIVERS)))
 OBJ := $(addsuffix .$(ARCH), $(OBJ))
diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h
index 779cf8844db9f77ea538ef92e8f4e11915fc994f..861fd3011affaf696d9f7bddf0082dbd298dc228 100644
--- a/Kernel/include/acess.h
+++ b/Kernel/include/acess.h
@@ -95,11 +95,11 @@ typedef void (*tThreadFunction)(void*);
  */
 typedef struct sKernelSymbol {
 	char	*Name;
-	Uint	Value;
+	tVAddr	Value;
 } tKernelSymbol;
-#define	EXPORT(_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (Uint)_name}
-#define	EXPORTV(_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (Uint)&_name}
-#define	EXPORTAS(_sym,_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (Uint)_sym}
+#define	EXPORT(_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (tVAddr)_name}
+#define	EXPORTV(_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (tVAddr)&_name}
+#define	EXPORTAS(_sym,_name)	tKernelSymbol _kexp_##_name __attribute__((section ("KEXPORT"),unused))={#_name, (tVAddr)_sym}
 /**
  * \}
  */
@@ -323,7 +323,7 @@ extern Uint32	BigEndian32(Uint32 Val);
  */
 extern int	vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args);
 extern int	sprintf(char *__s, const char *__format, ...);
-extern Uint	strlen(const char *Str);
+extern size_t	strlen(const char *Str);
 extern char	*strcpy(char *__dest, const char *__src);
 extern char	*strncpy(char *__dest, const char *__src, size_t max);
 extern int	strcmp(const char *__str1, const char *__str2);
@@ -349,7 +349,7 @@ extern int	UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
  * \}
  */
 
-extern Uint	rand(void);
+extern int	rand(void);
 extern int	CallWithArgArray(void *Function, int NArgs, Uint *Args);
 
 // --- Heap ---
@@ -416,7 +416,7 @@ extern tUID	Threads_GetUID(void);
 extern tGID	Threads_GetGID(void);
 extern int	SpawnTask(tThreadFunction Function, void *Arg);
 extern Uint	*Threads_GetCfgPtr(int Id);
-extern int	Threads_SetName(char *NewName);
+extern int	Threads_SetName(const char *NewName);
 extern void	Mutex_Acquire(tMutex *Mutex);
 extern void	Mutex_Release(tMutex *Mutex);
 extern int	Mutex_IsLocked(tMutex *Mutex);
diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c
index 14950dd5db39e41392d3de8ed58d6bf35a065009..6e8d60e427e6b301162acc3b9a740f1a9b02b242 100644
--- a/Kernel/syscalls.c
+++ b/Kernel/syscalls.c
@@ -25,7 +25,6 @@ extern Uint	Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data);
 extern int	Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer);
 extern int	Proc_Execve(char *File, char **ArgV, char **EnvP);
 extern Uint	Binary_Load(char *file, Uint *entryPoint);
-extern int	Threads_SetName(char *NewName);
 extern int	Threads_SetUID(Uint *errno, tUID ID);
 extern int	Threads_SetGID(Uint *errno, tGID ID);
 extern int	Threads_SetFaultHandler(Uint Handler);
diff --git a/Kernel/threads.c b/Kernel/threads.c
index f81e25d612abad8ed408c2aea18ef6916559757b..c9a123d14274c6c4589a04041e1addc7a8ea0bef 100644
--- a/Kernel/threads.c
+++ b/Kernel/threads.c
@@ -35,10 +35,11 @@ extern void	Proc_Start(void);
 extern tThread	*Proc_GetCurThread(void);
 extern int	Proc_Clone(Uint *Err, Uint Flags);
 extern void	Proc_CallFaultHandler(tThread *Thread);
+extern int	GetCPUNum(void);
 
 // === PROTOTYPES ===
 void	Threads_Init(void);
- int	Threads_SetName(char *NewName);
+ int	Threads_SetName(const char *NewName);
 char	*Threads_GetName(int ID);
 void	Threads_SetPriority(tThread *Thread, int Pri);
 tThread	*Threads_CloneTCB(Uint *Err, Uint Flags);
@@ -123,12 +124,12 @@ void Threads_Init(void)
 }
 
 /**
- * \fn void Threads_SetName(char *NewName)
+ * \fn void Threads_SetName(const char *NewName)
  * \brief Sets the current thread's name
  * \param NewName	New name for the thread
  * \return Boolean Failure
  */
-int Threads_SetName(char *NewName)
+int Threads_SetName(const char *NewName)
 {
 	tThread	*cur = Proc_GetCurThread();
 	char	*oldname = cur->ThreadName;
@@ -662,6 +663,12 @@ void Threads_AddActive(tThread *Thread)
 {
 	SHORTLOCK( &glThreadListLock );
 	
+	if( Thread->Status == THREAD_STAT_ACTIVE ) {
+		tThread	*cur = Proc_GetCurThread();
+		Warning("WTF, CPU%i %p (%i %s) is adding %p (%i %s) when it is active",
+			GetCPUNum(), cur, cur->TID, cur->ThreadName, Thread, Thread->TID, Thread->ThreadName);
+	}
+	
 	// Set state
 	Thread->Status = THREAD_STAT_ACTIVE;
 	Thread->CurCPU = -1;
@@ -680,8 +687,8 @@ void Threads_AddActive(tThread *Thread)
 	#if SCHEDULER_TYPE == SCHED_LOTTERY
 	giFreeTickets += caiTICKET_COUNTS[ Thread->Priority ];
 	# if DEBUG_TRACE_TICKETS
-	Log("Threads_AddActive: %p %i (%s) added, new giFreeTickets = %i",
-		Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
+	Log("Threads_AddActive: CPU%i %p %i (%s) added, new giFreeTickets = %i",
+		GetCPUNum(), Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
 	# endif
 	#endif
 	
@@ -718,8 +725,8 @@ tThread *Threads_RemActive(void)
 	// no need to decrement tickets, scheduler did it for us
 	
 	#if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
-	Log("Threads_RemActive: %p %i (%s) removed, giFreeTickets = %i",
-		ret, ret->TID, ret->ThreadName, giFreeTickets);
+	Log("Threads_RemActive: CPU%i %p %i (%s) removed, giFreeTickets = %i",
+		GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets);
 	#endif
 	
 	SHORTREL( &glThreadListLock );
diff --git a/Kernel/vfs/handle.c b/Kernel/vfs/handle.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d679be2866d3dbf7fbf9901490bbbd6f333fbbd
--- /dev/null
+++ b/Kernel/vfs/handle.c
@@ -0,0 +1,99 @@
+/*
+ * Acess2 VFS
+ * - AllocHandle, GetHandle
+ */
+#define DEBUG	0
+#include <acess.h>
+#include <mm_virt.h>
+#include "vfs.h"
+#include "vfs_int.h"
+#include "vfs_ext.h"
+
+// === CONSTANTS ===
+#define MAX_KERNEL_FILES	128
+
+// === PROTOTYPES ===
+tVFS_Handle	*VFS_GetHandle(int FD);
+ int	VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
+
+// === GLOBALS ===
+tVFS_Handle	*gaUserHandles = (void*)MM_PPD_VFS;
+tVFS_Handle	*gaKernelHandles = (void*)MM_KERNEL_VFS;
+
+// === CODE ===
+/**
+ * \fn tVFS_Handle *VFS_GetHandle(int FD)
+ * \brief Gets a pointer to the handle information structure
+ */
+tVFS_Handle *VFS_GetHandle(int FD)
+{
+	tVFS_Handle	*h;
+	
+	//Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
+	
+	if(FD < 0)	return NULL;
+	
+	if(FD & VFS_KERNEL_FLAG) {
+		FD &= (VFS_KERNEL_FLAG - 1);
+		if(FD >= MAX_KERNEL_FILES)	return NULL;
+		h = &gaKernelHandles[ FD ];
+	} else {
+		if(FD >= CFGINT(CFG_VFS_MAXFILES))	return NULL;
+		h = &gaUserHandles[ FD ];
+	}
+	
+	if(h->Node == NULL)	return NULL;
+	//Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
+	return h;
+}
+
+int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
+{
+	 int	i;
+	
+	// Check for a user open
+	if(bIsUser)
+	{
+		// Allocate Buffer
+		if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
+		{
+			Uint	addr, size;
+			size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
+			for(addr = 0; addr < size; addr += 0x1000)
+				MM_Allocate( (Uint)gaUserHandles + addr );
+			memset( gaUserHandles, 0, size );
+		}
+		// Get a handle
+		for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
+		{
+			if(gaUserHandles[i].Node)	continue;
+			gaUserHandles[i].Node = node;
+			gaUserHandles[i].Position = 0;
+			gaUserHandles[i].Mode = Mode;
+			return i;
+		}
+	}
+	else
+	{
+		// Allocate space if not already
+		if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
+		{
+			Uint	addr, size;
+			size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
+			for(addr = 0; addr < size; addr += 0x1000)
+				MM_Allocate( (Uint)gaKernelHandles + addr );
+			memset( gaKernelHandles, 0, size );
+		}
+		// Get a handle
+		for(i=0;i<MAX_KERNEL_FILES;i++)
+		{
+			if(gaKernelHandles[i].Node)	continue;
+			gaKernelHandles[i].Node = node;
+			gaKernelHandles[i].Position = 0;
+			gaKernelHandles[i].Mode = Mode;
+			return i|VFS_KERNEL_FLAG;
+		}
+	}
+	
+	return -1;
+}
diff --git a/Kernel/vfs/main.c b/Kernel/vfs/main.c
index 4fe8cf96807e2687dfd9520feb2208e916e14994..ef1cd569bfc35c73a3708d0718ea2bf9d59ab36c 100644
--- a/Kernel/vfs/main.c
+++ b/Kernel/vfs/main.c
@@ -90,7 +90,7 @@ char *VFS_GetTruePath(char *Path)
 void VFS_GetMemPath(char *Dest, void *Base, Uint Length)
 {
 	Dest[0] = '$';
-	itoa( &Dest[1], (Uint)Base, 16, BITS/4, '0' );
+	itoa( &Dest[1], (tVAddr)Base, 16, BITS/4, '0' );
 	Dest[BITS/4+1] = ':';
 	itoa( &Dest[BITS/4+2], Length, 16, BITS/4, '0' );
 	Dest[BITS/2+2] = '\0';
diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c
index 5420b33a4f35e417dd63373bcf8e22b22419202e..b0de784122ef81cd484b394f1fb2768821c45dc8 100644
--- a/Kernel/vfs/open.c
+++ b/Kernel/vfs/open.c
@@ -4,23 +4,20 @@
  */
 #define DEBUG	0
 #include <acess.h>
-#include <mm_virt.h>
 #include "vfs.h"
 #include "vfs_int.h"
 #include "vfs_ext.h"
 
 // === CONSTANTS ===
 #define	OPEN_MOUNT_ROOT	1
-#define MAX_KERNEL_FILES	128
 #define MAX_PATH_SLASHES	256
 
 // === IMPORTS ===
 extern tVFS_Node	gVFS_MemRoot;
 extern tVFS_Mount	*gVFS_RootMount;
 
-// === GLOBALS ===
-tVFS_Handle	*gaUserHandles = (void*)MM_PPD_VFS;
-tVFS_Handle	*gaKernelHandles = (void*)MM_KERNEL_VFS;
+extern tVFS_Handle	*VFS_GetHandle(int FD);
+extern int	VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode);
 
 // === CODE ===
 /**
@@ -512,50 +509,10 @@ int VFS_Open(char *Path, Uint Mode)
 		return -1;
 	}
 	
-	// Check for a user open
-	if(Mode & VFS_OPENFLAG_USER)
-	{
-		// Allocate Buffer
-		if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
-		{
-			Uint	addr, size;
-			size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
-			for(addr = 0; addr < size; addr += 0x1000)
-				MM_Allocate( (Uint)gaUserHandles + addr );
-			memset( gaUserHandles, 0, size );
-		}
-		// Get a handle
-		for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
-		{
-			if(gaUserHandles[i].Node)	continue;
-			gaUserHandles[i].Node = node;
-			gaUserHandles[i].Position = 0;
-			gaUserHandles[i].Mode = Mode;
-			LEAVE('i', i);
-			return i;
-		}
-	}
-	else
-	{
-		// Allocate space if not already
-		if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
-		{
-			Uint	addr, size;
-			size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
-			for(addr = 0; addr < size; addr += 0x1000)
-				MM_Allocate( (Uint)gaKernelHandles + addr );
-			memset( gaKernelHandles, 0, size );
-		}
-		// Get a handle
-		for(i=0;i<MAX_KERNEL_FILES;i++)
-		{
-			if(gaKernelHandles[i].Node)	continue;
-			gaKernelHandles[i].Node = node;
-			gaKernelHandles[i].Position = 0;
-			gaKernelHandles[i].Mode = Mode;
-			LEAVE('x', i|VFS_KERNEL_FLAG);
-			return i|VFS_KERNEL_FLAG;
-		}
+	i = VFS_AllocHandle( !!(Mode & VFS_OPENFLAG_USER), node, Mode );
+	if( i > 0 ) {
+		LEAVE('x', i);
+		return i;
 	}
 	
 	Log("VFS_Open: Out of handles");
@@ -612,50 +569,10 @@ int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode)
 		return -1;
 	}
 	
-	// Check for a user open
-	if(Mode & VFS_OPENFLAG_USER)
-	{
-		// Allocate Buffer
-		if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
-		{
-			Uint	addr, size;
-			size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
-			for(addr = 0; addr < size; addr += 0x1000)
-				MM_Allocate( (Uint)gaUserHandles + addr );
-			memset( gaUserHandles, 0, size );
-		}
-		// Get a handle
-		for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
-		{
-			if(gaUserHandles[i].Node)	continue;
-			gaUserHandles[i].Node = node;
-			gaUserHandles[i].Position = 0;
-			gaUserHandles[i].Mode = Mode;
-			LEAVE('i', i);
-			return i;
-		}
-	}
-	else
-	{
-		// Allocate space if not already
-		if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
-		{
-			Uint	addr, size;
-			size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
-			for(addr = 0; addr < size; addr += 0x1000)
-				MM_Allocate( (Uint)gaKernelHandles + addr );
-			memset( gaKernelHandles, 0, size );
-		}
-		// Get a handle
-		for(i=0;i<MAX_KERNEL_FILES;i++)
-		{
-			if(gaKernelHandles[i].Node)	continue;
-			gaKernelHandles[i].Node = node;
-			gaKernelHandles[i].Position = 0;
-			gaKernelHandles[i].Mode = Mode;
-			LEAVE('x', i|VFS_KERNEL_FLAG);
-			return i|VFS_KERNEL_FLAG;
-		}
+	i = VFS_AllocHandle( !!(Mode & VFS_OPENFLAG_USER), node, Mode );
+	if( i > 0 ) {
+		LEAVE('x', i);
+		return i;
 	}
 	
 	Log_Error("VFS", "VFS_OpenChild - Out of handles");
@@ -787,32 +704,6 @@ int VFS_ChRoot(char *New)
 	return 1;
 }
 
-/**
- * \fn tVFS_Handle *VFS_GetHandle(int FD)
- * \brief Gets a pointer to the handle information structure
- */
-tVFS_Handle *VFS_GetHandle(int FD)
-{
-	tVFS_Handle	*h;
-	
-	//Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
-	
-	if(FD < 0)	return NULL;
-	
-	if(FD & VFS_KERNEL_FLAG) {
-		FD &= (VFS_KERNEL_FLAG - 1);
-		if(FD >= MAX_KERNEL_FILES)	return NULL;
-		h = &gaKernelHandles[ FD ];
-	} else {
-		if(FD >= CFGINT(CFG_VFS_MAXFILES))	return NULL;
-		h = &gaUserHandles[ FD ];
-	}
-	
-	if(h->Node == NULL)	return NULL;
-	//Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
-	return h;
-}
-
 // === EXPORTS ===
 EXPORT(VFS_Open);
 EXPORT(VFS_Close);
diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c
index 07234df05b0ece0c7c770efde8bdeb31b0399a3d..88d92db5990cb046e3cf4b93ae7d02ec0c9fa896 100644
--- a/Modules/IPStack/link.c
+++ b/Modules/IPStack/link.c
@@ -115,6 +115,9 @@ void Link_WatchDevice(tAdapter *Adapter)
 	if( !gbLink_CRCTableGenerated )
 		Link_InitCRC();
 	
+	Threads_SetName(Adapter->Device);
+	Log_Log("NET", "Thread %i watching '%s'", Threads_GetTID(), Adapter->Device);
+	
 	// Child Thread
 	while(Adapter->DeviceFD != -1)
 	{