ntdll misc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



License: X11

ChangeLog:

  Jon Griffiths <jon_p_griffiths@xxxxxxxxx>

  +dlls/ntdll/ntdll.spec dlls/ntdll/error.c dlls/ntdll/rtlstr.c
    Add RtlNtStatusToDosErrorNoTeb,RtlGet/Set/RestorLastWin32Error,
    RtlGUIDFromString,RtlStringFromGUID

   +dlls/ntdll/tests/rtlstr.c
     Test Rtl guid<->string conversions


__________________________________
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/
diff -ur wine/dlls/ntdll/error.c wine-test/dlls/ntdll/error.c
--- wine/dlls/ntdll/error.c	2003-09-24 20:21:28.000000000 +0000
+++ wine-test/dlls/ntdll/error.c	2003-12-11 19:23:53.000000000 +0000
@@ -20,6 +20,7 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 #include <stdarg.h>
 
 #include "ntstatus.h"
@@ -42,7 +43,7 @@
 static const struct error_table error_table[20];
 
 /**************************************************************************
- *           RtlNtStatusToDosError (NTDLL.@)
+ *           RtlNtStatusToDosErrorNoTeb (NTDLL.@)
  *
  * Convert an NTSTATUS code to a Win32 error code.
  *
@@ -53,7 +54,7 @@
  *  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 +82,70 @@
     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().
+ */
+#ifdef __i386__
+__ASM_GLOBAL_FUNC( RtlGetLastWin32Error, ".byte 0x64\n\tmovl 0x34,%eax\n\tret" );
+#else
+DWORD WINAPI RtlGetLastWin32Error(void)
+{
+    return NtCurrentTeb()->LastErrorValue;
+}
+#endif
+
+/***********************************************************************
+ *      RtlSetLastWin32Error (NTDLL.@)
+ *      RtlRestoreLastWin32Error (NTDLL.@)
+ *
+ * Set the per-thread error value.
+ *
+ * PARAMS
+ *  err [I] The new error value to set
+ *
+ * RETURNS
+ *  The previous error value of the thread.
+ */
+#ifdef __i386__
+__ASM_GLOBAL_FUNC( RtlSetLastWin32Error,
+                   ".byte 0x64\n\tmovl 0x34,%eax\n\t"
+                   "movl 4(%esp),%ecx\n\t"
+                   ".byte 0x64\n\tmovl %ecx,0x34\n\t"
+                   "ret $4" );
+#else
+DWORD WINAPI RtlSetLastWin32Error( DWORD err )
+{
+    DWORD previous = NtCurrentTeb()->LastErrorValue;
+    NtCurrentTeb()->LastErrorValue = err;
+    return previous;
+}
+#endif
 
 /* conversion tables */
 
diff -ur wine/dlls/ntdll/ntdll.spec wine-test/dlls/ntdll/ntdll.spec
--- wine/dlls/ntdll/ntdll.spec	2003-12-07 19:33:00.000000000 +0000
+++ wine-test/dlls/ntdll/ntdll.spec	2003-12-11 19:23:53.000000000 +0000
@@ -416,6 +416,7 @@
 @ stub RtlGetElementGenericTable
 @ stdcall RtlGetFullPathName_U(wstr long ptr ptr)
 @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr)
+@ stdcall RtlGetLastWin32Error()
 @ stdcall RtlGetLongestNtPathLength()
 @ stub RtlGetNtGlobalFlags
 @ stdcall RtlGetNtProductType(ptr)
@@ -423,6 +424,7 @@
 @ 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)
@@ -476,6 +478,7 @@
 @ 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)
@@ -500,6 +503,7 @@
 @ stdcall RtlRaiseException(ptr)
 @ stdcall RtlRaiseStatus(long)
 @ stdcall RtlRandom(ptr)
+@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error
 @ stdcall RtlReAllocateHeap(long long ptr long)
 @ stub RtlRealPredecessor
 @ stub RtlRealSuccessor
@@ -521,6 +525,7 @@
 @ 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
@@ -530,7 +535,7 @@
 @ stdcall RtlSizeHeap(long long ptr)
 @ stub RtlSplay
 @ stub RtlStartRXact
-@ stub RtlStringFromGUID
+@ stdcall RtlStringFromGUID(ptr ptr)
 @ stdcall RtlSubAuthorityCountSid(ptr)
 @ stdcall RtlSubAuthoritySid(ptr long)
 @ stub RtlSubtreePredecessor
diff -ur wine/dlls/ntdll/rtlstr.c wine-test/dlls/ntdll/rtlstr.c
--- wine/dlls/ntdll/rtlstr.c	2003-12-07 19:33:00.000000000 +0000
+++ wine-test/dlls/ntdll/rtlstr.c	2003-12-11 19:23:53.000000000 +0000
@@ -1799,3 +1799,135 @@
     } /* 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;
+}
diff -ur wine/dlls/ntdll/tests/rtlstr.c wine-test/dlls/ntdll/tests/rtlstr.c
--- wine/dlls/ntdll/tests/rtlstr.c	2003-10-07 13:52:45.000000000 +0000
+++ wine-test/dlls/ntdll/tests/rtlstr.c	2003-12-11 19:23:53.000000000 +0000
@@ -25,14 +25,17 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#define INITGUID
 #include "ntstatus.h"
 #include "windef.h"
 #include "winbase.h"
 #include "wine/test.h"
+#include "wine/unicode.h"
 #include "winnt.h"
 #include "winnls.h"
 #include "winreg.h"
 #include "winternl.h"
+#include "guiddef.h"
 
 /* Function ptrs for ntdll calls */
 static HMODULE hntdll = 0;
@@ -64,6 +67,8 @@
 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 +135,8 @@
 	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 +1676,38 @@
        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 && !strcmpW(str.Buffer, szGuid), "Endianess broken\n");
+}
 
 START_TEST(rtlstr)
 {
@@ -1690,16 +1729,17 @@
 	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 of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux