Commit ae0ca564 authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

Added RtlNtStatusToDosErrorNoTeb, RtlGet/Set/RestoreLastWin32Error,

RtlGUIDFromString, RtlStringFromGUID.
parent f7cae999
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include "config.h" #include "config.h"
#include "wine/port.h"
#include <stdarg.h> #include <stdarg.h>
#include "ntstatus.h" #include "ntstatus.h"
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
#include "winreg.h" #include "winreg.h"
#include "winternl.h" #include "winternl.h"
#include "winerror.h" #include "winerror.h"
#include "thread.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll); WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
...@@ -42,7 +44,7 @@ struct error_table ...@@ -42,7 +44,7 @@ struct error_table
static const struct error_table error_table[20]; static const struct error_table error_table[20];
/************************************************************************** /**************************************************************************
* RtlNtStatusToDosError (NTDLL.@) * RtlNtStatusToDosErrorNoTeb (NTDLL.@)
* *
* Convert an NTSTATUS code to a Win32 error code. * Convert an NTSTATUS code to a Win32 error code.
* *
...@@ -53,7 +55,7 @@ static const struct error_table error_table[20]; ...@@ -53,7 +55,7 @@ static const struct error_table error_table[20];
* The mapped Win32 error code, or ERROR_MR_MID_NOT_FOUND if there is no * The mapped Win32 error code, or ERROR_MR_MID_NOT_FOUND if there is no
* mapping defined. * mapping defined.
*/ */
ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status ) ULONG WINAPI RtlNtStatusToDosErrorNoTeb( NTSTATUS status )
{ {
const struct error_table *table = error_table; const struct error_table *table = error_table;
...@@ -81,6 +83,53 @@ ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status ) ...@@ -81,6 +83,53 @@ ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status )
return ERROR_MR_MID_NOT_FOUND; return ERROR_MR_MID_NOT_FOUND;
} }
/**************************************************************************
* RtlNtStatusToDosError (NTDLL.@)
*
* Convert an NTSTATUS code to a Win32 error code.
*
* PARAMS
* status [I] Nt error code to map.
*
* RETURNS
* The mapped Win32 error code, or ERROR_MR_MID_NOT_FOUND if there is no
* mapping defined.
*/
ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status )
{
/* FIXME: This function obviously does something with the Teb */
return RtlNtStatusToDosErrorNoTeb( status );
}
/**********************************************************************
* RtlGetLastWin32Error (NTDLL.@)
*
* Get the current per-thread error value set by a system function or the user.
*
* PARAMS
* None.
*
* RETURNS
* The current error value for the thread, as set by SetLastWin32Error() or SetLastError().
*/
DWORD WINAPI RtlGetLastWin32Error(void)
{
return NtCurrentTeb()->LastErrorValue;
}
/***********************************************************************
* RtlSetLastWin32Error (NTDLL.@)
* RtlRestoreLastWin32Error (NTDLL.@)
*
* Set the per-thread error value.
*
* PARAMS
* err [I] The new error value to set
*/
void WINAPI RtlSetLastWin32Error( DWORD err )
{
NtCurrentTeb()->LastErrorValue = err;
}
/* conversion tables */ /* conversion tables */
......
...@@ -416,6 +416,7 @@ ...@@ -416,6 +416,7 @@
@ stub RtlGetElementGenericTable @ stub RtlGetElementGenericTable
@ stdcall RtlGetFullPathName_U(wstr long ptr ptr) @ stdcall RtlGetFullPathName_U(wstr long ptr ptr)
@ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr)
@ stdcall RtlGetLastWin32Error()
@ stdcall RtlGetLongestNtPathLength() @ stdcall RtlGetLongestNtPathLength()
@ stub RtlGetNtGlobalFlags @ stub RtlGetNtGlobalFlags
@ stdcall RtlGetNtProductType(ptr) @ stdcall RtlGetNtProductType(ptr)
...@@ -423,6 +424,7 @@ ...@@ -423,6 +424,7 @@
@ stdcall RtlGetProcessHeaps(long ptr) @ stdcall RtlGetProcessHeaps(long ptr)
@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr) @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)
@ stub RtlGetUserInfoHeap @ stub RtlGetUserInfoHeap
@ stdcall RtlGUIDFromString(ptr ptr)
@ stdcall RtlIdentifierAuthoritySid(ptr) @ stdcall RtlIdentifierAuthoritySid(ptr)
@ stdcall RtlImageDirectoryEntryToData(long long long ptr) @ stdcall RtlImageDirectoryEntryToData(long long long ptr)
@ stdcall RtlImageNtHeader(long) @ stdcall RtlImageNtHeader(long)
...@@ -476,6 +478,7 @@ ...@@ -476,6 +478,7 @@
@ stdcall RtlNewSecurityObject(long long long long long long) @ stdcall RtlNewSecurityObject(long long long long long long)
@ stdcall RtlNormalizeProcessParams(ptr) @ stdcall RtlNormalizeProcessParams(ptr)
@ stdcall RtlNtStatusToDosError(long) @ stdcall RtlNtStatusToDosError(long)
@ stdcall RtlNtStatusToDosErrorNoTeb(long)
@ stub RtlNumberGenericTableElements @ stub RtlNumberGenericTableElements
@ stdcall RtlNumberOfClearBits(ptr) @ stdcall RtlNumberOfClearBits(ptr)
@ stdcall RtlNumberOfSetBits(ptr) @ stdcall RtlNumberOfSetBits(ptr)
...@@ -500,6 +503,7 @@ ...@@ -500,6 +503,7 @@
@ stdcall RtlRaiseException(ptr) @ stdcall RtlRaiseException(ptr)
@ stdcall RtlRaiseStatus(long) @ stdcall RtlRaiseStatus(long)
@ stdcall RtlRandom(ptr) @ stdcall RtlRandom(ptr)
@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error
@ stdcall RtlReAllocateHeap(long long ptr long) @ stdcall RtlReAllocateHeap(long long ptr long)
@ stub RtlRealPredecessor @ stub RtlRealPredecessor
@ stub RtlRealSuccessor @ stub RtlRealSuccessor
...@@ -521,6 +525,7 @@ ...@@ -521,6 +525,7 @@
@ stdcall RtlSetEnvironmentVariable(ptr ptr ptr) @ stdcall RtlSetEnvironmentVariable(ptr ptr ptr)
@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long) @ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
@ stub RtlSetInformationAcl @ stub RtlSetInformationAcl
@ stdcall RtlSetLastWin32Error(long)
@ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long) @ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long)
@ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long) @ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long)
@ stub RtlSetSecurityObject @ stub RtlSetSecurityObject
...@@ -530,7 +535,7 @@ ...@@ -530,7 +535,7 @@
@ stdcall RtlSizeHeap(long long ptr) @ stdcall RtlSizeHeap(long long ptr)
@ stub RtlSplay @ stub RtlSplay
@ stub RtlStartRXact @ stub RtlStartRXact
@ stub RtlStringFromGUID @ stdcall RtlStringFromGUID(ptr ptr)
@ stdcall RtlSubAuthorityCountSid(ptr) @ stdcall RtlSubAuthorityCountSid(ptr)
@ stdcall RtlSubAuthoritySid(ptr long) @ stdcall RtlSubAuthoritySid(ptr long)
@ stub RtlSubtreePredecessor @ stub RtlSubtreePredecessor
......
...@@ -1799,3 +1799,135 @@ NTSTATUS WINAPI RtlIntegerToUnicodeString( ...@@ -1799,3 +1799,135 @@ NTSTATUS WINAPI RtlIntegerToUnicodeString(
} /* if */ } /* if */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/*************************************************************************
* RtlGUIDFromString (NTDLL.@)
*
* Convert a string representation of a GUID into a GUID.
*
* PARAMS
* str [I] String representation in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
* guid [O] Destination for the converted GUID
*
* RETURNS
* Success: STATUS_SUCCESS. guid contains the converted value.
* Failure: STATUS_INVALID_PARAMETER, if str is not in the expected format.
*
* SEE ALSO
* See RtlStringFromGUID.
*/
NTSTATUS WINAPI RtlGUIDFromString(const UNICODE_STRING *str, GUID* guid)
{
int i = 0;
const WCHAR *lpszCLSID = str->Buffer;
BYTE* lpOut = (BYTE*)guid;
TRACE("(%s,%p)\n", debugstr_us(str), guid);
/* Convert string: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
* to memory: DWORD... WORD WORD BYTES............
*/
while (i < 37)
{
switch (i)
{
case 0:
if (*lpszCLSID != '{')
return STATUS_INVALID_PARAMETER;
break;
case 9: case 14: case 19: case 24:
if (*lpszCLSID != '-')
return STATUS_INVALID_PARAMETER;
break;
case 37:
if (*lpszCLSID != '}')
return STATUS_INVALID_PARAMETER;
break;
default:
{
WCHAR ch = *lpszCLSID, ch2 = lpszCLSID[1];
unsigned char byte;
/* Read two hex digits as a byte value */
if (ch >= '0' && ch <= '9') ch = ch - '0';
else if (ch >= 'a' && ch <= 'f') ch = ch - 'a' + 10;
else if (ch >= 'A' && ch <= 'F') ch = ch - 'A' + 10;
else return STATUS_INVALID_PARAMETER;
if (ch2 >= '0' && ch2 <= '9') ch2 = ch2 - '0';
else if (ch2 >= 'a' && ch2 <= 'f') ch2 = ch2 - 'a' + 10;
else if (ch2 >= 'A' && ch2 <= 'F') ch2 = ch2 - 'A' + 10;
else return STATUS_INVALID_PARAMETER;
byte = ch << 4 | ch2;
switch (i)
{
#ifndef WORDS_BIGENDIAN
/* For Big Endian machines, we store the data such that the
* dword/word members can be read as DWORDS and WORDS correctly. */
/* Dword */
case 1: lpOut[3] = byte; break;
case 3: lpOut[2] = byte; break;
case 5: lpOut[1] = byte; break;
case 7: lpOut[0] = byte; lpOut += 4; break;
/* Word */
case 10: case 15: lpOut[1] = byte; break;
case 12: case 17: lpOut[0] = byte; lpOut += 2; break;
#endif
/* Byte */
default: lpOut[0] = byte; lpOut++; break;
}
lpszCLSID++; /* Skip 2nd character of byte */
i++;
}
}
lpszCLSID++;
i++;
}
return STATUS_SUCCESS;
}
/*************************************************************************
* RtlStringFromGUID (NTDLL.@)
*
* Convert a GUID into a string representation of a GUID.
*
* PARAMS
* guid [I] GUID to convert
* str [O] Destination for the converted string
*
* RETURNS
* Success: STATUS_SUCCESS. str contains the converted value.
* Failure: STATUS_NO_MEMORY, if memory for str cannot be allocated.
*
* SEE ALSO
* See RtlGUIDFromString.
*/
NTSTATUS WINAPI RtlStringFromGUID(const GUID* guid, UNICODE_STRING *str)
{
static const WCHAR szFormat[] = { '{','%','0','8','l','X','-',
'%','0','4','X','-', '%','0','4','X','-','%','0','2','X','%','0','2','X',
'-', '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
'%','0','2','X','%','0','2','X','}','\0' };
TRACE("(%p,%p)\n", guid, str);
str->Buffer = (WCHAR*)RtlAllocateHeap( ntdll_get_process_heap(), 0, 40 * sizeof(WCHAR));
if (!str->Buffer)
{
str->Length = str->MaximumLength = 0;
return STATUS_NO_MEMORY;
}
str->Length = str->MaximumLength = 40;
sprintfW(str->Buffer, szFormat, guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
return STATUS_SUCCESS;
}
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#define INITGUID
#include "ntstatus.h" #include "ntstatus.h"
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
#include "winnls.h" #include "winnls.h"
#include "winreg.h" #include "winreg.h"
#include "winternl.h" #include "winternl.h"
#include "guiddef.h"
/* Function ptrs for ntdll calls */ /* Function ptrs for ntdll calls */
static HMODULE hntdll = 0; static HMODULE hntdll = 0;
...@@ -64,6 +66,8 @@ static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICOD ...@@ -64,6 +66,8 @@ static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICOD
static CHAR (WINAPI *pRtlUpperChar)(CHAR); static CHAR (WINAPI *pRtlUpperChar)(CHAR);
static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *); static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *);
static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(long, UNICODE_STRING *); static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(long, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*);
static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*);
/*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/ /*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/
/*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/ /*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/
...@@ -130,6 +134,8 @@ static void InitFunctionPtrs(void) ...@@ -130,6 +134,8 @@ static void InitFunctionPtrs(void)
pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar"); pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar");
pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString"); pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString");
pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString"); pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString");
pRtlGUIDFromString = (void *)GetProcAddress(hntdll, "RtlGUIDFromString");
pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID");
} /* if */ } /* if */
} }
...@@ -1669,6 +1675,38 @@ static void test_RtlIntegerToChar(void) ...@@ -1669,6 +1675,38 @@ static void test_RtlIntegerToChar(void)
int2str[0].value, int2str[0].base, int2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION); int2str[0].value, int2str[0].base, int2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION);
} }
static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-',
'0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-',
'0','B','0','C','0','D','0','E','0','F','0','A','}','\0' };
DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x0A);
static void test_RtlGUIDFromString(void)
{
GUID guid;
UNICODE_STRING str;
NTSTATUS ret;
str.Length = str.MaximumLength = (sizeof(szGuid) - 1) / sizeof(WCHAR);
str.Buffer = (LPWSTR)szGuid;
ret = pRtlGUIDFromString(&str, &guid);
ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret);
ok(memcmp(&guid, &IID_Endianess, sizeof(guid)) == 0, "Endianess broken\n");
}
static void test_RtlStringFromGUID(void)
{
UNICODE_STRING str;
NTSTATUS ret;
str.Length = str.MaximumLength = 0;
str.Buffer = NULL;
ret = pRtlStringFromGUID(&IID_Endianess, &str);
ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret);
ok(str.Buffer && !lstrcmpW(str.Buffer, szGuid), "Endianess broken\n");
}
START_TEST(rtlstr) START_TEST(rtlstr)
{ {
...@@ -1690,15 +1728,16 @@ START_TEST(rtlstr) ...@@ -1690,15 +1728,16 @@ START_TEST(rtlstr)
test_RtlAppendUnicodeStringToString(); test_RtlAppendUnicodeStringToString();
} /* if */ } /* if */
if (pRtlInitUnicodeStringEx) { if (pRtlInitUnicodeStringEx)
test_RtlInitUnicodeStringEx(); test_RtlInitUnicodeStringEx();
} /* if */ if (pRtlDuplicateUnicodeString)
if (pRtlDuplicateUnicodeString) {
test_RtlDuplicateUnicodeString(); test_RtlDuplicateUnicodeString();
} /* if */ if (pRtlFindCharInUnicodeString)
if (pRtlFindCharInUnicodeString) {
test_RtlFindCharInUnicodeString(); test_RtlFindCharInUnicodeString();
} /* if */ if (pRtlGUIDFromString)
test_RtlGUIDFromString();
if (pRtlStringFromGUID)
test_RtlStringFromGUID();
/* /*
* test_RtlUpcaseUnicodeChar(); * test_RtlUpcaseUnicodeChar();
* test_RtlUpcaseUnicodeString(); * test_RtlUpcaseUnicodeString();
......
...@@ -1239,7 +1239,7 @@ PVOID WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,ULONG); ...@@ -1239,7 +1239,7 @@ PVOID WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,ULONG);
void WINAPI RtlReleasePebLock(void); void WINAPI RtlReleasePebLock(void);
void WINAPI RtlReleaseResource(LPRTL_RWLOCK); void WINAPI RtlReleaseResource(LPRTL_RWLOCK);
ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID); ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID);
DWORD WINAPI RtlRestoreLastWin32Error(DWORD); void WINAPI RtlRestoreLastWin32Error(DWORD);
void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *);
void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *);
...@@ -1253,7 +1253,7 @@ NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL, ...@@ -1253,7 +1253,7 @@ NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,
NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING); NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING);
NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN); NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
NTSTATUS WINAPI RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN); NTSTATUS WINAPI RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
DWORD WINAPI RtlSetLastWin32Error(DWORD); void WINAPI RtlSetLastWin32Error(DWORD);
NTSTATUS WINAPI RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN); NTSTATUS WINAPI RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN);
NTSTATUS WINAPI RtlSetTimeZoneInformation(const TIME_ZONE_INFORMATION*); NTSTATUS WINAPI RtlSetTimeZoneInformation(const TIME_ZONE_INFORMATION*);
ULONG WINAPI RtlSizeHeap(HANDLE,ULONG,PVOID); ULONG WINAPI RtlSizeHeap(HANDLE,ULONG,PVOID);
......
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