Implemented _wfullpath.

diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index abf27d5..22dfba6 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -512,6 +512,171 @@
 }
 
 /* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
+static void wmsvcrt_fln_fix(MSVCRT_wchar_t *path)
+{
+  int dir_flag = 0, root_flag = 0;
+  MSVCRT_wchar_t *r, *p, *q, *s;
+  MSVCRT_wchar_t szbsdot[] = { '\\', '.', 0 };
+
+  /* Skip drive */
+  if (NULL == (r = strrchrW(path, ':')))
+    r = path;
+  else
+    ++r;
+
+  /* Ignore leading slashes */
+  while ('\\' == *r)
+    if ('\\' == r[1])
+      strcpyW(r, &r[1]);
+    else
+    {
+      root_flag = 1;
+      ++r;
+    }
+
+  p = r; /* Change "\\" to "\" */
+  while (NULL != (p = strchrW(p, '\\')))
+    if ('\\' ==  p[1])
+      strcpyW(p, &p[1]);
+    else
+      ++p;
+
+  while ('.' == *r) /* Scrunch leading ".\" */
+  {
+    if ('.' == r[1])
+    {
+      /* Ignore leading ".." */
+      for (p = (r += 2); *p && (*p != '\\'); ++p)
+	;
+    }
+    else
+    {
+      for (p = r + 1 ;*p && (*p != '\\'); ++p)
+	;
+    }
+    strcpyW(r, p + ((*p) ? 1 : 0));
+  }
+
+  while ('\\' == path[strlenW(path)-1])   /* Strip last '\\' */
+  {
+    dir_flag = 1;
+    path[strlenW(path)-1] = '\0';
+  }
+
+  s = r;
+
+  /* Look for "\." in path */
+
+  while (NULL != (p = strstrW(s, szbsdot)))
+  {
+    if ('.' == p[2])
+    {
+      /* Execute this section if ".." found */
+      q = p - 1;
+      while (q > r)           /* Backup one level           */
+      {
+	if (*q == '\\')
+	  break;
+	--q;
+      }
+      if (q > r)
+      {
+	strcpyW(q, p + 3);
+	s = q;
+      }
+      else if ('.' != *q)
+      {
+	strcpyW(q + ((*q == '\\') ? 1 : 0),
+	       p + 3 + ((*(p + 3)) ? 1 : 0));
+	s = q;
+      }
+      else  s = ++p;
+    }
+    else
+    {
+      /* Execute this section if "." found */
+      q = p + 2;
+      for ( ;*q && (*q != '\\'); ++q)
+	;
+      strcpyW (p, q);
+    }
+  }
+
+  if (root_flag)  /* Embedded ".." could have bubbled up to root  */
+  {
+    for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
+      ;
+    if (r != p)
+      strcpyW(r, p);
+  }
+
+  if (dir_flag)
+  {
+    MSVCRT_wchar_t szbs[] = { '\\', 0 };
+    
+    strcatW(path, szbs);
+  }
+}
+
+/*********************************************************************
+ *		_wfullpath (MSVCRT.@)
+ */
+MSVCRT_wchar_t *_wfullpath(MSVCRT_wchar_t * absPath, const MSVCRT_wchar_t* relPath, unsigned int size)
+{
+  MSVCRT_wchar_t drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
+  MSVCRT_wchar_t res[MAX_PATH];
+  size_t len;
+  MSVCRT_wchar_t szbs[] = { '\\', 0 };
+
+
+  res[0] = '\0';
+
+  if (!relPath || !*relPath)
+    return _wgetcwd(absPath, size);
+
+  if (size < 4)
+  {
+    *MSVCRT__errno() = MSVCRT_ERANGE;
+    return NULL;
+  }
+
+  TRACE(":resolving relative path '%s'\n",debugstr_w(relPath));
+
+  _wsplitpath(relPath, drive, dir, file, ext);
+
+  /* Get Directory and drive into 'res' */
+  if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
+  {
+    /* Relative or no directory given */
+    _wgetdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 :  0, res, MAX_PATH);
+    strcatW(res,szbs);
+    if (dir[0])
+      strcatW(res,dir);
+    if (drive[0])
+      res[0] = drive[0]; /* If given a drive, preserve the letter case */
+  }
+  else
+  {
+    strcpyW(res,drive);
+    strcatW(res,dir);
+  }
+
+  strcatW(res,szbs);
+  strcatW(res, file);
+  strcatW(res, ext);
+  wmsvcrt_fln_fix(res);
+
+  len = strlenW(res);
+  if (len >= MAX_PATH || len >= (size_t)size)
+    return NULL; /* FIXME: errno? */
+
+  if (!absPath)
+    return _wcsdup(res);
+  strcpyW(absPath,res);
+  return absPath;
+}
+
+/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
 static void msvcrt_fln_fix(char *path)
 {
   int dir_flag = 0, root_flag = 0;