Added RtlNtStatusToDosErrorNoTeb, RtlGet/Set/RestoreLastWin32Error,
authorJon Griffiths <jon_p_griffiths@yahoo.com>
Fri, 12 Dec 2003 05:56:44 +0000 (05:56 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 12 Dec 2003 05:56:44 +0000 (05:56 +0000)
RtlGUIDFromString, RtlStringFromGUID.

dlls/ntdll/error.c
dlls/ntdll/ntdll.spec
dlls/ntdll/rtlstr.c
dlls/ntdll/tests/rtlstr.c
include/winternl.h

index c764d494bffd76e423413a26d79ae77f1ba38eda..919863efcf7bc4f2bda21f27114bb5315e331323 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 #include <stdarg.h>
 
 #include "ntstatus.h"
@@ -28,6 +29,7 @@
 #include "winreg.h"
 #include "winternl.h"
 #include "winerror.h"
+#include "thread.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
@@ -42,7 +44,7 @@ struct error_table
 static const struct error_table error_table[20];
 
 /**************************************************************************
- *           RtlNtStatusToDosError (NTDLL.@)
+ *           RtlNtStatusToDosErrorNoTeb (NTDLL.@)
  *
  * Convert an NTSTATUS code to a Win32 error code.
  *
@@ -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
  *  mapping defined.
  */
-ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status )
+ULONG WINAPI RtlNtStatusToDosErrorNoTeb( NTSTATUS status )
 {
     const struct error_table *table = error_table;
 
@@ -81,6 +83,53 @@ ULONG WINAPI RtlNtStatusToDosError( NTSTATUS status )
     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 */
 
index b389fc4ff8133a4420ae1b0ed4aa55e2c7b76571..5d79b40fc5a40cbb5b26fe30e06fa863d39e4df3 100644 (file)
 @ stub RtlGetElementGenericTable
 @ stdcall RtlGetFullPathName_U(wstr long ptr ptr)
 @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr)
+@ stdcall RtlGetLastWin32Error()
 @ stdcall RtlGetLongestNtPathLength()
 @ stub RtlGetNtGlobalFlags
 @ stdcall RtlGetNtProductType(ptr)
 @ stdcall RtlGetProcessHeaps(long ptr)
 @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)
 @ stub RtlGetUserInfoHeap
+@ stdcall RtlGUIDFromString(ptr ptr)
 @ stdcall RtlIdentifierAuthoritySid(ptr)
 @ stdcall RtlImageDirectoryEntryToData(long long long ptr)
 @ stdcall RtlImageNtHeader(long)
 @ stdcall RtlNewSecurityObject(long long long long long long)
 @ stdcall RtlNormalizeProcessParams(ptr)
 @ stdcall RtlNtStatusToDosError(long)
+@ stdcall RtlNtStatusToDosErrorNoTeb(long)
 @ stub RtlNumberGenericTableElements
 @ stdcall RtlNumberOfClearBits(ptr)
 @ stdcall RtlNumberOfSetBits(ptr)
 @ stdcall RtlRaiseException(ptr)
 @ stdcall RtlRaiseStatus(long)
 @ stdcall RtlRandom(ptr)
+@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error
 @ stdcall RtlReAllocateHeap(long long ptr long)
 @ stub RtlRealPredecessor
 @ stub RtlRealSuccessor
 @ stdcall RtlSetEnvironmentVariable(ptr ptr ptr)
 @ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
 @ stub RtlSetInformationAcl
+@ stdcall RtlSetLastWin32Error(long)
 @ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long)
 @ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long)
 @ stub RtlSetSecurityObject
 @ stdcall RtlSizeHeap(long long ptr)
 @ stub RtlSplay
 @ stub RtlStartRXact
-@ stub RtlStringFromGUID
+@ stdcall RtlStringFromGUID(ptr ptr)
 @ stdcall RtlSubAuthorityCountSid(ptr)
 @ stdcall RtlSubAuthoritySid(ptr long)
 @ stub RtlSubtreePredecessor
index 8017be75fa7d4ce569ba5f88d1a38f5abca3dfd8..2dea83f0fcaf80dc9b6aeba520ae820b32e74246 100644 (file)
@@ -1799,3 +1799,135 @@ NTSTATUS WINAPI RtlIntegerToUnicodeString(
     } /* if */
     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;
+}
index cd2ec9c6a7ad41716c362e4198d55ca17b335f50..d7795a4fc6e8bb0b06043f334bfcf76588da1212 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#define INITGUID
 #include "ntstatus.h"
 #include "windef.h"
 #include "winbase.h"
@@ -33,6 +34,7 @@
 #include "winnls.h"
 #include "winreg.h"
 #include "winternl.h"
+#include "guiddef.h"
 
 /* Function ptrs for ntdll calls */
 static HMODULE hntdll = 0;
@@ -64,6 +66,8 @@ static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICOD
 static CHAR     (WINAPI *pRtlUpperChar)(CHAR);
 static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const 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 *pRtlFreeUnicodeString)(PUNICODE_STRING);*/
@@ -130,6 +134,8 @@ static void InitFunctionPtrs(void)
        pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar");
        pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString");
        pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString");
+       pRtlGUIDFromString = (void *)GetProcAddress(hntdll, "RtlGUIDFromString");
+       pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID");
     } /* if */
 }
 
@@ -1669,6 +1675,38 @@ static void test_RtlIntegerToChar(void)
        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)
 {
@@ -1690,16 +1728,17 @@ START_TEST(rtlstr)
        test_RtlAppendUnicodeStringToString();
     } /* if */
 
-    if (pRtlInitUnicodeStringEx) {
-       test_RtlInitUnicodeStringEx();
-    } /* if */
-    if (pRtlDuplicateUnicodeString) {
+    if (pRtlInitUnicodeStringEx)
+        test_RtlInitUnicodeStringEx();
+    if (pRtlDuplicateUnicodeString)
         test_RtlDuplicateUnicodeString();
-    } /* if */
-    if (pRtlFindCharInUnicodeString) {
+    if (pRtlFindCharInUnicodeString)
         test_RtlFindCharInUnicodeString();
-    } /* if */
-       /*
+    if (pRtlGUIDFromString)
+        test_RtlGUIDFromString();
+    if (pRtlStringFromGUID)
+        test_RtlStringFromGUID();
+        /*
         * test_RtlUpcaseUnicodeChar();
         * test_RtlUpcaseUnicodeString();
         * test_RtlDowncaseUnicodeString();
index 64560274bd2512c25703b74d193f6b4087167011..adaa823842d88aefa94d0e77fe4ffdd722becd20 100644 (file)
@@ -1239,7 +1239,7 @@ PVOID     WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,ULONG);
 void      WINAPI RtlReleasePebLock(void);
 void      WINAPI RtlReleaseResource(LPRTL_RWLOCK);
 ULONG     WINAPI RtlRemoveVectoredExceptionHandler(PVOID);
-DWORD     WINAPI RtlRestoreLastWin32Error(DWORD);
+void      WINAPI RtlRestoreLastWin32Error(DWORD);
 
 void      WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *);
 void      WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *);
@@ -1253,7 +1253,7 @@ NTSTATUS  WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,
 NTSTATUS  WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING);
 NTSTATUS  WINAPI RtlSetOwnerSecurityDescriptor(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 RtlSetTimeZoneInformation(const TIME_ZONE_INFORMATION*);
 ULONG     WINAPI RtlSizeHeap(HANDLE,ULONG,PVOID);