Commit d6da1f33 authored by Alexandre Julliard's avatar Alexandre Julliard

Implemented RtlIsNameLegalDOS8Dot3 (based on a patch by Eric Pouech).

Implemented RtlUpcaseUnicodeStringToCountedOemString.
parent 2c76bc1c
......@@ -443,7 +443,7 @@
@ stdcall RtlIntegerToUnicodeString(long long ptr)
@ stdcall RtlIsDosDeviceName_U(wstr) RtlIsDosDeviceName_U
@ stub RtlIsGenericTableEmpty
@ stub RtlIsNameLegalDOS8Dot3
@ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr)
@ stdcall RtlIsTextUnicode(ptr long ptr)
@ stdcall -ret64 RtlLargeIntegerAdd(long long long long)
@ stdcall -ret64 RtlLargeIntegerArithmeticShift(long long long)
......@@ -552,7 +552,7 @@
@ stdcall RtlUpcaseUnicodeChar(long)
@ stdcall RtlUpcaseUnicodeString(ptr ptr long)
@ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long)
@ stub RtlUpcaseUnicodeStringToCountedOemString
@ stdcall RtlUpcaseUnicodeStringToCountedOemString(ptr ptr long)
@ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long)
@ stub RtlUpcaseUnicodeToCustomCPN
@ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long)
......
/*
* Ntdll path functions
*
* Copyright 2002 Alexandre Julliard
* Copyright 2002, 2003 Alexandre Julliard
* Copyright 2003 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -22,6 +23,9 @@
#include "winternl.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
......@@ -123,3 +127,73 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name )
}
return 0;
}
/******************************************************************
* RtlIsNameLegalDOS8Dot3 (NTDLL.@)
*
* Returns TRUE iff unicode is a valid DOS (8+3) name.
* If the name is valid, oem gets filled with the corresponding OEM string
* spaces is set to TRUE if unicode contains spaces
*/
BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode,
OEM_STRING *oem, BOOLEAN *spaces )
{
int dot = -1;
unsigned int i;
char buffer[12];
OEM_STRING oem_str;
BOOLEAN got_space = FALSE;
if (!oem)
{
oem_str.Length = sizeof(buffer);
oem_str.MaximumLength = sizeof(buffer);
oem_str.Buffer = buffer;
oem = &oem_str;
}
if (RtlUpcaseUnicodeStringToCountedOemString( oem, unicode, FALSE ) != STATUS_SUCCESS)
return FALSE;
if (oem->Length > 12) return FALSE;
/* a starting . is invalid, except for . and .. */
if (oem->Buffer[0] == '.')
{
if (oem->Length != 1 && (oem->Length != 2 || oem->Buffer[1] != '.')) return FALSE;
if (spaces) *spaces = FALSE;
return TRUE;
}
for (i = 0; i < oem->Length; i++)
{
switch (oem->Buffer[i])
{
case ' ':
/* leading/trailing spaces not allowed */
if (!i || i == oem->Length-1 || oem->Buffer[i+1] == '.') return FALSE;
got_space = TRUE;
break;
case '.':
if (dot != -1) return FALSE;
dot = i;
break;
default:
/* FIXME: check for invalid chars */
break;
}
}
/* check file part is shorter than 8, extension shorter than 3
* dot cannot be last in string
*/
if (dot == -1)
{
if (oem->Length > 8) return FALSE;
}
else
{
if (dot > 8 || (oem->Length - dot > 4) || dot == oem->Length - 1) return FALSE;
}
if (spaces) *spaces = got_space;
return TRUE;
}
......@@ -836,6 +836,46 @@ NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString( STRING *dst,
/**************************************************************************
* RtlUpcaseUnicodeStringToCountedOemString (NTDLL.@)
*
* NOTES
* Same as RtlUpcaseUnicodeStringToOemString but doesn't write terminating null
*/
NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString( STRING *oem,
const UNICODE_STRING *uni,
BOOLEAN doalloc )
{
NTSTATUS ret;
UNICODE_STRING upcase;
if (!(ret = RtlUpcaseUnicodeString( &upcase, uni, TRUE )))
{
DWORD len = RtlUnicodeStringToOemSize( &upcase ) - 1;
oem->Length = len;
if (doalloc)
{
oem->MaximumLength = len;
if (!(oem->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, len )))
{
ret = STATUS_NO_MEMORY;
goto done;
}
}
else if (oem->MaximumLength < len)
{
ret = STATUS_BUFFER_OVERFLOW;
oem->Length = oem->MaximumLength;
if (!oem->MaximumLength) goto done;
}
RtlUnicodeToOemN( oem->Buffer, oem->Length, NULL, upcase.Buffer, upcase.Length );
done:
RtlFreeUnicodeString( &upcase );
}
return ret;
}
/**************************************************************************
* RtlUpcaseUnicodeToMultiByteN (NTDLL.@)
*/
NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
......
......@@ -26,6 +26,8 @@ static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPD
LPCSTR src, DWORD srclen );
static UINT (WINAPI *pRtlDetermineDosPathNameType_U)( PCWSTR path );
static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name );
static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN );
static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
static void test_RtlDetermineDosPathNameType(void)
{
......@@ -145,6 +147,75 @@ static void test_RtlIsDosDeviceName(void)
}
}
static void test_RtlIsNameLegalDOS8Dot3(void)
{
struct test
{
char *path;
BOOLEAN result;
BOOLEAN spaces;
};
static const struct test tests[] =
{
{ "12345678", TRUE, FALSE },
{ "123 5678", TRUE, TRUE },
{ "12345678.", FALSE, 2 /*not set*/ },
{ "1234 678.", FALSE, 2 /*not set*/ },
{ "12345678.a", TRUE, FALSE },
{ "12345678.a ", FALSE, 2 /*not set*/ },
{ "12345678.a c", TRUE, TRUE },
{ " 2345678.a ", FALSE, 2 /*not set*/ },
{ "1 345678.abc", TRUE, TRUE },
{ "1 8.a c", TRUE, TRUE },
{ "1 3 5 7 .abc", FALSE, 2 /*not set*/ },
{ "12345678. c", TRUE, TRUE },
{ "123456789.a", FALSE, 2 /*not set*/ },
{ "12345.abcd", FALSE, 2 /*not set*/ },
{ "12345.ab d", FALSE, 2 /*not set*/ },
{ ".abc", FALSE, 2 /*not set*/ },
{ "12.abc.d", FALSE, 2 /*not set*/ },
{ ".", TRUE, FALSE },
{ "..", TRUE, FALSE },
{ "...", FALSE, 2 /*not set*/ },
{ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE, 2 /*not set*/ },
{ NULL, 0 }
};
const struct test *test;
UNICODE_STRING ustr;
OEM_STRING oem, oem_ret;
WCHAR buffer[200];
char buff2[12];
BOOLEAN ret, spaces;
ustr.MaximumLength = sizeof(buffer);
ustr.Buffer = buffer;
for (test = tests; test->path; test++)
{
oem.Buffer = test->path;
oem.Length = strlen(test->path);
oem.MaximumLength = oem.Length + 1;
pRtlOemStringToUnicodeString( &ustr, &oem, FALSE );
spaces = 2;
oem_ret.Length = oem_ret.MaximumLength = sizeof(buff2);
oem_ret.Buffer = buff2;
ret = pRtlIsNameLegalDOS8Dot3( &ustr, &oem_ret, &spaces );
ok( ret == test->result, "Wrong result %d/%d for '%s'", ret, test->result, test->path );
ok( spaces == test->spaces, "Wrong spaces value %d/%d for '%s'", spaces, test->spaces, test->path );
if (strlen(test->path) <= 12)
{
char str[13];
int i;
strcpy( str, test->path );
for (i = 0; str[i]; i++) str[i] = toupper(str[i]);
ok( oem_ret.Length == strlen(test->path), "Wrong length %d/%d for '%s'",
oem_ret.Length, strlen(test->path), test->path );
ok( !memcmp( oem_ret.Buffer, str, oem_ret.Length ),
"Wrong string '%.*s'/'%s'", oem_ret.Length, oem_ret.Buffer, str );
}
}
}
START_TEST(path)
......@@ -153,6 +224,9 @@ START_TEST(path)
pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U");
pRtlIsDosDeviceName_U = (void *)GetProcAddress(mod,"RtlIsDosDeviceName_U");
pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
test_RtlDetermineDosPathNameType();
test_RtlIsDosDeviceName();
test_RtlIsNameLegalDOS8Dot3();
}
......@@ -1021,7 +1021,7 @@ NTSTATUS WINAPI RtlInt64ToUnicodeString(ULONGLONG,ULONG,UNICODE_STRING *);
NTSTATUS WINAPI RtlIntegerToChar(ULONG,ULONG,ULONG,PCHAR);
NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG,ULONG,UNICODE_STRING *);
ULONG WINAPI RtlIsDosDeviceName_U(PCWSTR);
BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(PUNICODE_STRING,POEM_STRING,PBOOLEAN);
BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
DWORD WINAPI RtlIsTextUnicode(LPVOID,DWORD,DWORD *);
LONGLONG WINAPI RtlLargeIntegerAdd(LONGLONG,LONGLONG);
......@@ -1109,6 +1109,7 @@ void WINAPI RtlUnwindEx(FRAME_POINTERS,PVOID,PEXCEPTION_RECORD,PVOID,PCONTE
WCHAR WINAPI RtlUpcaseUnicodeChar(WCHAR);
NTSTATUS WINAPI RtlUpcaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING *,BOOLEAN);
NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString(STRING*,const UNICODE_STRING*,BOOLEAN);
NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING*,const UNICODE_STRING*,BOOLEAN);
NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString(STRING*,const UNICODE_STRING*,BOOLEAN);
NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD);
NTSTATUS WINAPI RtlUpcaseUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment