#define IS_PATH_SEPARATOR(x) (((x)==L'\\')||((x)==L'/'))
+/* GLOBALS ********************************************************************/
+
+static const UNICODE_STRING _condev =
+{
+ .Length = sizeof(L"\\\\.\\CON") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"\\\\.\\CON"),
+ .Buffer = L"\\\\.\\CON"
+};
+
+static const UNICODE_STRING _lpt =
+{
+ .Length = sizeof(L"LPT") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"LPT"),
+ .Buffer = L"LPT"
+};
+
+static const UNICODE_STRING _com =
+{
+ .Length = sizeof(L"COM") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"COM"),
+ .Buffer = L"COM"
+};
+
+static const UNICODE_STRING _prn =
+{
+ .Length = sizeof(L"PRN") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"PRN"),
+ .Buffer = L"PRN"
+};
+
+static const UNICODE_STRING _aux =
+{
+ .Length = sizeof(L"AUX") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"AUX"),
+ .Buffer = L"AUX"
+};
+
+static const UNICODE_STRING _con =
+{
+ .Length = sizeof(L"CON") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"CON"),
+ .Buffer = L"CON"
+};
+
+static const UNICODE_STRING _nul =
+{
+ .Length = sizeof(L"NUL") - sizeof(WCHAR),
+ .MaximumLength = sizeof(L"NUL"),
+ .Buffer = L"NUL"
+};
/* FUNCTIONS *****************************************************************/
DotLen = RtlpGetDotSequence (p+1);
DPRINT("DotSequenceLength %u\n", DotLen);
- DPRINT("prev %S p %S\n",prev,p);
-
- if (DotLen == 0)
+ DPRINT("prev '%S' p '%S'\n",prev,p);
+
+ if (DotLen == 0)
{
prev = p;
- do
- {
- p++;
- }
- while ((*p) != 0 && (*p) != L'\\');
+ p = wcschr(p + 1, L'\\');
+ if (p == NULL)
+ {
+ break;
+ }
}
else if (DotLen == 1)
{
}
+/*
+ * @implemented
+ */
ULONG STDCALL RtlGetLongestNtPathLength (VOID)
{
return (MAX_PATH + 9);
}
+/*
+ * @implemented
+ */
ULONG STDCALL
RtlDetermineDosPathNameType_U(PWSTR Path)
{
* offset in bytes to DOS device name from beginning of buffer in high word
* and size in bytes of DOS device name in low word */
+/*
+ * @implemented
+ */
ULONG STDCALL
RtlIsDosDeviceName_U(PWSTR DeviceName)
{
ULONG Length = 0;
ULONG Offset;
PWCHAR wc;
+ UNICODE_STRING DeviceNameU;
if (DeviceName == NULL)
{
if (Type == 6)
{
+ DeviceNameU.Length = DeviceNameU.MaximumLength = Length * sizeof(WCHAR);
+ DeviceNameU.Buffer = DeviceName;
if (Length == 7 &&
- !_wcsnicmp (DeviceName, L"\\\\.\\CON", 7))
+ RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_condev, TRUE))
return 0x00080006;
return 0;
}
}
Offset = wc - DeviceName;
Length -= Offset;
+ DeviceNameU.Length = DeviceNameU.MaximumLength = 3 * sizeof(WCHAR);
+ DeviceNameU.Buffer = wc;
/* check for LPTx or COMx */
if (Length == 4 && wc[3] >= L'0' && wc[3] <= L'9')
return 0;
}
- if (!_wcsnicmp (wc, L"LPT", 3) ||
- !_wcsnicmp (wc, L"COM", 3))
+ if (RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_lpt, TRUE) ||
+ RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_com, TRUE))
{
return ((Offset * 2) << 16 ) | 8;
}
/* check for PRN,AUX,NUL or CON */
if (Length == 3 &&
- (!_wcsnicmp (wc, L"PRN", 3) ||
- !_wcsnicmp (wc, L"AUX", 3) ||
- !_wcsnicmp (wc, L"NUL", 3) ||
- !_wcsnicmp (wc, L"CON", 3)))
+ (RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_prn, TRUE) ||
+ RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_aux, TRUE) ||
+ RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_nul, TRUE) ||
+ RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_con, TRUE)))
{
return ((Offset * 2) << 16) | 6;
}
}
+/*
+ * @implemented
+ */
ULONG STDCALL
RtlGetCurrentDirectory_U(ULONG MaximumLength,
PWSTR Buffer)
}
+/*
+ * @implemented
+ */
NTSTATUS STDCALL
RtlSetCurrentDirectory_U(PUNICODE_STRING name)
{
return STATUS_SUCCESS;
}
-
+/*
+ * @implemented
+ */
ULONG STDCALL
RtlGetFullPathName_U(PWSTR DosName,
ULONG size,
PWSTR *FilePart)
{
WCHAR *wcs, var[4], drive;
- int len;
- int reallen;
+ ULONG len;
+ ULONG templen = 0;
DWORD offs, sz, type;
UNICODE_STRING usvar, pfx;
PCURDIR cd;
NTSTATUS Status;
+ WCHAR TempFullPathName[MAX_PATH] = L"";
DPRINT("RtlGetFullPathName_U %S %ld %p %p\n",
DosName, size, buf, FilePart);
if (!len)
return 0;
- reallen=len;
/* strip trailing path separator (but don't change '\') */
if ((len > 1) &&
IS_PATH_SEPARATOR(DosName[len - 1]))
len--;
if (FilePart)
- *FilePart = L'\0';
- memset (buf, 0, size);
+ *FilePart = NULL;
+ *buf = 0;
CHECKPOINT;
/* check for DOS device name */
offs = sz >> 17;
sz &= 0x0000FFFF;
if (sz + 8 >= size)
- return sz + 10;
+ return sz + 10;
wcscpy (buf, L"\\\\.\\");
wcsncat (buf, DosName + offs, sz / sizeof(WCHAR));
return sz + 8;
break;
case 2: /* x:\xxx */
- *DosName = towupper (*DosName);
+ *DosName = RtlUpcaseUnicodeChar (*DosName);
break;
case 3: /* x:xxx */
- drive = towupper (*DosName);
+ drive = RtlUpcaseUnicodeChar (*DosName);
DosName += 2;
len -= 2;
CHECKPOINT;
- if (drive == towupper (cd->DosPath.Buffer[0]))
+ if (drive == RtlUpcaseUnicodeChar (cd->DosPath.Buffer[0]))
{
CHECKPOINT;
- wcscpy (buf, cd->DosPath.Buffer);
+ memcpy (TempFullPathName, cd->DosPath.Buffer, cd->DosPath.Length);
+ templen = cd->DosPath.Length / sizeof(WCHAR);
}
else
{
CHECKPOINT;
- usvar.Length = 2 * swprintf (var, L"=%c:", drive);
- usvar.MaximumLength = 8;
+ var[0] = L'=';
+ var[1] = drive;
+ var[2] = L':';
+ var[3] = 0;
+ usvar.Length = 3 * sizeof(WCHAR);
+ usvar.MaximumLength = 4 * sizeof(WCHAR);
usvar.Buffer = var;
pfx.Length = 0;
- pfx.MaximumLength = size;
- pfx.Buffer = buf;
+ pfx.MaximumLength = MAX_PATH;
+ pfx.Buffer = TempFullPathName;
Status = RtlQueryEnvironmentVariable_U (NULL,
&usvar,
&pfx);
CHECKPOINT;
if (Status == STATUS_BUFFER_TOO_SMALL)
return pfx.Length + len * 2 + 2;
- swprintf (buf, L"%c:\\", drive);
+ memcpy (TempFullPathName, var, 6);
+ templen = 3;
+ }
+ else
+ {
+ templen = pfx.Length / sizeof(WCHAR);
}
+
}
break;
case 4: /* \xxx */
- wcsncpy (buf, cd->DosPath.Buffer, 2);
+ wcsncpy (TempFullPathName, cd->DosPath.Buffer, 2);
+ TempFullPathName[2] = 0;
+ templen = wcslen(TempFullPathName);
break;
case 5: /* xxx */
- wcscpy (buf, cd->DosPath.Buffer);
+ memcpy (TempFullPathName, cd->DosPath.Buffer, cd->DosPath.Length);
+ templen = cd->DosPath.Length / sizeof(WCHAR);
break;
case 7: /* \\. */
- wcscpy (buf, L"\\\\.\\");
- len = 0;
+ memcpy (TempFullPathName, L"\\\\.\\", 8);
+ templen = 4;
break;
default:
return 0;
}
- DPRINT("buf \'%S\' DosName \'%S\' len %ld\n", buf, DosName, len);
+ RtlReleasePebLock();
+
+ DPRINT("TempFullPathName \'%S\' DosName \'%S\' len %ld\n", TempFullPathName, DosName, len);
/* add dosname to prefix */
- wcsncat (buf, DosName, len);
+ memcpy (TempFullPathName + templen, DosName, len * sizeof(WCHAR));
+ len += templen;
+ TempFullPathName[len] = 0;
CHECKPOINT;
/* replace slashes */
- for (wcs = buf; *wcs; wcs++)
- if (*wcs == L'/')
- *wcs = L'\\';
+ wcs = wcschr(TempFullPathName, L'/');
+ while(wcs)
+ {
+ *wcs = L'\\';
+ wcs = wcschr(wcs + 1, L'/');
+ }
+
+ if (len == 2 && TempFullPathName[1] == L':')
+ {
+ TempFullPathName[len++] = L'\\';
+ TempFullPathName[len] = 0;
+ }
- len = wcslen (buf);
- if (len < 3 && buf[len-1] == L':')
- wcscat (buf, L"\\");
- DPRINT("buf \'%S\'\n", buf);
- RtlpEatPath (buf);
- DPRINT("buf \'%S\'\n", buf);
+ DPRINT("TempFullPathName \'%S\'\n", TempFullPathName);
+ RtlpEatPath (TempFullPathName);
+ DPRINT("TempFullPathName \'%S\'\n", TempFullPathName);
- len = wcslen (buf);
+ len = wcslen (TempFullPathName);
- /* find file part */
- if (FilePart)
+ if (len < (size / sizeof(WCHAR)))
{
- for (wcs = buf + len - 1; wcs >= buf; wcs--)
+ memcpy (buf, TempFullPathName, (len + 1) * sizeof(WCHAR));
+
+ /* find file part */
+ if (FilePart)
{
- if (*wcs == L'\\')
+ *FilePart = wcsrchr(buf, L'\\');
+ if (*FilePart)
+ {
+ (*FilePart)++;
+ }
+ else
{
- *FilePart = wcs + 1;
- break;
+ *FilePart = buf;
}
}
- }
-
- RtlReleasePebLock();
+ }
return len * sizeof(WCHAR);
}
+/*
+ * @unimplemented
+ */
BOOLEAN STDCALL
RtlDosPathNameToNtPathName_U(PWSTR dosname,
PUNICODE_STRING ntname,
ULONG Type;
ULONG Size;
ULONG Length;
+ ULONG tmpLength;
ULONG Offset;
- WCHAR fullname[2*MAX_PATH];
+ WCHAR fullname[MAX_PATH + 1];
PWSTR Buffer = NULL;
RtlAcquirePebLock ();
/* Set NT prefix */
Offset = 0;
- wcscpy (Buffer, L"\\??\\");
+ memcpy (Buffer, L"\\??\\", 4 * sizeof(WCHAR));
+ tmpLength = 4;
Type = RtlDetermineDosPathNameType_U (fullname);
switch (Type)
{
case 1:
- wcscat (Buffer, L"UNC\\");
+ memcpy (Buffer + tmpLength, L"UNC\\", 4 * sizeof(WCHAR));
+ tmpLength += 4;
Offset = 2;
break; /* \\xxx */
Offset = 4;
break; /* \\.\xxx */
}
- wcscat (Buffer, fullname + Offset);
- Length = wcslen (Buffer);
+ Length = wcslen(fullname + Offset);
+ memcpy (Buffer + tmpLength, fullname + Offset, (Length + 1) * sizeof(WCHAR));
+ Length += tmpLength;
/* set NT filename */
ntname->Length = Length * sizeof(WCHAR);
{
memset (nah, 0, sizeof(CURDIR));
cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName);
- if (Type == 5 && cd->Handle &&
- !_wcsnicmp (cd->DosPath.Buffer, fullname, cd->DosPath.Length / 2))
+ if (Type == 5 && cd->Handle)
{
+ RtlInitUnicodeString(&us, fullname);
+ if (RtlEqualUnicodeString(&us, &cd->DosPath, TRUE))
+ {
Length = ((cd->DosPath.Length / sizeof(WCHAR)) - Offset) + ((Type == 1) ? 8 : 4);
nah->DosPath.Buffer = Buffer + Length;
nah->DosPath.Length = ntname->Length - (Length * sizeof(WCHAR));
nah->DosPath.MaximumLength = nah->DosPath.Length;
nah->Handle = cd->Handle;
+ }
}
}
}
+/*
+ * @implemented
+ */
ULONG
STDCALL
RtlDosSearchPath_U (
}
+/*
+ * @unimplemented
+ */
BOOLEAN STDCALL
RtlDoesFileExists_U(IN PWSTR FileName)
{